Using Node.js on a Raspberry Pi to listen to MIDI messages from an Avid S6L console to trigger HTTP requests or run scripts

Back in the summer, I posted about a project I had recently finished, which involved sending HTTP requests to a server that would then relay a MIDI output message based on the request that was sent.

We’ve been using that software (dubbed midi-relay) since then to be able to control our Chroma-Q Vista lighting desks remotely across vlans by using stream decks running Companion. It works pretty well, especially since the midi-relay software is configured to run directly on the lighting consoles upon startup. We have even set up a few crontab entries to send CURL commands to the light desks to turn them on at certain times when we don’t want to be on-site just to press a button.

In anticipation of completing my most recent project, “LiveCaption“, which takes audio and transcribes it to text in real-time, I started working on midi-relay 2.0: listening to MIDI input and using that to trigger a response or action.

I figured it was time this thing had a logo.

In both auditoriums at my church, we have Avid S6L audio consoles. These consoles can do a lot, and like most consoles, they have GPIO pinouts to allow you to trigger things remotely, whether as an action originating from the sound console, or externally that then triggers something on the console like recalling a snapshot, muting an input, etc.

Screen Shot 2019-11-19 at 4.23.54 PM
Stock photo of the console I found on the Internet.
These are (some of) the I/O pins on the S6L console. It has GPIO and MIDI ports. We use the footswitch input for setting tap tempo.

I started looking at the possibility of using the GPO pins on the console to trigger an external action like sending an HTTP request to Ross Dashboard, Companion, etc. However, there are only 8 GPO pins on this audio board, so I knew that could be a limiting factor down the road in terms of the number of possible triggers I could have.

The S6L also has MIDI In and Out, and through the Events section of the console, it can be used as either a trigger (MIDI In) or an action (MIDI Out) on just about anything.

