[possible new binding] openHAB Eventbus to MQTT

Hello together,

I’m currently working on a project that requires to access devices in openHAB using MQTT.

The plan is to develop an Add-on that

  • listens on the internal openHAB event bus and publishes events like the ItemStateChanged event to an MQTT Broker so that various other applications could react to these events.
  • receives commands like a ItemCommandEvent from a MQTT Broker and publishes them to the internal event bus

The final goal would be make the functionality of the REST API and SSE available over MQTT.

I’m aware of the openHAB Remote Binding that archives something similar but one of the constraints I’m facing is that the REST API from openHAB may not be used for the project. I’m thinking more of something along the line of the old openHAB2.5 Event Bus Rules.

I currently have a pretty basic but working proof of concept, but before continuing development I would like to hear feedback from the community.

Do you think this is a feasible approach?
What are your feelings about opening internal events to the outside using MQTT?
And do you see a use case for this proposed Add-on?

Hi,

this is easily possible with HABApp - no need to develop another binding.
All you need is to setup a rule to create the events from the MQTT messages which should be easy to do.

What is wrong with using that approach without a binding?

Probably not. Not as an add-on but it’s not a technical limitation. See below.

There are use cases for it for sure.

The maintainers by policy do not allow add-ons access to the Items and Item events for Items that are not linked to that binding. In other words, they would not accept an add-on that does this because it needs access to the Item events from Items not linked to it. Furthermore, bindings should not see nor react to Item update events.

This is why the EventBus wasn’t implemented as part of the MQTT binding in the first place and why I wrote the EventBus rules in collaboration with the original MQTT binding author. Note that at the 3.2 release hopefully there will be a marketplace where users can find and install such rule sets the same as add-ons. Though I’m thinking it will probably be post 3.2 release.

Wouldn’t this violate the requirement not to use the REST API?

If they can’t use the Remote openHAB binding they probably can’t use HABApp or MQTT2Any or sensorReporter or any of the other many things out there that can interact with OH and export events as MQTT.

If he runs HABApp on the Server next to openHAB it’s not necessary to expose the rest API.
The only thing outgoing will be MQTT.

The java rules binding connects to both the eventbus and the itemregistry to fetch events and state changes. I don’t see any technical difficulty in implementing something that sends this info to a mqtt broker.

OP didn’t say he couldn’t expose the REST API. They said the REST API may not be used for this project (almost sounds like a school project). HABApp still uses the REST API so without further information for why the REST API can’t be used for this project I’d not assume that HABApp would be allowed any more than the Remote openHAB binding is.

There is no problem doing it from Rules Automation add-ons. It would kind of defeat the point of Rules if they couldn’t react to Item events. It’s a restriction of bindings though. Unless the devs have changed their minds, a binding would not be allowed that sort of access to Items and Item events.

MQTT 2.5+ Event Bus shows how to do it in Rules DSL, JavaScript, and Python. There is nothing that would make it difficult to do in any of the languages including the Java Rules. If you were to code up a Java rules example I’d be happy to add it to that tutorial as well. It’s really not that many lines of code really. I JavaScript it’s about 10 LOC to do it all (not counting the rules definition proforma stuff).

Thank you all for your nice and valuable feedback.

Thank you for pointing out the rules regarding a binding accessing items from another binding, I wasn’t aware of that.
The openHAB2.5 Event Bus Rules seemed like a wired workaround for what the proposed binding would have done. Now I know why :grinning:

This may be a possible workaround for my limitation. As rlkoshak correctly inferred it is indeed a project for university therefore I’ll have to check if this would be allowed. Thank you.

I have a theoretical question. One addresses the event bus. The linked example only refers to States:

import HABApp
from HABApp.openhab.events import ItemStateEvent
from HABApp.openhab.items import Thing
from HABApp.mqtt.items import MqttItem


