Migration von MQTT 1.x zu 2.5+

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Michdo93
Beiträge: 54
Registriert: 6. Jul 2021 13:39
Answers: 1

Migration von MQTT 1.x zu 2.5+

Beitrag von Michdo93 »

Hey, hey,

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>
Die MQTT-Eventbus-Konfiguration:

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}
Dann eben verschiedene "Clients":

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>
Die MQTT-Eventbus-Konfiguration:

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
Ich nutze zum "Debuggen" das Tool MQTT.fx. Verbinde mich mit dem Broker. Und scanne alle Topics. So erkenne ich bspw. ob ein Topic überhaupt vorhanden ist, wenn Daten nicht gesendet werden würden. Oder kann quasi den Nachrichtenaustausch "überwachen". Ist ja egal. Man kann ja auch testweise das System durcheinander bringen. Ein Fenster öffnen und dann eine Nachricht abschicken, dass dieses geschlossen wäre und so spezielle Grenzfälle betrachten.

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
Orientiere ich mich an openHAB 3, dann kann ich diesen Code ja bereitstellen, was das ganze ja leichter zu lesen macht:

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: "#"
Anstelle localhost oder 127.0.0.1 würde ich bei den anderen Instanzen 192.168.0.5 eintragen. Die Things sind wie gesagt online. Heißen einfach MQTT Broker.

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
Ich habe Python und DSL-Rules ausgetestet. Funktioniert beides nicht. Da die Last-Will-Topics funktionieren und die Things auch online sind, schaffe ich es nicht, die ganzen Items zu publishen.

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
Da fängt es schon an

Code: Alles auswählen

mqtt_eb_in_chan = "mqtt:broker:mosquitto:publishTrigger"
oder

Code: Alles auswählen

mqtt_eb_in_chan = "mqtt:broker:mosquitto:eventbus"
Mit

Code: Alles auswählen

mqtt_eb_puball = False
müsste ich bspw. folgendes machen:

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
Geht dies auch für Gruppen? Ich habe bspw. folgende Konstellation:

Code: Alles auswählen

Group gSmartHome "Smart-Home (Fakultaet IN)" <house>
Group gZimmer "Zimmer" <group> (gSmartHome)
Group gKonferenz "Konferenz" <corridor> (gZimmer)
Also würde es reichen, nur bei einer Gruppe dann bspw. [eb_update] hinzuzufügen, damit alle Untergruppen dies erkennen könnten? So, würde ich jetzt DSL Rules nutzen, natürlich entsprechend die Frage: Müssen alle Gruppen String sein? Ich habe quasi verschiedene Zimmer und in diesen Zimmern sind dann Gruppen je Gerätarte und je Gerät. Also quasi Lampen, Wandlampen und Wandlampe 1. Items dann in der untergeordnetsten Gruppe. Also viel verschachtelt. Ist dies vielleicht ein Problem? Ich würde ja eigentlich erwarten, dass die Gruppendefinition keine Rolle spielen sollte.

Code: Alles auswählen

Group:String PubItems_CMD
Group:String PubItems_UPD
Muss dies allgemein der Fall sein, also auch bei Python, wegen den States?

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
Müsste ja soweit passen.

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    
Scheinbar funktioniert dieses Member of Group bei meiner openHAB 2 Instanz nicht. Dachte daran, dass ich vielleicht noch etwas nachinstallieren muss für dieses Design Pattern. Ist dies bei Python bereits ein Problem? Irgendwie sender er maximal nur das raus, was in einer Alexa-Gruppe bei mir drinnen steht. Was auch immer dort anders wäre. Benötigt das Python-Skript im Community-Ordner dieses Member of Group Pattern? Ist dies in openHAB 3 Standard oder müsste ich es auch manuell einrichten? Bzw. was müsste ich wo hin kopieren und wie konfigurieren?

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
Und im Gegensatz zum Last-Will-Topic kann ich diese Rule einsetzen, für den Online Status:

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
Funktioniert aber offensichtlich ebenfalls nicht.