Photo Nov 19, 1 28 22 PM
The Events page on an Avid S6L console. All kinds of things can be used as triggers and actions here! In this particular event, I’ve created a trigger that when the Snapshot “Band” is loaded, it sends MIDI Out on Channel 1 with Note 22 (A#0) at Velocity 100. MIDI-Relay then listens for that MIDI message and sends an HTTP POST request to the LiveCaption server to stop listening for caption audio.

We already have a snapshot that we load when we go to the sermon/message that mutes things, sets up aux sends, etc. and I wanted to be able to use that snapshot event to automatically start the captioning service via the REST API I had already built into LiveCaption.

In the previous version, midi-relay could only send Note On/Off messages and the custom MSC (MIDI Show Control) message type I had written just for controlling our Vista lighting consoles. With version 2.0, midi-relay can now send MIDI out of all of the channel voice MIDI message types:

  • Note On / Note Off
  • Polyphonic Aftertouch
  • Control Change
  • Program Change
  • Pitch Bend
  • Channel Pressure / Aftertouch

It can also send out:

  • MSC (MIDI Show Control), which is actually a type of SysEx message
  • Raw SysEx messages, formatted in either decimal or hexadecimal

And, midi-relay can now listen for all of those channel voice and SysEx messages and use it to trigger one of the following:

  • HTTP GET/POST (with JSON data if needed)
  • AppleScript (if running midi-relay on MacOS)
  • Shell Script (for all OS’s)

There are a few software and hardware products out there that can do similar things, like the BomeBox, but I wanted to build something less-expensive and something that could run on a Raspberry Pi, which is exactly how we’ve deployed midi-relay in this case.

Photo Nov 19, 1 27 32 PM
Here is the Raspberry Pi running midi-relay, connected to the MIDI ports on the S6L via a USB to MIDI interface. It tucks away nicely at the back of the desk.

Now we can easily and automatically trigger the caption service to start and stop listening just by running the snapshots on the audio console that we were already doing during that transition in the service. This makes it easier for our volunteers and they don’t really have to learn a new thing.

Here’s a video of it in action:



If you’d like to check out version 2.0 of midi-relay, you can download both the source code and binaries from GitHub:

The documentation is pretty thorough if you want to use the API to send relay messages or set up new triggers, but you can also use the new Settings page running on the server to do all that and more.

Screen Shot 2019-11-19 at 4.21.28 PM
From the Settings page, you can view available MIDI ports, add/delete Triggers, view detected midi-relay hosts running on the network, and send Relay messages to other hosts.

And if you’re a Companion user for your stream deck, I updated the module for Companion to support the new channel voice MIDI relay messages as well! You’ll need to download an early alpha release of Companion 2.0 to be able try that out. Search for “Tech Ministry MIDI Relay” in Companion.

Here’s a list of the Raspberry Pi parts I used, off Amazon:

Photo Nov 19, 3 52 56 PM

I hope this is helpful to you and your projects! If you need any help implementing along the way, or have ideas for improvement, don’t hesitate to reach out!


  1. I am using Tally Arbiter on a Raspberry Pi 4 together with 3 x M5StickC’s for live streaming our church meetings. I love it – thanks so much for producing this! I am building a roadcase and want to make the PI startup and run headless. Can you give me any advice on how I can automate the three steps I currently have to do each time at startup – 1) login 2) change directory 3) start node index.js
    Sorry I am not very code savvy! I would be much obliged 🙂


    1. Hey John! I’m so glad my software is valuable to you. I wasn’t sure if you needed midi-relay instructions or Tally Arbiter instructions since you commented on a midi relay post. But both of them can work with pm2 on a raspberry pi and I have instructions posted in each repository on Github that walk you through that process. Try that and if you get stuck, reach out to me via the contact form and we can get it figured out!


  2. Hi. I’m trying to set up MIDI control for a Roland V-1HD through MIDI relay, I can get the Basic CC/PC commands working, but i’m having trouble with the SysEx messages.
    There is a short tutorial that i have linked below that shows the examples of the CC/PC and SysEx commands, though the provided SysEx commands do not work for me. Do you have any ideas. I’m fairly sure something is wrong with my formatting, but I cant find any examples of a SysEx message


      1. Hi, I managed to get it to work with decimal. Hex was disagreeing.
        I’m now starting to work on a derivative of the midi relay companion app that will let me have full control over the V-1HD with state feedback thanks to this. Though even without the state feedback. midi relay has helped with simplifying the process of streaming our church services. So thanks for your work.

        Liked by 1 person

  3. Hi, I managed to get it to work with decimal. Hex was disagreeing.
    I’m now starting to work on a derivative of the midi relay companion app that will let me have full control over the V-1HD with state feedback thanks to this. Though even without the state feedback. midi relay has helped with simplifying the process of streaming our church services. So thanks for your work.


  4. hi joseph

    just found your midi relay , it is so cool ; i need to send sysex message to control my boss gt1 multi effect with my footpedal board roland fcb1010
    question is if i try to send sysex like F0 41 00 00 00 00 30 12 60 00 01 40 01 5E F7 your monitor replied sysex-invalid
    so i try F0,41,00…… but same

    could you please help me to convert message in right format , thank you


  5. Hi Joseph

    Very nice module, thank you.

    On Windows 10 everything is working with our companion setting, our plan is now to install this module on a raspberry pi. We have the companion raspberry image what is based on Raspberry Pi OS Lite, after installing node.js its not possible to start the module.

    root@raspberrypi:/home/pi/midi-relay-2.2.0# node main.js
    throw err;

    Error: Cannot find module ‘request’
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:668:15)
    at Function.Module._load (internal/modules/cjs/loader.js:591:27)
    at Module.require (internal/modules/cjs/loader.js:723:19)
    at require (internal/modules/cjs/helpers.js:14:16)
    at Object. (/home/pi/midi-relay-2.2.0/main.js:6:17)
    at Module._compile (internal/modules/cjs/loader.js:816:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
    at Module.load (internal/modules/cjs/loader.js:685:32)
    at Function.Module._load (internal/modules/cjs/loader.js:620:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:877:12)
    root@raspberrypi:/home/pi/midi-relay-2.2.0# L

    Running as service was also not successful.

    root@raspberrypi:/home/pi/midi-relay-2.2.0# npm install -g pm2
    npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See for details.
    /usr/bin/pm2 -> /usr/lib/node_modules/pm2/bin/pm2
    /usr/bin/pm2-dev -> /usr/lib/node_modules/pm2/bin/pm2-dev
    /usr/bin/pm2-docker -> /usr/lib/node_modules/pm2/bin/pm2-docker
    /usr/bin/pm2-runtime -> /usr/lib/node_modules/pm2/bin/pm2-runtime
    npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.3.2 (node_modules/pm2/node_modules/chokidar/node_modules/fsevents):
    npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {“os”:”darwin”,”arch”:”any”} (current: {“os”:”linux”,”arch”:”arm”})
    npm WARN ws@7.4.6 requires a peer of bufferutil@^4.0.1 but none is installed. You must install peer dependencies yourself.
    npm WARN ws@7.4.6 requires a peer of utf-8-validate@^5.0.2 but none is installed. You must install peer dependencies yourself.

    + pm2@5.1.0
    updated 1 package in 34.312s

    Do we need another Raspberry OS or can we download an image?

    Thanks for your help


  6. Hello Joseph,
    I want to cobtrol some things of my smart Home through http-requests over bitfocus companion with a spare behringer X-Touch Mini Controller with your great Tool ‘midi-relay’ on a raspberry pi zero (thanks for that great piece of Software, it’s just what i was looking for!) . The Software runs, i can See the midi controller with /midi_inputs but the Web gui doesnt Show anything but empty fields and the Buttons have no functions at all. Could you figure out what May be wrong here?
    Thank you in advance for your help!


      1. Hello Joseph,
        Thank you for your Quick answer. I run it as a service with pm2 from the binaries, but it doesn’t run neither. Refreshing the midi Devices doesn’t show anything.
        Any hint?
        Best regards,


    1. Hello Joseph,
      When trying to open a port using the API directly I get an error

      SyntaxError: Unexpected token m in JSON at position 11 at JSON.parse () at parse (/home/pi/midi-relay/linux-armv7/midi-relay-2.0/node_modules/body-parser/lib/types/json.js:89:19) at /home/pi/midi-relay/linux-armv7/midi-relay-2.0/node_modules/body-parser/lib/read.js:128:18 at AsyncResource.runInAsyncScope (async_hooks.js:190:9) at invokeCallback (/home/pi/midi-relay/linux-armv7/midi-relay-2.0/node_modules/raw-body/index.js:231:16) at done (/home/pi/midi-relay/linux-armv7/midi-relay-2.0/node_modules/raw-body/index.js:220:7) at IncomingMessage.onEnd (/home/pi/midi-relay/linux-armv7/midi-relay-2.0/node_modules/raw-body/index.js:280:7) at IncomingMessage.emit (events.js:314:20) at endReadableNT (_stream_readable.js:1241:12) at processTicksAndRejections (internal/process/task_queues.js:84:21)

      Seems there’s a general problem..

      Best regards, Stefan


  7. Hi Joseph,
    that seems to be the problem. API works now, I had to change the way I set the quotes. That was my mistake. Sorry.
    The web-gui isnt working at all (on my Rapsberry Pi Zero W), but thats not that important now, because I can change the triggers over the json-file directly now.
    Thank you for your help!

    Best regards, Stefan


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s