MQTT best current practice

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

Vorheriges Thema - Nächstes Thema

martinp876

sorry, bin etwas knapp in der Zeit und die nächsten Wochen auch nicht verfügbar.
Beta-User hat schon recht (und auch nicht?) "back to topic": die "best-current-practice" passt mir nicht - aus meiner Sicht "ist nicht gut genug". Um gut zu bewerten kommt es auf die Kriterien an - und hier sind mir meine klar, die allgemeinen aber - entweder nicht verständlich oder ich stimme nicht überein.

Ich befasse mich nun - nicht 100% freiwillig - mit dem MQTT2-SERVER. Auch hier habe ich ein Problem, die Philisophie dieses Moduls zu verstehen - oder die Philosphie von FHEM - egal. Was mir "aufgefallen" ist:
 - der "server" legt versteckte Entites an. An diese ist nur umständlich heranzukommen. Warum versteckt man das?
 - Der Server legt bei allen Devices das Reading "subscription" an. Dieses ist hässlich lang, versaut das gesamte Web-frontent und sagt mir erst einmal garnichts - also sinnlos. Steuern kann ich den Inhalt so einfach einmal garnicht.
 - im Server gibt es interessante Logs, kann man über "verbose" steuern. Nicht schlecht? ich denke doch schlecht. Wenn ich den einschalte kann ich nicht auf MQTT2_DEVICES filtern. Das wäre einmal eine Sache.
 - der Server kennt die IP Adresse der Devices - cool - warum wird ie geheim gehalten?

Wie würde das im meiner Welt aussehen
 - die Sub- Elemente des Servers kann man gerne "verstecken" - die versauen die Ansicht (ich vermute, das war auch der Grund dafür)
 - Ein (oder mehrere) "get <MQTT2_DEVICE> info" geben mir aber die Informationen, welche im "Server-Child" vorhanden sind - und dass ich verbunden bin. Derer Infors habe ich immer mehrere, ggf auch mit level. So ein "get" tut garnicht weh.
 - dass man mit "internals" (dem führenden ".") oder im room hidden infos versteckt kann doch nur der lesbarkeit geschuldet sein.
 - mein standard "get <name> list hidden" zeigt mir alle - auch die ausgeblendeten  - Einträge einer entity. Und "get <name> list modul" die des Moduls - auch hier darf es keine Geheimnisse geben.
 - die IP Adresse ist bei MQTT eine elementare Information. So lange nicht alles über fhem einstellbar ist will man auf die Webseite abbiegen und das Device prüfen oder konfogurieren.
 - die Information "subscription" ist in einem "get Info" hervorragend aufgehoben.
 - in propably associated sollte das auch auftauche
 - warum so zurückhaltend mit der Info? Wie ich sagte, mein System-Add-On Modul gibt mit einem "Fellows" über "get" Informationen, wer mit wem verbunde ist und wie. Wer triggert wen. Hier triggert der Server die entites über dispatch.
 - was das Server-logging angeht - bei CUL_HM hatte ich dem "Server" - also dem IO-device - die Option engebaut, über ein attribut festzulegen, von welchem Device ich die Messages loggen will. Zumindest für mich ist das extrem hilfreich gewesen, meist will ich nicht den Server sondern die Kommunikation zu einem Device untersuchen.
 - ich werden nun die Infos aus dem Server im Device sichtbar machen - erst einmal muss ich sie verstehen.
 - der Server selbst wir ein "get assiciated info" bekommen - oder mein "MQTT-router". So geht es jedenfalls nicht.
 ==> es darf keine geheimen Infos geben - alles, ALLES  muss abfragbar sein - über inteligente Komamndos im Web- Interface - nicht verhandelbar.

Noch einmal - hoffentlich anschaulicher: während auf der einen Seite unleserliche und unbedeutende Readings das Forntend zerstören dürfen, werden einfache und hilfreiche Informationen maximal versteckt. Was ist hier der Antrieb und das Konzept?