class ExampleOpenhabToMQTTRule(HABApp.Rule):
    """This Rule mirrors all updates from OpenHAB to MQTT"""

    def __init__(self):
        super().__init__()

        for item in HABApp.core.Items.get_all_items():
            if isinstance(item, (Thing, MqttItem)):
                continue
            item.listen_event(self.process_update, ItemStateEvent)

    def process_update(self, event):
        assert isinstance(event, ItemStateEvent)

        print(f'/openhab/{event.name} <- {event.value}')
        self.mqtt.publish(f'/openhab/{event.name}', str(event.value))


ExampleOpenhabToMQTTRule()

If I now want commands for this on another instance, I would use the ItemCommandEvent, wouldn’t I?

import HABApp
from HABApp.openhab.events import ItemCommandEvent
from HABApp.openhab.items import Thing
from HABApp.mqtt.items import MqttItem


class ExampleOpenhabToMQTTRule(HABApp.Rule):
    """This Rule mirrors all updates from OpenHAB to MQTT"""

    def __init__(self):
        super().__init__()

        for item in HABApp.core.Items.get_all_items():
            if isinstance(item, (Thing, MqttItem)):
                continue
            item.listen_event(self.process_update, ItemCommandEvent)

    def process_update(self, event):
        assert isinstance(event, ItemCommandEvent)

        print(f'/openhab/{event.name} <- {event.value}')
        self.mqtt.publish(f'/openhab/{event.name}', str(event.value))


ExampleOpenhabToMQTTRule()

Ideally, I would then distinguish between /state or /command in the topic.

As you can see, it is still untested, but just a consideration. What is still missing for an event bus is subscribing. Probably create an MQTT Thing again, configure the broker and use a trigger channel. One points to /command and one to /state (if you use different instances) and you would then have emulated an event bus, wouldn’t you? Is there anything else that needs to be taken into account?

I can’t speak for the HABApp parts but in general you have to watch out for infinite loops. You never want to subscribe to both commands and events at the same time or you end up going around and around as a command results in an update which ends up in a command and so on. I discuss this quite a bit at MQTT 2.5+ Event Bus which is pretty much exactly what you are proposing except with a HABApp implementation instead of using the built in OH Rules.

Generally, one instance of OH will “own” the device. The device owner will only subscribe for commands and only publish updates. The “remote” devices will only subscribe for updates and only publish commands. Ideally you’ll also want to turn off autoupdate on the “remote” Items so they don’t change state until after the “owner” OH reports that the Item changed state.

Yes - as @rlkoshak sais you really have to watch out to not build infinite loops.
If you use the /state, /command and /update suffix everything should be fine.

Instead of

if isinstance(item, (Thing, MqttItem)):

you can also do

if not isinstance(item, OpenhabItem):

Hi,

maybe I forget something. I tried it with your code to just have a look if I can see any topics. So I copied the code to /etc/openhab2/habapp/rules/mqtt.py.

With sudo systemctl status habapp.service I retrieve as example:

Sep 29 09:45:50 OpenHABVM habapp[14657]: /openhab/OpenHABVM_Swap_Available_Percent <- 99.8
Sep 29 09:45:50 OpenHABVM habapp[14657]: /openhab/OpenHABVM_Memory_Available_Percent <- 33.9
Sep 29 09:45:50 OpenHABVM habapp[14657]: /openhab/OpenHABVM_Sensor_CPUTemp <- None
Sep 29 09:45:50 OpenHABVM habapp[14657]: /openhab/OpenHABVM_Storage_Available <- 9542

What’s missing is that I can scan the topics with MQTT.fx or subscribe to it. So I have not connected habapp with my mosquitto broker. How can I do that?

Inside the configuration.yaml I have:

mqtt:
  connection:
    client_id: HABApp
    host: '<my-ip>'
    port: 1883
    user: ''
    password: ''
    tls: true
    tls_ca_cert: ''  # Path to a CA certificate that will be treated as trusted
    tls_insecure: false
  general:
    listen_only: false  # If True HABApp will not publish any value to the broker
  publish:
    qos: 0  # Default QoS when publishing values
    retain: false # Default retain flag when publishing values
  subscribe:
    qos: 0  # Default QoS for subscribing
    topics:
    - '#'
    - 0

