Some basic DMX questions

I just spun up the QLC+ RPi image on a Raspberry Pi 3. So far, so good, though I haven’t had a chance to really stress it yet.

I’m running the full version of QLC+ on my desktop Mac, and save the config files on this computer using the full version. This works great as I keep the Pi fully headless.

When I want to open this full version, I go into the config manager of the QLC+ Pi (at qlc.local:9999 on my local network) and open a blank config to keep the two instances from interfering with each other. Then, I open the config file using the full version and make my tweaks. When I’m done, I then reload the config file and go into the system tab to apply it as the startup default.

1 Like

Thanks Dome.
I switched the card from a 16GB Sandisk Ultra to 64 GB Sandisk High Endurance and put the same image on it, then ran df -h and realised it was only allocating 1.7G to /dev/root.

My windows brain struggle with allocating more disk space until I found FAQ #3 in Massimo’s guide, which gives instructions to allocate the rest of the disk space:
sudo raspi-config
7 Advanced Options
Expand Filesystem

Now I have 59G and node is installed and running.

2 Likes

I’m glad you figured that part out. I totally spaced about the need to resize the partition and ran into that same issue last night.

1 Like

In case anyone else is trying to figure out the ID’s of your widgets and has the same problem I did where the Test_Web_API did not work ( QLC+ Web API Test ), the widget IDs can just as easily be found in the QLC+ .qwx file (just save it somewhere and open in a text editor).

Here’s an example:

<Slider Caption=“Slider 4” ID=“4” WidgetStyle=“Slider” InvertedAppearance=“false”>

4 is the widget ID.

2 Likes

That’s a much easier way to find these values. Thanks for posting!

Just to share a method, we’re installing this soon

Smart-Show lighting NetPixel-Quad & 4 SPi line balancers, with QLCplus running in an X session on an ODroid.

1 Like

Not fair Stuart. Now I have to have one too.

I have some Arduino boards that detect buttons and then publish to a MQTT “buttons” topic to announce that button number x has been pressed (one Arduino mega can detect 30 or 40 different lights switches via CAT6). It’s cheap and good for DIY but maybe not commercially viable.

An OpenHAB MQTT thing subscribes to the “buttons” topic and a rule detects the button presses, decides which scene to turn on or off in QLC+ and then publishes a widget ID and brightness to a “qlc” topic (“12|255” to turn widget 12 on or “12|0” to turn it off). This tells QLC+ (via the websockets API) to turn on/off the widget that controls the scene (or what ever else you want to control).

Node red listens to the qlc topic and passes the string (“12|255”) directly to QLC+ via a websocket as described previously, except there is no switches or triggers or intelligence of any kind in node red - it simply forwards the widget ID and brightness to QLC+ and QLC+ applies it.

The most surprising thing is that this seems to be reliable so far.

What’s the downside of this approach? Is it nice and simple and reliable? Or have I missed something important that’s going to bite me somehow?

This is the node red stuff:

And this is the OpenHAB rule:

If it works, then it works.

If you primarily use MQTT, you could do everything within Node-RED if you wanted, which leaves openHAB2 free to be the gateway to other hardware protocols and user interfaces.

I was very reluctant to go anywhere near MQTT, but I have to admit that one of the brokers that runs within Node-RED seems to work very well.

Hi

I’ve just tried the Test_Web_APi thing and it didn’t work for me ether.

So I copied the HTML and hosted it on the static server of openHAB2, but edited the destination WS IP and it’s working :smile:

Which has lead me to create a Node-RED flow to convert a Dashboard Colour picker into 3 WS commands to feed into QLCplus

