MQTT best current practice

Begonnen von martinp876, 26 Juli 2026, 09:56:44

Vorheriges Thema - Nächstes Thema

rudolfkoenig

ZitatEs wird EINE "Device-routing-entity" geben welche eben den Parser und router beinhaltet.
Da in diesem Fall die MQTT2_DEVICE Funktionalitaet eher hinderlich ist, empfehle ich ein separates Modul zu bauen, und diesem per MQTT2_SERVER Attribut clientOrder den Vorrang zu geben.

martinp876

Sorry - ich bin langsam - im Antworten und codieren.

MQTT_DEVICE vs MQTT2_DEVICE: sorry,  werde mich bemühen. Anmerkung: die unterschiede habe ich nie ergründet, werde ich auch nicht mehr. Als User sehe ich diese Vielfalt nicht als Vorteil sondern als verwirrend. Die klare, einzeilige Empfehlung: wann nehme ich was - fehlt mir.

Performance ist nicht DAS erste Thema. Usability ist prio 1. Performance ist immer ein Thema - insbesondere bei "Familien" mit vielen Entites

Wieso einfach, wenn es auch kompliziert geht? Sehe ich auch so. Nur eben anders. Das UI ist aus meiner Sicht kompliziert, die Codierung eher einfach. Ich will es ungekehrt - und zwar zwingend. Als Codeschreiber mache ich mir einmal richtig Gedanken, also User komme ich hoffentlich einfach zurecht

Da in diesem Fall die MQTT2_DEVICE Funktionalitaet eher hinderlich ist, empfehle ich ein separates Modul zu bauen, und diesem per MQTT2_SERVER Attribut clientOrder den Vorrang zu geben.
==>Ich denke (so ich es verstanden habe) ich stimme zu. Allerdings sehe ich eine m.E. einfachere Lösung - beschreibe ich weiter unten.

Zu den offensichtlich vielen Vorschlägen, wo was in Sachen MQTT umgesetzt ist, alles scheinbar nach einem anderen Konzept: Ich habe am Ende weder Zeit noch Nerven, mir jede Installation anzusehen, zu testen, zu bewerten, anzupassen. Ich werden schneller sein, meine Idee einfach umzusetzen - da bekomme ich was ich will - sogar generisch, usable, erweiterbar und schneller als it 1000 fehlversuchen und "fast-richtig".

Im nächsten Post mein Ansatz. Mich würden dann Kommentare interessieren zu
- Konzeptidee
- Umsetzung
- Anregungen

martinp876

Mein Konzept läuft schon, auch wenn noch etliche Arbeiten zu erledigen sind. Zumindest für die Receive-Seite.

1) was kann mein Ansatz mehr als MQTT2_DEVICE? Nichts. Es werden MQTT messages in Readings umgesetzt - fertig.
2) Ziele
2a) Kompatibilität: ich werde mich an MQTT2_DEVICE anwanzen - d.h. mit eigenem zusatz-Code funktionalität erweitern/ergänzen/anpassen
2b) Usability: die halte ich aktuell für inakteptabel. Was ich als best-current-practice gesehen habe ist nicht das, mit dem ich also User umgehen kann/will/werde.
2c) flexibilität: Natürlich werden Erweiterungen (neue Module) möglich sein. Da ich von exterm begrenztem Interesse der Komumnity ausgehe werde ich das UI hierzu in Grenzen halten.
Gemäß dem Motto: "wer nach allen Seiten offen ist kann nicht ganz dicht sein" wird es Regeln geben an die sich zu halten ist oder die erzwungen werden.
3) Umsetzung
3a) repository vs library: die aktuellen "Templates" werden je entity kopiert und angepasst. Das geht für mich garnicht. Code im UI (attr ReadingList), unübersichtlich, fehleranfälling => nogo.
Mein Konzept: "attr model". Messages werden gemäß "model" geparst. Der Parser wird über "config-hashes" konfiguriert. Die Konfigs sind in einem .pm verankert. So ist es de-facto bei allen modulen, so sollte es hier sein.
Usability: setze attr model shellyPM2 - done.
Channel-funktion wird nach dem gleichen Konzept funktionieren
4) provisioning
4a) CID: Man sagte mir schon, es sein ein Holzweg - nur kann ich es aktuell nicht erkennen.
4aa) kann man die CID nutzen ist das ein Quantensprung in der Unsetzbarkeit. Tasmota und shelly machen das prima. Über pah's rasenmäher kann ich keine Aussage machen - ignoriere ich also
Mit CID kann ich - wie es bei allen anderen device auch üblich ist - die Attribute und Eingenschaften des Empfängers ermitteln und entsprechend parsen - perfekt.
4b) model: die Message wird gemäß den model-regeln in Readings umgesetzt
4c) channel - oder function: der Name des attributs ist noch offen, wird aber die Funktion der Entity festlegen, also bspw den Kanal. Die ermittelten Readings werden nur zu dieser Entity propagiert, wenn die "Function" dies einfordert.
4d) evalMQTT: eine evaluierungs-option. Meine Erfahrung ist, dass es extrem erregend und umständlich ist, die Messages des Device zu erfassen um sie dann überhaupt in Templates umsetzen zu können. Da die CID bislang "fehlte" war es auch nicht ganz einfach. Setzt man dieses Attribut werden die Messages incl. topic in Readings sichtbar und man kann an seinem Template arbeiten. So stelle ich mit usability vor. Anhand des Konzepts könnte man sich eine eval-entity für unbekannte/neue Devices anlegen und hier die - gelegentlich seltenen - messages loggen. Im UI, wie es sein sollte
5) UI Umsetzung:
5a) es wird EINE routing-entity definiert
  define MQTTroute MQTT2_DEVICE route
  attr MQTTroute readingList .*:.*:.* {muParseMQTT($NAME,$CID,$TOPIC,$EVENT)}