Beta-User

Zitat von: martinp876 am 04 Oktober 2026, 18:47:33Noch einmal - hoffentlich anschaulicher: während auf der einen Seite unleserliche und unbedeutende Readings das Forntend zerstören dürfen, werden einfache und hilfreiche Informationen maximal versteckt. Was ist hier der Antrieb und das Konzept?
Solange du davon überzeugt bist, dass deine Handvoll WLAN-Shelly oder Tasmota-Gadgets ausreichen, um allgemeingültige Schlüsse und Vorgaben zu machen, werden wir vermutlich nicht zu dem gemeinsamen Nenner kommen, dass ein geschlossenes "Konzept" nicht allgemein zielführend sein wird.

Daher muss/kann/wird es immer so sein, dass man eben schlimmstenfalls "alles" zeigt, was irgendwie zu einem Gadget gehört und der User die undankbare Aufgabe hat, wichtiges von unwichtigem zu unterscheiden und das beste daraus zu machen.

Zitat von: martinp876 am 04 Oktober 2026, 18:47:33- der Server kennt die IP Adresse der Devices - cool - warum wird ie geheim gehalten?
1. Sie ist aus MQTT-Sicht eigentlich völlig irrelevant. Das irgendwie für relevant zu halten, ist nahe an der Annahme, die ClientID sei wichtig. (Eine direkte Option, das Web-Interfaces eined Gadgets aufzurufen, das zufällig überhaupt eine IP-Adresse hat, ist durchaus praktisch, aber das hat nichts mit MQTT zu tun!)

Meine dringliche Empfehlung auch hier: Die IP-Adresse nicht überbewerten!

2. Das list zeigt auf die temporäre Instanz.

Zitat von: martinp876 am 04 Oktober 2026, 18:47:33- der "server" legt versteckte Entites an. An diese ist nur umständlich heranzukommen. Warum versteckt man das?
Die "Logik" dahinter ist dieselbe wie bei anderen TCP/IP-Verbindungen (z.B. FHEMWEB) auch: Jede Verbindung ist eine temporäre Instanz, und das list eines MQTT2_DEVICES zeigt sie, wenn sie vorhanden/bekannt ist. Das ist nicht der Fall, wenn
a) MQTT2_CLIENT als IO verwendet wird, oder
b) das Gadget gar nicht direkt per TPC/IP eingebunden ist. (Das versteht man nicht, wenn man eine Handvoll WLAN-Shelly oder Tasmota-Gadgets als allgemeingültige Referenz betrachtet).

Zitat von: martinp876 am 04 Oktober 2026, 18:47:33- die Information "subscription" ist in einem "get Info" hervorragend aufgehoben.
Guter Punkt. In der Vergangenheit war die Info häufig hilfreich für den User-Support, aber eigentlich ist das etwas, was zur Verbindung (temporäre MQTT2_SERVER-Instanz) gehört, und auch nur (wie IP und ClientID) dann bekannt ist, wenn überhaupt dieser Server-Typ (in derselben FHEM-Instanz) im Einsatz ist.

Zitat von: martinp876 am 04 Oktober 2026, 18:47:33- in propably associated sollte das auch auftauche
Nun, über das Internal ist es verlinkt, ob es eine Doppelung oder andere Lösung braucht, ist m.E. eine Geschmacksfrage.

Nur meine 2ct.
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

Beta-User

