MQTT1 items with multiple PUB SUB -->> migrate to MQTT 2.x

After days of trial and error and reading, I have moved all my switches from MQTT 1.x to 2.x binding, OH 2.5.

Success
Most of my switches are easy ON/OFF types, nothing fancy going on.
I have things working, and MQTT 2.5 is working well, and MQTT Explorer observes all the events just fine.

ISSUE
My current MQTT 2.x items have multiple inbound, outbound messages to drive different user interfaces, and drive an I2C controlled switch board/relay controller.
Things seem to be constrained to using one Command topic, and one State topic.

MQTT Topics and message summary;

  • /first two rows are dedidcated to driving OpenHab Item logic - these have been moved into Thing format OK and work well.
  • /Switchboard drives I2C logic for operating relays
  • /HMI drives touch screens for panel status updates, and receiving touch commands

Maybe I’ve built myself a birds nest of logic, but it has worked well and I’m very happy with it.

Current state of my MQTT 2.x ITEMS file - example

Switch KitchenLightSwitch1 “Kitchen 1” (gAllLights,gAllKitchenLights) [ “Lighting” ]
{channel = “mqtt:topic:pi4MqttBroker:KitchenLightSwitch1:light”,
autoupdate=“false” ,mqtt="
<[broker:myhome/kitchen/light/switch/row1/command:command:MAP(arduino.map)],]
<[broker:myhome/kitchen/light/switch/row1/command:command:MAP(arduino.map)],
>[broker:myhome/switchboard/switchboard1/command:command:ON:A,1,1],
>[broker:myhome/switchboard/switchboard1/command:command:OFF:A,1,0],
>[broker:myhome/HMI/page0/kitchen/light/switch/row1/state:state:ON:1],
>[broker:myhome/HMI/page0/kitchen/light/switch/row1/state:state:OFF:0],

My new MQTT 2.5 Thing configuration looks like this, and is working well… but only one Command, and one State.

Thing topic KitchenLightSwitch1 “Kitchen LightSwitch1 .thing” @ “Kitchen” {
Channels:
Type switch : light “Kitchen LightSwitch1 .thing” [ stateTopic=“myhome/kitchen/light/switch/row1/state”, commandTopic=“myhome/kitchen/light/switch/row1/command” ]
}

Question:
What is the proper design pattern to move my list of 1.x MQTT pub/sub logic to a “Thing”?.. or maybe I dont.
Each Thing seems constrained to one command, and one topic… i need a few more.

From reading, and seeing what other people drive MQTT logic with, I think I'm supposed to move the logic into Rules, and fire off the needed MQTT messages using Rules?

I need to manage the last 4 rows MQTT 1.x Pub Sub messages to somwhere.

[broker:myhome/switchboard/switchboard1/command:command:ON:A,1,1],
[broker:myhome/switchboard/switchboard1/command:command:OFF:A,1,0],
[broker:myhome/HMI/page0/kitchen/light/switch/row1/state:state:ON:1],
[broker:myhome/HMI/page0/kitchen/light/switch/row1/state:state:OFF:0],

Is using Rules the best approach? Is Rules the best/correct design pattern?
Or maybe there is another Thing type I can use to get the same result?

Each MQTT channel can have one pub and one sub.

Items may be linked to more than one channel.

Looking at the sort of things you are mashing together though, I might represent each real device with one Item but handle these individual Items as Groups.

I agree with rossko57. The generally considered best practice is:

  • each device is represented by a separate Thing
  • if there is more than one actuator or sensor on that Thing, each is represented by a Channel

From there you have two choices. You can link multiple channels to the same Item or you can link only one channel to individual Items. You could then use rules or, as rossko57 indicates, you can use Groups. When you send a command to a Group, the command gets forwarded to all of it’s members. So, for example, you would define KitchenLightSwitch1 as

Group:Switch:OR(ON,OFF) KitchenLightSwitch1

Then you would have three separate Items for the three devices:

Switch KitchenLightSwitch1_Kitchen (KitchenLightSwitch1) { channel="thing id that pub/sub to myhome/kitchen/light/switch/row1/command" }
Switch KitchenLightSwitch1_SwitchBoard (KitchenLightSwitch1) { channel="thing id that pub/sub to myhome/switchboard/switchboard1/command" }
Switch KitchenLightSwitch1_HMI (KitchenLightSwitch1) { channel="thing id that pub/sub to myhome/HMI/page0/kitchen/light/switch/row1/state" }

