[Gelöst] MQTT / Alter von Einträgen und DOIF

Begonnen von Kobold67, 10 April 2019, 18:06:40

Vorheriges Thema - Nächstes Thema

Kobold67

Hallo Zusammen,

Ich habe mir eine Überwachung von Heizungsventilen für die Fussbodenheizung gebastelt. Dabei frage ich die Ventile über Schalter ab, welche ich über eigene Schaltung (ESP32) per MQTT dann an FHEM melde. Die Abfrage erfolgt im Minutentakt, dass reicht bei der Trägheit der Ventile.

In FHEM habe ich nun PushSafer angebunden, damit wenn sich die Schaltung verabschiedet, automatisch auf den Handy benachrichtigt werde. Leider kommt das beim ESP32 selten, aber immer noch vor.

Hier die Auszüge aus meiner FHEM.LOG:


2019.04.10 18:01:00 5: PUBLISH: 1(17)(0)(13)hvmon/valve_1ON
2019.04.10 18:01:00 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/valve_1:ON
2019.04.10 18:01:00 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/valve_1\000ON
2019.04.10 18:01:00 5: PUBLISH: 1(17)(0)(13)hvmon/valve_2ON
2019.04.10 18:01:00 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/valve_2:ON
2019.04.10 18:01:00 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/valve_2\000ON
2019.04.10 18:01:00 5: PUBLISH: 1(17)(0)(13)hvmon/valve_3ON
2019.04.10 18:01:00 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/valve_3:ON
2019.04.10 18:01:00 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/valve_3\000ON
2019.04.10 18:01:00 5: PUBLISH: 1(17)(0)(13)hvmon/valve_4ON
2019.04.10 18:01:00 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/valve_4:ON
2019.04.10 18:01:00 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/valve_4\000ON
2019.04.10 18:01:00 5: PUBLISH: 1(18)(0)(13)hvmon/valve_5OFF
2019.04.10 18:01:00 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/valve_5:OFF
2019.04.10 18:01:00 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/valve_5\000OFF
2019.04.10 18:01:00 5: PUBLISH: 1(17)(0)(13)hvmon/valve_6ON
2019.04.10 18:01:00 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/valve_6:ON
2019.04.10 18:01:01 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/valve_6\000ON
2019.04.10 18:01:01 5: PUBLISH: 1(17)(0)(13)hvmon/valve_7ON
2019.04.10 18:01:01 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/valve_7:ON
2019.04.10 18:01:01 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/valve_7\000ON
2019.04.10 18:01:01 5: PUBLISH: 1(18)(0)(13)hvmon/valve_8OFF
2019.04.10 18:01:01 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/valve_8:OFF
2019.04.10 18:01:01 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/valve_8\000OFF
2019.04.10 18:01:01 5: PUBLISH: 1(20)(0)(12)hvmon/statusONLINE
2019.04.10 18:01:01 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/status:ONLINE
2019.04.10 18:01:01 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/status\000ONLINE
2019.04.10 18:01:01 5: PUBLISH: 1(21)(0)(13)hvmon/versionv1.3.0
2019.04.10 18:01:01 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/version:v1.3.0
2019.04.10 18:01:01 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/version\000v1.3.0
2019.04.10 18:01:01 5: PUBLISH: 1#(0)(11)hvmon/buildApr 10 2019 - 07:21:33
2019.04.10 18:01:01 4: mqtt_192.168.178.20_50621 HVMON PUBLISH hvmon/build:Apr 10 2019 - 07:21:33
2019.04.10 18:01:01 5: mqtt: dispatch autocreate=simple\000HVMON\000hvmon/build\000Apr 10 2019 - 07:21:33

Ich habe dafür ein DOIF programmiert, welches mich, wenn der Status sich 2 Minuten nicht ändert alarmieren soll:


# Watchdog fuer FHEM
define di_hvmon_watchdog_1 DOIF ([?MQTT2_HVMON:status:sec] < 120)\
(set pushmsg message "HVMON: OFFLINE seit 120s" t="FHEM")\
(set pushmsg message "HVMON: OFFLINE seit 30 min" t="FHEM")\
(set pushmsg message "HVMON: OFFLINE seit 1h" t="FHEM")
setuuid di_hvmon_watchdog_1 5ca90898-f33f-04a6-2634-930285dbf96c0e66
attr di_hvmon_watchdog_1 do resetwait
attr di_hvmon_watchdog_1 room System
attr di_hvmon_watchdog_1 wait 0,1680,1800

# Watchdog fuer FHEM
define di_hvmon_watchdog_2 DOIF ([?MQTT2_HVMON:status:sec] < 7200) (set pushmsg message "HVMON: OFFLINE" t="FHEM")
setuuid di_hvmon_watchdog_2 5ca90898-f33f-04a6-b074-3b847540af290ce5
attr di_hvmon_watchdog_2 repeatcmd 21600
attr di_hvmon_watchdog_2 room System
attr di_hvmon_watchdog_2 verbose 5


