MQTT Publish JSON data using a Switch Item

  • Platform information:
    • OS: Docker container in Ubuntu
    • openHAB version: 2.5.1
  • Issue of the topic: Nothing gets published

Hi there!

I’ve have a couple of MQTT topics in my mosquitto brooker that I’d like to read and write to in openHAB. Everything is configured using paper ui. Reading values works very well and I can do various transformations.

Yesterday I had my Sonos system incorporated into MQTT using sonos2mqtt. I know there is a component for integrating with Sonos but I find it very versatile to use MQTT. This question is specifically not about Sonos, just giving you the background.

Listing the retained MQTT topics:
mosquitto_sub -v -h localhost -t 'sonos/#'

sonos/status/friggeboden/state {"ts":1581958655420,"name":"friggeboden","val":"STOPPED"}
sonos/status/friggeboden/volume {"ts":1581958655442,"name":"friggeboden","val":9}
sonos/status/friggeboden/muted {"ts":1581958655442,"name":"friggeboden","val":false}
sonos/status/vardagsrummet/volume {"ts":1582010985780,"name":"vardagsrummet","val":15}
sonos/status/vardagsrummet/muted {"ts":1581963454348,"name":"vardagsrummet","val":false}
sonos/status/vardagsrummet/state {"ts":1582010986534,"name":"vardagsrummet","val":"PLAYING"}
sonos/status/badrummet/state {"ts":1582019346901,"name":"badrummet","val":"STOPPED"}
sonos/status/badrummet/volume {"ts":1581958655438,"name":"badrummet","val":25}
sonos/status/badrummet/muted {"ts":1581958655438,"name":"badrummet","val":false}

Quite nice if I may say so myself. (friggeboden, vardagsrummet and badrummet are room names).

I have defined a connection to a MQTT broker in paper UI and I have also defined a generic MQTT Thing which I’ve called Sonos generic MQTT Thing

I have also defined channels on the Sonos generic MQTT Thing. Since I’m not so interested in retrieving the timestamp and the room name value of each topics I extract only the val value from the MQTT topic. I have used a string type channel for the state, a number channel for the volume and a switch type channel for the muted topic.

In my Items file, I’ve defined a couple of item definitions

// Sonos
Switch Sonos_Connected "Sonos Connected [MAP(sv_network.map):%s]" <network> (Sonos) {channel="mqtt:topic:sonos:connected"}
String Sonos_Friggeboden_State "Sonos Friggeboden status [%s]" <text> (Sonos) {channel="mqtt:topic:sonos:friggeboden-state"}
Number Sonos_Friggeboden_Volume "Friggeboden Volym [%.0f]" <speaker> (Sonos) {channel="mqtt:topic:sonos:friggeboden-volume"}
Switch Sonos_Friggeboden_Muted "Friggeboden muted" (Sonos) {channel="mqtt:topic:sonos:friggeboden-muted"}
Switch Sonos_Test "Sonos Testswitch" (Sonos) {channel="mqtt:topic:sonos:test"}

My problems starts when I want to update my MQTT topics from openHAB.

I assume that I can use a single channel for both reading and writing to a single MQTT topic. I have also assumed that I need to transform the value that I publish to the correct type. That is, if I wish the MQTT topic to hold a JSON string I will need to create that JSON data string first and the channel type must be of string type.

While testing I have created a string type channel that I’ve called Sonos Test. MQTT Command Topic: sonos/test`

Outgoing Value Transformation: JS:sonos2jsonval.js

(function(x) {
    var t = Math.round(+new Date()/1);
    var obj = { ts: t, val: x };
    var result = JSON.stringify(obj);
    return result;
})(input)

Fo testing purposes I’ve created a sitemap.

sitemap sonos label="Sonos Speakers"
{
Frame label="State"
    {
        Default item=Sonos_Test
    }
}

Anyway, nothing gets published to my MQTT brooker. I think I’ve tried everything including several variants of transformations and maps. I guess it’s not easy to give some kind of help for my issue. Maybe there is an easy “how to” for setting up the most simple example of MQTT publishing from within openHAB using only paper UI and a very simple sitemap to alter the value. Maybe something is broken, I can’t tell.

openhab> feature:list | grep mqtt
openhab-core-io-transport-mqtt                    x 2.5.0            x          x Started     x distro-2.5.1             x
openhab-transport-mqtt                            x 2.5.0            x          x Started     x distro-2.5.1             x MQTT Transport
openhab-misc-mqttbroker                           x 2.5.1            x          x Uninstalled x openhab-addons-2.5.1     x MQTT Broker Moque                    tte
openhab-binding-mqtt                              x 2.5.1            x x        x Started     x openhab-addons-2.5.1     x MQTT Binding
openhab-persistence-mqtt                          x 1.14.0           x          x Uninstalled x openhab-addons-2.5.1     x MQTT Persistence

Thanks for any advice in this matter :wink:

EDIT: It might be so that changing an Item using the GUI of a sitemap makes a postUpdate on the item and MQTT doesn’t seem to trigger on that. I just started to test using a rule to issue a sendCommand on the item and now things seem to happen. Need further testing and reading though.

There is a potential for an infinite loop if you check the box to treat incoming messages as a command. Otherwise it should be fine.

Correct, you need to convert it to JSON.

Not necessarily. There are all sorts of features built into the Generic MQTT Thing Channel config that lets you do this there without creating a separate String Channel and Rule.

It looks like for mute you need to convert ON to {"ts":123234,"name":"friggeboden","val":true}, correct? The gotcha here is that timestamp. How “functional” is that? If you post a bogus value will the message still work or will that mess everything up?

If you can post a bogus value, than a simple Map transformation on the outgoing channel should be sufficient. If you need that timestamp to be real, you need to use a JS transform. I think the following will work along the lines you are already trying. You can do this all on the Number Channel. You don’t need to create a separate String Channel for this.

Based on my very brief research, shouldn’t that be Date.now()?

We probably need to see your Thing config for mqtt:topic:sonos:test.

The GUI always sendCommands. We also probably need some logs as well.

Thanks @rlkoshak

Further investigation shows that there are specifich MQTT topics for commanding. The topics I was referring to are read only. :wink: