How to process a JSON message with special chars

I have a little battery-powered 6 button scene controller (Zigbee), hooked up to Sonoff Zigbee hub with Tasmota installed.

When I press the first button, and pipe the message through JSON node, I get this:

The unique thing about this button is: 0006!00: ""

When I press other buttons, they give the following:
Button 2: 0006!01: ""
Button 3: 0008!02: "015507000000"
Button 4: 0008!02: "005507000000"
Button 5: 0300!4C: "0145000700000000000000"
Button 6: 0300!4C: "0345000700000000000000"

I don't care about the meaning of these buttons, I just want to be able to do different things in a function node.

This doesn't seem to work, can anyone help me?

(Also pls suggest a better way, the nested IFs are a bit lame!)

if (msg.topic == "tasmotas/zigbee-hub/B67D/tele/SENSOR") {
    if (typeof msg.payload.ZbReceived != undefined) {
        if (typeof msg.payload.ZbReceived.SceneController1 != undefined) {
            if (typeof msg.payload.ZbReceived.SceneController1["0006!00"] != undefined) {
                msg.payload = 0
            }
            if (typeof msg.payload.ZbReceived.SceneController1["0006!01"] != undefined) {
                msg.payload = 1
            }
            if (typeof msg.payload.ZbReceived.SceneController1["0006!03"] != undefined) {
                if (msg.payload.ZbReceived.SceneController1["0008!02"] == "015507000000") {
                    msg.payload = 2
                }
                if (msg.payload.ZbReceived.SceneController1["0008!02"] == "005507000000") {
                    msg.payload = 3
                }
            }
            if (typeof msg.payload.ZbReceived.SceneController1["0300!4C"] != undefined) {
                if (msg.payload.ZbReceived.SceneController1["0300!4C"] == "0145000700000000000000") {
                    msg.payload = 4
                }
                if (msg.payload.ZbReceived.SceneController1["0300!4C"] == "0345000700000000000000") {
                    msg.payload = 5
                }
            }
            msg.topic = "home/light/gf_pergola/scene"
            return msg
        }
    }
}


You can access the value of these properties using square bracket notation.

Also, there is a built-in helper...

There’s a great page in the docs that will explain how to use the debug panel to find the right path to any data item.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

BX00Cy7yHi

https://nodered.org/docs/user-guide/messages

Hi Steve - thanks. I started writing this forum post before I remembered about square bracket notation, then continued as if the problem was something else. Apologies - I should rename the topic as it's misleading now...

I've updated my first post with the function code I'm using, but it's not feeding anything back. Any idea why that might be?

Do you actually need to test for the [0xxxx]?
I have zigbee switches with a sonoff bridge (ie similar output) and test the values the devices send.

I think so, the value is empty for certain button presses, i.e. msg.payload.xyz.0006!00 = ""

The object key seems to determine which button is being pressed, not the value.
Not sure why, I think this Aqara button pad is designed for dimming and other things... I just want to treat it like 6 separate buttons.

Remove all the excessive testing and stop using typeof X != undefined.

if (x != null) { is enough.

Also, if the topic matches, then surely that is enough of a test to determine its a message of interest.

Also, use node.warn("some message") in your code to help you understand what parts are being hit

Thanks. (And for your updated bit about using node.warn) - very useful.

I just want to treat it like 6 separate buttons.

Each value is a "separate" button.

There is no value for some buttons! That's the problem... the key value pair is like this:
{"0006!00": ""}, hence needing to test for the key, not the value

You could use a lookup object.
e.g.

if(msg.payload.ZbReceived != null){
    const lookup = {
        "0006!00": 0,
        "0006!01": 1,
        "0008!02015507000000" : 2,
        "0008!02005507000000": 3,
        "0300!4C0145000700000000000000": 4,
        "0300!4C0345000700000000000000": 5
    }

    let search = Object.entries(msg.payload.ZbReceived.sceneController1);
    search = search.find(e => e[0].includes("!")).join("");
    msg.payload = lookup[search];
}
if(msg.payload === undefined){
    msg = null;
    node.warn("No match!");
}
return msg;

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.