Ich habe es bisher nicht geschafft, dass wenn sich der Status für 2 min nicht ändert, benachrichtigt werde. Ich habe hier schon einen Versuch mit dem ? gemacht, da ich beim Neustart sonst benachrichtigt werde.

Vorher hatte ich eine Lösung, die auf den Zustand OFFLINE (last will topic by MQTT) reagiert. Da jedoch hier manchmal kurzfristig (ca. 1s) die Verbindung weg ist, gab es zu viele Fehlmeldungen.

Hier noch der HVMON (Heat Valve Monitor):


Internals:
   CID        HVMON
   DEF        HVMON
   DEVICETOPIC MQTT2_HVMON
   FUUID      5c44e643-f33f-04a6-f3c2-6d59b4da6ffd61df
   IODev      mqtt
   LASTInputDev mqtt
   MSGCNT     99209
   NAME       MQTT2_HVMON
   NR         205
   STATE      ONLINE
   TYPE       MQTT2_DEVICE
   mqtt_MSGCNT 99209
   mqtt_TIME  2019-04-10 19:18:01
   READINGS:
     2019-04-10 19:18:01   build           Apr 10 2019 - 07:21:33
     2019-04-10 19:18:01   status          ONLINE
     2019-04-10 19:18:00   valve_1         OFF
     2019-04-10 19:18:00   valve_2         OFF
     2019-04-10 19:18:00   valve_3         ON
     2019-04-10 19:18:00   valve_4         ON
     2019-04-10 19:18:01   valve_5         OFF
     2019-04-10 19:18:01   valve_6         ON
     2019-04-10 19:18:01   valve_7         ON
     2019-04-10 19:18:01   valve_8         OFF
     2019-04-10 19:18:01   version         v1.3.0
Attributes:
   IODev      mqtt
   readingList HVMON:hvmon/status:.* status
HVMON:hvmon/version:.* version
HVMON:hvmon/build:.* build
HVMON:hvmon/valve_1:.* valve_1
HVMON:hvmon/valve_2:.* valve_2
HVMON:hvmon/valve_3:.* valve_3
HVMON:hvmon/valve_4:.* valve_4
HVMON:hvmon/valve_5:.* valve_5
HVMON:hvmon/valve_6:.* valve_6
HVMON:hvmon/valve_7:.* valve_7
HVMON:hvmon/valve_8:.* valve_8
   room       System
   stateFormat { ReadingsVal($name, "status", "OFFLINE"); }


Was mache ich falsch?

LG Swen

Otto123

Bitte dies hier beachten: Codetags benutzen und keine Bilder sondern list posten.
Man kann die Beiträge auch editieren :)

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Kobold67


Otto123

Moin,

ich denke mit erledigt meintest Du jetzt nicht deine eigentliche Frage?

In der Doku gibt es doch dieses Beispiel - mal mit deinem Device:
define di_push DOIF ([MQTT2_HVMON])(set pushmsg "sensor failed again")
attr di_push wait 1800
attr di_push do resetwait

Das müsste doch der Ansatz sein den Du brauchst?

Allerdings weiß ich nicht ob das mqtt Device weiterhin Events liefert "wenn deine Schaltung sich verabschiedet"

Wobei ich deine Abfrage nicht verstehe:
([?MQTT2_HVMON:status:sec] < 120) im status steht doch online? Mir ist auch nicht klar was das "sec" bedeutet und bewirken soll?

Mit dem ? hat Dein Ausdruck keinen trigger mehr, das wird also nie aktiviert. Das ist aus meiner Sicht völlig falsch.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Kobold67

Hallo Otto,

Danke für den Tipp. Ich teste ihn bis spätestens zum Wochenende.

Mein Code stammt auch aus der Kommandoreferenz:


Zeitspanne eines Readings seit der letzten Änderung

Bei Readingangaben kann die Zeitspanne mit [<Device>:<Reading>:sec] in Sekunden seit der letzten Änderung bestimmt werden.

Anwendungsbeispiel: Licht soll angehen, wenn der Status des Bewegungsmelders in den letzten fünf Sekunden upgedatet wurde.

define di_lamp DOIF ([BM:state:sec] < 5) (set lamp on-for-timer 300)
attr di_lamp do always

Bei HM-Bewegungsmelder werden periodisch Readings aktualisiert, dadurch wird das Modul getrigger, auch wenn keine Bewegung stattgefunden hat. Der Status bleibt dabei auf "motion". Mit der obigen Abfrage lässt sich feststellen, ob der Status aufgrund einer Bewegung tatsächlich upgedatet wurde.


Daher kam bei mir die Idee auf, dass ich das letzte Reading damit prüfen kann.

Noch ein paar Erläuterungen:

Ich hatte früher einen ESP8266 im Einsatz. Da dort wenig GPIOs zur Verfügung stehen, haben ich dort so ziemlich alles belegt, was ging. Dabei gibt es auch eine Pin (nicht dokumentiert), der ebenfalls einen Neustart des ESP8266 verhindert, wenn er auf Masse liegt (durch ein geschaltetes Ventil.

Sowohl der ESP8266 als auch der ESP32 haben werden mit FreeRTOS betrieben. Beim ESP32 verhält sich FreeRTOS etwas zickiger, so stürzt der ESP32 mit einer Kernel Panic ab, wenn meine 7590 einen Kanalwechsel für das WLAN durchgeführt hat. Das habe ich jetzt abgeschaltet. Es gibt aber immer noch sporadisch (ca. 1 Monat) das Problem, das das FreeRTOS abstürzt, dass heisst mein Program (auf Arduino-Basis) wird  nicht mehr ausgeführt.

Dann wird als Last Will Topic der Status von ONLINE auf OFFLINE geändert. Den werde ich mit Deinem Code-Snippet mal ausprobieren.

Wenn alles funktioniert, dann setze ich den Beitrag den regelkonform auf GELÖST.

Gruß

Swen

Otto123

Hallo Swen,

ja habs gefunden, irgendwie ist die Doku von DOIF zu lang  :D und manchmal finde ich Implementierungen von Features nicht unbedingt logisch nachvollziehbar. Aber das ist mein Problem. ;D
Was mir jetzt auffällt: Das ist sicher ein Ansatz, aber dann würde ich das erstmal genauso machen wie es dasteht.
([MQTT2_HVMON:status:sec] < 120) und mit do always.
Oder Du lässt das mit den sec weg:
([MQTT2_HVMON:status]) und nimmst do resetwait mit deinen gestaffelten Zeiten. Jede Änderung müsste das DOIF triggern und die Bedingung wird wahr (außer wenn der status 0 wird - hab ich gestern verstanden :) ). Das do resetwait setzt jedes mal den Waittimer zurück und es kommt damit normalerweise nie zur Ausführung.
Aber da gibt es vielleicht noch Dinge, die ich jetzt nicht beachtet habe  ::)

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Damian

([MQTT2_HVMON:status:sec] < 120)

ist leider nicht mehr aktuell, da muss ich die Doku anpassen.

Diese Bedingung wird jetzt nur noch getriggert, wenn sich der Status ändert, nicht mehr, wenn sich andere Readings (im Beispiel war es das motion-Reading bei HM) des Devices ändern. Wenn der Status triggert ist aber das Alter von Status 0, daher macht die Abfrage so keinen Sinn.

siehe: https://fhem.de/commandref_DE.html#DOIF_checkReadingEvent wenn man wieder auf alle Readings des Devices triggern will.

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Kobold67

#7
Hallo Otto, hallo Damian,

Vielen Dank für Eure Hilfe, jetzt sieht es so aus:


# Watchdog fuer FHEM
define di_hvmon_watchdog_1 DOIF ([MQTT2_HVMON:"status:.OFFLINE"])\
(set pushmsg message "HVMON: OFFLINE seit 120s" t="FHEM")\
(set pushmsg message "HVMON: OFFLINE seit 30 min" t="FHEM")\
(set pushmsg message "HVMON: OFFLINE seit 1h" t="FHEM")
setuuid di_hvmon_watchdog_1 5ca90898-f33f-04a6-2634-930285dbf96c0e66
attr di_hvmon_watchdog_1 do resetwait
attr di_hvmon_watchdog_1 room System
attr di_hvmon_watchdog_1 wait 120,1680,1800

# Watchdog fuer FHEM
define di_hvmon_watchdog_2 DOIF ([MQTT2_HVMON:"status:.OFFLINE"]) (set pushmsg message "HVMON: OFFLINE" t="FHEM" pr="2")
setuuid di_hvmon_watchdog_2 5ca90898-f33f-04a6-b074-3b847540af290ce5
attr di_hvmon_watchdog_2 wait 21600
attr do resetwait
attr di_hvmon_watchdog_2 room System
attr di_hvmon_watchdog_2 verbose 5


Jetzt werde ich mir noch eine Push-Nachricht bauen, da ich später nicht nur ein Push senden möchte, sondern auch die Stromversorgung über eine schaltbare Steckdose trennen möchte und so einen Neustart einleiten möchte.

Dann nächste Ziel ist es dann, mit derselben Schaltung (ESP32 mit I2C und SPI-Anschlüssen) mit einen RS23-to-TTL-Wandler meine Luxtronic 1 anzuzapfen und die Temperaturen usw. ebenfalls über MQTT an FHEM zu melden. Teile sind schon über AliExpress bestellt  :)

Gruß

Swen

Damian

Ja nach Grad der Dringlichkeit kann man auch punktuell sein System mit einem Einzeiler nach Ausfällen checken:

siehe: https://forum.fhem.de/index.php/topic,99461.msg928974.html#msg928974
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Kobold67

Hallo Damian,

Interessante Idee. Werde ich für den 2. Watchdog einsetzen, da ich hier mit einer täglichen Erinnerung auskomme. Mir ging es nur darum, dass es mir bei längeren Abwesenheit nicht durch die Lappen geht.

Gruß

Swen