Batteriestatus und Speicherung des letzten Wechsel

Begonnen von Amenophis86, 12 Januar 2018, 19:23:20

Vorheriges Thema - Nächstes Thema

FunkOdyssey

Ich danke dir. Ich habe leider sowieso festgestellt, dass ich meine gesamte Logik überarbeiten muss.
Aber du hast mir schon sehr geholfen.

MadMax-FHEM

Zitat von: FunkOdyssey am 07 April 2020, 12:34:34
Ich danke dir. Ich habe leider sowieso festgestellt, dass ich meine gesamte Logik überarbeiten muss.
Aber du hast mir schon sehr geholfen.

Ich dachte mir schon, dass das etwas ;)

Aber jeder wie er es haben will...

Gerne, viel Spaß noch, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Betonklotz

Hallo Joachim,

magst du deine my_CalculateBatteryLife($Device) Funktion posten? Baue mir gerade auch etwas (wobei das super simpel ist, da nur HM Geräte mit Angabe der Batterie Spannung), scheitere aber an der Laufzeitberechnung. Dachte ich lese einfach den letzten Wechsel aus (wird ja gespeichert) und subtrahiere das aktuelel Datum. Aber irgendwie stehe ich da mit Perl auf Kriesgsfuss... Ein kleiner Tipp reicht mir sonst auch schon.

Gruß, Robert

Zitat von: MadMax-FHEM am 27 März 2020, 14:40:06
Auch habe ich eine Routine die "berechnet" wann zuletzt gewechselt wurde, also die "Laufzeit" der Batterie protokolliert.
So sehe ich wie lange die Batterien so bei den diversen Geräten (in der Regel) halten/gehalten haben (my_CalculateBatteryLife)...

MadMax-FHEM

#303
Hi Robert,

klar! :)


sub my_CalculateBatteryLife($)
{
  my ($Device)  = @_;
  my $ActualLifeTimes = ReadingsVal($myDummyBatteryLifeTimes, $Device, "");
  my $LastChange = ReadingsAge($myDummyLastBatteryChange, $Device, 0);
  my $WeeksSinceLastChange = $LastChange % 604800;
  $WeeksSinceLastChange = ($LastChange - $WeeksSinceLastChange) / 604800;
 
  if($WeeksSinceLastChange > 0)
  {
    # appending actual calculated life time to last life times of device in dummy
    $ActualLifeTimes .= " $WeeksSinceLastChange";
    fhem("setreading $myDummyBatteryLifeTimes $Device $ActualLifeTimes");
  }
 
  Log3(undef, 3, "my_CalculateBatteryLife     Device: $Device    LastChange: $LastChange     WeeksSinceLastChange: $WeeksSinceLastChange");
}



  my $ActualLifeTimes = ReadingsVal($myDummyBatteryLifeTimes, $Device, "");


hier wäre wohl ReadingsNum "korrekter"...
...wie auch an anderen Stellen wie ich grad sehe ;)


Ich rufe die Sub jeweils auf, bevor ich die Readings bzgl. "Batterie ist wieder ok" setze (dann ist ja der Zeitstempel des letzten Wechsels noch im Zeitstempel des Readings im Dummy für Wechsel des jeweiligen Devices hinterlegt (-> ReadingsAge)...


      # we are "in the loop" of "ok" (again)
      # check if battery is actually low -> possibly changed
      if((ReadingsVal($myDummySignalMessageStatesFhemBot, $SignalDevice, "none") eq "low" || ReadingsVal($myDummyBatteryStates, $Device, 100) < 50) && ReadingsAge($Device, "powerOn", 0) < 2 * $my_DayInSeconds)
      {
        # calculate lifetime since last change
        my_CalculateBatteryLife($Device);
        # set date/time for changed battery if it was low before (so probably a change happended)
        fhem("setreading $myDummyLastBatteryChange $Device Battery changed:");
        # set the signal state (back) to none
        fhem("setreading $myDummySignalMessageStatesFhemBot $SignalDevice none");
      }


Ich speichere die "Haltbarkeit" dann im Dummy $myDummyBatteryLifeTimes (ich habe zu Beginn dafür "globale" Variablen, dann kann ich die Namen einfach ändern, falls ich das will/"muss" / du kannst nat. auch einfach direkt den Namen des Dummy angeben, dan halt vorher anlegen! ;)  )...

Bei mir heißt er: dmBatteryLifeTimes

Hier ein list:


Internals:
   FUUID      5c573a6a-f33f-753d-ac1f-3012ffe7f5aff1ee
   NAME       dmBatteryLifeTimes
   NR         202
   STATE      ???
   TYPE       dummy
   READINGS:
     2019-12-27 06:57:16   Heizkoerperthermostat_SchlaZi 153
     2019-08-29 22:32:20   Heizkoerperthermostat_WoZi 145
     2020-02-18 22:28:09   Wandthermostat_Bad 65 66
     2019-10-15 18:42:48   Wandthermostat_Buero 63
     2019-10-12 09:37:24   Wandthermostat_EssZi 59 67
     2019-02-23 10:05:11   Wandthermostat_Kueche 54 46
     2019-11-12 00:03:48   Wandthermostat_SchlaZi 66 67
     2019-09-09 10:41:39   Wandthermostat_WC 64 64
     2019-09-19 17:10:57   Wandthermostat_WoZi 61 65
Attributes:


Man sieht hier ("Space separiert" / ich lese ja die letzte Laufzeit aus und füge die neu berechntete mit "Space" hinzu: $ActualLifeTimes .= " $WeeksSinceLastChange"; / bislang funktioniert das) die "Laufzeiten" in Wochen (wenn ich mich nicht "verrechnet" hab)...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Betonklotz

Hallo Joachim,

danke dir.

Habe bei mir nun ein

#####################################################
# calculate the lifetime of the batteries in weeks and stores it in dummy
sub my_CalculateBatteryLife($)
{
my ($Device)  = @_;
my $myDummyBatteryLifeTimes = "BatterieLebensdauer";
my $BatteryChanged = "LetzterBatterieWechsel";
my $ActualLifeTimes = ReadingsVal($myDummyBatteryLifeTimes, $Device, "");
my $LastChange = ReadingsAge($BatteryChanged, $Device, 0);
my $WeeksSinceLastChange = $LastChange % 604800;
$WeeksSinceLastChange = ($LastChange - $WeeksSinceLastChange) / 604800;
my $Loglevel = 3;

if($WeeksSinceLastChange > 0)
{
# appending actual calculated life time to last life times of device in dummy
$ActualLifeTimes .= " $WeeksSinceLastChange";
readingsSingleUpdate($defs{$myDummyBatteryLifeTimes}, $Device, $ActualLifeTimes, 0);
}
if($Loglevel >=3) {Log3(undef, 3, "my_CalculateBatteryLife     Device: $Device    LastChange: $LastChange     WeeksSinceLastChange: $WeeksSinceLastChange");}
}

drin, also quasi eine 1:1 Übernahme deines Codes. Aber werde das sehr wahrscheinlich noch mal aufblähen/umbauen, das gefällt mir noch nicht...
- letzte Batteriewechsel jeweils mit Datum speichern (ja, man könnte aktuell vom letzten bekannten Wechsel immer zurückrechnen)
- Vorhersage wann die Batterien fällig werden (==> muss ich einen 10er Pack bestellen weil weitere Geräte anstehen, oder reichen zwei aus)
- jeweils den Typ/Marke/MHD/Bezugsquelle mit abspeichern

Gruß, Robert

MadMax-FHEM

#305
Zitat von: Betonklotz am 15 April 2020, 13:55:02
Hallo Joachim,

danke dir.

Gerne!
Und klar: pass an/bau um ;)

Zitat von: Betonklotz am 15 April 2020, 13:55:02
- letzte Batteriewechsel jeweils mit Datum speichern (ja, man könnte aktuell vom letzten bekannten Wechsel immer zurückrechnen)
- Vorhersage wann die Batterien fällig werden (==> muss ich einen 10er Pack bestellen weil weitere Geräte anstehen, oder reichen zwei aus)
- jeweils den Typ/Marke/MHD/Bezugsquelle mit abspeichern

Gut "Vorhersage" könnte man machen: at was täglich (oder wöchentlich) prüft, wie lange die Batterie letztes Mal gehalten hat und dann frühzeitig "warnt"...
...setzt aber voraus, dass das schon eine Weile läuft/gelaufen ist.

Wie du siehst halten die Batterien der Heizkörperthermostate so knapp 3 Jahre, Wandthermostate knapp 1,5 Jahre und bei meinem Außenthermometer habe ich seit 4 Jahren noch nicht gewechselt ;)

Allerdings ist es meist so, dass die Leer-Meldung kommt und das Gerät meist noch so 1-2 Wochen (manchmal sogar noch über einen Monat) "rennt"...

EDIT: drum hab ich auch die Prüfung auf powerUp (bei Homematic) eingebaut, weil gerade die Fenstersensoren (v.a. die "optischen") echt lange zwischen "low" und "ok" wechseln...

Gewechselt wird bei mir dann bei "dead" ;)

Bzgl. "merken" welcher Typ hab ich schon was erweitert:
https://forum.fhem.de/index.php/topic,82637.msg1014387.html#msg1014387

Weil ich kann mir das auch nie merken... ;)

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Betonklotz

Hallo Joachim,

so kompliziert würde ich es gar nicht machen...
Laufzeit des letzten Satz Batterien + aktuelles Dateum des Wechsels = Prognose bis wann es hält. Als Text ist das völlig i.O. Wenn sich dann ein Gerät meldet, dann schaue ich in den "Raum" "Batterie" und sehe dort was ansteht. Denn die Erfahrung "Batterien halte noch ewig" mache ich auch gerade ;-)
Deshalb: die Batterien halten bis Motor Err ansteht, dafür gibt es ja extra das Register Error Position ;-) Vorher gibt es nur leichte (Kauf-)Hinweise, wenn der Motor steht dann ein bitte austauschen. Wobei 3 Jahre schaffe ich wohl nicht, bei mir verrecken so langsam die ersten Heizkörperthermostate (mit den "mitgekauften" Batterien).

Gruß, Robert

MadMax-FHEM

Ich hab fast nur Bausätze, da sind keine Batterien dabei...
...daher habe ich (fast) nirgends Originalbatterien...

Viel Spaß beim Umsetzen!

Kannst ja hier vorstellen...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Betonklotz

Hallo Joachim,

wird noch etwas länger dauern.
Hadere noch ob ich alles als userattr dem Device zuordne (schließlich sind die Batterien, Wechselzeiten usw. Device spezifisch), oder es wie jetzt weiterhin über dummys mache. Muss mich mal belesen was besser ist, bzw. wie es für mich am einfachsten geht.

Grüße, Robert

Betonklotz

Hallo Joachim,