So I changed the port from 8883 to 1883 because of the mosquitto port. So have I left out any important step?

What do you mean exactly? Can you rephrase - I don’t understand …

Hi,

I have Mosquitto installed and I use it as an MQTT Broker with openHAB. Currently I use both. The MQTT 1.x and MQTT 2.x Binding. All the topics from the MQTT bindings I can see if I connect with MQTT.fx to the broker with and port 1883. If I go to Subscribe and click on Scan to show all topics, I can’t find any topics with /openhab/.... as the habapp.service shows. I only can see something like /openHAB/in/${item}/state configured in the /etc/openhab2/services/mqtt-eventbus.cfg file. So I know that my Mosquitto Broker works fine and that openHAB can use it.

Instead of using these bindings I want to give habapp a chance. I thought that If I say that and the port 1883 is enough. But the linked script for mirroring openHAB State Events to MQTT will not mirror it to the Mosquitto Broker. I can see that the topics which I can find with sudo systemctl status habapp.service are registered on the Mosquitto Broker. So that means for me that habapp does not have access to my Mosquitto Broker.

The configuration of Mosquitto is that anonymous access is allowed. And there is no password or user set. So it should be very easy to access to the Mosquitto Broker. Perhaps I really have overlooked a step. I haven’t read anything in the habapp documentation either. As far as I know, the configuration.yaml file should be sufficient for the configuration of the Mosquitto Broker.

I’ll ask otherwise stupidly, maybe I’m getting it wrong. Would I need a Thing for habapp? Or does habapp need a clue which Thing for a MQTT broker it needs? I thought I could access the MQTT broker directly with habapp as I do with other programs, so that ultimately habapp accesses it on its own without openHAB.

In other words:

self.mqtt.publish(f'/openhab/{event.name}', str(event.value))

I understand that this line means, that self.mqtt is configured in the configuration.yaml file. And that the topic is, to stay in the notation of the MQTT 1.x binding, /openhab/{$item}.

The bottom line is that I don’t have a connection to the Mosquitto broker with habapp or see that a topic from habapp is provided there. The habapp.service is online. Habapp seems to run. Or do I have to configure something else in habapp?

Since I am only “new” to habapp, I have another question. Are there any logs I could look at? Maybe there is a problem with the connection to the Mosquitto Broker. I think that would be helpful at this point.

Is it understandable? Do you need more information? Maybe some read and write permissions? In /opt/habapp habapp is installed, in /etc/openhab2/habapp is the configuration folder.

Thanks in advance.

No - it works through the API.

Yes there are. There is a HABApp.log in the configured log folder and a HABApp_Events.log which shows the events. Take a look at the logging.yml to see the configured paths.
I suggest you take a look at the HABApp.log. You’ll see a successful MQTT connection there.
Do you really use TLS to connect to the broker?

Okay, I tried to create the openHAB Eventbus with HABApp. I have a problem with subscribing the states. Subscribing commands will work fine.

I installed on both openHAB instances HABApp like described in the documentation. I call them MASTER and SLAVE. On the master I installed the MQTT 2.x binding and mosquitto and configured a thing which has access to the mosquitto broker. On the slave I installed also the MQTT 2.x binding and configured a thing which has access to the mosquitto broker from the master. Both things has a Public Trigger channel. The master has /openhab/out/+/command and the slave has /openhab/in/+/state.

So here is the master’s config.yml:

directories:
  logging: log  # Folder where the logs will be written to
  rules: rules # Folder from which the rule files will be loaded
  param: params # Folder from which the parameter files will be loaded
  config: config # Folder from which configuration files (e.g. for textual thing configuration) will be loaded
  lib: lib # Folder where additional libraries can be placed