#107
[OT]
Zitat von: martinp876 am 04 Oktober 2026, 18:47:33während auf der einen Seite unleserliche und unbedeutende Readings das Forntend zerstören dürfen
Wenn man sich CUL_HM heute rückblickend ansieht, gibt es da auch "Spam":
define Rollladen_Bad_OG CUL_HM xyz
attr Rollladen_Bad_OG .mId 006A
attr Rollladen_Bad_OG IOgrp VCCU
attr Rollladen_Bad_OG commStInCh off
attr Rollladen_Bad_OG expert defReg,rawReg
attr Rollladen_Bad_OG firmware 2.11
attr Rollladen_Bad_OG model HM-LC-BL1PBU-FM
attr Rollladen_Bad_OG serialNr bla
attr Rollladen_Bad_OG subType blindActuator
#  NTFY_ORDER 48-Rollladen_Bad_OG
#  disableNotifyFn 1
#  READINGS:
#  [viele Restriktions-spezifisch Infos]
#
Ein Haufen für den User nicht sinnvoll änderbare Angaben, die man auch "in one" unterbringen könnte und ggf. lieber in ein "set"-Kommando als "force" unterbringen könnte?
Das "globale notify"-Dingens ist in dem Modul direkt schlicht nicht gut aufgehoben, eigentlich gehört das (nach meiner persönlichen, heutigen Lesart) in eine (verpflichtende!) "Zwischenschicht", bestehend aus HMInfo, VCCU und Actiondetector.
Und dass man "commStInCh" immer noch bei jedem (mehrkanaligem) Device setzen muss, ist imo Unfug. Es mag einzelne User geben, die das anschalten wollen...

Aber solche "Altlasten" zu korrigieren, ist halt nicht vermittelbar, that's all.

Btw.:
10_CUL_HM.pm erzeugt ghost devices mit Anwendung von fhem delete  kennst du? Das wäre m.E. eine Altlast, die man beseitigen sollte, und auch nicht in neue Modulvarianten perpetuieren...
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

TomLee

ZitatAlso ein 1. "channel" mit einem simplen "ein/aus", und ein mehrfarbiges Licht als 2. channel.
::)
Hab doch erwähnt das ich nur mit dem Shelly und einem Tasmota Stecker gespielt hatte!?

SetExtensions fehlen: Fehler bei mir
  • SetExtensions prüft auf on/off in der Liste, die MQTT2_DEVICE aus der setList übergibt. Die Kette (SE_Next) läuft erst danach.
  • Mit sets=hook kommen on/off erst in der Kette dazu, also zu spät. Deshalb gibt es kein on-for-timer, toggle usw. Mit dem attrTemplate standen on/off in der setList, deshalb ging es da.
  • Lösung entweder in SetExtensions.pm (erst die Kette nach der Liste fragen, dann ergänzen) oder im Modul (SetExtensions selbst mit erweiterter Liste aufrufen, mit Sperre gegen den Wiedereintritt). Mir wäre ersteres lieber, das müsste aber Rudi entscheiden.

2. Kanal "klassisch"
  • sets=hook kann bisher nur Knöpfe und Auswahllisten. Slider, Farbe und Freitext nicht, und dann fällt das ganze Gerät auf setList zurück.
  • Die Konvention state + on/off bekommt nur der erste Kanal. Der Licht-Kanal behält POWER2:on,off. Ohne setStateList schreibt MQTT2_DEVICE deshalb den Befehlsnamen nach state, daher dein "state brightness".

Mappings passen nicht
  • Die Setter werden umbenannt (brightness, color, colorTemp, white, effect), die Readings aus RESULT kommen aber roh (Dimmer, Color, CT, White, Scheme).
  • Scheme kommt als Zahl, effect erwartet einen Namen. Die Rückabbildung fehlt.
  • Ziel wäre: Reading heißt wie der Setter, Werte in beide Richtungen gleich.

return undef
  • Von den 141 "return undef" im Fork stammen 113 aus dem Original, 28 von mir. Die pauschale Ausnahme in der .perlcriticrc ist meine, und ihre Begründung trifft nur auf einen Teil zu.
  • Welche Kommentare meinst du konkret? Dann schaue ich, ob sie von mir sind.

