Script to escape " in json to publish on MQTT

  • Platform information:
    • Hardware: Orangepi 3 LTS
    • OS: Armbian 22.11.1
    • Java Runtime Environment: OpenJDK Runtime Environment Zulu11.43+100-CA (build 11.0.9.1+1-LTS)
    • openHAB version: 3.4
  • Issue of the topic:
    I am trying to send data produced by tuya cli to mqtt with mosquitto sub.

I have a bunch of Tuya zigbee temperature and humidity sensors around the house. I have not been able to configure tuya-mqtt to read them. Fortunately tuya-cli can read each of the sensors separately like this:

tuya-cli get --ip 192.168.0.114 --id bf828770253d********** --key 322f1a********** --cid a4c138********** --protocol-version 3.3
{ '1': 174, '2': 255, '4': 100 }

I would like to write an Openhab script that calls tuya-cli, converts the output and publishes it e.g. with mosquitto sub to sensor specific topics. id and key stay the same, sensors are identified by cid.

Need model script to convert json data for publishing on mqtt

tuya-cli provides data output in the following format

{ '1': 174, '2': 255, '4': 100 }

As far as I understand to publish this with mosquitto_sub it has to be of the format

"{\"1\":\"174\", \"2\":\"255\",\"4\":\"100\ }"

I know a little python, but that is all. I would be greatly thankful for help to create an Openhab script or rule that would call tuya-cli, convert the data and publish it to mqtt.

Some progress here. Wrote a short python script:

import subprocess
import os
output=subprocess.check_output(['./readsensor.sh'])
output = output.decode('utf8').replace("'", "\\\"")
print(output)

readsensor.sh uses tuya-cli to read a sensor:

!/bin/sh
tuya-cli get --ip 192.168.0.114 --id bf828770253d********** --key 322f1a********** --cid a4c138********** --protocol-version 3.3

This combination gets the temperature and humidty as a json from the sensor with cid a4c138… and converts them to a json in right format.

Next step is to export the json to mosquitto_pub. Any advice is warmly welcome!

Hmmm, this seems to be the long way around doing this. I’m sorry I missed the original post, I may have saved you some time.

This would probably be easiest handled in a rule as opposed to messing with an external script.

You can use the Exec binding or a rule with executCommandLine to call tuya-cli can get the JSON. And since you are not doing any processing on it, you can use the MQTT add-on and the publishMQTT action to publish it as is.

No need to escape anything or anything like that.

In JS Scripting the code using executeCommandLine would look something like this:

var result = actions.Exec.executeCommandLine(time.Duration.ofSeconds(20), 'tuya-cli', 'get', '--ip 192.168.0.114', '--id bf828770253d**********', '--key 322f1a**********', '--cid a4c138**********', '--protocol-version 3.3');
actions.Things.getActions("mqtt", "broker:thing:id").publishMQTT('topic', result, false);

In Rules DSL it would look something like

var result = executeCommandLine(Duration.ofSeconds(20), 'tuya-cli', 'get', '--ip 192.168.0.114', '--id bf828770253d**********', '--key 322f1a**********', '--cid a4c138**********', '--protocol-version 3.3')
getActions("mqtt", "broker:thing:id").publishMQTT('topic', result, false)

No matter what rules language you choose, it’s basically a two liner. You’d probably want to trigger the rule periodically using a cron trigger.

If you use the Exec binding it becomes a one liner. You’d configure the polling period there and link a String Item to the Out Channel. Create a rule to trigger when that Item updates and publish the state of the Item in the rule.

1 Like

Thank you! Will test and report.

Tested with the following rule:

var result = executeCommandLine(Duration.ofSeconds(30), "tuya-cli", "get", "--ip 192.168.0.114", "--id bf828770253restremoved", "--key 322f1restremoved", "--cid a4c138restremoved"," --protocol-version 3.3")
getActions("mqtt", "mqtt:broker:8d03removed").publishMQTT("tuya/radiohuone", result, false)

Result on mosquitto_sub:

tuya/radiohuone error: unknown option '--ip 192.168.0.114'

Seems like the wrong result is published?

Split them like this “–ip”, “1.2.3.4”

2 Likes

That did the trick!

This works:

var result = actions.Exec.executeCommandLine(time.Duration.ofSeconds(20), "tuya-cli", "get", "--ip", "192.168.0.114", "--id", "bf828mostofitremoved", "--key", "322mostofitremoved", "--cid", "a4c13mostofitremoved", "--protocol-version", "3.3");

Thanks!