location:
  latitude: 0.0
  longitude: 0.0
  elevation: 0.0
mqtt:
  connection:
    client_id: HABApp
    host: <master_ip>
    port: 1883
    user: ''
    password: ''
    tls: false
    tls_ca_cert: ''  # Path to a CA certificate that will be treated as trusted
    tls_insecure: true
  general:
    listen_only: false  # If True HABApp will not publish any value to the broker
  publish:
    qos: 0  # Default QoS when publishing values
    retain: false # Default retain flag when publishing values
  subscribe:
    qos: 0  # Default QoS for subscribing
    topics:
    - '#'
    - 0
openhab:
  connection:
    host: <master_ip>
    port: 8080
    user: ''
    password: ''
  general:
    listen_only: false  # If True HABApp will not change anything on the openHAB instance.
    wait_for_openhab: true # If True HABApp will wait for items from the openHAB instance before loading any rules on startup
  ping:
    enabled: true  # If enabled the configured item will show how long it takes to send an update from HABApp and get the updated value back from openhabin milliseconds
    item: HABApp_Ping # Name of the Numberitem
    interval: 10 # Seconds between two pings
directories:
  logging: log  # Folder where the logs will be written to
  rules: rules # Folder from which the rule files will be loaded
  param: params # Folder from which the parameter files will be loaded
  config: config # Folder from which configuration files (e.g. for textual thing configuration) will be loaded
  lib: lib # Folder where additional libraries can be placed
location:
  latitude: 0.0
  longitude: 0.0
  elevation: 0.0
mqtt:
  connection:
    client_id: HABApp
    host: 192.168.0.5
    port: 1883
    user: ''
    password: ''
    tls: false
    tls_ca_cert: ''  # Path to a CA certificate that will be treated as trusted
    tls_insecure: true
  general:
    listen_only: false  # If True HABApp will not publish any value to the broker
  publish:
    qos: 0  # Default QoS when publishing values
    retain: false # Default retain flag when publishing values
  subscribe:
    qos: 0  # Default QoS for subscribing
    topics:
    - '#'
    - 0
openhab:
  connection:
    host: 192.168.0.5
    port: 8080
    user: ''
    password: ''
  general:
    listen_only: false  # If True HABApp will not change anything on the openHAB instance.
    wait_for_openhab: true # If True HABApp will wait for items from the openHAB instance before loading any rules on startup
  ping:
    enabled: true  # If enabled the configured item will show how long it takes to send an update from HABApp and get the updated value back from openhabin milliseconds
    item: HABApp_Ping # Name of the Numberitem
    interval: 10 # Seconds between two pings

And here ist the slave’s config.yml:

directories:
  logging: log  # Folder where the logs will be written to
  rules: rules # Folder from which the rule files will be loaded
  param: params # Folder from which the parameter files will be loaded
  config: config # Folder from which configuration files (e.g. for textual thing configuration) will be loaded
  lib: lib # Folder where additional libraries can be placed
location:
  latitude: 0.0
  longitude: 0.0
  elevation: 0.0
mqtt:
  connection:
    client_id: HABApp
    host: <master_ip>
    port: 1883
    user: ''
    password: ''
    tls: false
    tls_ca_cert: ''  # Path to a CA certificate that will be treated as trusted
    tls_insecure: true
  general:
    listen_only: false  # If True HABApp will not publish any value to the broker
  publish:
    qos: 0  # Default QoS when publishing values
    retain: false # Default retain flag when publishing values
  subscribe:
    qos: 0  # Default QoS for subscribing
    topics:
    - '#'
    - 0
openhab:
  connection:
    host: <slave_ip>
    port: 8080
    user: ''
    password: ''
  general:
    listen_only: false  # If True HABApp will not change anything on the openHAB instance.
    wait_for_openhab: true # If True HABApp will wait for items from the openHAB instance before loading any rules on startup
  ping:
    enabled: true  # If enabled the configured item will show how long it takes to send an update from HABApp and get the updated value back from openhabin milliseconds
    item: HABApp_Ping # Name of the Numberitem
    interval: 10 # Seconds between two pings