Es ist auch kein Fehler in MQTT.fx:

Code: Alles auswählen

mosquitto_sub -v -h <broker-ip> -p 1883 -t '#'
OpenHABVM/status OFFLINE
Das Thing ist online. Man muss manchmal nur den Cache löschen...

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 '#'


Also der Broker wäre jetzt bspw. auf dem localhost oder auch unter 127.0.0.1 zu finden und liefert nichts zurück. Würde ich jetzt openHAB neustarten, würde das Thing "offline" gehen und seinen Last-Will-Topic versenden. Das ist aber auch wirklich das einzige, was funktioniert.

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.

Benutzeravatar
udo1toni
Beiträge: 15269
Registriert: 11. Apr 2018 18:05
Answers: 245
Wohnort: Darmstadt

Re: Migration von MQTT 1.x zu 2.5+

Beitrag von udo1toni »

Also, wenn Du auf OH3 gehen willst, vergiss den mqtt Event Bus, den gibt es nicht mehr. Genau für Deine Anwendung, mehrere openHAB Instanzen miteinander zu verbinden, kannst Du das Remote Addon verwenden, dazu ist es gedacht. Meines Wissens kann openHAB3 damit sogar auf openHAB2 Instanzen zugreifen.

Was MQTT betrifft: Die Konfiguration in mqtt.cfg entspricht dem MQTT Broker Thing (der Bridge) in MQTT2/3. Ansonsten bietet es sich an, einzelne Devices als einzelne Things anzulegen, und darunter pro Eigenschaft einen Channel.
Das stateTopic abonniert openHAB um über Publishes benachrichtigt zu werden, auf das commandTopic published openHAB den Payload selbst.
openHAB4.3.6 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Michdo93
Beiträge: 54
Registriert: 6. Jul 2021 13:39
Answers: 1

Re: Migration von MQTT 1.x zu 2.5+

Beitrag von Michdo93 »

Der untere Teil ist mir klar. Danke trotzdem.

Ich würde auf den MQTT-Eventbus nur ungern verzichten. Aber dann könnte ich mir eventuell ein Python-Skript zurechtlegen.

Das Remote openHAB Binding (Add-on) nutzt leider kein MQTT. Das ich die openHAB Instanzen über das remote openHAB Binding miteinander kommunzieren lasse, wäre nur ein Teil, der gewünschten Lösung. Es verwendet REST. Ich habe sehr viele Studentenprojekte, sehr viel Programmcode, was mit openHAB interagiert. Egal ob Roboter, MagicMirror, Unity 3D-Modelle, Hololens usw. Da müsste ich sonst hingehen und jeden Programmcode umstellen, sollte ich über MQTT nicht publishen und subscriben können bzw. die Topics für state und command zur Verfügung stellen usw.

Mit verschiedenen Präsentationen für Unternhemen, Nachfolge-Projekte usw. würde immer wieder mal etwas anderes präsentiert werden. Ich bin ehrlich, ich habe keine Ahnung, was alles im Archiv ist und eventuell mal rausgekramt werden würde. Das könnten ja auch tausenden Smartphone Apps sein, die MQTT nutzen.

Bei den Design Pattern hatte ich ja zu openHAB 2.5 einen Eventbus gefunden:
https://community.openhab.org/t/mqtt-2- ... -bus/76938

Also noch bin ich ja auf openHAB 2.5. Dort funktioniert er leider auch nicht. Nachdem Upgrade würde ja dann das MQTT 1.x Binding verschwinden und ich hätte gar nicht mehr die Möglichkeit obiges nachzubilden. Nur in meiner VM habe ich openHAB 3, was quasi genau gleich wäre, wie dass was ich in openHAB 2.5 habe, nur quasi als Untersuchung, was ich umstellen müsste.