diese Entity bekommt ALLE messages.
5b) Client-entites (hoffentlich die korrekte Wortwahl)
  define <myMQTTdev> MQTT2_DEVICE <CID>
  attr <myMQTTdev> userattr model function evalMQTT:0,1
  attr <myMQTTdev> model shellyPM2
  attr <myMQTTdev> function switch_0
  -   readingList ist verboten!
5c) natürlich werde ich die Kommandos entsprechend generisch erweitern um bspw die Readings vomUI aus bereinigen zu können. Dafür habe ich schon utilitis um "minderbemittelte" Module zu pimpen ;)

6) Performance 
Inhaltlich denke ich geht es in Rudis Richtung, nur ein anderer Gedanke/Umsetzung.
Dank der Konstruktion von MQTT2_DEVICE kann sich die routing-entiy einfach einklinken - in schlicht alles. Damit ereiche ich
- jede message wir nur von einer Entity empfangen
- jede Message wird nur einmal zerlegt -nach model. Ich werden verhindern, dass einer CID unterschiedliche Model Attribute untergejubelt werden (wer nach allen Seite...)
- da es mehrere Entites mit gleicher CID geben kann (Kanäle) wird hier das Verteilen der Readings vorgenommen.
6a) prepare/cache
Das Processing hängt also von den Enities und deren Attributen ab - eine wilde Sucherei.... wird es natürlich nicht geben. Wie in jedem ordentlichen System bereitet man sich vor, wenn es an der Zeit ist. MQTTroute wird also hashes und caches haben mit Doziers über alle relevanten MQTT2_DEVICEs. Über ntf "global" wird es auf Stand gehalten - logisch. Dafur hat Rudi das sicher auch eingebaut.

Wie ist der Stand bei mir: läuft grundsätzlich, noch nicht vorzeigbar.
MQTTroute ist am Start, devices sind eingerichtet, readings werden ordnungsgemäß propagiert.
=>die 10% inspiration sind umgesetzt, von den 90% transpiration bin ich erst bei 20%

betateilchen

Zitat von: martinp876 am 15 August 2026, 08:08:59Anmerkung: die unterschiede habe ich nie ergründet,

  • Die Module MQTT_.* sind die erste Generation und benötigen noch zusätzliche externe perl Module.
  • Die Module MQTT2_.* wurden von Rudi viel später gebaut, um das MQTT Protokoll ohne die externen Abhängigkeiten in FHEM verwenden zu können.

Zitat von: martinp876 am 15 August 2026, 08:08:59Als User sehe ich diese Vielfalt nicht als Vorteil sondern als verwirrend. Die klare, einzeilige Empfehlung: wann nehme ich was - fehlt mir.

Es geht nicht um "Vielfalt" im Sinne von "wähle aus, was Du verwenden möchtest", sondern um technische Weiterentwicklung.

Du kannst prinzipiell beide Serien für alles verwenden. MQTT2 hat den Vorteil, dass Anpassungen und Bugfixing zeitnah umgesetzt werden.