directories:
  logging: log  # Folder where the logs will be written to
  rules: rules # Folder from which the rule files will be loaded
  param: params # Folder from which the parameter files will be loaded
  config: config # Folder from which configuration files (e.g. for textual thing configuration) will be loaded
  lib: lib # Folder where additional libraries can be placed
location:
  latitude: 0.0
  longitude: 0.0
  elevation: 0.0
mqtt:
  connection:
    client_id: HABApp
    host: 192.168.0.5
    port: 1883
    user: ''
    password: ''
    tls: false
    tls_ca_cert: ''  # Path to a CA certificate that will be treated as trusted
    tls_insecure: true
  general:
    listen_only: false  # If True HABApp will not publish any value to the broker
  publish:
    qos: 0  # Default QoS when publishing values
    retain: false # Default retain flag when publishing values
  subscribe:
    qos: 0  # Default QoS for subscribing
    topics:
    - '#'
    - 0
openhab:
  connection:
    host: 192.168.0.5
    port: 8080
    user: ''
    password: ''
  general:
    listen_only: false  # If True HABApp will not change anything on the openHAB instance.
    wait_for_openhab: true # If True HABApp will wait for items from the openHAB instance before loading any rules on startup
  ping:
    enabled: true  # If enabled the configured item will show how long it takes to send an update from HABApp and get the updated value back from openhabin milliseconds
    item: HABApp_Ping # Name of the Numberitem
    interval: 10 # Seconds between two pings

Then here you can see the mqtt.py-Rule for HABApp on the master server:

import HABApp
from HABApp.openhab.events import ItemStateEvent
from HABApp.openhab.items import Thing
from HABApp.openhab.items import OpenhabItem
from HABApp.mqtt.items import MqttItem


class ExampleOpenhabToMQTTRule(HABApp.Rule):
    """This Rule mirrors all updates from OpenHAB to MQTT"""

    def __init__(self):
        super().__init__()

        for item in HABApp.core.Items.get_all_items():
            #if isinstance(item, (Thing, MqttItem)):
            if not isinstance(item, OpenhabItem):
                continue
            item.listen_event(self.process_update, ItemStateEvent)

    def process_update(self, event):
        assert isinstance(event, ItemStateEvent)

        print(f'/openhab/{event.name} <- {event.value}')
        self.mqtt.publish(f'/openhab/in/{event.name}/state', str(event.value))


ExampleOpenhabToMQTTRule()

And here is the pendant for the slave:

import HABApp
from HABApp.openhab.events import ItemCommandEvent
from HABApp.openhab.items import Thing
from HABApp.openhab.items import OpenhabItem
from HABApp.mqtt.items import MqttItem


class ExampleOpenhabToMQTTRule(HABApp.Rule):
    """This Rule mirrors all updates from OpenHAB to MQTT"""

    def __init__(self):
        super().__init__()

        for item in HABApp.core.Items.get_all_items():
            #if isinstance(item, (Thing, MqttItem)):
            if not isinstance(item, OpenhabItem):
                continue
            item.listen_event(self.process_update, ItemCommandEvent)

    def process_update(self, event):
        assert isinstance(event, ItemCommandEvent)

        print(f'/openhab/{event.name} <- {event.value}')
        self.mqtt.publish(f'/openhab/out/{event.name}/command', str(event.value))


ExampleOpenhabToMQTTRule()

Then I have created a mqtt.rule file on both instances to subscribe using the Public Trigger channel. Here for the master:

import org.eclipse.smarthome.model.script.ScriptServiceUtil

// MQTT naming convention i use:
//
//commandPublishTopic = /openHAB/out/${item}/command
//stateSubscribeTopic = /openHAB/in/${item}/state

// MASTER
var boolean commandSubscribeTopic = true
var boolean stateSubscribeTopic = false