Wenn es komplett nicht mehr gehen sollte und ich eben aus den openhab-rules-tools von Herrn Khoshak eben nicht den Eventbus nutzen kann, müsste ich mir natürlich etwas einfallen lassen.

Ich probiere jetzt mal einfach ein Python-Script aus, mit dem ich versuche die REST-API zu nutzen und dass dann per MQTT publishe. Beim Subscriben müsste ich ja die REST-API dann wiederrum nutzen und State oder Command setzen. Ich meine ich habe auch ein Bash-Script mit dem ich über REST Werte setze, die ich in openHAB dann sehe. Prinzipiell genau dieselbe Vorgehensweise.

Michdo93
Beiträge: 54
Registriert: 6. Jul 2021 13:39
Answers: 1

Re: Migration von MQTT 1.x zu 2.5+

Beitrag von Michdo93 »

Ah okay, ein Blick in die REST API verrät mir ja, dass ich maximal dann States darüber abrufen kann:

Code: Alles auswählen



    get /items
        Get all available items.

    put /items
        Adds a list of items to the registry or updates the existing items.

    delete /items/{itemName}/members/{memberItemName}
        Removes an existing member from a group item.

    put /items/{itemName}/members/{memberItemName}
        Adds a new member to a group item.

    delete /items/{itemname}
        Removes an item from the registry.

    get /items/{itemname}
        Gets a single item.

    post /items/{itemname}
        Sends a command to an item.

    put /items/{itemname}
        Adds a new item to the registry or updates the existing item.

    delete /items/{itemname}/metadata/{namespace}
        Removes metadata from an item.

    put /items/{itemname}/metadata/{namespace}
        Adds metadata to an item.

    get /items/{itemname}/state
        Gets the state of an item.

    put /items/{itemname}/state
        Updates the state of an item.

    delete /items/{itemname}/tags/{tag}
        Removes a tag from an item.

    put /items/{itemname}/tags/{tag}
        Adds a tag to an item.

Ich glaube ich analyisere den Code dann doch mal näher, vielleicht fällt mir eine Alternative ein. Oder ich vergebe ein Studentenprojekt in die Richtung :lol:

Benutzeravatar
udo1toni
Beiträge: 15269
Registriert: 11. Apr 2018 18:05
Answers: 245
Wohnort: Darmstadt

Re: Migration von MQTT 1.x zu 2.5+

Beitrag von udo1toni »

Ich verstehe nun aber nicht so ganz, warum Du überhaupt mehrere openHAB Instanzen laufen lassen willst/musst. Und das mit mqtt müsstest Du auch noch mal erläutern. Das mqtt2 Addon kann (bis auf den event Bus) alles, was mit dem mqtt1 Binding geht. Es kann allerdings dank Thing-Modell sogar bestimmte Ginge besser (oder effizienter) als mqtt1.
openHAB4.3.6 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Michdo93
Beiträge: 54
Registriert: 6. Jul 2021 13:39
Answers: 1

Re: Migration von MQTT 1.x zu 2.5+

Beitrag von Michdo93 »

