NEWS
Frage: MQTT Server (Broker) in Adapter benötigt
-
Hi,
ich möchte einen MQTT-Server (Broker) in den Fully Browser Adapter integrieren und hab das Vorhaben hier gepostet.
Hintergrund: Die Fully Browser App (Android) agiert – optional zuschaltbar – als MQTT-Client und publiziert Status und Events an einen MQTT-Server - siehe https://www.fully-kiosk.com/en/#mqtt - das ist alles. (Kommandos senden an den Fully (z.B. "Bildschirm aus") geht allerdings nur über die REST API lt. Doku, und nicht via MQTT.)
Diese Infos und Events vom Fully möchte ich nun im Adapter abgreifen, brauche also dafür einen MQTT-Server (Broker).Macht es Sinn, hier einen Server direkt im Adapter zu implementieren, also etwa mittels mqtt-connection oder aedes?
Etwa die Adapter mqtt, Shelly, und Sonoff haben eigene Server implementiert und nutzen dafür mqtt-connection.
Mein Test mit mqtt-connection im Entwicklungs-Adapter funktioniert. Aber etwaclient.on('publish' ...)
wirft alle paar Millisekunden ein neues Paket aus. Also wohl viel zu oft. Mit aedes auch so bei (this.aedes.on('publish', (packet, client) => {
).
Jetzt müsste ich mich vermutlich deutlich mehr in MQTT einlesen und damit viel Zeit verbringen, dabei auch mit QOS, PUBREC usw. .... Darauf habe ich aber keine allzu große Lust, zumal das schon viele andere vor mir ausgiebig machten und implementiertenMein Zwischenfazit:
Too much effort for this simple use case... Ich will ja nur paar Daten abgreifen. Dazu kommt die Arbeit an Maintenance einer solchen MQTT-Implementierung, etc...Nur: es gibt kein aktives node.js-Modul auf Github bzw. npm, welches mir diese Arbeit abnehmen könnte, und z.B. auf aedes basiert. Hab wirklich alles durchsucht
Aber es gibt ja noch den ioBroker mqtt-Server-Adapter, der die komplette Arbeit abnimmt.
Die Readme des Adapters meint: [...] saves always the values into the States-DB, so it can be processed by other adapters..Ok. Also besser diesen Adapter nutzen und dann von meinem Adapter aus nur die States/Objekte auslesen? Gibt halt auch Redundanz...
Was ist hier denn der empfehlenswerte Weg?
-
@acgua ich könnte damit völlig Leben.
Du müsstest in deinem Adapter dann ja nur den Pfad dafür Konfigurierbar machen.
Ich habe mehrere FullyKiosk Browser am laufen und dementsprechend mehrere Instanzen.
Überall habe ich schon zusätzlich MQTT konfiguriert. -
schau dir den zigbee2mqtt adapter mal an.. da ist der mqtt server einfach implemmentiert..
-
@acgua sagte in Frage: MQTT Server (Broker) in Adapter benötigt:
Etwa die Adapter mqtt, Shelly, und Sonoff haben eigene Server implementiert
Der Grund dafür ist aber nicht, dass es so viel Spaß macht, sondern damit man wirklich sicherstellen kann, dass sich nur Geräte von Shelly oder auch nur Sonoff-Geräte mit dem (integrierten) MQTT-Broker verbinden. Einfach, um die ganzen Nachrichten von anderen Clients nicht filtern zu müssen. Da sind auch keine vollwertigen MQTT-Broker implementiert. Ein Subscribe usw. läuft einfach ins leere. Also eine Nachricht von Client A (publish) an Client B (subscribe) weiterzuleiten, ist dort gar nicht umgesetzt (weil nicht notwendig).
Man könnte ja auch eine Adapter-Konfiguration anbieten, dass man den Adapter gegen einen bestehenden MQTT-Broker verbindet. Machen einige Adapter ja auch schon so.
Langfristig wäre es ganz schön, wenn man für den MQTT-Server Adapter Plugins programmieren könnte (so wie beim web Adapter). Dann bekäme man einfach Nachrichten rein, welche man abonniert hat.
-
@haus-automatisierung
Der Adapter reagiert dann ja auf Änderungen der Datenpunkte unterhalb eines bestimmten Pfades vonmqtt.x
, sollte also kein Problem mit der Subscription haben, die Werte sind ja eh schon da.Ich würde die Idee das der Adapter das bestehende MQTT nutzt gut finden. Wenn z.B. nach einem Firmwareupdate da neue Topics erscheinen kann man diese Nutzen auch wenn der Adapter damit noch nichts anfangen kann
Letztendlich ist es auch alles eine Frage der Leistungsfähigkeit. Der Sonoff-Adapter kackt bei meinen über 100 Tasmotageräten ab, deshalb nutze ich den in dieser Hinsicht leistungsfähigeren Mosquitto-Broker - und dann eigene Skripte.
-
@arteck - Danke, das hatte ich auch gesehen (main/lib/mqttServerController.js), ist mit aedes umgesetzt, aber halt nur mit listen und dann Info-Ausgabe in ein paar Zeilen und leider für meinen Use Case so nicht hilfreich...
@haus-automatisierung
Danke, kann ich sehr gut nachvollziehen, warum man eigene Server in den Adaptern implementiert hat.Langfristig wäre es ganz schön, wenn man für den MQTT-Server Adapter Plugins programmieren könnte (so wie beim web Adapter). Dann bekäme man einfach Nachrichten rein, welche man abonniert hat.
+1
@BananaJoe
Danke für die "Unterstützung", den mqtt-Adapter zu nehmen
Mittlerweile hab ich übrigens herausgefunden, dass der Fully Browser nach einem Neustart nur jede Minute ein neues Info-Paket sendet, nicht alle paar Millisekunden. Nur nach mehreren "intensiven" Tests in der Entwicklungsumgebung kommen diese dann wieder alle paar ms rein. Wohl aber nur aufgrund meiner Tests. Ich schau mir das noch näher an.
Aber so wie es aussieht, kann ich wohl doch aedes verwenden in einer sauberen Umgebung und Infos kommen nur jede Minute, Events sofort, wie es sein soll. Jeweils als QOS 1 und Info als retain, event als nicht retain.Code-Auszug
/** * fired when a client publishes a message packet on the topic */ this.aedes.on('publish', (packet, client) => { if (!client || !packet) return; if (packet.qos === 1 && packet.retain) { /** * Device Info coming in... * Per fully documentation: The complete device info will be published every 60 seconds as fully/deviceInfo/[deviceId] topic (retaining, QOS=1). */ const info = JSON.parse(packet.payload.toString()); this.adapter.log.debug(`[MQTT] Client ${info.ip4} Publish Info: topic: ${packet.topic}, qos: ${packet.qos}`); } else if (packet.qos === 1 && !packet.retain) { /** * Event coming in... * Per fully documentation: Events will be published as fully/event/[eventId]/[deviceId] topic (non-retaining, QOS=1). */ const event = JSON.parse(packet.payload.toString()); this.adapter.log.debug(`[MQTT] Client Publish Event: topic: ${packet.topic}, qos: ${packet.qos}, payload: ${packet.payload.toString()}`); } else { // Ignore return; } });