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
Built Distribution
Hashes for python_openhab_crud-0.2.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 12535a6c371df571443c1e9875d6399b8a3f5ecbe89d0a020337dd2386be703f |
|
MD5 | 6d9eb8b239a1d39a5de0256cb861af1e |
|
BLAKE2b-256 | e6f2ef18d3c625b278e079c9b0ee83c2d9e3be81487a339fdc7de4dee7f62d5b |