Migration von MQTT 1.x zu 2.5+
ich könnte Hilfe gebrauchen, wie ich vom MQTT Binding 1.x zu 2.5+ migriere. Derzeit läuft auf meinem Ubuntu Server und mehreren Raspberry Pi`s noch openHAB 2.5.12-1. Ich habe innerhalb einer separaten VM zumindest mal das vom Ubuntu Server migriert. Heißt zunächst openHAB 2.5 installiert und dann zunächst Ubuntu auf 20.04 geupgraded, dann Zulu-8 auf Zulu-11 geupgraded. Hierbei läuft openHAB 2.0 normal weiter. Bin dann hingegangen und habe openHAB auf 3.0.2 geupgraded. Things, Items etc. sind beibehalten worden. Bei Add-ons sind dann die lokal installierten verschwunden und eben alle Legacy 1.x Bindings, was ja zu erwarten ist. Gut, dass in /usr/share/openhab2/addons (neuer Pfad: usr/share/openhab/addons) installierte PlayStation Binding kann dann nach installiert werden. Dort würde das Thing nicht funktionieren. Bei dem Samsung TV ähnlich. Gehe aber einfach davon aus, dass dies daran liegt, dass man an beiden Endgeräten den Zugriff von anderen Geräten (in diesem Fall openHAB) erlauben muss.
Ich würde natürlich kein Thema zu MQTT aufmachen, wenn es mir nicht um MQTT gehen würde. In openHAB 2.5 habe ich für den Eventbus die Experimental Rule Engine installiert, die openHAB Helper Libraries, Jython und die openHAB Rules Tools. Habe mich an Rich Khoshak`s Anleitung zum Eventbus orientiert, es aber leider nicht zum Laufen bekommen:
https://community.openhab.org/t/mqtt-2- ... -bus/76938
Ist ja klar, dass ich in Vorarbeit mal austesten muss, wie ich mit MQTT weitermache. Bei openHAB 2 kann ich ja noch auf MQTT 1.x zurückgreifen, dort wäre es ja nicht notwendig. Für openHAB 2 und dann demnächst auch auf openHAB 3 geupgraded würde ja diesselbe Lösung dann funktionieren.
Ziel ist es, dass ich auf einer Instanz von allen Items die States publishe und die Commands subscribe. Während alle anderen Instanzen die States subscribed und die Commands published!
Ich habe viele unterschiedliche Geräte, die Informationen von openHAB über MQTT beziehen. Das sind Roboter, dass ist eine Hololens mit der wir dann Geräte steuern usw. Sehr viele unterschiedliche Projekte, die wir nicht von MQTT auf REST umstellen wollen. Wir bevorzugen eigentlich das Publisher Subscriber Modell, während REST ja Request Response nutzt.
openHAB Server
Die MQTT-Konfiguration:
Code: Alles auswählen
cat /etc/openhab2/services/mqtt.cfg
#
# Define your MQTT broker connections here for use in the MQTT Binding or MQTT
# Persistence bundles. Replace <broker> with an ID you choose.
#
# URL to the MQTT broker, e.g. tcp://localhost:1883 or ssl://localhost:8883
MQTTBroker.url=tcp://localhost:1883
# Optional. Client id (max 23 chars) to use when connecting to the broker.
# If not provided a random default is generated.
#<broker>.clientId=<clientId>
# Optional. True or false. If set to true, allows the use of clientId values
# up to 65535 characters long. Defaults to false.
# NOTE: clientId values longer than 23 characters may not be supported by all
# MQTT servers. Check the server documentation.
#<broker>.allowLongerClientIds=false
# Optional. User id to authenticate with the broker.
#MQTTBroker.user=<nope>
# Optional. Password to authenticate with the broker.
#MQTTBroker.pwd=<nope>
# Optional. Set the quality of service level for sending messages to this broker.
# Possible values are 0 (Deliver at most once),1 (Deliver at least once) or 2
# (Deliver exactly once). Defaults to 0.
MQTTBroker.qos=0
# Optional. True or false. Defines if the broker should retain the messages sent to
# it. Defaults to false.
#<broker>.retain=<retain>
# Optional. True or false. Defines if messages are published asynchronously or
# synchronously. Defaults to true.
MQTTBroker.async=false
# Optional. Defines the last will and testament that is sent when this client goes offline
# Format: topic:message:qos:retained <br/>
#<broker>.lwt=<last will definition>
Code: Alles auswählen
cat /etc/openhab2/services/mqtt-eventbus.cfg
# Name of the broker as it is defined in the openhab.cfg. If this property is not available, no event bus MQTT binding will be created.
broker=MQTTBroker
# When available, all status updates which occur on the openHAB event bus are published to the provided topic. The message content will
# be the status. The variable ${item} will be replaced during publishing with the item name for which the state was received.
statePublishTopic=/messages/states/${item}
# When available, all commands which occur on the openHAB event bus are published to the provided topic. The message content will be the
# command. The variable ${item} will be replaced during publishing with the item name for which the command was received.
#commandPublishTopic=
# When available, all status updates received on this topic will be posted to the openHAB event bus. The message content is assumed to be
# a string representation of the status. The topic should include the variable ${item} to indicate which part of the topic contains the
# item name which can be used for posting the received value to the event bus.
#stateSubscribeTopic=
# When available, all commands received on this topic will be posted to the openHAB event bus. The message content is assumed to be a
# string representation of the command. The topic should include the variable ${item} to indicate which part of the topic contains the
# item name which can be used for posting the received value to the event bus.
commandSubscribeTopic=/messages/commands/${item}
Die MQTT-Konfiguration:
Code: Alles auswählen
cat /etc/openhab2/services/mqtt.cfg
#
# Define your MQTT broker connections here for use in the MQTT Binding or MQTT
# Persistence bundles. Replace <broker> with an ID you choose.
#
# URL to the MQTT broker, e.g. tcp://localhost:1883 or ssl://localhost:8883
MQTTBroker.url=tcp://192.168.0.5:1883
# Optional. Client id (max 23 chars) to use when connecting to the broker.
# If not provided a default one is generated.
#<broker>.clientId=<clientID>
# Optional. User id to authenticate with the broker.
#MQTTBroker.user=<nope>
# Optional. Password to authenticate with the broker.
#MQTTBroker.pwd=<nope>
# Optional. Set the quality of service level for sending messages to this broker.
# Possible values are 0 (Deliver at most once),1 (Deliver at least once) or 2
# (Deliver exactly once). Defaults to 0.
#<broker>.qos=<qos>
# Optional. True or false. Defines if the broker should retain the messages sent to
# it. Defaults to false.
#MQTTBroker.retain=false
# Optional. True or false. Defines if messages are published asynchronously or
# synchronously. Defaults to true.
MQTTBroker.async=false
# Optional. Defines the last will and testament that is sent when this client goes offline
# Format: topic:message:qos:retained <br/>
#<broker>.lwt=<last will definition>
Code: Alles auswählen
cat /etc/openhab2/services/mqtt-eventbus.cfg
# Name of the broker as it is defined in the openhab.cfg. If this property is not available, no event bus MQTT binding will be created.
broker=MQTTBroker
# When available, all status updates which occur on the openHAB event bus are published to the provided topic. The message content will
# be the status. The variable ${item} will be replaced during publishing with the item name for which the state was received.
#statePublishTopic=
# When available, all commands which occur on the openHAB event bus are published to the provided topic. The message content will be the
# command. The variable ${item} will be replaced during publishing with the item name for which the command was received.
commandPublishTopic=/messages/commands/${item}
# When available, all status updates received on this topic will be posted to the openHAB event bus. The message content is assumed to be
# a string representation of the status. The topic should include the variable ${item} to indicate which part of the topic contains the
# item name which can be used for posting the received value to the event bus.
stateSubscribeTopic=/messages/states/${item}
# When available, all commands received on this topic will be posted to the openHAB event bus. The message content is assumed to be a
# string representation of the command. The topic should include the variable ${item} to indicate which part of the topic contains the
# item name which can be used for posting the received value to the event bus.
#commandSubscribeTopic=
- Also alle verbinden sich mit dem Broker auf der IP-Adresse von 192.168.0.5 und dem Port 1883.
- Die Items haben auf "Server" und "Client" dieselben Namen
- Alle openHAB-Instanzen nutzen dieselben Topics
Was mir bislang nicht gelungen ist, sind dann Topics zu scannen, die auf das MQTT Binding entweder 2.x oder 3.x hinweist. Also egal ob openHAB 2 oder openHAB 3 in der VM. Maximal das Last-Will-Topic und den Status Offline.
Was funktioniert ist, dass alle Instanzen sich mit ein und denselben Broker verbinden können. Zumindest sind alle Things online. Was ich zufällig mal hinbekommen hatte war, dass mit puball in der Python-Konfiguration sogar ein paar Topics vorhanden waren. Aber nicht alle und irgendwie kriege ich dies auch nicht so ganz reproduziert.
Die Mosquitto-Konfiguration:
Code: Alles auswählen
cat /etc/mosquitto/mosquitto.conf
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
allow_anonymous true
socket_domain ipv4
Code: Alles auswählen
UID: mqtt:broker:mosquitto
label: MQTT Broker
thingTypeUID: mqtt:broker
configuration:
lwtQos: 0
publickeypin: false
clientID: OpenHABVM
keepAlive: 60
lwtMessage: OFFLINE
secure: false
lwtTopic: OpenHABVM/status
certificatepin: true
password: <nope>
qos: 0
reconnectTime: 60000
port: 1883
host: localhost
lwtRetain: true
enableDiscovery: true
username: <nope>
channels:
- id: openhabvm-updates
channelTypeUID: mqtt:publishTrigger
label: OpenHABVM Updates
description: null
configuration:
stateTopic: openhabvm/out/+/state
separator: "#"
Auf dem Server sind Mosquitto und Mosquitto-Clients installiert. Auf den "Clients" würden die Mosquitto-Clients genügen:
Code: Alles auswählen
sudo apt install mosquitto mosquitto-clients
Natürlich würde ich gerne am Ende da rauskommen, wo ich mit MQTT 1.x derzeit bin. Ich sollte diese Struktur nachbauen. Bevor ich irgendwelche Items subscriben kann, sollte ich sie ja auch erst einmal publishen können, oder? Egal wie das letztlich funktioniert: Ich bekomme die Verknüpfung von Items zu MQTT einfach nicht hin.
Muss ich bei den Items noch etwas hinzufügen?!? Müssen die irgendwie getagged werden? Vielleicht überlese ich ja auch etwas und sehe den Fehler in meiner Konfiguration einfach nicht.
Ich weiß nicht, wie viele einen MQTT Eventbus nutzen anstelle von dem openHAB Remote Binding, die REST API etc. Aber sicherlich gibt es Leute, die MQTT ja auch anderweitig einsetzen und da vielleicht ähnliche Probleme hatten.
Ich gehe jetzt mal beide Versuche durch. Ob jetzt Python oder DSL Rules am Ende geschickter sind, ist ja egal. Ich kann von Python, Groovy und JavaScript HelloWorld loggen, also funktioniert in openHAB 2 die Rule Engine und in openHAB 3 die Automation ebenfalls.
Code: Alles auswählen
cat /etc/openhab/automation/lib/python/configuration.py
# -*- coding: utf-8 -*-
LOG_PREFIX = "jsr223.jython"
admin_email = "<nope>"
openhabHost = "localhost"
openhabPort = "8080"
# The Channel ID of the MQTT Event Bus subscription channel
mqtt_eb_in_chan = "mqtt:broker:mosquitto:publishTrigger"
# The name to use for this instance of openHAB, forms the root of the MQTT topic
# hierarchy.
mqtt_eb_name = "OpenHABVM-Test"
# Thing ID for the MQTT broker Thing.
mqtt_eb_broker = "mqtt:broker:mosquitto"
# Optional flag, when True all Item commands and updates are published.
# Defaults to True.
mqtt_eb_puball = True
Code: Alles auswählen
mqtt_eb_in_chan = "mqtt:broker:mosquitto:publishTrigger"
Code: Alles auswählen
mqtt_eb_in_chan = "mqtt:broker:mosquitto:eventbus"
Code: Alles auswählen
mqtt_eb_puball = False
Code: Alles auswählen
Switch Foo [eb_command] // publishes only commands to the event bus
String Bar [eb_update] // publishes only updates to the event bus
Number Baz [eb_command,eb_update] // publishes both command and updates to the event bus
Code: Alles auswählen
Group gSmartHome "Smart-Home (Fakultaet IN)" <house>
Group gZimmer "Zimmer" <group> (gSmartHome)
Group gKonferenz "Konferenz" <corridor> (gZimmer)
Code: Alles auswählen
Group:String PubItems_CMD
Group:String PubItems_UPD
Machen wir zunächst mit der Python-Konfiguration noch weiter...
Code: Alles auswählen
/etc/openhab/automation/lib/python/community$ ls
'__init__$py.class' __init__.py 'rules_utils$py.class' rules_utils.py
/etc/openhab/automation/jsr223/python/community/mqtt_eb$ ls
mqtt_eb_pub.py mqtt_eb_sub.py
Muss ich in den Items etwas konfigurieren? Also MQTT Channels? Dachte das geht dann allgemein... Und muss man inzwischen eine Transformation anwenden? Vielleicht kann ich ja nur Strings versenden.
Habe ich für MQTT mit Python (Jython) etwas ausgelassen?
Wenn ich jetzt statt Python dann DSL Rules verwenden würden, hätte ich:
Code: Alles auswählen
val eb_br = "mqtt:broker:mosquitto" // Thing ID of the broker connection
val eb_name = "remote" // <client ID>
rule "Publish commands to the event bus"
when
Member of PubItems_CMD received command // eb_cmd_gr
then
val mqttActions = getActions("mqtt",eb_br)
mqttActions.publishMQTT(eb_name+"/out/"+triggeringItem.name+"/command",receivedCommand.toString)
end
rule "Publish updates to the event bus"
when
Member of PubItems_UPD received update // eb_upd_gr
then
val mqttActions = getActions("mqtt",eb_br)
mqttActions.publishMQTT(eb_name+"/out/"+triggeringItem.name+"/state",triggeringItem.state.toString)
end
Theoretisch hätte ich ja auch noch diese Rule später:
Code: Alles auswählen
rule "Subscribe for commands and updates from the event bus"
when
Channel "mqtt:broker:broker:remote-updates" triggered
then
var topic = receivedEvent.toString.split("#").get(0)
var state = receivedEvent.toString.split("#").get(1)
val itemName = topic.split("/").get(2)
val type = topic.split("/").get(3)
if(type == "command") sendCommand(itemName, state)
else postUpdate(itemName, state)
end
Code: Alles auswählen
rule "Eventbus Online"
when
System started or
Thing mqtt:broker:mosquitto changed to ONLINE
then
logInfo("mqtt-eb", "Reporting eventbus as online")
getActions("mqtt", "mqtt:broker:mosquitto").publishMQTT("openhab-remote/status", "ONLINE", true)
end
Es ist auch kein Fehler in MQTT.fx:
Code: Alles auswählen
mosquitto_sub -v -h <broker-ip> -p 1883 -t '#'
OpenHABVM/status OFFLINE
Code: Alles auswählen
sudo systemctl stop mosquitto.service
sudo rm /var/lib/mosquitto/mosquitto.db
sudo systemctl start mosquitto.service
mosquitto_sub -v -h <broker-ip> -p 1883 -t '#'
Ich komme daher zur Annahme, dass weder die Python Rules noch die DSL Rules funktionieren.
Hoffe ehrlicherweise, dass man mir da weiterhelfen kann. Komme mir irgendwie sau dumm vor. Das sollte doch funktionieren und irgendetwas fehlt mir.
Ich habe nur einen MQTT Broker erstellt. Kein MQTT System Broker und auch kein Generic MQTT Thing.
Liebe Grüße
Michi
PS: Sollten noch Informationen fehlen, dann bitte Bescheid geben, ich ergänze diese dann logischerweise.