Eine Empfehlung "wann nehme ich was" kann man nicht am Einsatzszenario festmachen. Gefühlt würde ich dazu raten, MQTT2 zu verwenden, einfach weil es die aktuellere Umsetzung in FHEM ist.

Anmerkung: Das Modul MQTT_GENERIC_BRIDGE lassen wir in dieser Betrachtung mal außen vor. Dessen Name passt nicht ganz in das beschriebene Schema. Dieses Modul ist als Zusatz in der Lage, sowohl mit MQTT als auch MQTT2 zu kommunizieren. Es stammt aber historisch auch noch aus der "MQTT"-Entstehungszeit.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Beta-User

#34
Zitat von: martinp876 am 15 August 2026, 08:09:424a) CID: Man sagte mir schon, es sein ein Holzweg - nur kann ich es aktuell nicht erkennen.

Stichprobe aus meinem aktuellen System zum Thema CID (praktisch alle mit MQTT2_SERVER als IO-Modul):
Count: 127 devices for devspec TYPE=MQTT2_DEVICE
Count: 118 devices for devspec TYPE=MQTT2_DEVICE:FILTER=DEF~.+
Count: 88 devices for devspec TYPE=MQTT2_DEVICE:FILTER=DEF~zigbee.+
Count: 12 devices for devspec TYPE=MQTT2_DEVICE:FILTER=DEF~inverter.+
Von den 127 vorhandenen entities haben also 9 gar keine CID. Es sind channel-Devices von echter Hardware.
Alleine 88 entfallen auf den ZigBee-Dienst (zigbee2mqtt). Diese CID sind also (vielleicht bis auf eine) "unechte" CID, die abgeleitet sind aus der Topic-Struktur, und von daher auch keine Mehr-Info zu TOPIC enthalten können.
Entsprechendes gilt für die "inverter"-CID, nur dass das nicht über einen docker-container kommt, sondern über einen ESP32 (mit nRF-Funkmodul und entsprechender firmware).

Sagt vielleicht mehr als Code-Analyse, warum das Berücksichtigen der CID keinen Mehrwert bietet; dieselben Infos sind (entsprechende Vorgaben an den Konfigurator berücksichtigend) eben auch in den Topics drin, und den Topic wertet man ja so oder so immer aus...

PS: Wenn man sich von "CID" aus der DEF etwas frei macht, wird auch sowas möglich:
define m2d_test MQTT2_DEVICE model=shellyPM2:function=switch_0:evalMQTT=1
#   CID        model=shellyPM2:function=switch_0:evalMQTT=1
#   DEF        model=shellyPM2:function=switch_0:evalMQTT=1
Spart ggf. eine Ladung umständlich einzuführender Attribute, die man einmal setzt...
Zitat von: betateilchen am 15 August 2026, 10:10:12Anmerkung: Das Modul MQTT_GENERIC_BRIDGE lassen wir in dieser Betrachtung mal außen vor. Dessen Name passt nicht ganz in das beschriebene Schema. Dieses Modul ist als Zusatz in der Lage, sowohl mit MQTT als auch MQTT2 zu kommunizieren. Es stammt aber historisch auch noch aus der "MQTT"-Entstehungszeit.
Code-technisch wäre es eigentlich für Martin interessant, aber er will ja partout diesen indirekten Weg über das Verbiegen einer MQTT2_DEVICE-Instanz gehen...
(Es ist in 0,nix zu klonen, um mit dem Klon dann Rudi's Vorschlag umzusetzen.)
Server: HP-elitedesk@Debian 13, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

rudolfkoenig

4a) CID: Man sagte mir schon, es sein ein Holzweg - nur kann ich es aktuell nicht erkennen.
Um es anders zu formulieren:

Ein Umstieg von MQTT2_SERVER zu MQTT2_CLIENT ist nicht moeglich, wenn CID eine zentrale Rolle spielt, weil man als Client diese Infos nicht kriegt.
Wenn MQTT2_SERVER ein bestimmtes v5 Feature, worauf das externe Geraet unbedingt besteht, nicht unterstuetzt, dann kann man das Geraet nicht anbinden.
Mit MQTT2_CLIENT ist das kein Problem, weil externe MQTT-Server wie mosquitto beide Protokolle (MQTT v3.11 und v5) gleichzeitig unterstuetzen.

Es gibt zunehmend mehr Protokollwandler nach MQTT (zigbee2mqtt, ble2mqtt, matter2mqtt, usw), die als Bridge fungieren, und mehrere Geraete via MQTT anbinden.
In diesem Fall kann man mit der CID der Bridge wenig anfangen.