Proactively getting status from MQTT devices

  • Platform information:
    • Raspberry Pi 3B+ running OpenHabian current version

I have some Sonoff devices configured with Tasmato to both issue ON/OFF commands and consume status messages correctly. Here’s a line from my Items file.

Switch T1Sonoff0103 "Test Lamp 3" <light> (LR,gLight) ["Lighting"] { mqtt=">[mosquitto:cmnd/GSONOFF01/POWER3:command:*:default], <[mosquitto:stat/GSONOFF01/POWER3:state:default]"}

This all works fine except when Openhab goes out of sync with the devices (reboot etc) of the device changes state without sending a power state change message. The next command to change the state does sort the problem but my wife gets a little freaked when I’m away and I toggle the lights via OH App to be sure they’re off!.

The question - Can I parse the regular telemetry MQTT messages like these

tele/GSONOFF01/STATE = {"Time":"2018-12-10T09:49:01","Uptime":"0T11:50:20","Vcc":3.438,"POWER1":"ON","POWER2":"OFF","POWER3":"ON","POWER4":"ON","Wifi":{"AP":1,"SSId":"9E63","RSSI":64,"APMac":"90:EF:68:48:FF:DF"}}
tele/GSONOFF01/SENSOR = {"Time":"2018-12-10T09:49:01","Switch1":"ON","Switch2":"ON"}

or can I proactively poll for the “standard” status messages like these

stat/GSONOFF01/POWER1 = ON

No, not without a rule and another proxy item or the MQTT action

But you can use the first option:
You will nee to install the JSONPATH transformation service in the paperUI

Switch T1Sonoff0103 "Test Lamp 3" <light> (LR,gLight) ["Lighting"] { mqtt=">[mosquitto:cmnd/GSONOFF01/POWER3:command:*:default], <[mosquitto:stat/GSONOFF01/POWER3:state:default], <[mosquitto:tele/GSONOFF01/STATE:state:JSONPATH($.POWER3)]" }

Vincent I got that working except I didn’t 100% describe what I needed :slight_smile:
I actually need the opposite of the result being returned. So if POWER3 is “ON” I actually need to translate this as “OFF”. You can see from this more complete example that I’m flipping the “cmnd” and “stat” MQTT messages.

Switch GSonoff0103 "Rear Lamp" <light> (LR,gLight) ["Lighting"] { mqtt=">[mosquitto:cmnd/GSONOFF01/POWER3:command:*:MAP(FLIP.map)], <[mosquitto:stat/GSONOFF01/POWER3:state:MAP(FLIP.map)]"}

FLIP.map just has in it
ON=OFF
OFF=ON

I spent this evening trying to see if this was possible with JSONPATH and have concluded it is not. I think that leaves me with JavaScript I’ve tried to craft a script and come up with this. I’ve tested it using JavaScript Tester online and it seems to do what I need:

function x (json,i) {

	var xx = "x";

	xx = json[i];
	if(xx == "OFF"){
		xx ="ON"
	} else if (xx == "ON") {
        xx = "OFF"
	}
	return xx; 
}
var json = {"Time":"2018-12-10T23:29:02","Uptime":"1T01:30:21","Vcc":3.439,"POWER1":"ON","POWER2":"ON","POWER3":"ON","POWER4":"ON","Wifi":{"AP":1,"SSId":"9E63","RSSI":58,"APMac":"90:EF:68:48:FF:DF"}}
x(json,"POWER3")

BTW - That’s my first JS ever. Awesome!

Questions
Am I on the right track?
Can I use JS transform with 2 parameters or will I need to do a script in transformation directory for each of POWER1,2,3 etc.?
How would I call this from the items file?

Correct

Almost

No

indeed

{"Time":"2018-12-10T23:29:02","Uptime":"1T01:30:21","Vcc":3.439,"POWER1":"ON","POWER2":"ON","POWER3":"ON","POWER4":"ON","Wifi":{"AP":1,"SSId":"9E63","RSSI":58,"APMac":"90:EF:68:48:FF:DF"}}

power1.js

(function(powerJson) {
    var data = JSON.parse(powerJson);
    var power = data.POWER1;
    if (power == 'ON') {
        power = 'OFF';
    } else {
        power = 'ON';
    }
    return power;
})(input)

Switch GSonoff0103 "Rear Lamp" <light> (LR,gLight) ["Lighting"] { mqtt=">[mosquitto:cmnd/GSONOFF01/POWER3:command:*:MAP(FLIP.map)], <[mosquitto:stat/GSONOFF01/POWER3:state:JS(power1.js)]"}

Guys, why not use the MAP transformation here. JS transformations are quite expensive to do for the system.

On a json with 4 different switches and variable time parameters?
How?

I see. So the regex transformation could be helpful then :smiley:

Apologies for the no response to this. I’ve been travelling for work since Monday. Vincent Thanks for all this help. I’m going to try it this week once I clear the job the “Boss” has stored up for me:)

Vincent,
Finally got to test. That worked. A just couple of tweaks needed. The *.items file need to look like this:

Switch GSonoff0103 “Rear Lamp” <light> (LR,gLight) [“Lighting”] { mqtt=">[mosquitto:cmnd/GSONOFF01/POWER1:command:*:MAP(FLIP.map)], <[mosquitto:tele/GSONOFF01/STATE:state:JS(power1.js)]"}

Thanks again for the “guidance” (aka doing my homework for me) :slight_smile:

You should use stat/sonoffname/POWER1 without transformation as your state topic

Hii
You can also use https://onlinexmltools.org/ for online xml converter like XML to JSON,YAML,CSV,BASE64,TSV,PlainText
XML to Minfiy XML to Beautify.