irgendwie stehe ich noch auf Kriegsfuss mit den Batterien...
Nachdem nun der erste Wechsel anstand, hagelte es Fehlermeldungen im Log und auch das reading "BatterieWechsel" hat nicht das aktuelle Datum drin :-(

2020.05.16 12:19:17 3: Motor of EG_ArbeitRobert_Heizung_Durchgang is in eror state, BatteryChange needed NOW
2020.05.16 12:22:42 3: CUL_HM set EG_ArbeitRobert_Heizung_Durchgang getConfig
2020.05.16 12:22:42 3: my_CalculateBatteryLife     Device: EG_ArbeitRobert_Heizung_Durchgang    LastChange: 0     WeeksSinceLastChange: 0
2020.05.16 12:22:42 1: ERROR: empty name in readingsBeginUpdate
2020.05.16 12:22:42 1: stacktrace:
2020.05.16 12:22:42 1:     main::readingsBeginUpdate           called by fhem.pl (4939)
2020.05.16 12:22:42 1:     main::readingsSingleUpdate          called by ./FHEM/99_BatteryCheckUtils.pm (215)
2020.05.16 12:22:42 1:     main::BatteryStatusFunction         called by (eval 524316) (1)
2020.05.16 12:22:42 1:     (eval)                              called by fhem.pl (1146)
2020.05.16 12:22:42 1:     main::AnalyzePerlCommand            called by fhem.pl (1171)
2020.05.16 12:22:42 1:     main::AnalyzeCommand                called by fhem.pl (1100)
2020.05.16 12:22:42 1:     main::AnalyzeCommandChain           called by ./FHEM/91_notify.pm (121)
2020.05.16 12:22:42 1:     main::notify_Exec                   called by fhem.pl (3775)
2020.05.16 12:22:42 1:     main::CallFn                        called by fhem.pl (3695)
2020.05.16 12:22:42 1:     main::DoTrigger                     called by fhem.pl (4062)
2020.05.16 12:22:42 1:     main::Dispatch                      called by ./FHEM/00_HMUARTLGW.pm (1463)
2020.05.16 12:22:42 1:     main::HMUARTLGW_Parse               called by ./FHEM/00_HMUARTLGW.pm (1566)
2020.05.16 12:22:42 1:     main::HMUARTLGW_Read                called by fhem.pl (3775)
2020.05.16 12:22:42 1:     main::CallFn                        called by fhem.pl (757)
2020.05.16 12:22:42 1: PERL WARNING: Use of uninitialized value $name in concatenation (.) or string at fhem.pl line 4794.
2020.05.16 12:22:42 3: eval: my $TYPE='CUL_HM';my $EVTPART0='batteryLevel:';my $NAME='EG_ArbeitRobert_Heizung_Durchgang';my $EVTPART1='3';my $SELF='NO.BatterieNotify';my $EVENT='batteryLevel: 3';{BatteryStatusFunction($NAME, $EVENT)}
2020.05.16 12:22:42 1: readingsUpdate(,EG_ArbeitRobert_Heizung_Durchgang,Batterie zuletzt gewechselt am/um: ) missed to call readingsBeginUpdate first.
2020.05.16 12:22:42 1: stacktrace:
2020.05.16 12:22:42 1:     main::readingsBulkUpdate            called by fhem.pl (4940)
2020.05.16 12:22:42 1:     main::readingsSingleUpdate          called by ./FHEM/99_BatteryCheckUtils.pm (215)
2020.05.16 12:22:42 1:     main::BatteryStatusFunction         called by (eval 524316) (1)
2020.05.16 12:22:42 1:     (eval)                              called by fhem.pl (1146)
2020.05.16 12:22:42 1:     main::AnalyzePerlCommand            called by fhem.pl (1171)
2020.05.16 12:22:42 1:     main::AnalyzeCommand                called by fhem.pl (1100)
2020.05.16 12:22:42 1:     main::AnalyzeCommandChain           called by ./FHEM/91_notify.pm (121)
2020.05.16 12:22:42 1:     main::notify_Exec                   called by fhem.pl (3775)
2020.05.16 12:22:42 1:     main::CallFn                        called by fhem.pl (3695)
2020.05.16 12:22:42 1:     main::DoTrigger                     called by fhem.pl (4062)
2020.05.16 12:22:42 1:     main::Dispatch                      called by ./FHEM/00_HMUARTLGW.pm (1463)
2020.05.16 12:22:42 1:     main::HMUARTLGW_Parse               called by ./FHEM/00_HMUARTLGW.pm (1566)
2020.05.16 12:22:42 1:     main::HMUARTLGW_Read                called by fhem.pl (3775)
2020.05.16 12:22:42 1:     main::CallFn                        called by fhem.pl (757)
2020.05.16 12:22:42 1: PERL WARNING: Use of uninitialized value $d in hash element at fhem.pl line 4547.
2020.05.16 12:22:42 3: eval: my $TYPE='CUL_HM';my $EVTPART0='batteryLevel:';my $NAME='EG_ArbeitRobert_Heizung_Durchgang';my $EVTPART1='3';my $SELF='NO.BatterieNotify';my $EVENT='batteryLevel: 3';{BatteryStatusFunction($NAME, $EVENT)}
2020.05.16 12:22:42 3: Battery change detected on HM device EG_ArbeitRobert_Heizung_Durchgang

Was soll mir diese Fehlermeldung sagen? ein

readingsBeginUpdate

habe ich bei mir nicht, bzw. finde ich nicht. Die Zeile 215 ist das zweite readingsSingleUpdate in dem Ausschnitt (poste sonst auch die ganze Datei wenn es das einfache rmacht)

##############################################
# HM Devices with batteryLevel
##############################################
elsif($TYPE eq "CUL_HM" and $BatteryType[0] eq "batteryLevel")
{
$ActBatLevel = ReadingsVal($Device, "batteryLevel", "0.0");
$MinBatLevel = ReadingsNum($Device, "R-lowBatLimitRT", "0.0");
$RemainingVoltageQuater = ($MaxBattery - $MinBatLevel) / 4; # to get 4 quaters for different colours and icons
if(ReadingsVal($BatteryStatus, $Device, "undef") eq "undef") # set battery level 100% and show in BatteryStatus-Device if new
{
readingsSingleUpdate($defs{$BatteryStatus},$Device, 100,0);
if($Loglevel >=1) {Log3(undef, 1, "$Device, added to $BatteryStatus");}
return undef;
}
if(($ActBatLevel - $MinBatLevel) > (3 * $RemainingVoltageQuater))
{
# check if battery was low before -> possibly changed
if(ReadingsNum($BatteryStatus, $Device, 100) <= 25)
{
# calculate lifetime since last change
my_CalculateBatteryLife($Device);
# set date/time for changed battery if it was low before (so probably a change happended)
readingsSingleUpdate($defs{$BatteryChanged}, $Device, $text_changed, 0);
if($Loglevel >=3) {Log3(undef, 3, "Battery change detected on HM device $Device");}
}

bin wieder mal ratlos...

Gruß, Robert

MadMax-FHEM

Da der Code den du verwendest nicht von mir ist: keine Ahnung.

Woher hast du den Code!?

Wie ganz zu Beginn des Threads zu lesen: die Basis war mal von mir kopiert...
...hat aber wenn ich mir deinen Codeschnipsel so ansehe nichts mehr/nicht mehr viel mit dem Ursprungs-Code zu tun...

Ich verwende in "meinem Original-Code" kein readingsSingleUpdate sondern mache alles mittels setreading...

Interessant wäre zu posten was in der Funktion my_CalculateBatteryLife (da scheint doch der Fehler herzukommen!?) drin steht...

Zitat
2020.05.16 12:22:42 3: my_CalculateBatteryLife     Device: EG_ArbeitRobert_Heizung_Durchgang    LastChange: 0     WeeksSinceLastChange: 0
2020.05.16 12:22:42 1: ERROR: empty name in readingsBeginUpdate

Auch sieht das hier komisch aus:


if(ReadingsNum($BatteryStatus, $Device, 100) <= 25)


Weil ReadingsNum so geht: ReadingsNum("DeviceName","ReadingName",Ersatzwert), daher würde ich (wenn die Namen "vernünftig" gewählt sind das eher so erwarten ReadingsNum($Device,$BatteryStatus,100)  )...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Betonklotz

#311
Hallo Joachim,

der Code ist der ursprüngliche, angereichert mit Infos von dir. Anbei die my_CalculateBatteryLife (c&p von dir aus https://forum.fhem.de/index.php/topic,82637.msg1042493/topicseen.html#msg1042493), aber wahrscheinlich bin ich schon zu blöd für c&p...

#####################################################
# calculate the lifetime of the batteries in weeks
# and stores/appends the value to dummy
sub my_CalculateBatteryLife($)
{
my ($Device)  = @_;
my $myDummyBatteryLifeTimes = "BatterieLebensdauer";
my $BatteryChanged = "LetzterBatterieWechsel";
my $ActualLifeTimes = ReadingsVal($myDummyBatteryLifeTimes, $Device, "");
my $LastChange = ReadingsAge($BatteryChanged, $Device, 0);
my $WeeksSinceLastChange = $LastChange % 604800;
$WeeksSinceLastChange = ($LastChange - $WeeksSinceLastChange) / 604800;
my $Loglevel = 3;

if($WeeksSinceLastChange > 0)
{
# appending actual calculated life time to last life times of device in dummy
$ActualLifeTimes .= " $WeeksSinceLastChange";
readingsSingleUpdate($defs{$myDummyBatteryLifeTimes}, $Device, $ActualLifeTimes, 0);
}
if($Loglevel >=3) {Log3(undef, 3, "my_CalculateBatteryLife     Device: $Device    LastChange: $LastChange     WeeksSinceLastChange: $WeeksSinceLastChange");}
}


Und die komische codestelle stammt ebenfalls aus dem Original
https://github.com/Amenophis86/Batteryfunktion/blob/no-BatteryStatusBot/99_BatteryCheckUtils.pm
An so wichtige Dinge die ich kaum verstehe gehe ich nicht dran...

MadMax-FHEM

Also ich hab mal geschaut und laut "Doku" ist ReadingsSingleUpdate so:


readingsSingleUpdate($hash,$reading,$value,$dotrigger);


Und damit für mich ebenso "komisch" (falsch!?) wie das zuvor erwähnte ReadingsVal...

Aber da nicht mein Code...
...kann ich dazu wenig sagen, leider.

Da wird wohl Amenophis86 was sagen müssen...

Sorry, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Betonklotz

Hallo Joachim,

trotzdem danke.
Batteriüberwachung ist nach wie vor auf der to-do Liste, aber derzeit komme ich zu nix (außer aufzuschrecken wenn Fehler im Log auftauchen...)

Gruß, Robert

Amenophis86

Lastchange Weeks etc ist nicht von mir. Frage mich wo der Code her kommt. Ich empfehle alles löschen und den Code aus github komplett neu kopieren.

Zusammen kopierte Dinge aus verschiedenen Dingen sind halt teilweise schwer kompatibel. Wie ich sehe hast du zwei Versionen zusammen kopiert, oder?
Aktuell dabei unser neues Haus mit KNX am einrichten. Im nächsten Schritt dann KNX mit FHEM verbinden. Allein zwei Dinge sind dabei selten: Zeit und Geld...