Publish MQTT raw bytearray

OH 3.0.2 Docker

Hello,

is possible to publish a bytearray through OH?
For a device I have to publish a bytearray like
cmd byte[] = { 192, 101, 108, 108, 111, 32 }

I also tried scripts:

mqttActions = getActions("mqtt", "mqtt:broker:323e452a3a")
mqttActions.publishMQTT("debug/nibe", "string")

But it seems the publishMQTT only accept strings
Did someone know a way to do this?

Yep. What is the actual payload you wanted to send? MQTT doesn’t understand array payloads, you would need to represent it in some way your subscriber(s) understand. JSON perhaps? Or you just want a naked 6-byte pattern?

Naked 6-byte pattern I think.
Ok look, I want to publish it like this (displayed with MQTT.fx):
2021-05-19 13_13_40-Window

For Example I can achieve this with the following:
/bin/sh -c "echo -en \"\xC0\x69\x02\x52\x9C\x65\" | mosquitto_pub -h 192.168.1.100 -t hbb33/config/nibe/read -s"

You could try encoding to a unicode string, like here -

I’m not convinced it will work.
Try first with a fixed string like
"u\00C0u\0069 ..."

“\u0069” work, char ‘i’, hex payload 69
“\u00C0” not, char ‘À’, hex payload C380

can i set how the bytes should be decoded?

Did you read the linked post?

Ah, I didn’t see it.

Okay I changed my Docker env to:

LC_ALL=en_US.ISO-8859-1
LANG=en_US.ISO-8859-1
LANGUAGE=en_US.ISO-8859-1

now the dsl script work fine:

var testinput = '\u00C0\u0069\u0002\u0052\u009C\u0065'
val mqttActions = getActions("mqtt", "mqtt:broker:323e452a3a")
mqttActions.publishMQTT("debug/nibe",testinput )

Can I safely change the env from UTF-8 to ISO-8859-1?
Do you know a way to decode a single string only in a dsl script?
Thanks for all!

I really don’t know; it seems a bit of a hack changing the whole system for one application.
Maybe there’s a way to load just one string in a particular character set.

What?

Can I set a charset in this script?

var testinput = '\u00C0\u0069\u0002\u0052\u009C\u0065'
val mqttActions = getActions("mqtt", "mqtt:broker:323e452a3a")
mqttActions.publishMQTT("debug/nibe",testinput )

Is there a function like the Java String using a specified charset that work in a dsl script?
String(byte[] bytes, Charset charset) with Charset.forName("ISO-8859-1")

Probably. Start here?

Might or might not work, depending what the framework and binding do with the string along the way.

Thanks for your patience, but it doesn’t seem to work that way

var testinput = '\u00C0\u0069\u0002\u0052\u009C\u0065'
val byte[] iso88591bytes = testinput.getBytes(java.nio.charset.Charset.forName("ISO-8859-1"))
for ( byte b : iso88591bytes )
        logInfo('',String.format("%x", b))
val str = new String ( iso88591bytes, java.nio.charset.Charset.forName("ISO-8859-1"))

logInfo('',str)
val mqttActions = getActions("mqtt", "mqtt:broker:323e452a3a")
mqttActions.publishMQTT("debug/nibe",str )

encoding work fine, in the logfile I see this output:

2021-05-26 14:36:43.644 [INFO ] [org.openhab.core.model.script.      ] - c0
2021-05-26 14:36:43.646 [INFO ] [org.openhab.core.model.script.      ] - 69
2021-05-26 14:36:43.648 [INFO ] [org.openhab.core.model.script.      ] - 2
2021-05-26 14:36:43.650 [INFO ] [org.openhab.core.model.script.      ] - 52
2021-05-26 14:36:43.652 [INFO ] [org.openhab.core.model.script.      ] - 9c
2021-05-26 14:36:43.654 [INFO ] [org.openhab.core.model.script.      ] - 65

But decoding the byte won’t work until I change the global charset.
Not nice but I guess I have to accept it that way

That’s a shame, but not too surprising, depending on internal string handling.

The Serial binding has an extra bit of magic to deal with this, the binary parameter.
As binary messages are perfectly legit in MQTT I think it might be worth logging a github enhancement request for MQTT binding for some similar feature.

All right, thanks for your help.

I just looked in on github. The function publishMQTT() uses

connection.publish(topic, value.getBytes() connection.getQos(), retain != null && retain.booleanValue())

and because of value.getBytes() it uses the global charset :neutral_face: