Erweiterung des Geräts um battery-Reading ESP-01

Begonnen von Qwz80, 18 Dezember 2016, 10:29:49

Vorheriges Thema - Nächstes Thema

Qwz80

Hallo,

ich versuche jetzt seit Stunden meinem ESP8266 einen Batteriestatus zu verpassen. Das habe ich unter https://wiki.fhem.de/wiki/Batterieüberwachung gefunden. Konkret geht es um diesen Code:

battery { return "ok" if ( (time_str2num(ReadingsTimestamp($NAME,"state","0")) - time_str2num(OldTimestamp($NAME))) > 600 );; return "low" }

Nur leider klappt das nicht. Bei jedem Reading setzt er immer auf low. Dabei braucht man ja laut der Seite nix als die Zeit anzupassen. Meine Readings kommen alle 300 sek. Auch die Code Erläuterung bringt mich nicht weiter. 

$NAME - ist die Variable für das Device (und braucht nicht angepasst zu werden)
battery {...} - Name des userreadings mit Spezifikation, vgl. [2]
return "ok" if ( ... );; return "low" - Spezifikation: Reading = "ok", wenn if erfüllt, sonst "low"
time_str2num(ReadingsTimestamp($NAME,"state","0") - Aktueller Timestamp in Sekunden, vgl. [3], [4]
time_str2num(OldTimestamp($NAME)) - Letzter Timestamp im Log in Sekunden (egal ob FileLog oder DbLog)


Probeweise habenich ein anderes Device mit Readings mit dem Attr gefüttert. Doch auch hier, er setzt immer low, sonald ein Reading reinkommt.

Hat sich etwas geändert? Ich möchte eigentlich nur, dass wenn kein neues Reading nach 10min kommt, er das userreading auf low setzt, ansonsten eben ok.

viegener

Vielleicht habe ich ja etwas missverstanden, aber meiner Meinung nach macht der Vergleich folgendes:

Wenn der Abstand zwischen zwei Updates GRÖSSER als 10min ist, wird OK gesetzt und
immer wenn regelmässig updates (häufiger als 10 min) wird low gesetzt

Also bei aktivem Device, der regelmässig updates schickt wird immer low herauskommen.

Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Qwz80

#2
Nun ja. Eigentlich soll es so nicht gehen. Es geht ja darum, dass wenn keine neuen Readings nach 600 Sekunden kommen, kann man davon ausgehen, dass der Kontakt wie auch immer weg ist (Batterie leer, Geräte Defekt, Geklaut etc.).

So habe ich den Wiki Text auch verstanden. Zitat Wiki: Die Idee ist, den zeitlichen Abstand des aktuellen Timestamps mit dem letzten geloggten Timestamp zu vergleichen und daraus auf den Batteriestatus zu schliessen - bspw. Abstand > 10min = Batterie low.

Ich bekomme das jedenfalls nicht in den Griff  :P

Edit. Ich habe es einfach mal umgedreht. Low und OK vertauscht. Er macht also das nach deiner Beschreibung.

Ob das jetzt so funktioniert?

viegener

So wie es da steht (auch im wiki) macht es jedenfalls aus meiner Sicht keinen Sinn, man möchte ja genau den Fall als low deklarieren, wenn lange kein update mehr gekommen ist. Umgedreht sollte das eigentlich der Fall sein.

Vielleicht kannst Du ja den wiki-Autor mal auf das Problem ansprechen. Es wäre ja schön, wenn das geändert würde?
Achso und vielleicht Deinen Link im ersten Beitrag korrigieren?
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Qwz80

Hab ich geändert. Grundsätzlich sollte es so aber richtig sein, oder?

battery { return "low" if ( (time_str2num(ReadingsTimestamp($NAME,"state","0")) - time_str2num(OldTimestamp($NAME))) > 600 );; return "ok" }

Zumindest scheint es bisher gut zu funktionieren  :D Danke für die Hilfe! Tolles Forum. Ich versuche den Autor mal zu kontaktieren und hier auf den Thread aufmerksam zu machen.

viegener

Ja für mich klingt das so vernünftig (allerdings ohne das selber in Betrieb zu haben)
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

costa2

Zitat von: Qwz80 am 18 Dezember 2016, 11:54:40
Hab ich geändert. Grundsätzlich sollte es so aber richtig sein, oder?

battery { return "low" if ( (time_str2num(ReadingsTimestamp($NAME,"state","0")) - time_str2num(OldTimestamp($NAME))) > 600 );; return "ok" }

Zumindest scheint es bisher gut zu funktionieren  :D Danke für die Hilfe! Tolles Forum. Ich versuche den Autor mal zu kontaktieren und hier auf den Thread aufmerksam zu machen.

Genau so habe ich es auch getestet, das funktioniert aber aus folgendem Grund nicht.
Wenn das Device nicht mehr sendet, also die Batterie leer ist, wird auch das Reading nicht mehr aktualisiert, somit auch das userReading nicht.
Daher ändert sich der Status nicht.
Getestet habe ich das, indem ich die Batterie aus dem Device entfernt habe.

Volker
RPI3, Nanocul 433 MHz, 433 MHz Steckdosen, DVB-T Stick für 868 MHz TX Sensoren, MOBILE ALERTS Sensoren und Gateway

viegener

Um das Problem zu umgehen habe ich noch ein wiederholendes at, dass regelmässig ein setreading auf den devices ausführt, damit der batterie-check funktioniert
Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

Gundermann

Hier ist schon lange "Funkstille", aber wenn man sich mit FHEM und dem Thema Batterieüberwachung beschäftigt und das zu überwachende Device keinen Batteriestatus sendet, landet man irgendwann hier oder im Wiki auf https://wiki.fhem.de/wiki/Batterieüberwachung. Die Idee, aus dem Alter des Reading "state" auf eine eventuell leere Batterie zu schließen, wollte ich umsetzen, habe schon einige Stunden ohne Erfolg damit verbracht und glaube jetzt eine recht einfache Lösung mit DOIF gefunden zu haben.

Das zu überwachende Device soll ein Reading erhalten, das ich "battery" nenne und mit dem Attribut "userReadings" erzeuge. Mit attr <device> userReadings battery { return "ok" if ( (time_str2num(ReadingsTimestamp($NAME,"state","0")) - time_str2num(OldTimestamp($NAME))) < 600 ); return "low" } halte ich mich den Vorschlag aus dem Wiki-Beitrag. Ist aber eigentlich egal, denn wenn das neue Reading angezeigt wird, lösche ich das Attribut wieder. Das Reading selbst wird dadurch nicht gelöscht. Nun kann man mit einem simplen DOIF dem Reading z.B. einen beliebigen Text zuweisen. DOIF bietet dazu die Möglichkeit, die Zeitspanne eines Readings seit der letzten Änderung zu bestimmen (siehe commandref), und genau das ist ja die Idee.

Mein DOIF zur Batterieüberwachung des Garagentores sieht also so aus:

define BatGaragentor DOIF ([+24:00:00] and [Tuerkontakt_Garage:state:sec]>172800) (setreading Tuerkontakt_Garage battery Batterie wahrscheinlich LEER) DOELSE (setreading Tuerkontakt_Garage battery Batterie wahrscheinlich OK)
attr BatGaragentor do always

Jetzt wird alle 24 Stunden geprüft, ob das Reading "state" des Türkontaktes älter als 172800 Sekunden (48 Stunden) ist. Für unser Garagentor ist das so ausreichend und wenn nach einer Woche Urlaub das Tor endlich wieder bewegt wird, verschwindet auch die (falsche) LEERmeldung spätestens am nächsten Tag wieder, sofern die Batterie nicht wirklich LEER ist. Mit DOELSEIF lassen sich so auch mehrere Devices überwachen.

Gundermann
FHEM auf RPi 4B | CUL 868 MHz | SIGNALduino 433 MHz | FRITZ!Dect | FS20 | Homematic | Intertechno | Sonoff | Shelly | IP-Kameras | Wettersensoren | ZigBee | ...
FHEM ist nicht Plug & Play. Man muss bereit sein hinter die Kulissen zu schauen.

Damian

Es gibt gefühlt zig Lösungen zu dem Thema, hier noch einmal eine, die alle möglichen Devices abdeckt.

defmod di_batteriecheck DOIF init {[18:00];;set_State([?@:"":"^[Bb]attery$":ReadingsAge($name,$reading,0) > 3600*24 or ReadingsVal($name,$reading,0) ne "ok",""])}

Im Status des Devices befinden sich die betroffenen Problemfälle.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Gundermann

Ich hatte nicht damit gerechnet, dass es hier eine so schnelle Reaktion gibt. DANKE dafür!
Die Lösung ist sehr komplex und liegt deutlich hinter meinen Horizont  ;). Werde mich aber damit auseinander setzen.

Den Hinweis
ZitatIm Status des Devices befinden sich die betroffenen Problemfälle.
verstehe ich nicht.

Gundermann
FHEM auf RPi 4B | CUL 868 MHz | SIGNALduino 433 MHz | FRITZ!Dect | FS20 | Homematic | Intertechno | Sonoff | Shelly | IP-Kameras | Wettersensoren | ZigBee | ...
FHEM ist nicht Plug & Play. Man muss bereit sein hinter die Kulissen zu schauen.

Damian

Mit Hilfe der Aggregationsfunktionen https://fhem.de/commandref_DE.html#DOIF_aggregation werden alle Readings im System durchsucht, die entweder Battery oder battery heißen, diese werden auf deren Alter mit ReadingsAge geprüft oder ob sie nicht ok sind. Das Ergebnis sind die dazugehörigen Devices. Diese werden mit set_State im Status dieses DOIFs gespeichert. Man könnte diese Informationen genauso verschicken oder sonst was damit tun.

Es wurde im DOIF-Perlmodus definiert/programmiert.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Gundermann

Verstanden. DANKE dafür!
DOIF ist ein wirklich mächtiges Werkzeug, aber man muss es auch "bedienen" können.

Gundermann
FHEM auf RPi 4B | CUL 868 MHz | SIGNALduino 433 MHz | FRITZ!Dect | FS20 | Homematic | Intertechno | Sonoff | Shelly | IP-Kameras | Wettersensoren | ZigBee | ...
FHEM ist nicht Plug & Play. Man muss bereit sein hinter die Kulissen zu schauen.

Damian

Zitat von: Gundermann am 04 November 2022, 18:40:30
Verstanden. DANKE dafür!
DOIF ist ein wirklich mächtiges Werkzeug, aber man muss es auch "bedienen" können.

Gundermann

Man kann ruhig klein im FHEM-Modus anfangen. Im Laufe der Zeit werden die Ansprüche höher und die Kenntnisse besser. Und dann kann man auch komplexere Problemstellungen, am besten gleich im Perl-Modus, lösen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

WW

Ich überwache meine Readings mit Hilfe des Moduls "readingsWatcher" (siehe https://forum.fhem.de/index.php?topic=49408.0). Funktioniert wunderbar. Für jedes zu überwachende Reading kann hierbei eine eigene Zeistspanne angegeben werden.

MfG
Willi
FHEM 6.x im Docker-Container (OMV4 auf ASRock J3455-ITX), FHEM 6.0 auf Raspi, Fritzbox 7490, CUL433, CUL868, Jeelink868, SIGNALduino, LaCrosseGateway, Shelly, Sonoff, ESP8266, ESP32, ESP32-Cam, LaCrosse, OneWire, Zigbee (Sonoff, Blitzwolf, IKEA, Lidl), Azzurro-WR/Pylontech-Bat., Lambda-Wärmepumpe