// SLAVE
// var boolean commandSubscribeTopic = false
// var boolean stateSubscribeTopic = true

// We need a group with all items as a Member of trigger.
// Creating one dynamicly. (Group dg_AllItems)
// ScriptServiceUtil.getItemRegistry.getItems() can not be used as a Member of trigger (I've tried :-)

rule "populate dynamic group dg_AllItems"
when
        Time cron "0 0/1 * * * ?"
then
        // add all items to the group
        ScriptServiceUtil.getItemRegistry.getItems().forEach[item | gSmartHome.addMember(item) ]

        // remove all items which no longer exist
        gSmartHome.members.filter(s | ScriptServiceUtil.getItemRegistry.getItems().filter[i | i.name.contains(s.name)].length == 0).forEach[item | gSmartHome.removeMember(item)]

        // remove the group from itself (odd.)
        gSmartHome.removeMember(gSmartHome)

        //DEBUG dg_AllItems.members.forEach[ item | logInfo("dg_AllItems_member",item.name) ]
end
/*
rule "publish commands to broker"
when
        Time cron "0 0/1 * * * ?"
then
        if (commandPublishTopic){
            val actions = getActions("mqtt","mqtt:broker:mosquitto")
            actions.publishMQTT("/openHAB/out/"+triggeringItem.name+"/command",receivedCommand.toString)
  }
end


rule "Publish command to broker"
when
    Member of gSmartHome received command
then
    if (commandPublishTopic){
            val actions = getActions("mqtt","mqtt:broker:mosquitto")
            actions.publishMQTT("/openHAB/out/"+triggeringItem.name+"/command",receivedCommand.toString)
  }
end

rule "Publish state to broker"
when
        Member of gSmartHome changed
then
        if (statePublishTopic){
                val actions = getActions("mqtt","mqtt:broker:mosquitto")
                actions.publishMQTT("/openHAB/in/"+triggeringItem.name+"/state",triggeringItem.state.toString)
      }
end

rule "publish states to broker"
when
        Time cron "0 0/1 * * * ?"
then
        if (statePublishTopic){
                val actions = getActions("mqtt","mqtt:broker:mosquitto")
                actions.publishMQTT("/openHAB/in/"+triggeringItem.name+"/state",triggeringItem.state.toString)
      }

end
*/

rule "Subscribe to broker"
when
        Channel "mqtt:broker:mosquitto:openhabvm-updates" triggered
then
        var evnt_payload = receivedEvent.getEvent.toString.split("#")
        var mqtttopic = evnt_payload.get(0).toString.split("/")
        var mqttcommand = evnt_payload.get(1)
        var mqttitem = mqtttopic.get(mqtttopic.length-2)
        var mqttcommandorstate = mqtttopic.get(mqtttopic.length-1)
        var ItemExists = gSmartHome.members.filter[item | item.name.contains(mqttitem)].length
        if (ItemExists > 0){

                if (commandSubscribeTopic &&   mqttcommandorstate == "command") {
                        sendCommand(mqttitem,mqttcommand)
                }
                else {
                        if (stateSubscribeTopic && mqttcommandorstate == "state") {
                                postUpdate(mqttitem,mqttcommand)
                        }
                }
        }
end

And here for the slave:

import org.eclipse.smarthome.model.script.ScriptServiceUtil

// MQTT naming convention i use:
//
//commandPublishTopic = /openHAB/out/${item}/command
//stateSubscribeTopic = /openHAB/in/${item}/state

// MASTER
//var boolean commandSubscribeTopic = true
//var boolean stateSubscribeTopic = false

// SLAVE
var boolean commandSubscribeTopic = false
var boolean stateSubscribeTopic = true

// We need a group with all items as a Member of trigger.
// Creating one dynamicly. (Group dg_AllItems)
// ScriptServiceUtil.getItemRegistry.getItems() can not be used as a Member of trigger (I've tried :-)

rule "populate dynamic group dg_AllItems"
when
        Time cron "0 0/1 * * * ?"
