Transformations of MQTT messages

Hi, from a door contact, I get MQTT messages of the form
{"contact":true,"linkquality":55,"battery":100,"voltage":3125}

I want to save the contact status and the battery status. For the contact, I would have to extract the contact field and translate the boolean value to OpenClosed.

  1. Is this possible inside the item definition, or do I have to define a raw string item and parse it in a rule?
  2. If it is possible in an item definition, is there any issue receiving the same mqtt message in multiple items?

Thanks in advance!

Yes it is. You can do both

Not a problem
You just need to install the JSONPATH transformation service in the PaperUI
For example:

String Contact { mqtt="<[broker:topic:state:*:JSONPATH($.contact)]" }
Number Voltage { mqtt="<[broker:topic:state:*:JSONPATH($.voltage)]" }
2 Likes

Withe trhe new mqtt Binding it is possible as well. One benefit i see is that the new binding is able to establish a contact channel.

by the way, can someone check if you can apply transformations directly on the channel links of MQTTv2? (I haven’t installed it yet)

Thanks, but this does only half of what I wanted. There is a dedicated item type for theses switches, Contact.
For that, I have to translate true/false to on/off. How do I combine that with JSONPATH?

discusses combining transformations, but the solution would only have an advantage to writing a rule if I could manage to not hardcode the JSON fieldname …

I don’t see how you can avoid hardcoding this…

see another example of js transformation here:

Your problem here is that the json.contact returns true or false
openHAB needs OPEN or CLOSED for a contact item.
Unfortunately, you can’t “nest” transformation services. So you will need a transformation that does it all.

Install the javascript transform
Create a file called “doorcontact.js” in the tranform folder with the folowing contents:

(function(jsonString) {
var data = JSON.parse(jsonString);
var doorState = data.contact;
if (doorState.contact) {
    doorState = 'OPEN';
} else {
    doorState = 'CLOSED';
return doorState;
})(input)

Invert the OPEN and CLOSED in case true is CLOSED. I don’t know…

Your item is then:

String Contact { mqtt="<[broker:topic:state:*:JS(doorcontact.js)]" }

Thanks, I have by now implemented almost exactly that. Where does the “title” part come from? For me, it seems to work without it.

Soory, that’s a remnant from old code
I have corrected above

Hi,
Maybe late, but I’m struggling with a similar problem.
I have a Tasmota-device which I configured to send a JSON (?) string when activated : {“contact”:“1”} or {“contact”:“0”}. I want to modify that 1 or 0 to Closed or Open.
When I configure the item as a string :

String myWemos02 "Wemos02 [%s]" {mqtt="<[mosq:stat/wemos01/SWITCH1:state:default]"}

I can see the contact changing in HabPanel, the whole JSONPATH-string.
With JSONPATH I can send the state (0 or 1) to the item in HabPanel. I have to use a modified version of your config :

String myWemos02 "Wemos02 [%s]" {mqtt="<[mosq:stat/wemos01 SWITCH1:state:JSONPATH($.contact)]"}

See the missing *:. If I add those I get an error.
Now the third step : use javascript to do the modification :

String myWemos02 "Wemos02 [%s]" {mqtt="<[mosq:stat/wemos01/SWITCH1:state:JS(switchcontact.js)]"}

switchcontact.js is this :

(function(jsonString) {
var data = JSON.parse(jsonString);
var contactState = data.contact;

if (contactState == 0) {
    contactState = 'OPEN';
} else {
    contactState = 'CLOSED';
return contactState;
})(input)

I tried this in an online javascript tester and it’s fine. Unfortunately, Openhab2 gives an error :

2019-04-11 19:28:05.463 [WARN ] [.mqtt.internal.MqttMessageSubscriber] - Error processing MQTT message.
org.openhab.core.transform.TransformationException: An error occurred while executing script.
        at org.openhab.core.transform.TransformationHelper$TransformationServiceDelegate.transform(TransformationHelper.java:67) ~[201:org.openhab.core.compat1x:2.4.0]
        at org.openhab.binding.mqtt.internal.MqttMessageSubscriber.processMessage(MqttMessageSubscriber.java:133) [239:org.openhab.binding.mqtt:1.13.0]
        at org.openhab.io.transport.mqtt.internal.MqttBrokerConnection.messageArrived(MqttBrokerConnection.java:570) [240:org.openhab.io.transport.mqtt:1.13.0]
        at org.eclipse.paho.client.mqttv3.internal.CommsCallback.deliverMessage(CommsCallback.java:475) [240:org.openhab.io.transport.mqtt:1.13.0]
        at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:379) [240:org.openhab.io.transport.mqtt:1.13.0]
        at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:183) [240:org.openhab.io.transport.mqtt:1.13.0]
        at java.lang.Thread.run(Thread.java:748) [?:?]

I even tried the simplest function :

(function(i) {
 return "TEST";
}(input)

Gives the same error.
I don’t know what to try next. Any help ?
I’m running Openhab2.40. Javascript transformation is installed.

Hi,
I found a solution.
I modified the tasmota MQTT-message to send only 0 or 1. Now with a MAP I have the desired result.
But I would like to know what’s going wrong with the javascript.