Skip to main content

An MQTT Event Bus for openHAB.

Project description

Python openHAB Event Bus

An MQTT Event Bus for openHAB. This Event Bus mirrors the Item Events ItemStateEvent and ItemCommandEvent via MQTT. An ItemStateEvent is received when the state of an item is updated. This can be a postUpdate by a Rule or when something is operated on the device and the state is changed via the corresponding Binding. An ItemCommandEvent is received when a command is sent to an item via a channel. This can be a sendCommand in a Rule or when serving an element in the Sitemap.

What is an Event Bus

Generally speaking, an event bus is a design pattern for how devices can be operated. The state indicates the status of an item. This item can be, for example, a switch that is set to ON. If I switch off this device accordingly, the state will also change to OFF. The device therefore publishes the state of this switch item via a topic. To operate the device, however, a command is used. With the command OFF I give the device the command to change the state to OFF. If this device is ON, it will be switched off accordingly. With the command ON I would switch the device on again. For this the device must be able to subscribe via a topic.

A command therefore requires the change of a state. However, it should be noted that a command is not the same as a state. Commands and states are often called differently. For example, I can imagine the commands louder or quieter at a loudspeaker and as a state I get a number that indicates how loud this loudspeaker is.

The openHAB Event Bus allows to apply this design pattern to any Item in openHAB. So I can operate an item via other programs or even other openHAB instances. But I can only configure that either State is published and Command is subscribed or Command is published and State is subscribed.

Installation

You can install it by using pip:

python3 -m pip install python-openhab-eventbus

Usage

You have to import the EventBus from openhab:

from openhab import EventBus

In the next step you have to create an EventBus object instance:

# Main function.
if __name__ == "__main__":
    event_bus = EventBus("http://<openhab_ip>:8080", "<openhab_username>", "<openhab_password>", "<mqtt_ip", <mqtt_port>, "<mqtt_username>, "<mqtt_password>", "<statePublishTopic>", "<commandPublishTopic>", "<stateSubscribeTopic>", "<commandSubscribeTopic>")

The program must be able to access the REST API of openHAB as well as the MQTT broker to be used. Both openHAB and the MQTT broker do not have to run on the same computer as the program itself. Also, openHAB and the MQTT Broker may run on different computers. However, the computers must be in the same network. As MQTT broker I use Mosquitto myself. However, the program should be compatible with all brokers.

You have to replace <openhab_ip> with your openHAB IP address. <openhab_username> and <openhab_password> is needed to connect to the REST API of openHAB. Depending on your configuration you may not need to use a username and password. Instead of one str each for the username and password of your openHAB user, you have to pass None accordingly.

To connect to the MQTT broker, an MQTT client is required. The program uses paho-mqtt for this purpose. The client therefore needs an IP address to this broker and the port under which this broker can be reached. For this you have to replace <mqtt_ip> and <mqtt_port> accordingly. <mqtt_ip> is a str and <mqtt_port> is an int. Mosquitto as example uses the port 1883 by default.

It is possible for an MQTT broker to allow anonymous access. This means that one does not have to specify a user name and password. In this case <mqtt_username> and <mqtt_password> must be replaced by None. Otherwise, a str must be used accordingly.

The REST API uses server-sent events (SSE) to check whether an ItemStateEvent or an ItemCommandEvent has been triggered. If this is the case, the State is queried for an ItemStateEvent via a GET request for this Item and this is published, or the command for this Item is published for an ItemCommandEvent.

Whether ItemStateEvent's or ItemCommandEvent's are considered is determined when setting the topics for the MQTT client.

The topic statePublishTopic specifies a topic to be used to publish ItemStateEvent's. If it is set, no commandPublishTopic may be specified. A commandPublishTopic, on the other hand, specifies a topic that publishes ItemCommandEvent's. Both can be passed via a str. The other topic should be set to None.

The topic stateSubscribeTopic specifies a topic to be used to subscribe State's of an Item. If it is set, no commandSubscribeTopic may be specified. A commandSubscribeTopic, on the other hand, specifies a topic that subscribes Command's. Both can be passed via a str. The other topic should be set to None.

So in the end you have the following two configuration options:

from openhab import EventBus

# Main function.
if __name__ == "__main__":
    event_bus = EventBus("http://192.168.0.5:8080", None, None, "192.168.0.5", 1883, None, None, "openhab/${item}/state", None, None, "openhab/${item}/command")

And:

from openhab import EventBus

# Main function.
if __name__ == "__main__":
    event_bus = EventBus("http://192.168.0.11:8080", None, None, "192.168.0.5", 1883, None, None, None, "openhab/${item}/command", "openhab/${item}/state", None)

What would happen in this example? The openHAB instance 192.168.0.5 publishes the State's of its Item's. The openHAB instance 192.168.0.11 subscribes the State's for its Item's. If the same Item's are present, both instances have the same State's.

If you execute a Command on 192.168.0.11, this is published and also triggers a Command on 192.168.0.5, which means that the State's will be changed and would be published from there again.

Now we have seen something else extremely important: ${item}. This is a placeholder for the items. For each topic, this placeholder is replaced with the name of the item accordingly. It is important to pass this placeholder. Otherwise the program will not work.

How the topics look like, you can define yourself:

openhab/${item}/state
openhab/${item}/command
/openhab/${item}/state
/openhab/${item}/command
openhab/out/${item}/state
openhab/out/${item}/command
openhab/in/${item}/state
openhab/in/${item}/command
messages/states/${item}
messages/commands/${item}
/messages/states/${item}
/messages/commands/${item}
smarthome/${item}/state
smarthome/${item}/command
...

You still have to give the program a name and save it as a Python file. Let's say you name it eventbus.py, then you can call it like this:

python3 eventbus.py

A better suggestion is to run the program at system startup and start, stop or restart depending on openHAB. A service is recommended for this. Let's assume that we name the service <event_bus.service> and put it in /etc/system/system/:

[Unit]
Description=Python openHAB MQTT Event Bus
Requires=openhab.service
After=openhab.service
BindsTo=openhab.service
PartOf=openhab.service

[Service]
Type=simple
User=openhab
Group=openhab
UMask=002
ExecStart=/usr/bin/python3 </path/to/>eventbus.py
Restart=on-failure
RestartSec=30s

[Install]
WantedBy=openhab.service

Please replace </path/to/> with the path to your file and if you does not name your file eventbus.py you have to replace this too. As example it could be /home/ubuntu/eventbus.py If your username is ubuntu and you have placed the file in the home directory of your ubuntu user.

At least you have to run and enable your service:

sudo systemctl start event_bus.service
sudo systemctl enable event_bus.service

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

python_openhab_eventbus-1.0.0-py3-none-any.whl (7.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page