gateway(...)->log / runtimeRef
  • Das Gateway kapselt die FHEM-Zugriffe, damit die lib-Teile ohne FHEM testbar sind. Im Modul selbst bringt die Umleitung nichts, Log3 direkt wäre lesbarer.
  • runtimeRef sucht in der Registry die Referenz mit Topic und Wertabbildung (solid→0 ...) und liefert "topic payload" an MQTT2_DEVICE zurück. Der Grund: Gespeicherter Discovery-Text wird nie per eval ausgeführt. Beides ist so aus dem Original übernommen.
effect:solid,wake_up,cycle_up,cycle_down,random { MQTT2_DISCOVERY_runtimeRef($NAME, 'r_f4fbc911c2dffdd1', $EVENT) }
Falls dir der Fork zum Nachvollziehen zu groß ist: Im Anhang ein kleiner Entwurf von vorletzter Woche in Richtung MQTT2_Utils (rund 530 Zeilen, Aufbau angelehnt an RHASSPY, eine Regel je Zeile am Zielgerät). Bisher kann er nur lesen, die Sets hängen an derselben SetExtensions-Frage wie oben. Mach damit, was dir nützt.
  • Archiv im FHEM-Verzeichnis auspacken, die beiden Dateien landen unter FHEM/ und lib/FHEM/MQTT2/Utils/.
  • Nach dem define "set mqttUtils activate", das trägt MQTT2_Utils vorn in die clientOrder des IODev ein.
define mqttUtils MQTT2_Utils <MQTT2_SERVER|MQTT2_CLIENT> [prefix=mqtt] [devspec=TYPE=MQTT2_DEVICE]
set mqttUtils activate
attr <device> mqttUtilsRules <topic> <quelle> <ziel> [<umrechnung>]

Beta-User

Zitat von: TomLee am 05 Oktober 2026, 13:59:38Mach damit, was dir nützt.
:)

Erst mal kurz reinschauen :)  :)  :) . Allerkürzeste Zusammenfassung: Bis auf den für mich überflüssigen Test-Part (überflüssig = ich verstehe nicht, wie es funktionieren soll und was das effektiv hilft), scheint mir das - bis auf das unbedingt einzubauende "forceNEXT"-Attribut sowohl für das Modul wie seine Clients (dort als "key" in einem anderen Attribut) erst mal eine Basis für eventuelle Diskussionen zu sein. (mehr unten)

Zitat von: martinp876 am 28 September 2026, 20:47:51Bei der Menge an Mitarbeitern bietet es sich an, Ziele in einem Dokument festzuhalten. Das macht weniger Spass, ist am Ende aber hilfreich. Erst einmal zu codieren und dann zu schauen, was es geworden ist um noch etwas zu tunen ist verbreitet.. aber...
https://scheissprojekt.de/hausbau.html
Manchmal ist v.a. eine Skizze dessen hilfreich, wie das Haus am Ende aussehen soll. Die "Pfriemeleien" zum tunen an MQTT2_DEVICE sind m.E. aus den genannten Gründen nicht vermittelbar.

Von daher soll es bei dem ersten Wurf zu MQTT2_Utils v.a. darum gehen zu zeigen, wie sich das ganze ggf. in die heutige MQTT-Welt einpassen lassen könnte.

Elementar wichtig ist dabei, wann welches Modul überhaupt welche Infos bekommt. Und genau darum geht es bei "forceNEXT": Im Prinzip sollte das neue Modul erst mal alle unbekannten Messages abfangen und NICHT [NEXT] aus Parse() zurückgeben. Jedenfalls, wenn es z.B. so konfiguriert ist, dass es alle Tasmota-like messages auswerten soll. Dann sind (nur) alle diese rauszufiltern, MQTT2_DEVICE bekommt die nicht mehr zu sehen, es sei denn, für einzelne Devices würde etwas anders (dort) konfiguriert.

(sorry, sehr kurz)
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