then
        // add all items to the group
        ScriptServiceUtil.getItemRegistry.getItems().forEach[item | gSmartHome.addMember(item) ]

        // remove all items which no longer exist
        gSmartHome.members.filter(s | ScriptServiceUtil.getItemRegistry.getItems().filter[i | i.name.contains(s.name)].length == 0).forEach[item | gSmartHome.removeMember(item)]

        // remove the group from itself (odd.)
        gSmartHome.removeMember(gSmartHome)

        //DEBUG dg_AllItems.members.forEach[ item | logInfo("dg_AllItems_member",item.name) ]
end
/*
rule "publish commands to broker"
when
        Time cron "0 0/1 * * * ?"
then
        if (commandPublishTopic){
            val actions = getActions("mqtt","mqtt:broker:mosquitto")
            actions.publishMQTT("/openHAB/out/"+triggeringItem.name+"/command",receivedCommand.toString)
  }
end


rule "Publish command to broker"
when
    Member of gSmartHome received command
then
    if (commandPublishTopic){
            val actions = getActions("mqtt","mqtt:broker:mosquitto")
            actions.publishMQTT("/openHAB/out/"+triggeringItem.name+"/command",receivedCommand.toString)
  }
end

rule "Publish state to broker"
when
        Member of gSmartHome changed
then
        if (statePublishTopic){
                val actions = getActions("mqtt","mqtt:broker:mosquitto")
                actions.publishMQTT("/openHAB/in/"+triggeringItem.name+"/state",triggeringItem.state.toString)
      }
end

rule "publish states to broker"
when
        Time cron "0 0/1 * * * ?"
then
        if (statePublishTopic){
                val actions = getActions("mqtt","mqtt:broker:mosquitto")
                actions.publishMQTT("/openHAB/in/"+triggeringItem.name+"/state",triggeringItem.state.toString)
      }

end
*/

rule "Subscribe to broker"
when
        Channel "mqtt:broker:general:openhabvm-updates" triggered
then
        var evnt_payload = receivedEvent.getEvent.toString.split("#")
        var mqtttopic = evnt_payload.get(0).toString.split("/")
        var mqttcommand = evnt_payload.get(1)
        var mqttitem = mqtttopic.get(mqtttopic.length-2)
        var mqttcommandorstate = mqtttopic.get(mqtttopic.length-1)
        var ItemExists = gSmartHome.members.filter[item | item.name.contains(mqttitem)].length
        if (ItemExists > 0){

                if (commandSubscribeTopic &&   mqttcommandorstate == "command") {
                        sendCommand(mqttitem,mqttcommand)
                }
                else {
                        if (stateSubscribeTopic && mqttcommandorstate == "state") {
                                postUpdate(mqttitem,mqttcommand)
                        }
                }
        }
end

Well it is nearly the same as you can find here: How to: MQTTv2 Eventbus rules

What works better is that publishing states and commands are nearly work to 100%. This I can`t reach only using the linked rules and I have never reached with @rlkoshak’s eventbus solution: MQTT 2.5+ Event Bus

So this approach might be the most stable. What unfortunately does not work is that I can subscribe to the state on the slave. On the master, as I said, I have no problem subscribing to commands from the slave.

I must be missing something here. As you can see, I have also named the Things differently. But it doesn’t matter, only the channel and the Mosquitto connection are needed. But I can definitely access the broker of the master from the slave. I can test this in the command line or the publishing works.

Does anyone see an error? Perhaps someone would like to test this for themselves. The broker installation and how to configure the Thing can actually be copied from the two links.

Kind regards

I’ve never seen nor seen reported any commands or updates being dropped with the MQTT 2.5+ EventBus. I can’t fix things if I don’t know they are a problem.

Given this is all MQTT, if messages are being dropped it’s probably just a matter of changing the QOS on the subscription topic to 1 or 2 and changing the publisher to publish using QOS 1 or 2.