KitchenLightSwitch1 will be ON if any of it’s members are ON. Sending a command to KitchenLightSwitch will be forwarded to all of the members.

If you do not follow the Group approach, you can put all the channels on the one Item, but you will probably need to use the follow profile on the switchboard and hmi channels. My only concern here is that I don’t know how/whether the follow profile will work with more than one channel following.

Given that you are driving some other external UI, if you have control over the MQTT topics that it publishes/subscribes to, you might be able to do away with configuring MQTT on these Items at all and use MQTT 2.5 Event Bus (I’ve recently rewritten this to make setup and use a little simpler).

Thanks Rich,
I have started work on implementing this now… it’s a new approach for me to get head around. But it makes sense. Thank you.

Regarding “mashing” together from the first post. I made a decision early on that I did not want to have to touch each ancilary device every time I made a code change in OpenHab, or added new devices.
For this reason my switchboard controllers (Arduino with some I2C sheilds from Freetronics) for managing 230 volt relays in the mainbaord are written once for use many times. I can add as many shields as needed, or replicate the arduino and shields to other switchboards. I’ve not had to recompile them since deploying them some years ago. I can just keep adding devices (lights, coffee machine, fans etc), and only ever need to manage the logic and device parameters in OpenHab.

The generic nature of the Ardino code allows me to control all logic and changes from within OpenHab… and not have re-complie and upload to Arduio every time there is a change.

The same applies to the Nextion panels i have wall mounted. They are completly dynamic and update thier UX/UI based on OpenHab MQTT messaging. So i dont need to re-complile and upload via local SD every time there is an evironment change.

My attempt at trying to describe the switch board logic in image below (or maybe it’s attached).

I hope this is an ok rationale for the need to use mutiple inbound and outbound MQTT messages for each Item/Thing. Because specific messages are needed to achieve my “low maintenance/zero re-code” goal of my “switchboard” and “Nextion HMI” code. These ancilary devices are delivered with generic code that can be re-used over and over again.

Many thanks for your descriptive and helpful guidance.

Thinking out loud, maybe I’m supposed to be writing a binding for the switchboard Ardino and Nextion HMI… and this would simplifty my MQTT messaging birds nest… Developing a Binding maybe beyond my skill level though.

Alright, so you are encoding relay numbers etc. into the topic. The more conventional way is to use fixed topic to target some box and pass variables in the payload (which is why the MQTT binding isn’t really set up for variable topics).

But you got what you got. For publishing from openHAB, you don’t have to use generic channels with fixed topics.
You can use MQTT Actions to publish to arbitrary topics from a rule.
So, route all your Item commands to a rule, which can build a topic from Item name, command type etc.

It’s not really clear to me how the responses come back to openHAB - is there only one topic involved there (per relay), and so more suited to conventional binding channel?

It’s perfectly reasonable to use different in/out techniques.

ok, thanks for that info. Actions sounds good.
Googling for actions, most links seem to have a pre-requisite for MQTT 1.x binding… any chance you can direct me to a MQTT 2.x binding reference for Actions? or maybe it’s the same?
e.g.:
https://docs.openhab.org/v2.2/addons/actions/mqtt/readme.html

Not the same. Things change over time, beware old advice. Search posts in this forum for getActions() - which is the v2.x way to do it - and publishMQTT()
Docs


Scroll to “Rule Actions”

Looking more closely at your incoming topic, I’m a bit stumped with that.
Both relay number and state are encoded in the topic, yes?
Relay number is fine, we can have separate generic MQTT binding channels for each relay.

We can use wildcard in the topic subscribed to, so that both on and off messages are seen in one channel.
But …
I do not know a way you can inspect the incoming topic to find out what the wildcard was.
It’s useless.

I think you may be stuck with defining several channels with all topic variants of incoming state - not so bad for on/off only - and linking each relay Item to a pair of channels to get state updates.

EDIT - here we go! You can define a trigger channel, not as part of a generic Thing, but directly on the broker Bridge.
You can use wildcards in the subscribe topic.
When message received, it triggers an openHAB event, nothing to with Items at all.

A rule however can be triggered by this event channel, and the rule can examine the event content - which includes both MQTT topic AND payload.
So a rule can analyse incoming topic into relay number and state, and then update the appropriate Item.
It’s close to a mirror of the publish-by-rule part.

I’ve been the long way round to re-invent Rick’s Event Bus, of course.

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.