ZitatLösung entweder in SetExtensions.pm (erst die Kette nach der Liste fragen, dann ergänzen) oder im Modul (SetExtensions selbst mit erweiterter Liste aufrufen, mit Sperre gegen den Wiedereintritt). Mir wäre ersteres lieber, das müsste aber Rudi entscheiden.
Ich habe SetExtensionsFn so umgebaut, das SetExtensions selbst am Ende der Liste ausgefuehrt wird.

TomLee

#111
ZitatBis auf den für mich überflüssigen Test-Part (überflüssig = ich verstehe nicht, wie es funktionieren soll

Zum Hintergrund:

Was ,,Tests" eigentlich sind

Bei einem Projekt, mit dem ich mich jetzt schon länger beschäftige und mit "KI" gearbeitet wird, habe ich gelernt, wie dort gearbeitet wird:
Zu jeder Änderung gehören Tests. Das klingt erst mal nach Mehrarbeit, ist aber im Grunde nur das, was wir in FHEM sowieso machen, nur aufgeschrieben.

Wenn du in FHEM etwas änderst, probierst du es aus: set, get, ins Log schauen, in FHEMWEB nachsehen. Ein Test ist genau dieses Ausprobieren als kleines Programm.
Der Vorteil: Man kann es nach jeder Änderung in Sekunden wiederholen, statt alles von Hand neu durchzuklicken. Man merkt auch sofort, wenn eine Änderung an einer Stelle etwas ganz anderes kaputt gemacht hat.

Grob gibt es drei Sorten:

  • Eine einzelne Funktion prüfen. Wie wenn du in der FHEM-Kommandozeile
    { KalenderWoche("2026-12-28") }eingibst und schaust, ob 53 herauskommt. Der Test schreibt Eingabe und erwartetes Ergebnis fest auf und meldet sich, sobald etwas anderes herauskommt. Am Jahreswechsel, bei der Zeitumstellung oder bei leeren Werten findet man so Fehler, an die man beim Ausprobieren nie gedacht hätte.
  • Das Ganze prüfen, mit Wegwerf-Daten. Das Testprogramm baut eine eigene Umgebung mit Beispieldaten auf, führt Abläufe durch und prüft das Ergebnis. Danach wird alles wieder gelöscht. Das ist wie eine zweite FHEM-Instanz nur zum Ausprobieren: Die echte Installation wird nie angefasst.
  • Die Oberfläche ferngesteuert bedienen. Ein Browser ohne sichtbares Fenster öffnet die Seite, tut zum Beispiel so, als wäre er ein Handy, klickt oder wischt und misst danach nach: Ist das Element sichtbar? Ist die Seite breiter als der Bildschirm? Wie viele Pixel sind übrig? Manches sieht man beim Anschauen nicht, beim Nachmessen schon.

Warum das mit KI so wichtig ist

Eine KI kann keinen Bildschirm anschauen und kein Handy in die Hand nehmen. Sie kann nur Programme laufen lassen und deren Ausgabe lesen. Ohne Tests rät sie, ob ihr Code funktioniert. Mit Tests prüft sie es nach und findet viele ihrer eigenen Fehler selbst, bevor ich sie überhaupt zu sehen bekomme.

Wo die Grenze liegt

Ein simulierter Klick ist kein echter Finger. Ob sich etwas im Alltag gut anfühlt, muss am Ende trotzdem ein Mensch ausprobieren. Tests ersetzen das Ausprobieren nicht. Sie sorgen dafür, dass man nur noch das ausprobieren muss, was ein Programm nicht beurteilen kann.



Zu MQTT2_Utils hab ich erstmal noch nichts weiteres beizutragen, weil ich mit anderem beschäftigt bin. Dazu muss erst eine Zeit kommen, in der ich Abends noch fit bin und es mich packt da einzudenken.



ZitatIch habe SetExtensionsFn so umgebaut, das SetExtensions selbst am Ende der Liste ausgefuehrt wird.

Danke