Also ich hab dummerweise das Pech ein Labor zu betreuen für IT-Studenten. Wir haben mehrere Raspberry Pi`s an denen sie lokal arbeiten können und Rules definieren und andere Dinge. Da gehen wir quasi nur hin und sagen, dass auf diesen Raspberry Pi`s entsprechend nur diese bestimmte Items zur Verfügung sind. Von openHAB aus könnten Sie damit quasi nicht die anderen Projektgruppen stören und dort andere Items bedienen um Geräte ein- und auszuschalten. Wobei das gar nicht mal so relevant wäre. Die verschiedenen Raspbbery Pi`s bräuchte es ja theoretisch gar nicht. Wenn es nur um die Bedienung der Geräte hier im Labor ginge, dann würde ja der Server auf dem die VM läuft ausreichen.

Jetzt haben eben Studentenprojekte Zugriff auf Geräte über openHAB mittels MQTT. Egal ob unser Roboter die Rollos steuert, die Jalousien, Lichter, den Beamer etc. Oder ob ein 3D-Modell virtualisiert das Labor steuern kann oder wir mit einer VR-Brille durch das Labor gehen und über Gestiken Geräte steuern. All das funktioniert, in dem diese Geräte den openHAB-Server nutzen über MQTT. Ich meine es ist schon cool mit VR-Brille durch zu laufen und Geräte zu bedienen. Oder einen Roboter zu haben, der hier durchfährt und verschiedene Geräte steuert. Der Grund warum wir openHAB nutzen ist ja der, dass man ja die Geräte unter einen Hut kriegen muss. Die Philips Hue Lampen wären ja unkritisch. Das kann man ja von allen Geräten steuern über die REST-Api. Aber auf einigen Geräten oder in einigen Programmiersprachen und anderen Dingen, kannst du eben die Geräte nicht direkt ansprechen oder einbinden oder wie auch immer. Da bietet uns ja openHAB sehr viele Möglichkeiten über Bindings an. Dann eben die Items fertig und zack, der Umweg über openHAB und es wäre alles steuerbar.

Hab aber jetzt gemerkt, dass dieser Event Bus den man quasi für openHAB 2 nach installieren kann gar nicht funktioniert.

Michdo93
Beiträge: 54
Registriert: 6. Jul 2021 13:39
Answers: 1

Re: Migration von MQTT 1.x zu 2.5+

Beitrag von Michdo93 »

Ich trenne dies bewusst in zwei Nachrichten.

Also der Channel für MQTT 2.5 ist scheinbar offline. Das Thing zu dem MQTT Broker ist online. Mosquitto auch. Subscribe ich z.b. OpenHABVM/status, erhalte ich OFFLINE.

Im Jython-Code steht ja bspw.

Code: Alles auswählen

@log_traceback
def online(event):
    """Publishes ONLINE to mqtt_eb_name/status on System started."""

    init_logger.info("Reporting the event bus as ONLINE")
    from configuration import mqtt_eb_broker, mqtt_eb_name
    actions.get("mqtt", mqtt_eb_broker).publishMQTT("{}/status"
                                                    .format(mqtt_eb_name),
                                                    "ONLINE", True)

Geht leider nicht. Ich bin mir sicher oben alle anderen Informationen zum Thing und zur Konfiguration gegeben zu haben.

Was geht sind aber definitiv die Helper Libraries:

Code: Alles auswählen


13:30:10.164 [DEBUG] [re.automation.internal.RuleEngineImpl] - The trigger 'Time_cron_0_10_e1372dc0e09911eba3b60242f41ee9fd_e1821970e09911ebac930242f41ee9fd' of rule '74f10848-ff84-46de-9d7d-2fa440c07329' is triggered.
13:30:10.169 [INFO ] [jsr223.javascript                    ] - |Hello World JavaScript!|
13:30:10.168 [INFO ] [smarthome.event.RuleStatusInfoEvent  ] - 74f10848-ff84-46de-9d7d-2fa440c07329 updated: RUNNING
13:30:10.168 [INFO ] [jsr223.groovy                        ] - Hello World Groovy!
13:30:10.175 [DEBUG] [re.automation.internal.RuleEngineImpl] - The rule '768f5a9a-7c7e-4ae7-a878-d75f7ffaafc0' is executed.
13:30:10.165 [INFO ] [.Jython Hello World (cron decorators)] - Hello World Python!
13:30:10.167 [DEBUG] [re.automation.internal.RuleEngineImpl] - The trigger 'aTimerTrigger' of rule 'b1cde4b0-1b2e-4957-8247-261dffa0fbac' is triggered.
13:30:10.166 [DEBUG] [re.automation.internal.RuleEngineImpl] - The trigger '9ec06fc0-f5c3-4496-856a-cca4fca68ce8-HelloWorld-js' of rule '768f5a9a-7c7e-4ae7-a878-d75f7ffaafc0' is triggered.
13:30:10.175 [DEBUG] [re.automation.internal.RuleEngineImpl] - The rule 'b1cde4b0-1b2e-4957-8247-261dffa0fbac' is executed.
Also alles ist openhab:openhab und +x zugeordnet. Hab dies eben noch einmal gecheckt.

Code: Alles auswählen

sudo apt install mosquitto mosquitto-clients
Logisch, merkt man ja auch beim Thing bereits. Ansonsten von dem Pfad, wo man die openhab_rules_tools entpackt hat:

Code: Alles auswählen

cp -r rules_utils/automation $OH_CONF
cp -r mqtt_eb/automation $OH_CONF
Alles im richtigen Verzeichnis.

Nicht funktionieren bedeutet für mich: Keine der Logs ist zu sehen, die mqtt_eb schreiben sollte.

Dann hole ich mal aus:

Installation Next-Generation Rule Engine

OpenHAB --> PaperUI --> Addons --> Misc --> Next-Generation Rule Engine --> Install

Installation openHAB Helper Libraries

Code: Alles auswählen

sudo systemctl stop openhab2.service
cd ~
wget https://github.com/openhab-scripters/openhab-helper-libraries/archive/master.zip
unzip master.zip

sudo cp -R ~/openhab-helper-libraries/Core/* /etc/openhab2/
sudo chmod -R 777 /etc/openhab2/automation
sudo chown -R openhab:openhab /etc/openhab2/automation
Installation Jython

Code: Alles auswählen

sudo mv /etc/openhab2/automation/lib/python/configuration.py.example /etc/openhab2/automation/lib/python/configuration.py
sudo mv /etc/openhab2/automation/lib/python/personal/__init__.py.example /etc/openhab2/automation/lib/python/personal/__init__.py

sudo nano /etc/default/openhab2
EXTRA_JAVA_OPTS="-Xms1024m -Xmx1536m -XX:+HeapDumpOnOutOfMemoryError -Xbootclasspath/a:/etc/openhab2/automation/jython/jython-standalone-2.7.0.jar -Dpython.home=/etc/openhab2/automation/jython -Dpython.path=/etc/openhab2/automation/lib/python"

sudo mkdir -p /etc/openhab2/automation/jython
wget https://repo1.maven.org/maven2/org/python/jython-standalone/2.7.0/jython-standalone-2.7.0.jar
sudo mv ~/jython-standalone-2.7.0.jar /etc/openhab2/automation/jython/jython-standalone-2.7.0.jar
sudo chmod -R 777 /etc/openhab2/automation/jython/
sudo chown -R openhab:openhab /etc/openhab2/automation/jython/

sudo cp -R ~/openhab-helper-libraries/Script\ Examples/Python/hello_world.py /etc/openhab2/automation/jsr223/python/personal/hello_world.py
sudo chmod +x /etc/openhab2/automation/jsr223/python/personal/hello_world.py
sudo chown -R openhab:openhab /etc/openhab2/automation/jsr223/python/personal/hello_world.py
Installation JavaScript

Code: Alles auswählen

sudo mv /etc/openhab2/automation/lib/javascript/configuration.js.example /etc/openhab2/automation/lib/javascript/configuration.js

sudo cp -R ~/openhab-helper-libraries/Script\ Examples/JavaScript/HelloWorld.js /etc/openhab2/automation/jsr223/javascript/personal/HelloWorld.js
sudo chmod +x /etc/openhab2/automation/jsr223/javascript/personal/HelloWorld.js
sudo chown -R openhab:openhab /etc/openhab2/automation/jsr223/javascript/personal/HelloWorld.js
Installation Groovy

Code: Alles auswählen

wget https://dl.bintray.com/groovy/maven/apache-groovy-binary-2.4.12.zip

oder
wget https://archive.apache.org/dist/groovy/2.4.12/distribution/apache-groovy-binary-2.4.12.zip

unzip apache-groovy-binary-2.4.12.zip

sudo mv ~/groovy-2.4.12/lib/groovy*.jar /usr/share/openhab2/runtime/lib/ext
sudo chmod +x /usr/share/openhab2/runtime/lib/ext/*.jar
sudo chown -R openhab:openhab /usr/share/openhab2/runtime/lib/ext

sudo cp -R ~/openhab-helper-libraries/Script\ Examples/Groovy/HelloWorld.groovy /etc/openhab2/automation/jsr223/groovy/personal/HelloWorld.groovy
sudo chmod +x /etc/openhab2/automation/jsr223/groovy/personal/HelloWorld.groovy
sudo chown -R openhab:openhab /etc/openhab2/automation/jsr223/groovy/personal/HelloWorld.groovy

Hab dann HelloWorld bearbeitet:

Code: Alles auswählen

sudo nano /etc/openhab2/automation/jsr223/python/personal/hello_world.py
sudo nano /etc/openhab2/automation/jsr223/javascript/personal/HelloWorld.js
sudo nano /etc/openhab2/automation/jsr223/groovy/personal/HelloWorld.groovy
Also einfach, wie ihr bereits gesehen habt, hinzugefügt, dass ich am Satz schon erkenne, ob Python/Jython, JavaScript oder Groovy.

Damit all dies funktioniert:

Code: Alles auswählen

sudo rm -rf /var/lib/openhab2/cache/*
sudo rm -rf /var/lib/openhab2/tmp/*

sudo systemctl start openhab2.service
sudo systemctl restart openhab2.service
Dann habe ich mich mit der Karaf-Konsole verbunden:

Code: Alles auswählen

log:set DEBUG org.openhab.core.automation
log:set DEBUG jsr223
log:tail
Klar für den MQTT Eventbus mqtt_eb wäre Groovy und JavaScript nicht notwendig. Aber ich dokumentiere ja immer, was man wie macht. Alle HelloWord-Beispiele gingen ja nachweislich.

Ergo kann der Fehler nur in der Installation von den openhab_rules_tools liegen...

Und das waren nur zwei Copy-Befehle, dann wieder chmod und chown.

Oder bin ich mit dem Entschluss schon daneben, dass mqtt_eb nicht funktioniert? Wenn mqtt_eb funktionieren würde, müsste er doch statt OFFLINE dann ONLINE im Topic als Message versenden.

Michdo93
Beiträge: 54
Registriert: 6. Jul 2021 13:39
Answers: 1

Re: Migration von MQTT 1.x zu 2.5+

Beitrag von Michdo93 »

Gut, dann doch noch die Installation, die scheinbar ja nicht so glücklich war:

Code: Alles auswählen

cd ~
git clone https://github.com/rkoshak/openhab-rules-tools.git
cp -r ~/openhab-rules-tools/rules_utils/automation $OH_CONF
cp -r ~/openhab-rules-tools/mqtt_eb/automation $OH_CONF

sudo chmod -R 777 /etc/openhab2/automation
sudo chown -R openhab:openhab /etc/openhab2/automation

cat $OH_CONF/automation/lib/python/configuration.py.example | xclip

sudo nano $OH_CONF/automation/lib/python/configuration.py
Dann natürlich das über xclip Kopierte einfügen und anpassen.

Benutzeravatar
udo1toni
Beiträge: 15269
Registriert: 11. Apr 2018 18:05
Answers: 245
Wohnort: Darmstadt

Re: Migration von MQTT 1.x zu 2.5+

Beitrag von udo1toni »

Es gibt in mqtt2 keinen Event Bus. Ich dachte, das hättest Du schon vorher erkannt?

Du kannst allenfalls alle Items auf mqtt verfügbar machen (jedes einzelne).
openHAB4.3.6 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Michdo93
Beiträge: 54
Registriert: 6. Jul 2021 13:39
Answers: 1

Re: Migration von MQTT 1.x zu 2.5+

Beitrag von Michdo93 »

Nein, sorry, hatte ich nicht erkannt. Dachte eigentlich dieses Jython-Programm würde dies dann ermöglichen.

Ich teste morgen mal, einen Teil auf REST umzustellen und zumindest eine Raspberry Pi mittels dem Remote openHAB Binding dann anzubinden.

Ein Gedanke der mir kam ist ja: http://localhost:8080/rest/items liefert mir ja alle Items. http://localhost:8080/rest/items/iKuech ... e_Leistung bspw. für iKueche_Homematic_Steckdose_Leistung.

Ich kann ja einen Cronjob/Crontask nutzen und theoreitsch ein Jython- oder JavaScript-Programm schreiben. Also eine Brdige schreiben. Einmal MQTT zu REST und einmal REST zu MQTT. Anhand von dem Attribut Name könnte ich ja das Topic festlegen und so mit einer Schleife gerade alle Items publishen. Später beim Subscriben dann umgekehrt: Anhand vom letzten "Pfad" der Topic-Adresse wieder die Zuordnung zum Item.

Definitiv erst nach meinem Urlaub :D Aber zumindest geht das mit "Alle" dann über den Umweg REST sicherlich recht angenehm. Weil dann kann man dort schleifen nutzen und braucht nicht irgendwelche Trigger für Member of Group, die gar nicht funktionieren oder mit tausenden Veraschachtelungen Probleme macht.

Ich kann sowohl in Python REST APIs abfragen, als auch mit JavaScript MQTT nutzen. Also effektiv wäre also beides denkbar. Dann könnte man dies doch mit ein wenig Aufwand programmiert bekommen, dass man MQTT nutzt.

Man hätte dann aber nur state und nicht state und command.

Weil das hier vom Prinzip ging nicht:

Code: Alles auswählen

rule "Publish all"
when 
      Member of myGroupOfItems changed
then
   val actions = getActions("mqtt","mqtt:broker:myUnsecureBroker")
   actions.publishMQTT("allItems/"+triggeringItem.name,triggeringItem.state.toString)
end
Oder:

Code: Alles auswählen

from core.rules import rule
from core.triggers import when

@rule("Publish all")
@when("Member of OutItems changed")
def MQTTPublishOut(event):
    output1 = event.itemName
    output2 = str(event.itemState)
    actions.get("mqtt","mqtt:broker:f79d2a84").publishMQTT("allItemsout/"+output1,output2)

@rule("Receive all")
@when("Channel mqtt:broker:f79d2a84:TriggerIn triggered")
def MQTTPublishIn(event):
    input1 = event.event
    input2 = input1.split("/")
    input3 = input2[1].split("#")
    events.sendCommand(input3[0], input3[1])
Ich habe den Hinweis, dass ich in /etc/openhab/automation/lib/python/core/triggers.py auch erst einmal die Trigger hierfür freischalten müsste. Aber so wie ich das sehe, wäre alles freigeschalten:

https://community.openhab.org/t/mqtt-br ... -2-x/71769

Stehen ja in der Datei nur Kommentare, was welche Klasse tut, aber die Funktionen sind freigeschalten. Sehe nicht, dass da irgendeine Funktion auskommentiert wäre. Wäre dies also vielleicht doch möglich und ich hätte bloß einen Fehler gemacht?

Nebenbei bemerkt. Ein REST-Abfrage in Python klappt. Aber in Jython ist dies vielleicht nicht möglich. Gleicher Programmcode, kennt den PYTHONPATH, aber ist immer noch am Laden. Selbst wenn jetzt noch eine Antwort kommt, ist dies erheblich langsamer.

Antworten