[
    {
        "id": "32414ca1.373bc4",
        "type": "websocket out",
        "z": "fe6c4c4c.494c7",
        "name": "QLCplus on Odroid C4",
        "server": "",
        "client": "7913f01c.6095a",
        "x": 1280,
        "y": 1060,
        "wires": []
    },
    {
        "id": "86899306.76d3f",
        "type": "function",
        "z": "fe6c4c4c.494c7",
        "name": "",
        "func": "var RED = msg.payload.r;\nvar GREEN = msg.payload.g;\nvar BLUE = msg.payload.b;\nvar ALPHA = msg.payload.a;\n\nvar REDch = 60, GREENch = 61, BLUEch = 62; // The sliders in QLCplus that control the RGB elements\n\n\nvar REDmsg = { payload:REDch + \"|\" + RED };\nvar GREENmsg = { payload:GREENch + \"|\" + GREEN };\nvar BLUEmsg = { payload:BLUEch + \"|\" + BLUE };\n\n\nreturn [ [ REDmsg, GREENmsg, BLUEmsg ]];\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 680,
        "y": 1060,
        "wires": [
            [
                "65b64860.00b0c8",
                "32414ca1.373bc4"
            ]
        ]
    },
    {
        "id": "65b64860.00b0c8",
        "type": "debug",
        "z": "fe6c4c4c.494c7",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "msg",
        "x": 870,
        "y": 1100,
        "wires": []
    },
    {
        "id": "c1b9028d.c76e1",
        "type": "ui_colour_picker",
        "z": "fe6c4c4c.494c7",
        "name": "",
        "label": "QLCplus",
        "group": "adff93ca.07855",
        "format": "rgb",
        "outformat": "object",
        "showSwatch": true,
        "showPicker": false,
        "showValue": false,
        "showHue": false,
        "showAlpha": false,
        "showLightness": true,
        "square": "false",
        "dynOutput": "true",
        "order": 3,
        "width": 0,
        "height": 0,
        "passthru": true,
        "topic": "",
        "x": 430,
        "y": 1060,
        "wires": [
            [
                "86899306.76d3f",
                "c9696228.20064"
            ]
        ]
    },
    {
        "id": "d4a8d33c.2da23",
        "type": "inject",
        "z": "fe6c4c4c.494c7",
        "name": "GREEN",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"r\":0,\"g\":255,\"b\":0,\"a\":1}",
        "payloadType": "json",
        "x": 190,
        "y": 1060,
        "wires": [
            [
                "c1b9028d.c76e1"
            ]
        ]
    },
    {
        "id": "c9696228.20064",
        "type": "debug",
        "z": "fe6c4c4c.494c7",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "msg",
        "x": 470,
        "y": 1120,
        "wires": []
    },
    {
        "id": "f60fa2f2.595ec",
        "type": "inject",
        "z": "fe6c4c4c.494c7",
        "name": "BLUE",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"r\":0,\"g\":0,\"b\":255,\"a\":1}",
        "payloadType": "json",
        "x": 210,
        "y": 1100,
        "wires": [
            [
                "c1b9028d.c76e1"
            ]
        ]
    },
    {
        "id": "4478c90c.b32438",
        "type": "inject",
        "z": "fe6c4c4c.494c7",
        "name": "RED",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"r\":255,\"g\":0,\"b\":0,\"a\":1}",
        "payloadType": "json",
        "x": 210,
        "y": 1020,
        "wires": [
            [
                "c1b9028d.c76e1"
            ]
        ]
    },
    {
        "id": "7913f01c.6095a",
        "type": "websocket-client",
        "z": "",
        "path": "ws://192.168.178.94:9999/qlcplusWS",
        "tls": "",
        "wholemsg": "false"
    },
    {
        "id": "adff93ca.07855",
        "type": "ui_group",
        "z": "",
        "name": "Test",
        "tab": "bd9e1305.3582",
        "order": 3,
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "bd9e1305.3582",
        "type": "ui_tab",
        "z": "",
        "name": "Home",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]

It shouldn’t be too difficult to convert an openHAB2 colour picker value into these commands

That looks interesting.

I thought we should have a list of payloads in this post that can be sent to QLCPlus:

Set widget:
“[Widget ID]|[value]”
This confused me for a while - I thought all we could do was send widget ID and value.

Run a function:
“QLC+API|setFunctionStatus|[function ID]|1”
(0 for off)
Runs any QLC function without using a widget/slider

Set channel in Simple Desk:
“CH|[DMX address]|[value]”

Control cue list:
“STEP|[Cue List ID]|[Operation]|[Step - optional]”

Change frame page:
"[Frame ID]|‘NEXT_PG’ or ‘PREV_PG’

You can also get stuff:
QLC+API|getChannelsValues|[Universe index]|[DMX start address]|[Channels count]
likewise for any of the other functions listed on https://www.qlcplus.org/Test_Web_API.html - I haven’t listed the other get functions

Any of these commands can be sent from an openHAB rule to QLCPlus using my simple example above.

For my home automation, I’m trying to keep all logic in openHAB so that NodeRed just passes the commands to QLCPlus. I guess this will get more interesting when I need feedback from QLCPlus to openHAB.

1 Like