nachdem Homematic nun EOL ist - und teuer - und die IP version auch teuer und mächtig indirekt bin ich bei shelly und Tasmota vermeintlich fündig geworden. Ich versuche nun diese beiden in deren generischen Versionen über MQTT2 in die bestehende Installation einzubinden. Die bestehende Beschreibubg ist sehr mächtig - ich hatte jedoch einige Probleme (auch weil ich nur sehr selten weiter arbeite...) das ganze mit Hand und Fuss einzubauen - und habe es immer noch nicht. Ertstes wirkliches Objekt ist ein Shelly 2 kanal schalter (eigentlich einfach).
Anforderungen der Implementierung sind (für mich auf der Hand liegend):
- einfache Handhabung der Installation (keine endlos langen Attribute!)
- performantes System - ich rechne leicht mit 30+ devices und 100+ entities in fhem.
- automatische Systemprüfung - sind alle devices erreichbar
- nahtlose Einbindung in das bestehende System - beinhaltet, dass alle Readingnamen denen üblichen konventionen entsprechen
- Kanal Entities - zumindest möglich. Ein System funktioniert nur so generisch
Dass mir die Attribute zu lang sind, somit schlecht überprüfbar und ausserdem die Webdarstellung torpedeiren - nun ja - werde ich ändern.
Performance-wise: die CID muss der Schlüssel zur Prüfung und erstellung der Readings sein. Das ist aktuell ein suchen über sämtliche regexp - passt mit meinen Performance-regeln nicht zusammen.
Die Erstellung der ReadingsList regeln ist für meine Lesart komplex - da die Namen der einzelnen Elements nicht klar erklärt ist - ich habe es am Ende durch endlose Experimente geprüft.
Schlüssel zur Erstellung der Readings ist "json2nameValue". zum Ersten fehlt hier eine "ordentliche" Dokumentation (und wie immer - im Forum nachlesen ist für Anwendung, ersetzt nie eine Dokumentation). wie wann und wo die postitiv und negativ filter eingesetzt werden, welche Optionen von anderen abhängig sind,... am Besten den Code nachlesen. Wie die jsonmap aussehen muss - keine Beispiele.
json2nameValue nutzt als Trenner der hierarchiestufen "_". Das ist m.E. maxinal ungeschickt, da dies typisch auch in den Namen vorkommt. In den endgültigen Readigns will ich natürlich nur "temperatur" stehen haben - und nicht die dem device eigene MQTT Hierarchie. Leider kann ich die Stufen nachträglich nicht mehr identifizieren, also nach "_" splitten - zumindest nicht sauber.
Logisch (für mich) - ich will die gemeldeten Datenpunkte verarbeiten (zustand des Ausgangs), egal über welche Methode er eingeholt wurde. Ich muss die Stufen also auflösen können.
Anhand der Stufen muss ich erkennen können, welcher Kanal sich gemeldet hat.
Am Ende muss ich die Kanalangabe, den Readingnamen und den Value in FHEM-Momenklatur übersetzen. Also ein
...switch_1_...output true
in
<channel1>level on
sowie dupliziert - da fhem dies bspw bei dimmern auch als state und pct benötigt - sowie der korrekten entity zugewiesen.
==> es ist (für mich) nicht hinnehmbar, dass MQTT im Frontend (readings) sich von anderen unterscheidet
==> die einfachen Methoden, dies zu übersetzen, entites zuzuweisen und auch die Values anzupassen habe ich nicht gefunden.
==> eine performante Lösung für das auflösen der Events in Readings - ohne exzesives regexp gesuche - suche ich ebenfalls
wie geht ihr damit um? Bin ich allein und bin ich auf den Holzweg?
ggf. werde ich wieder einmal den Code frisieren müssen
Warum nicht im richtige Forumbereich "MQTT" diskutieren?
Als ich mit mqtt angefangen habe, war mein erster Schritt, mich von dem ganzen Attribut-Gedöns, das man versucht, per template aufzuzwingen, verabschiedet habe. Die devices habe ich so angelegt, wie ich es mir vorgestellt habe.
Wenn ich einmal ein device eines bestimmten Typs erstellt habe, verwende ich dieses als Vorlage, falls weitere Geräte des gleiche Typs dazukommen. Im devicetopic muss ich dann nur die eindeutige ID ändern, und schon läuft das neue device.
Die ClientID spielt bei mir überhaupt keine Rolle. Sie ist nirgends definiert.
Als mqtt Server verwende ich mosquitto (auf einer Lightsail Instanz bei Amazon) und nanomq (hier im lokalen Netzwerk in einem proxmox container).
Diese Trennung mache ich deshalb, weil ich alle JsonMOD und HTTPMOD devices, die externe Quellen abfragen, auf Amazon ausgelagert habe und die ermittelten Werte dann per mqtt übertragen werden.
Die ganzen lokalen Shellies etc. brauchen aber keine Internetverbindung. Diese arbeiten komplett über den lokalen nanomq server.
Ist ja alles nett, und wer MQTT liebt, soll es auch nutzen. Aber versuch doch einfach mal (und bei ca. 30 Devices geht das problemlos...) das generische Shelly-Modul.
LG
pah
Zitat von: Prof. Dr. Peter Henning am 26 Juli 2026, 13:14:12Ist ja alles nett, und wer MQTT liebt, soll es auch nutzen. Aber versuch doch einfach mal (und bei ca. 30 Devices geht das problemlos...) das generische Shelly-Modul.
es gibt weitere MQTT - wie ich schon sagte bspw Tasmote (generisch,also nocht sonos). Die (meine) Idee ist, nicht x unterschiedliche Protokolle zu prüfen, lernen, anpassen. Shelly ist nur ein Beispiel - ESP32 und derivate ist für generische Ansätze in sonderfällen maximal flexiben. Eine spezial-Shelly Lösung ist daher endlich - und einarbeiten müssste ich mich auch noch. Ich sprach von
30+ devices - wenn man einmal anfängt geht es hier erst los!
ZitatDie ClientID spielt bei mir überhaupt keine Rolle. Sie ist nirgends definiert.
die CID wird in MQTT quasi immer einbezogen - und steht in der ReadingList an erster Stelle, vor dem ":". Ausserdem erscheint sie im define - oder was soll da rein?
Diesen Teil sehe ich einmal so (korrigieren mich)
define devicename CID
attr devicename readinglist CID:<topic>:<value> <action>eigentlich hätte ich mir genau so die Definition des Attributs vorgestellt. Allerdings ist die CID in der Definition nicht vorgeschrieben. Daher werden bei jeder FHEM entity auch alle CIDs zugelassen.
Die CID ist prädestiniert um als Adresse zu fungieren (sagt ja der Name schon).
Wenn ich keine sinnvolle Alternative finde werde ich es genau so - und stringent - implementieren:
- im Define steht die CID
- Für Kanäle einer CID überlege ich noch. Der 2-fach switch hat eigentlich 4 Kanäle, frei programmierbar: 2 mal out und 2 mal in
- Readings werden auf die CID gefiltert - die wird in der message immer geliefert - bietet sich nicht nur an, das ist sicher die Idee von MQTT
- Readings der Kanäle brauchen einen diskriminator - definier ich mir noch
- Auswertung der Readings (readinglist-pendant) wird über die Adresse/ID (bei MQTT also CID) der/den entities zugewiesen
- Templates muss es auch geben hier bietet es sich an, wie bei CUL_HM (und sicher auch anderen) ein "model" zu definieren (Attribut) worüber das template ausgewählt wird
- da es wie immer keine weiteren interessenten gibt ist es nicht (wie bei CUL_HM) notwendig, user-templates zuzulassen. Wäre aber kein Problem, ist schon erprobt.
- ich werde nicht umhin kommen, eine subroutine zu schreiben, welche die Auswertung durchführt
- Giganto-Attribute mit unendlikch code sind keine Option - nicht übersichtlich, nicht wartbar, nicht managebar.
Noch einmal, es ins rechte Licht zu rücken - vielen Dank für MQTT2 und auch json2nameval. Ist prima - aber ist für meine Ansprüche nicht ausreichend.
Eine Lösung mit auslagerungen - auch nach Amazon - lehne ich (bis jetzt) strikt ab.
Zitat von: martinp876 am 26 Juli 2026, 14:11:38die CID wird in MQTT quasi immer einbezogen - und steht in der ReadingList an erster Stelle, vor dem ":".
Dein Versteifen auf die CID halte ich persönlich für einen Holzweg.
Und in MQTT 5 ist die CID mehr oder weniger vollständig optional bzw. wird leer übergeben.
Zitat von: martinp876 am 26 Juli 2026, 14:11:38Ausserdem erscheint sie im define - oder was soll da rein?
Bei mir erscheint in keinem define eine CID.
defmod ku_Licht_Vintage MQTT2_DEVICE
attr ku_Licht_Vintage IODev nanomq
attr ku_Licht_Vintage devicetopic shellies/ShellyVintage-34945479E80B/light/0
Basierend auf dem devicetopic werden dann readingList und setList befüllt.
Ich glaube, die CID erscheint im define, wenn autocreate das device erstellt. Autocreate setzt die ja auch in die readingList, wenn mich nicht alles täuscht.
Kann man sich aber, wie betateilchen richtig sagt, komplett sparen. Das ist nur eine zusätzliche Fehlerquelle. Einfach in den Geräten ordentliche Topics konfigurieren und gut ist.
Zitat von: martinp876 am 26 Juli 2026, 13:43:25nicht x unterschiedliche Protokolle zu prüfen, lernen, anpassen
Na, da ich die ersten Jahre über das Shelly-Modul gepflegt habe, kenne ich das API sehr genau. Protokoll gibt es da, wenn man es genau nimmt, genau eines: REST. Aber, und das vor allem wegen der starken Veränderung des API über die Zeit, mit ganz unterschiedlichen Spezifikationen. Das Shelly-Modul verbirgt das vor dem Anwender, um eben nicht diesen ganzen Zoo verstehen zu müssen.
LG
pah
@pah: Du hast ja recht, aber die Frage hier im Thread ist nicht "Shelly best practice" sondern "MQTT best practice".
Spätestens, wenn man irgendwann ein mqtt-sprechendes device einsetzt, das nicht vom Shelly-Modul abgedeckt wird (z.B. weil es gar nicht von Shelly stammt) muss man mit (mindestens) zwei verschiedenen Ansätzen arbeiten. MQTT ist dabei der Weg, das mehr oder weniger zu vereinheitlichen.
Zitat von: passibe am 26 Juli 2026, 16:37:06Ich glaube, die CID erscheint im define, wenn autocreate das device erstellt
Ok, ich arbeite weder mit autocreate noch mit attrTemplate.
Das macht mir die Arbeit schon erheblich leichter und meine mqtt devices funktionieren so, wie ich es mir vorgestellt habe.
Für mich ist das Attribut devicetopic jedenfalls sehr viel wichtiger und hilfreicher als eine CID, zumal man in dem Attribut innerhalb eines devices sogar unterschiedliche devicetopics definieren kann, um beispielsweise eingehende mqtt-Nachrichten unterschiedlicher Geräte in einem einzigen FHEM device zusammenzuführen.
Zitat von: betateilchen am 26 Juli 2026, 16:55:47MQTT ist dabei der Weg, das mehr oder weniger zu vereinheitlichen.
Ich habe viele Devices, die FHEM via MQTT versorgen, dazu gehören zwei E-Autos und drei Staubsaugerroboter.
Meine Erfahrung: Nix einheitlich, Geräte verhalten sich komplett unterschiedlich.
LG
pah
Etwas Hintergrund zu ClientID (aka CID) in FHEM:
- die CID des Senders kennt nur der MQTT Server. "Normale" MQTT Clients, die ueber einen externen Broker arbeiten, haben keine Ahnung, wer eine Nachricht gesendet hat.
- MQTT2_SERVER & MQTT2_DEVICE sind entstanden, damit die MQTT Anbindung in FHEM einfacher wird, autocreate war einer der Ziele.
- MQTT2_DEVICE erweitert beim Empfang einer unbekannter Nachricht das readingsList der Instanz mit der gleichen ClientID.
- das funktioniert ohne Weiteres mit MQTT2_SERVER. Bei einem externen Broker (d.h. MQTT2_CLIENT) muss man ein bridgeRegexp Attribut setzen (was je nach Topic eine ClientID erfindet), damit autocreate funktioniert.
- beim Implementieren von MQTT2 hatte ich keine Erfahrung mit MQTT Geraeten, ich bin davon ausgegangen, dass Geraete der gleichen Art auch die gleichen Topics verwenden. Deswegen wurde das ClientID Teil der readingList. Aus heutiger Sicht ist ClientID im readingList ueberfluessig und sollte ausgebaut werden, da ein so angelegtes readingList nicht ohne Aenderung ueber einen externen Broker bedient werden kann.
- ClientID in der readingList ist ueberfluessig, weil die ueblichen MQTT-Geraete eine eindeutige ID als Teil des Topics seinden. Es sei denn der (unerfahrene) Benutzer meint das Topic selbst bestimmen zu wollen, wodurch die muehsam vorbereiteten attrTemplates nicht mehr anwendbar sind.
- es gibt einige Geraete (eher selten), die temporaere oder leere ClientIDs verwenden.
nun - ich lerne gerne.
die CID kennt der Sender selbst und der Broker sieht sie in jedem Fall. Zustimmung. Allerdings habe ich mit dem Begriff "Client" ein Problem - und hier stellen sich struktur-Fragen.
Die Idee und Semantik der Broker und Client berstehe ich als ein Sender triggert ein Device wobei der Broker das Routing übernimmt. Hier enrolt man sich um über die event (welchen einen eben interessieren) informiert wird.
die vorhandenen Module sehe ich aber anders. Der Server ist kein Broker sondern nur das IO device. Mein MQTT-Device ist kein Client sonder das Abbild/die visualisierung des externen devices.
Der Broker ist eigentilch das fhem-notify. Hier werden die trigger an die clients weitergereicht und führen zu Aktionen. FHEM-notify somit der inter-protokol-broker in MQTT sprache. Geht natürlich in beide Richtungen.
==> klar, kann man anders machen - aber bislang sind die Abbilder der HW nur die Darstellung und das Interface zu den HW-devices.
Was Rudi sagt ist eine Möglchkeit. Der erste Teil des Topic welcher bei shelly "prefix" genannt wird, wird per default mit der CID gleich gesetzt. Den Prefix wollte ich "aufsparen" - wofür weiss ich auch noch nicht.
Wenn man also die CID nicht nutzt und der prefix faktisch als ID genutzt wird ist das auch eine Lösung - grundsätzlich das gleiche Ergebnis.
Das ändert aber rein gar nichts an der zuordnung/FHEM-routing der Messages. "Meine" FHEM entity lauscht mit, was die MQTT-HW so alles von sich gibt. Sie ist also interessiert an allen messages (jetzt neu:) mit diesem Prefix. Meine Entity wird also mit diesen Prefix getaggt werden - irgendwo (DEF oder ATTR - wurscht). Dann werden alle messages der Entity verarbeitet - unutzes verworfen... so wie bei jeder anderen HW in FHEM ebenso.
Durch das Setzen der Readings welche sich daraus ergeben werden dann die notifies gespeist - und so weiter.
Damit ist die Entity erst einmal in fhem eingebunde wie alles andere auch. Und wie bei allen anderen IOs kann man (jetzt neu) über den Prefix genau die entites füttern, welche diesem Prefix zugeordnet sind. Damit bietet sich DEF als Tagging-Point an.
Danke für die Diskussion über CID - generell ändert dies nur marginal meine Darstellung. Das "routing" im MQTT Server ist für mich immer noch unpassend. Es ist eher ein broker, welchen ich an dieser Stelle nicht brauche. Das passt auch nicht zu FHEM.
@pah: mit Sonderfällen muss man gesondert umgehen.
p.s.: auch auswerten könnte man die source information in der message. Ist aber umständlicher, wäre aber wohl eindeutig.
"Topic " ist deutlich geschmeidiger und sollte reichen.
Vorab @Rudi: Magst du https://forum.fhem.de/index.php?topic=116162.0 mal im für MQTT passenden Bereich anpinnen?
Der geht wohl gerne mal unter...
@martinp876:
Der Thread wäre vermutlich im MQTT-Foren-Bereich besser aufgehoben als unter "Sonstiges"...
Neben dem og. Thread würde ich https://wiki.fhem.de/wiki/MQTT2_DEVICE_-_Schritt_f%C3%BCr_Schritt als Einstiegslektüre empfehlen, nach wie vor sind beide auf dem ziemlich letzten Stand der Dinge.
Was "Server" und "Client" angeht, stellt sich mir die Frage, was daran die Frage ist. FHEM stellt zwei Module bereit, eines zum verbinden als Client an einem "extern" laufenden Server, eines als "Server", der in der MQTT-Sprache eben nicht mehr "Broker" heißt, aber von "typischen Clients" (wie den Shelly- oder Tasmota-ESPs) als Server-Dienst akzeptiert wird.
Dass das in der FHEM-Funktionalität zugleich IO-Module im zweistufigen Modulaufbau sind, ist doch damit nicht ausgeschlossen.
Da die Welt der "typischen MQTT-Clients" sehr bunt ist (und teils dadurch geprägt zu sein scheint, dass mal eben der Azubi eine MQTT-Funktionalität eingebaut hat - ohne Rücksicht auf Sinnhaftigkeit dessen, was da passiert - ) ist leider weiter Stand der Dinge.
Dazu eine Art "shared best practices" bereit zu stellen, war der Gedanke hinter attrTemplate. Wer es nicht mag oder besser weiß, kann ja sein eigenes Ding zusammenschustern. Jedenfalls: Da ist der Versuch zu finden, "FHEMische" Devices/entities zu basteln mit "üblichen" Steuerungsfunktionen und Reading-Namen.
Sicher nicht perfekt, aber vorhanden...
@martinp876:
vielleicht könntest Du Dich gedanklich (meinetwegen vorübergehend) von der FHEM-eigenen MQTT2-Implementierung des Servers verabschieden. Dann wird das Grundverständnis zu mqtt vermutlich etwas klarer. Letztlich handelt es sich um ein Protokoll und nicht um Hardwarestrukturen.
Du wirfst meines Erachtens gerade zu viele Dinge zusammen in einen Topf, die da nicht zusammen hineingehören.
ZitatVorab @Rudi: Magst du https://forum.fhem.de/index.php?topic=116162.0 mal im für MQTT passenden Bereich anpinnen?
Erledigt.
ZitatDa die Welt der "typischen MQTT-Clients" sehr bunt ist (und teils dadurch geprägt zu sein scheint, dass mal eben der Azubi eine MQTT-Funktionalität eingebaut hat - ohne Rücksicht auf Sinnhaftigkeit dessen, was da passiert - ) ist leider weiter Stand der Dinge.
Gut formuliert. MQTT erfordert einfach, sich von den eigenen Vorurteilen in Bezug auf Standardisierung zu trennen.
LG
pah
mir ist (ernsthaft) nicht klar, was an meiner Aussage unklar ist.
Der Server ist das IO welches die MQTT cienten mit den realen devices verbindet.
In der Welt ausserhalb kann man MQTT clienten direkt verbinden - das ist vollkommen klar.
Meine Annahme ist, dass ein Client in FHEM erst einmal "nur" alle Informationen des realen Device einsammelt und darstellt. Ok, die Senderichtung habe ich gerade unterschlagen.
So funktionieren zumindest einige andere Famielen in FHEM auch. Das ist eine Kernauffassung aus der sich dann exterm viel ableitet.
Also erste Frage: haben wir hier einen Konsenz oder sind die MQTT_DEVICES bei euch anders definiert?
a) mir ist klar, das man es anders machen KANN. Aber nicht muss.
b) ich muss und will nicht alles implementieren, was MQTT hergibt. Der obige Ansatz sollte reichen, MQTT in FHEM zu harmonisieren
c) mittelfristig ist es mir zu komplex, komplexe abhängigkeiten einzubauen - das werde ich in 2 Monaten nicht mehr warten können
Ich weiss also nicht, was ich durcheinander werfe. Ich habe gesehen, dass ein MQTT_DEVISE zugriff auf alle MQTT messages haben kann. Und genau das brauche ich nicht (KISS-Ansatz).
Ich wieder hole mich wohl,wenn ich also sage:
- die Funktion IO für den Server reicht mir aus
- ein Client oder auch MQTT_DEVICE bekommt alle Nachrichten seines realen Partners (Kanäle ist eine Abwandlung des gleichen)
- sämtliche interne Trigger werden über notify erledigt.
Das sehe ich als schlank und daher übersichtlich.
Es beraucht noch eine best-practice (nach der ich hier eigentlich gefragt habe) wie man die messages parsed, in Readings wandelt, filtert,...
Wenn der Grundgedanke nicht übereinstimmt - was ist ein Client "in FHEM" - dann kommen wir klar zu anderen Ergebnissen.
Noch eines (evtl wiederholt es sich): Ich will MQTT in FHEM einbinden und nicht umgekehrt.
Noch einmal explizit die Frage an das Auditorium das ein MQTT Client in FHEM leisten soll.
Und noch eines - sorry - meine (experiment-)shelly sind auch clients - formal. die tun auch real etwas. der fhem-client ist also immer nur ein Soft-Abbild. Das ist aus meiner sicht der entscheidende Unterschied zu realen Device.
@martinp876
Mein erster Post am Sonntag hat es nicht geschafft, seit dem hat sich die Diskussion weiter entwickelt.
Mit scheint, jetzt ein guter Zeitpunkt für einen neuen Versuch gekommen zu sein.
Ich setze MQTT inzwischen recht umfangreich ein: Tasmota, Shelly Gen1/Gen2, Zigbee2MQTT, OwnTracks, AWTRIX und einige eigene Dienste. Als Broker verwende ich direkt MQTT2_SERVER:
define MQTT2_FHEM_Server MQTT2_SERVER 1883 global
attr MQTT2_FHEM_Server autocreate complex
Meine Praxis ist dabei:
1. attrTemplate als Ausgangspunkt verwenden.
2. Danach readingList auf die wirklich benötigten Topics und Readings reduzieren.
3. Mehrkanalgeräte in mehrere MQTT2_DEVICE-Entities aufteilen, wo sinnvoll. Beim Rolladen natürlich nicht.
4. Mit devicetopic, jsonMap und manchmal auch etwas Perl in der readingList die MQTT-Daten auf FHEM-übliche Readings abbilden.
5. Erreichbarkeit über LWT beziehungsweise online/availability behandeln.
Ein Beispiel für einen Shelly Plus 1:
define GartenSteckdose MQTT2_DEVICE shellyplus1_xxxxxx
attr GartenSteckdose devicetopic zuhause/terrasse/steckdose
attr GartenSteckdose jsonMap
switch_state:state
switch_temperature_tC:temperature
switch_temperature_tF:0
params_wifi_sta_ip:ip
attr GartenSteckdose readingList
$DEVICETOPIC/online:.* online
$DEVICETOPIC/events/rpc:.* { json2nameValue($EVENT,"",$JSONMAP) }
$DEVICETOPIC/status/switch_0:.* {
$EVENT =~ s/"output":true/"state":"on"/g;;
$EVENT =~ s/"output":false/"state":"off"/g;;
json2nameValue($EVENT,"switch_",$JSONMAP)
}
attr GartenSteckdose setList
toggle:noArg $DEVICETOPIC/rpc {"id":0,"src":"fhem","method":"Switch.Toggle","params":{"id":0}}
off:noArg $DEVICETOPIC/rpc {"id":0,"src":"fhem","method":"Switch.Set","params":{"id":0,"on":false}}
on:noArg $DEVICETOPIC/rpc {"id":0,"src":"fhem","method":"Switch.Set","params":{"id":0,"on":true}}
on-for-timer $DEVICETOPIC/rpc {"id":0,"src":"fhem","method":"Switch.Set","params":{"id":0,"on":true,"toggle_after":$EVTPART1}}
attr GartenSteckdose setStateList on off
Damit wird aus dem Shelly-Feld output:true bewusst ein FHEM-typisches state:on. Die Zuordnung mache ich nicht erst nach dem vollständigen Flattening eines großen JSON-Baums, sondern bereits anhand des konkreten Topics status/switch_0.
Für Mehrkanalgeräte verwende ich getrennte FHEM-Devices. Ein Tasmota-Gerät (Shelly analog) mit zwei Relais sieht bei mir vereinfacht so aus:
define LichtTisch MQTT2_DEVICE DVES_xxxxxx
attr LichtTisch devicetopic zuhause/wohnzimmer/licht
attr LichtTisch readingList
tele/$DEVICETOPIC/LWT:.* LWT
tele/$DEVICETOPIC/STATE:.* {
my $r=json2nameValue($EVENT);;
return { map { $_ => $r->{$_} }
grep { /^(?:Uptime|POWER1|RSSI)$/ } keys %{$r} };;
}
stat/$DEVICETOPIC/RESULT:.* { json2nameValue($EVENT) }
attr LichtTisch setList
off:noArg cmnd/$DEVICETOPIC/POWER1 0
on:noArg cmnd/$DEVICETOPIC/POWER1 1
toggle:noArg cmnd/$DEVICETOPIC/POWER1 2
attr LichtTisch stateFormat POWER1
define LichtCouch MQTT2_DEVICE DVES_xxxxxx
attr LichtCouch devicetopic zuhause/wohnzimmer/licht
attr LichtCouch readingList
tele/$DEVICETOPIC/LWT:.* LWT
tele/$DEVICETOPIC/STATE:.* {
my $r=json2nameValue($EVENT);;
return { map { $_ => $r->{$_} }
grep { /^(?:Uptime|POWER2|RSSI)$/ } keys %{$r} };;
}
stat/$DEVICETOPIC/RESULT:.* { json2nameValue($EVENT) }
attr LichtCouch setList
off:noArg cmnd/$DEVICETOPIC/POWER2 0
on:noArg cmnd/$DEVICETOPIC/POWER2 1
toggle:noArg cmnd/$DEVICETOPIC/POWER2 2
attr LichtCouch stateFormat POWER2
Beide Entities haben dieselbe CID und dasselbe devicetopic. Die Trennung erfolgt durch die konkreten Topics beziehungsweise durch das Filtern auf POWER1 oder POWER2. So können Automatisierungen mit normalen FHEM-Devices wie LichtTisch und LichtCouch arbeiten, ohne die MQTT-Kanalstruktur kennen zu müssen.
Bei Zigbee2MQTT ist es meist noch kürzer:
define Kuechenlicht MQTT2_DEVICE zigbee_kuechenlicht
attr Kuechenlicht devicetopic zigbee2mqtt/zuhause/kueche/licht
attr Kuechenlicht readingList
$DEVICETOPIC:.* {
my $r=json2nameValue($EVENT);;
$r->{state}=lc($r->{state}) if defined $r->{state};;
return $r;;
}
$DEVICETOPIC/availability:.* availability
attr Kuechenlicht setList
on:noArg $DEVICETOPIC/set {"state":"ON"}
off:noArg $DEVICETOPIC/set {"state":"OFF"}
brightness:colorpicker,BRI,0,5,255 $DEVICETOPIC/set {"state":"ON","brightness":$EVTPART1}
attr Kuechenlicht setStateList on off
Hier normalisiere ich ON/OFF direkt auf on/off. Die Erreichbarkeit kommt separat über availability.
Mein Fazit: Ich versuche nicht, aus jedem eingehenden JSON automatisch ein universelles FHEM-Device zu erzeugen. MQTT ist für mich zunächst der Transport. Die Übersetzung in die FHEM-Nomenklatur erfolgt pro Gerätefamilie über attrTemplate, readingList, jsonMap und gegebenenfalls eine kleine Perl-Funktion.
Die langen Attribute sind in der Weboberfläche tatsächlich wenig angenehm. In der Konfigurationsdatei sind sie mit Einrückung und Zeilenumbrüchen aber noch gut wartbar. Wichtig für die Performance ist aus meiner Sicht vor allem, Topics möglichst konkret zu abonnieren und aus großen JSON-
Nachrichten nur die tatsächlich benötigten Readings zurückzugeben.
Damit habe ich auch bei vielen Geräten und getrennten Kanal-Entities bislang keine praktischen Performanceprobleme festgestellt.
Grüße Sidey
@Sidey:
Besser kann man das kaum zusammenfassen.
@martinp876
Das mit den langen Attributen ist lästig, aber für ein generisches ("fhem-client-") Modul kaum zu vermeiden, denn letztlich muss irgendwo die Info hin, wie eine auf ein bestimmtes Topic kommende Payload auszuwerten sein soll (readingList) bzw. wie und wohin ggf. von FHEM aus zu sendende Anweisungen bzw. Anfragen zusammenzubauen sind (setList/getList).
Die "alte" Implementierung (IO-Modul MQTT, "fhem-clients" MQTT_DEVICE/MQTT_BRIDGE) macht das statt der o.g. Attribute (zu MQTT2_DEVICE) durch eine Vielzahl der "immergleichen" Attribute, ohne die Option, direkt Perl-Funktionen aufzurufen oder "generische" Variablen (=>devicetopic) zu verwenden.
Da die Einrichtung eine einmalige Sache ist, ist das mit den multiline-Attributen m.E. weiterhin der praktikabelste Weg.
Für manche Zwecke rufe ich auch schon mal direkt modifizierte Varianten von json2nameValue() auf. Hier z.B. ein (zigbee-) Device, das an den zigbee2mqtt-Dienst eben sekündlich Daten sendet, die dann von dort aus auch so (ungefiltert) eingehen:
defmod Solaranlage_FI MQTT2_DEVICE zigbee_0xblub
attr Solaranlage_FI devicetopic zigbee2mqtt/0xblub
attr Solaranlage_FI readingList $DEVICETOPIC:.* { FHEM::attrT_z2m_eocr_Utils::j2nV_extended($NAME,$EVENT) }\
$DEVICETOPIC/availability:.* { $EVENT=~s{state}{availability}x;; my $ret=json2nameValue($EVENT);; $ret->{state}='off' if $ret->{availability} eq 'offline';; return $ret }
Es gibt auch noch ein paar fhem-client-Module, die sehr spezifischen Code beinhalten, aber das macht in der Regel nur Sinn, wenn es eigentlich nicht darum geht, erst mal Infos zu sammeln, die dann FHEM-typisch per notifyFn weiter ausgewertet werden. (Bsp: RHASSPY als Sprachsteuerungsoption).
Ansonsten wäre meine Anregung, dich an die für MQTT@FHEM üblichen Begrifflichkeiten zu gewöhnen, sonst gibt das eine Unzahl von Einbruchsstellen für Missverständnisse... (Meintest du in deinem letzten Beitrag tatsächlich MQTT_DEVICE, oder war nicht doch MQTT2_DEVICE gemeint? Eindeutig letzteres...)
@Sidey,
1) dein Ansatz der FHEM Entites bezüglich der Kanäle entspricht exakt meiner Vorstellung - und Planung.
2) die Auswertung der ReadingList werde ich mir Ansehen
@Beta-User
ZitatDas mit den langen Attributen ist lästig, aber für ein generisches ("fhem-client-") Modul kaum zu vermeiden...
sehe ich ganz und garnicht so. Ok, wenn man es in Attributen machen will, schon. Aber notwendig ist das nicht. Ich habe einfach eine Sub in meinen Utils hierfür erstellt.
attr mydevice coverAbDoor:shelly.*:.* {muParseMQTT($NAME,$CID,$TOPIC,$EVENT)}diese werden ich ausbauen analog wie es bei CUL_HM funktioniert.
- dem MQTT Device werden ich einen "Modelnamen" zu weisen (attr) und ggf eine "Kanal" extra. Weiter werde ich eine ID verankern in def oder in attr - funktional egal.
- die (meine) templates werde ich dann in einer entsprechenden Struktur hinterlegen, welche die Auswertung und die Readings steuert. Um kompatibel zu bleiben wird die Struktur in gewohnter weise zurückgegeben.
Damit erreiche ich, dass die Auswertung für alle gleichem Model gleich (gut oder schlecht) ist.
- Auch setlist wird über das "model" gesteuert werden. Wie alle Typen welche ich ernsthaft betreibe werden auch hier noch meine generischen kommandos addiert - da kann ich die setlist abfrühstücken.
damit ist meine Installation (cfg) einfach zu prüfen - der Rest ist code und nach "abnahme" statisch und stabil. So brauche ich es.
also danke für den Vorschlag zu den readings - interessiert mich sehr.
@pha @Beta-User klar was ihr sagt - unklar, was ich damit anfangen soll. JEDES device und jede variante/kanalmodel muss jemand /werde ich bei Einsatz prüfen müssen und ein Template erstellen.
Das ganze geht noch nicht meine Bedenken der Performance an. Und da bin ich etwas sensibel... mal sehen, evlrt glätte ich MQTT_DEVICE etwas.
Und dann kommt noch die Maintenance Aufgabe - bspw prüfen der Devices auf "lebt noch".
Vielen Dank für die gute Diskussion bis jetzt.
Zitat von: martinp876 am 29 Juli 2026, 18:41:381) dein Ansatz der FHEM Entites bezüglich der Kanäle entspricht exakt meiner Vorstellung - und Planung.
Wir haben da vermutlich alle miteinander eine ziemlich ähnliche Vorstellung: Jeder (on-/off-) schaltbare (Haupt-) Kanal sollte ein fhem-device ("entity") ergeben.
Einige "Sonderlocken", die es sonst (fast) nur in CUL_HM gibt, finden sich auch in MQTT2_DEVICE: So kann man (via setStateList) einen on-Befehl übergangsweise mit "set_on" nach "state" bekommen, bis die Bestätigung von der Hardware zurückkommt, dasselbe z.B. für "brightness" oder "pct"...
Die allermeisten in attrTemplate (mqtt2.template) hinterlegten Beispiele berücksichtigen das ;).
Zitat von: martinp876 am 29 Juli 2026, 18:41:38sehe ich ganz und garnicht so. Ok, wenn man es in Attributen machen will, schon. Aber notwendig ist das nicht. Ich habe einfach eine Sub in meinen Utils hierfür erstellt.
Code Auswählen Erweitern
attr mydevice coverAbDoor:shelly.*:.* {muParseMQTT($NAME,$CID,$TOPIC,$EVENT)}diese werden ich ausbauen analog wie es bei CUL_HM funktioniert.
Zwei Anmerkungen:
1. Ist das nicht genau das, was ich beschrieben habe? Du nimmst ein Attribut und schreibst rein, wie eingehende Info zu verarbeiten ist? Wie lange der auslösende Topic-Abschnitt ist, ist in dem Zusammenhang erst mal irrelevant, da in der Regel auf der Hardware zu konfigurieren.
2. Tipp: Verwirf den Gedanken, $CID sei irgendwie wichtig. Klare Topic-Strukturen sind hilfreich, alles andere zur Identifikation der dahinter liegenden Hardware kann (und sollte) man daraus ableiten können.
Zitat von: martinp876 am 29 Juli 2026, 18:41:38Und dann kommt noch die Maintenance Aufgabe - bspw prüfen der Devices auf "lebt noch".
"pct set_90" hatte ich ja bereits als Indikator genannt.
Was "LWT" angeht, sind meine Erfahrungen etwas gemischt. MQTT2_SERVER hat da bei mir z.B. ein Problem mit einem Tasmota, der (jetzt) im LAN hängt (der Vorgänger war mit demselben Symptom via WLAN eingebunden...).
Und was macht man mit Hardware, die hinter einem (Hardware-Interfacing)-Dienst hängt? zigbee2mqtt geht offline, wenn die Software streikt, und dann ist alle Hardware, die dahinter hängt nicht mehr erreichbar (ähnlich, wie wenn das letzte CUL_HM-IO ausfällt). (Ähnliches gilt für den AHOY-DTU-ESP32, mit dem meine PV-Inverter abgehorcht werden).
Kurz: Sowas ist imo eine Aufgabe für ein Querschnittsmodul wie ReadingsWatcher (oder ein "at"...).
Was Performane angeht, kann man sicher das eine oder andere straffer vercoden, v.a., wenn man nur jeweils den Teil berücksichtigt, den man in der eigenen Installation braucht und dabei ggf. den "Zoo" noch dadurch vereinfacht, dass man nur bestimmte Hersteller/firmwares wählt. Solange das klappt, ist alles gut, wenn nicht, wird es schnell (imo) unwartbar.
Aber vermutlich übersehe ich was wichtiges oder wir sprechen aneinander vorbei.
ZitatMQTT2_SERVER hat da bei mir z.B. ein Problem mit einem Tasmota, der (jetzt) im LAN hängt (der Vorgänger war mit demselben Symptom via WLAN eingebunden...)
Zitat(Ähnliches gilt für den AHOY-DTU-ESP32, mit dem meine PV-Inverter abgehorcht werden)
Beides find ich interessant. Hattest Du dazu mal irgendwo mehr Hintergrund geteilt?
Zitat von: TomLee am 29 Juli 2026, 22:55:35Beides find ich interessant. Hattest Du dazu mal irgendwo mehr Hintergrund geteilt?
Nein, jedenfalls nicht, soweit ich mich entsinne.
Da das hier aber ziemlich OT (und nach wie vor im falschen Forenbereich) ist: https://forum.fhem.de/index.php?msg=1367219
Zitat1. Ist das nicht genau das, was ich beschrieben habe
vielleicht - nein, eher nicht. Musst du entscheiden.
Mein Code ist in einer Subroutine. Das ist für mich entscheidend. Die folgende Auswertung wird nämlich deutliche ausführlicher und subtiler als das, was ich in einem Attribut darstellen kann. Weiter wird die Subroutine generisch - und für ALLE devices gültig sein. Die Steuerung wird über Attribute erfolgen, welche dem Device anhängen - wie "model" oder "Channel".
So eine Routine gibt es auch in CUL_HM - da ist sie nicht sichtbar, weil im Code verankert.
Zitat2. Tipp: Verwirf den Gedanken, $CID sei irgendwie wichtig
also in MQTT_DEVICES wird dieser erst einmal extensiv ausgewertet.
Ich werde das prüfen. Typisch hat eine message in jeden Protokol eine source und eine destination adresse. Es gilt, diese zu identifizieren und dann die Readings mit den Messages der aus der source zu befüllen.
in ReadingsList werden die Level "source-select" und "content-eval" vermischt. Das macht die Sache nicht geradlinig.
Für Tasmota und shelly kann ich sowohl CID alsauch topic (bei shelly ist es prefix) einstellen. Ok, CID wird als Adresse ausserhalb von json genutzt - ist aber erste einmal egal.
Ich kann also die masse meiner Devcices sauber darüber identifizieren. Wenn mit welche unterkommen die hier schlampen werde ich das dann betrachen.
ZitatUnd was macht man mit Hardware, die hinter einem (Hardware-Interfacing)-Dienst hängt?
ich verstehe die Frage nicht. Natürlich verstehe ich die Aussage - allerdings verstehst du meinen Ansatz nicht. Hier ein paar Überlegungen und Statemens von mir
1) mit "Alive" stelle ich fest, dass ein Gerät erreichbar ist
2) Geräte sollte ich klassifizieren in "statisch" und "dynamisch" erreichbar. Fest installierte sind statisch während tragbare geräte in der Hosentasche das Haus auch verlassen dürfen. Statische MÜSSEN erreichbar sein
3) "dead" ist evtl die falsche Phrase - sie kann immer nur bedeuten "unreachable" (ist mir aber zu lang :) )
4) nicht erreichbar von statischen Devices ist IMMER einen Alarm (unterschiedlichen Levels ) wert - irgend etwas ist nicht mehr steuer oder überwachbar.
5) die Auswirkungen von "Dead" sind zu prüfen - also was soll das System 'automatisch' machen. m.E. sollte der State auf Dead gesetzt werden - ggf auch verschiedene Readings. Ein Thermostat liefert eben keine Werte mehr und damit ist das Reading "Temperatur" unsicher. Und unsicher ist für mich kein tragbarer zustand. Beachte, dass ich Temperatur ggf auch in Grafiken ansehe, den Zusammenhang mit "state" also nicht sehen kann.
6) alarm-hierarchie: über die denke ich schon etwas länger nach - habe auch einen Level in CUL_HM eingebaut. Ich vermute dass dies ausser mir keine nutzt. Die Überwachung der Geräte soll performance-schonend sein (logisch, gilt immer) - also werden nur die Devices (CUL_HM Nomenklatur) auf Alive geprüft. Die Kanäle bzw deren Readings werden ausgehend von Device entsprechend modifiziert
Der next-level, das IO also... das habe ich schon lange auf dem Schirm. Rein formal ist das kein Unterschied. Wenn das IO ausfällt sind alle geräte dahinter "dead" - oder sematisch korrekt "unreachable". Wir verstehen die Details und müssen sie hier nicht runter brechen: Multiple IOs, temporary stuck (device overload),...
==> Unreachable ist unreachable (und damit für FHEM dead). Kein Grund, das Device in den Müll zu werfen aber ein Grund tätig zu werden und das Problem zu lösen.
==> hat man ein instabiles System hat man eh verloren
ZitatWas Performane angeht, kann man sicher das eine oder andere straffer vercoden,
nun, ich sehe, dass für alle MQTT messages sämtliche devices mit allen Readings geprüft werden. Ok, die Prozessoren werden immer schneller... aber hier bin ich halt etwas eigen.
Mit steigender Anzahl der Devices potenziert sich das ganze. Mehr messages müssen gegen mehr regexp geprüft werden. Das geht m.E. besser. Ich probiere es gerade einmal - und da kommt führend eben die CID - oder der Topic - oder der prefix zum tragen.
kurz die Idee:
eines der obigen werde ich als "adresse" nutzen (das ist sicher) mit welcher ich die entity tagge.
Empfange ich die message suche ich das entsprechende Device. Hier lese ich die Tags "model" und "channel" (fix ist das noch nicht, sollte aber zum Verstehen der Idee reichen). Dementsprechend werde ich die message parsen und in Readings wandeln.
In der Entity setze ich also "Device-ID" und "Model" - und dann ggf noch "channel". Der Rest ist dann ein Template. So kann ich "baugleiche" devices spielend und übersichtlich einbauen und duplizieren.
Es gibt einiges zu feilen, klar
Meine 2 sehr kurzen ct:
- In "MQTT_DEVICES" (?) ist $CID nur relevant, wenn man sich statt dieses nicht existierenden Moduls mit MQTT2_DEVICE befasst (=> korrekte Terminologie ist mir wichtig, sonst reden wir weiter ständig aneinander vorbei). Was letzteres angeht, hat der Erfinder und Maintainer deutlich (in etwas anderen Worten) jüngst geäußert, dass er das zwischenzeitlich selbst für einen Irrweg hält...
- Die Welt der Geräte und Dienste, die das MQTT-Protokoll implementiert hat, ist sehr viel bunter, als du das mit deinen (mit Verlaub) eben mal 2 Typen beurteilen kannst.
- ad "alive" und den vermuteten allgemeinen Problemen bei ESP-basierter Hardware siehe auch https://forum.fhem.de/index.php?topic=145223.msg1367339#new
Kurz: Dein Ansatz ist m.E. ein unwartbarer Irr- und Sonderweg.
Wie gesagt: Meine 2ct.
Das ist übrigens zwar deutlich gesagt, aber nett gemeint, und den Code von CUL_HM kannte ich auch mal einigermaßen im Detail ;) .
Um noch was positives anzufügen:
Für (mehr oder weniger) jedes "model" bzw. "model-family" je eine spezifische Perl-Routine aufzurufen, dürfte eher zielführend sein. Es gibt durchaus Spezifika bei einzelnen Gerätegruppen (oder Diensten wie zigbee2mqtt), die über die generische Attribut-Auswertung via json2nameValue() nicht "gut" (und effizient) abgebildet sind. Z.B. sendet zigbee2mqtt die Batterie-Spannung typischerweise in mV...
Falls in diese Richtung Vorschläge kommen, befasse ich mich gerne damit!
nun - meine Experimente gehen voran - und mein Konzept nimmt gedanklich Gestalt an. Zu eueren Bedenken fehlt mir tatsächlich der Zugang - oder die Beispiele.
Hier noch einmal meine Anforderungen. Falls diese sich von euren unterscheiden können wir es versuchen, abzugleichen
Ziele und Requirements
1) MQTT in FHEM integrieren - nicht umgekehrt. D.h. ich muss nicht alles, was MQTT könnte auch machen. U.a. bedeutet dies, dass ein MQTT_DEVICE kein genereller Client ist sondern nur ein avatar des realen Geräts. Damit vereinfachen sich die Routing-Anforderungen
2) Tasmota und Shelly sind meine Kandidaten und Prototypen. Das Konzept wird offen sein so dass ich anderen integrieren kann wenn der Bedarf besteht
3) kodieren in Attributen (readingList) geht aus mehreren Gründen nicht. Zum einen wird die gesamte Darstellung dermassen versaut, dass es nicht mehr lesbar ist - geht garnicht. Zum 2. wird die Vergleichbarkeint 2er devices unangemessen schwer. MEINE templates werden nicht per Copy erstellt sondern per Referenz. Alles andere ist für mich am Ende nicht akzeptabel
4) die Performance beim Parsen ist wichtig - die aktuelle Implementierung unangemessen. Das geht deutlich besser
5) das einrichten einer entity muss mit wenigen Handgriffen UND übersichtlich erfolgen können
6) Entites auf Kanalbasis sindsowieso gesetzt
Zu den Einwänden
CID ist ein Holzweg
kann ich aktuell nicht erkennen. Shelly und Tasmota laufen bereits. Sollte ein Device "erscheinen" welches das nicht kann werde ich es betrachten und eine Lösung finden. MQTT arbeitet damit - src und dst werden übertragen (sollten wohl auch)... Ich sehe bislang kein Problem. Klar - der Anwender (also ich) muss die CID am Device korrekt einstellen.
eigene Implementierung des Servers
Ich werden sowieso nichts auf fhem veröffentlichen (neues Modul) wenn keine relevante Nachfrage besteht. Ich habe (leider) schon mehrere Module frisieren müssen.
Aktuell wird bei meinen Konzept der Server nicht angetastet - "DEVICE" ist der Kandidat.
Mein Konzept
Vorwort
ich erwarte nicht, dass es in MQTT3 umgesetzt wird. Ziel ist es wie immer, möglichst am alten Code festzuhalten.
realisierung
Es wird EINE "Device-routing-entity" geben welche eben den Parser und router beinhaltet.
defmod MQTTroute MQTT2_DEVICE
attr MQTTroute readingList .*:.*:.* {muParseMQTT($NAME,$CID,$TOPIC,$EVENT)}
Alle Messages werden in der Funktion "muParseMQTT" bearbeitet.
KEIN anderes MQTT2_DEVICE hat ein readindList Attribut.
MQTT2_DEVICEs werden getaggt mit CID, Model und function/channel. In der Wahl der Tag.Namen bin ich noch frei :)
MQTT2Modul wird Daten der Devices aufbereiten für performanten Zugriff. D.h. eine Referenztabelle CID->Entityname wird erstellt und maintained. Bei der Gelegenheit auch die anderen Tags von oben. MQTT hat also immer eine aktuelle und performante Referenz.
Hierzu wird sich MQTTroute an das global-notify hängen und alle updates durchführen. Das ist bereits eine standardübung - realisiere ich aber erst am Schluß. Und logisch - bei allen anderen entites wird notify unroled - unnötig, Performance.
Jede empfangene Nachricht wird also genau einmal geparst - wie folgt
1) prüfen der Adresse (aktuell immer noch CID). Abbruch, wenn keine passende Entity gefunden wird.
2) Zerlegen der Message mit json2namevalue. Da hier der Trenner "_" ist wird einem das Leben schwer gemacht - eben so dass die Beschreibung unvollständig ist. Aber der Anwender muss sich am Ende nicht mehr damit herumschlagen (ich vergesse das innerhalb von weingen Tagen!)
3) Anpassen der DP: Filtern und Übersetzen in Readings entsprechend dem Template. Hierzu wird es eine Tabelle(hash) geben, welche gemäß "model" die Anpassungen vornimmt.
4) die Values werden angepasst nach erstellten Regeln.
5) die DP/Readings werden gemäß "Kanal" oder "Funktion" gruppiert um sie zuweisen zu können, wenn der Tag passt
6) die Readings werden über ReadingBulk den Entites zugewiesen wie selektiert
User Interface
Templates erstelle ich als single-user in einem entsprechenden File - als hash. Für eine "öffentliche" implementierung kann man das auch "öffnen" und dem User hier eigenes erlauben. CUL_HM hat dies schon vor Jahren realisiert - erfolgreich, wenn auch nur selten notwendig.
Für alle existierenden Templates kann der User über die Tags einstellen, welche Funktionen er in der Entity sehen will. Damit lassen sich Kanäle einfach realisieren/abbilden und auch "sondergruppen" einblenden (und ausblenden!!!) wie eine IP configuration.
noch nicht betrachtet
Die setList werde ich mir später vornehmen.
Es wird weitere Kommandos brauchen - bspw ein clear-readings. Aber hierfür habe ich schon ein Standartmodul welches minimal-invasiv die Liste der set/get um m.E. notwendige erweitert ;)
Ist jetzt etwas hoplahop... hoffentlich halbwegs verständliche, vielleicht erntet es sogar die eine oder ander Zustimmung oder zumindest Interesse.
Ich bastle mal weiter wenn es einen hinreichenden Stand hat und interesse besteht stelle ich es natürlich vor.
Zitat von: martinp876 am 02 August 2026, 08:00:45dass ein MQTT_DEVICE kein genereller Client ist
...
defmod MQTTroute MQTT2_DEVICE
Kannst Du mal bitte irgendwann Deine Nomenklatur geradeziehen?
Warum schreibst Du immer von MQTT_DEVICE wenn Du dann ein define mit MQTT
2_DEVICE aufzeigst?
MQTT_DEVICE und MQTT2_DEVICE sind zwei völlig voneinander getrennte Module.
Diese Vermischung erschwert die Nachvollziehbarkeit Deiner Ergüsse erheblich.
Danke.
Und für Diskussionen zu MQTT/MQTT2 gibt es sogar ein eigenes Unterforum...
Zitat von: martinp876 am 02 August 2026, 08:00:45hoffentlich halbwegs verständliche, vielleicht erntet es sogar die eine oder ander Zustimmung oder zumindest Interesse.
Abgesehen von dem Benennungs-Ding, auf das betateilchen auch nochmal hingewiesen hat: halbwegs verständlich, und ja, durchaus interessant.
Anmerkungen:
- Wenn Performance DAS erste Leitkriterium ist, wäre der erste in diese Richtung wichtige Schritt, vom Server nur diejenigen Topics zu abonnieren, die einen für FHEM-Entities interessieren. Ergo: Externer Server, die subscriptions müssen dann von deiner Zwischenschicht verwaltet werden. Was das für dein "so wichtiges" CID-Ding bedeutet, liegt auf der Hand...
- Es gibt FHEM-Module, die das mit korrekten, automatisch generierten subscriptions bei einem externen Server heute schon machen. Bei Interesse würde ich einen Blick in Blick in MQTT_GENERIC_BRIDGE anempfehlen.
- Das eben genannte Modul hat auch eine Funktionalität, durch die der unter performance-Gesichtspunkten überflüssige erste Dispatch über dein MQTTroute-Device ersetzt; effektiver wäre ein eigenes MQTT3_BRIDGE-Modul.(MQTT_GENERIC_BRIDGE ist als package vercoded, du kannst einfach einen Klon machen und da erst mal nur deinen Code als ParseFn() anflanschen)
- Da meine genannten Beispiele für komplexere Zwischenschichten (zigbee2mqtt und AHOY-DTU) anscheinend nicht angekommen sind: Wir werden immer aneinander vorbei reden, wenn du sowas noch nie live erlebt hast. Als Prototypen für derartige Konstruktionen würde ich (zumindest empfangsseitig) einen ESP32 mit OpenMQTTGateway (BLE) empfehlen. Da geht es immer darum, dass man einen "Dienst" hat, der mehrere bzw. viele hinter dem Dienst liegende Hardwares auswerten (bzw. auch aktiv ansprechen) kann.
Ansonsten wäre zigbee2mqtt der Kandidat, Falls du neben den zu diesem Komplex zu findenden Infos im FHEM-Wiki weitere Details brauchst: Melden.
@martinp876
Ich kann mir gut vorstellen, dass die Verarbeitung von mqtt Nachrichten in gewissen Fällen optimiert werden könnte.
Z.B. durch den Einsatz einer Hash Table, welche Topics abbildet.
Ich gehe aber davon aus, dass es dadurch Verluste der Flexibilität gibt.
Was mich an deinen Ausführungen überrascht ist, dass Du nur ein einziges MQTT2_DEVIVE anlegst.
In was bildest Du denn die Readings und Schaltbefehle dann ab?
Ich kenne deine Code Anpassungen nicht, hast Du schon Werte, wie viel CPU Zyklen du je Nachricht einsparst?
Grüße Sidey
Wieso einfach, wenn es auch kompliziert geht?
Aber ist ja auch in Ordnung, bekanntlich führen mehrere Wege ans Ziel.
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.
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
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%
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.
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.)
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.
CID: bei Shelly sowie Tsamota kann ich die CID einstellen. Das ist mein Target.
Zitatdefine m2d_test MQTT2_DEVICE model=shellyPM2:function=switch_0:evalMQTT=1
geht wohl garnicht, geh tam Ziel vorbei. Die (zumindest meine) Idee ist doch eindeutig, das ein Entity genau die Messages IHRES device entpängt.
Model ist die HW, Function idee eingestelle Funktion. Damit filtere ich eben nicht die Messages MEINER entity heraus.
Vielmehr ergibt Model und Funcktion zusammen "mein" Template nachdem die Messages inhaltlich zerlegt und gefiltert werden sollen - das was ich aktuell als "model" Attribut vergebe. Alle meime shellyPM2/switch bekommen das Template.
Shelly als beispiel nutzt explitzit eine "einstellbare" CID welche mit shelly_<MAC> vorbelegt ist und damit weltweit eindeutig.
Zurück auf Start:
ich bin faul - eigentlich will ich ein einfaches Interface - OAMP (operation, administration, maintenance, provisioing). Gefühlt hat mich das einreichten des ersten und insbesonderen des 2. Devices deutlich zu viel Zeit gekostet, ist (ich gehe im Folgenden immer von mir aus) zu ... umständlich auf fast allen Ebenen.
Von mir bekommt es ein mangelhaft. Ich will niemanden zu nahe treten - ich sehe durchaus den schanken Ansatz des Moduls - ich will einen Schlangen Ansatz für mich als Anwender (OAPM&P). Dafür codiere ich gerne deutlich mehr.
Die einleitende Frage war: mache ich etwas falsch oder ist das schon die best-current-practice. Und das ist nun einmal so.
Zu Rudi's Ausführungen(kam vorher schon einmal): in FHEM gibt es offensichtlich und kaum verwunderlich einige MQTT basierende Module - ist ja schliesslich ein offener Standard. Cool fände ich nun ein generischer Sende/Empfangs "IO" welches die Messages einer Device-HW an die FHEM-entity (welche ein Abbild darstellt) routed und dort - ggf in einem modul erlegt wird.
Das kann ich aktuell nicht erkennen.
Ich kenne Beta-Users Module nicht - aber die CID ist m.E. (ich habe mich nicht eingearbeitet) eben eine eindeutige Kennung.
Shelly unterstützt dies in jeden Fall - ich sehe keine Einschrängung.
Bei Shelly kann ich auch direkte Device2Device kommandos schicken, so die Doku. Habe ich noch nicht genauer angesehen, aber der receiver muss in jeden Fall den Absender ein-eindeutig erkennen. Model und Typ sind in keinem Fall ausreichend! Wenn es nicht die CID ist, was ist es dann?
Und klar, da man die CID einstellen kann (bei genannten Devices) kann man Chaos anrichten. a) selbst schuld und b) Aufgabe der Maintenance, hier zu sniffen.
Da ich meine Shelly nun endlich sauber an den Start (oder in Stufe real-usable) setzen muss bleibt mir mangles ausreichender Alternative nur, es selbst fertig zu machen.
Mein Konzept steht:
#Dev 1 device information only
define m2d1_1 MQTT2_DEVICE <CID>
attr m2d1_1 model shellySwitch
attr m2d1_1 channel device
#Dev 1 channel0 information only
define m2d1_0 MQTT2_DEVICE <CID>
attr m2d1_0 model shellySwitch
attr m2d1_0 channel switch_0
#Dev 1 channel1 information only
define m2d1_1 MQTT2_DEVICE <CID>
attr m2d1_1 model shellySwitch
attr m2d1_1 channel switch_1
#Dev 2 all information
define m2d2 MQTT2_DEVICE <CID>
attr m2d2 model shellySwitch
#Dev 2 evaluate MQTT messages from this CID
define m2d2 MQTT2_DEVICE <CID>
attr m2d2 evalMQTT 1
Technisch wird es ein Modul myMQTT welches sich an MQTT2_DEVICE koppelt.
Ich denke dass es in Sachen Usability deutlich vorne liegt - das ist eh klar, ich mache es ja auch , wie ich denke.
Vorläufig werde ich es ohne meine System-addons bauen, damit einfach kopierbar. Später wird sich das sowieso ändern müssen, da grundsätzlich nützliche Funktionen für mich IMMER fehlen
Weiter werde ich die Template-Erstellung nicht mit einem "schönen" UI ausstatten - das brauch ich erst einmal nicht und wenn es keine anderen Interessenten gibt ist es vergebener Aufwand.
Die übrigen Diskussion war für mich sehr interessant und erweiternd. Aber es war nichts dabei, was mein Vorgehen ändert.
Schlusssatz: wenn es Interessenten an meinem Ansatz gibt - unverbindlich, klar -kann ich sie auf dem Laufenden halten.
Vielleicht nochmal ein Versuch der Klarstellung, ausgehend von diesem Codeschnippsel:
Zitat von: martinp876 am 15 August 2026, 08:09:42attr MQTTroute readingList .*:.*:.* {muParseMQTT($NAME,$CID,$TOPIC,$EVENT)}
Nur darauf bezog sich mein Hinweis, dass "$CID" keinen Mehrwert bietet und als zu übergebender Parameter entfallen kann bzw. sollte.
Zitat von: martinp876 am 23 August 2026, 17:20:17Die (zumindest meine) Idee ist doch eindeutig, das ein Entity genau die Messages IHRES device entpängt.
Sorry, wenn das für Verwirrung gesorgt hat. Dass man eine Art "identifier" benötigt, um ein einzelnes Stück Hardware (oder sogar einen bestimmten "Channel" auf der Hardware) eindeutig addressieren (und auswerten) zu können, steht außer Frage.
Nur steckt die meistens (Achtung: nicht immer!) im Topic, und genau da hat ja auch die bei Shelly, Tasmota und (fast) überall sonst einstellbare Option der ClientID _auch_ einen Niederschlag.
Für mich ist der korrekte Ort für die Hinterlegung dieses tragfähigen "identitifiers" nicht (zwingend) die DEF, sondern (eher) das Attribut "devicetopic" (wie auch immer man dein Parser das dann auswertet).
Jedenfalls: die heutigen MQTT2-Module nutzen die CID-Info, die im define steckt, ausschließlich dazu, dass die autocreate-Funktion einen Anhaltspunkt hat, welcher Instanz "unbekannte" Nachrichten zuzuordnen sind. Wenn du das anders erledigst, kann die DEF auch dafür genutzt werden, alle Info unterzubringen, die man sonst auch in eine Vielzahl von (neu einzuführenden) Attributen stecken kann.
Mein define-Vorschlag war (nur) dazu gedacht, einen Weg aufzuzeigen, wie man es auch machen kann, wenn man sich von diesem autocreate-Konzept verabschiedet. Es spricht andererseits auch nichts dagegen, die "identifier"-Info dann auch noch mit in die DEF zu schreiben, wenn man sie gerne dort haben will.
nun, bei Identifier sind wir uns eigentlich einig. Ja, Shelly sowie Tasmota haben neben der CID auch eine "Prefix" welchen sie nutzen. Dieser ist per default identisch zur CID - und ja, das habe ich gesehen, die genaue Analyse aber aufgeschoben.
Mittlerweile klar, beim Senden der Kommandos reagiert das Device auf den "Prefix".
Wie immer braucht das Kind einen Namen, sonst kann man damit nicht umgehen. "Prefix" scheint üblich zu sein, auch wenn ich lieber etwas mit "ID" gesehen hätte - egal.
Diesen Prefix habe ich natürlich auch gesehen - die Beurteilung aber aufgeschoben, da es am Konzept genau nichts ändert.
Da man das bei den mir vorliegenden Deivces einstellen kann, ist es möglich, lustige Sachen einzurichten, wie Stellvertreter-devices. All das ignoriere ich sehenden Auges - wer so etwas macht muss genau wissen was er tut - mit egal.
Die ID - jetzt eher "Prefix" gehört für mich in die Definition. Es ist bei mehreren Modulen so üblich, dass der UID hier steht - wie IP Adressen, Homematic-ID,... also die Adressen.
Zusammenfassend sehe ich in meiner Welt - und als Regel:
- der Prefix ist einer UID gleichzusetzen. Der Operator bekommt den Hinweis und die Verantwortung.
- mehrere Entities dürfen (in meiner installation) die gleiche UID haben. Die UID ist unique für die HW, nicht die Entity. Damit kann man unterschiedliche Funktionen eines Device in verscheidenen Entites abbilden (Kanäle, debug-entities, device,...)
- wie bei mir üblich wird (wenn ich erst einmal so weit bin) jedes HW-Device EINE Entity haben, über welche ich die Primary-Maintenance mache - also alive-check usw. Diese Entity kann natürlich parallel auch Kanäle beherbergen.
Zusammenfassend: an meiner Vorstellung der Architektur ändert sich durch die Verschiebung der CID auf Prefix nix (aber danke für den Hinweis!). Ich werde auch nicht alles zulassen und einbauen, was möglich ist oder bei irgendwelchen Rasenmähern vorkommt, sondern eine Struktur fordern (in meiner Installation).
Meine eigenen Dokumentation wird dies dann abbilden(damit ich auch morgen noch ein neues Device aufsetzen kann, wenn ich wieder alles vergessen habe :) )
Unter "prefix" hätte ich jetzt eher einen gemeinsamen Topic-Abschnitt für mehrere Hardwares einer "Familie" (z.B. shellies) verstanden, unter "identifier" tatsächlich was Hardware-bezogenes.
Ist aber erst mal nicht wichtig, wenn man davon absieht, dass du damit vermutlich wieder eine "eigene Terminologie" einführst, die nicht allgemein verständlich ist.
die CID sollte man nicht nehmen, weil das dann z.b. mit dem MQTT2_CLIENT nicht funktionieren dürfte. Ein anderes Problem sind bridges. Viele schicken ihre eigene CID, statt der von den verwalteten Geräten und manche auch garnichts. die CID ist aus meiner Sicht nicht entscheidend und wird von zuvielen Devices nicht einmal mitgesendet.
UID/CID/Prefix:
Das wir einen identifier benötigen steht für mich zumindest ausser Frage. Tasmota sowie Shelly trage einen solchen in CID sowie Prefix ein. Insbesondere der Fakt, dass ich kommandos an shelly nur mit diesem Prefix zustellen kann hat mich final bewogen, diesen als UID zu nutzen und die CID zu verwerfen/ersetzen.
Shelly und Tasmota nutzen hier die MAC - das sollte mehr als eindeutig sein. Stellt der Anwender nichts um steht Wert an beiden Stellen identisch.
==>
define <entity> MQTT[b]2[/b]_DEVICE <PREFIX>
Zurück zur anfänglichen Frage nach "Best Current Practice". Danke für alle erläuterungen - so ähnlich sah es bei mir auch aus. Und da ich dies als mangelhaft betrachte fragte ich nach, bevor ich es umschreibe, ob es nicht doch etwas smartes gibt.
Da sich nichts gefunden hat läuft mein "add-on" langsam aber stetig.
Was sind die Anforderungen?
1) templates müssen als Library erstellt werden. Repository ist nicht tragbar
2) ein baugleiches Device muss mit minimalem Aufwand funktionsgleich erstellt werden können
3) zu einem HW-Device mussen mehrere Entites funktionsbezogen erstellt werden können (2-fasch Schaltaktor,...
4) das Frontend muss einfach und geordnet sein
5) eine Eval Option ist bei MQTT unumgänglich - muss beinhaltet sein
und dann noch einiges mehr: DeadOrAlive, Verlinkungen, ...
Begriffe und Wording
Ein model ist zu definien und bildet eine HW-Funktion ab. ein shelly2PM bspw kann als 2-fach Schaltaktor, als Rollosteuerung oder als Jalousie genutzt werden. Man würde hier 2 oder 3 unterschiedliche templates anlegen.
Die function bezieht sich auf die Funktionsgruppen eines Models welche man darstellen will. So sind bspw bei einem Shelly2PM als schalter die Funktionen switch0/switch1/input0/input1/wifi/...vorhanden und müssen bedient werden - je nach Entity und wunsch.
Einrichten auf Basis einer bestehenden Templates
Hierzu muss man die Entity mit Prefix definieren, dann das Attribut "model" festlegen und ggf das Attribut "function". Mehr darf nicht notwendig sein.
Einrichten mit neuem Templates
Das ist spannnd - oder nervig - egal. Es ist sicher notwendig die Messages zu kennen, welche das Device so sendet. dafür setzt man das Attribut "evalMQTT" und die rohen messages werden in Readings gepackt.
Anhand einer Vorgabe erstellt man dann ein Template für das Model mit
- Topics to be collected
- readings in Topic to be ignored
- Grouping of DPs for later function selection
- translation of datapoints to readings
- translation of values to match FHEM standard
Processing
natürlich werden alle Daten für das Verarbeiten aufbereitet. Änderungen in der Konfiguration (Attr) werden umgehend berüchsichtigt
So weit steht es jetzt schon einmal. Für die Eingabe und die Prüfung der Templates habe ich noch kein frontend. Da es wohl keine Interessenten extern gibt, braucht es das auch nicht.
Implementierung ist ein addon modul zum bestehenden, also minimalincasiv
Kannst du mich einmal kurz aufklären, was du da eigentlich machst? Geht es dir nur darum MQTT Devices einfacher einzurichten oder was ist der Plan?
Zitat von: Guybrush am 06 September 2026, 12:51:43Kannst du mich einmal kurz aufklären, was du da eigentlich machst? Geht es dir nur darum MQTT Devices einfacher einzurichten oder was ist der Plan?
Nach meinem Verständnis:
Die aktuelle Implementierung der Analyse eingehender Nachrichten wird als unzureichend (v.a.: nicht performant genug) empfunden. Dabei geht es weniger um die Ersteinrichtung, sondern um den laufenden Betrieb.
Daher gehen ALLE eingehenden Nachrichten (einmalig!) durch einen Parser, der dann ermittelt, welche Instanz von MQTT2_DEVICE welche Infos (als Reading-Wert) erhält. Dabei kann eine Message - je nach Konfiguration mit den von Martin neu eingeführten Attributen - eben keiner, einer oder mehreren Instanzen von MQTT2_DEVICE "zugeordnet" werden.
Dementsprechend kann (bis auf das "Dispatch"-Device) in allen Instanzen von MQTT2_DEVICE auf das Setzen des Attributs "readingList" verzichtet werden.
Grundsätzlich finde ich den Ansatz interessant. Allerdings würde ich manches im Detail anders lösen: die vielen neuen Attribute sind imo unnötig, und der Code wäre besser in einem "MQTT2_DISPATCH"-Modul aufgehoben.
Ob das trägt (oder ggf. mit Hilfe deines "HomeAssistant-autocreate"-Moduls vereinfacht werden) könnte, wären die aus meiner Sicht spannenden Fragen.
Ist aber nur meine persönliche, vermutlich zu vereinfachende Zusammenfassung.
Bei allem Respekt vor der Arbeit, die hier hineingesteckt wird:
Ich sehe darin eine erhebliche Verkomplizierung des eigentlich einfachen MQTT-Prinzips.
Natürlich wird niemand gezwungen, das dann zu benutzen.
Ich rege trotzdem an, per Umfrage unter den FHEM-MQTT-Nutzern herauszufinden, wer sich eigentlich dafür interessiert.
LG
pah
Zitat von: Beta-User am 08 September 2026, 16:50:21Dementsprechend kann (bis auf das "Dispatch"-Device) in allen Instanzen von MQTT2_DEVICE auf das Setzen des Attributs "readingList" verzichtet werden.
Das will ich gar nicht. Bei mir ist es sogar so, dass gleiche Gerätetypen in MQTT2_DEVICEs unterschiedliche readingList verwenden.
Grundsätzlich habe ich in vielen Jahren FHEM die Erfahrung gemacht, dass ALLES, was mir irgendwie "automatisch" das Selbst-Nachdenken abnehmen möchte, am Ende vorne und hinten nicht funktioniert (im Sinne von: liefert mir nicht die erwarteten Ergebnisse) und ich schneller ans Ziel komme, wenn ich mir devices selbst und von Hand einrichte.
Das fängt bei autocreate an und geht weiter über die Verwendung von eventTypes, attrTemplates und was es da alles noch im FHEM-Universum gibt.
Einzige positive Ausnahme: Das Erzeugen von SVG Definitionen aus FileLog oder DbLog liefert mir brauchbare Ergebnisse, die ich dann gerne als Basis für meine Anpassungen verwende.
Insofern unterstütze ich den Einwand von pah zu 100%. Aber vermutlich wird eine Umfrage selbst nicht aussagefähig, da nur ein begrenzter Teilnehmerkreis sich dafür interessieren und ggf. teilnehmen wird.
Viele Anwender haben jetzt schon Probleme damit, das eigentlich simple MQTT in FHEM einzurichten. Das wird mit dem hier angefangenen "Projekt" nicht besser oder gar leichter verständlich werden.
genau das ist das problem. Interessanter Ansatz, aber schon schwer zu verstehen. Ich hab das auch so beobachtet, dass es zu oft an den reinen basics scheitert. die readingList bekommt man dank autocreate noch hin, auch wenn dann die readings zugemüllt werden. die setLists machen dann aber bei zuvielen Probleme. Einer der Gründe für MQTT2_DISCOVERY ;)