Ist es möglich ein Reading per perl zuüberschreiben?

Begonnen von kevkolb, 01 Dezember 2016, 15:12:58

Vorheriges Thema - Nächstes Thema

kevkolb

Mein Ziel ist es durch ein at Befehl der täglich um 05:55 ausgeführt wird soll überprüft werden ob ein Sensor neue Werte geliebter hat. Wenn das update der Werte grösser als 12 Stunden ist soll ein Reading geändert werden. Hier der at Befehl:
*05:55:55 {check_if_alive("MYSENSORS_03", 12);}
Ich habe ein kleines script versucht zu schreiben:
99_myUtil.pm
sub check_if_alive($$) {
  # Erwartet:
  # 1. Devicename
  # 2. Zeit in Stunden (älter als X --> Device dead)
  # Returns:
  # 0 -> Device dead
  # 1 -> Device alive
  # 2 -> Error
  my ($Device,$zeit) = @_;
  my ($Device) = @_;
  my $now = time;
  my $last_state_time = time_str2num(ReadingsTimestamp($Device,'humidity','0'));
  if ($last_state_time eq "0") {
    return 2;
  }

  my $age_in_hours = ($now - $last_state_time) / 3600;

  if ($age_in_hours > $zeit) {
    Log 1, ("check_if_alive: $Device dead,  is alive, letztes state war $age_in_hours Stunden her");
    Log 2, readingsBeginUpdate($Device");
    readingsBulkUpdate($Device, "battery", "low");
    readingsEndUpdate($Device, 1);
    return 0;
  }

Wenn ich den at Befehl ausführe steht folgendes im Log.
2016.12.01 14:57:58 1 : check_if_alive: MYSENSORS_03 is alive, letztes state war 0 Stunden her
2016.12.01 14:57:58 3 : Sensoren_at: Can't use string ("MYSENSORS_03") as a HASH ref while "strict refs" in use at fhem.pl line 3911.

Und natürlich ist auch das reading nicht geupdated worden. :o

Bitte um Anregungen

Otto123

Hi,

ich bin nicht so die Perl Leuchte aber mir fällt folgendes auf:

Du kannst offenbar den Bezug auf ein Objekt MYSENSORS_03 nicht herstellen --> http://perldoc.perl.org/strict.html#strict-refs
Ich hoffe Du meinst 99_myUtils.pm  ;)
Wozu diese Folge:   my ($Device,$zeit) = @_;
  my ($Device) = @_;

???
Ist gar die zweite Zeile das Problem?

Also nur Anregungen  :D

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

Puschel74

Wie Otto schon geschrieben hat stossen auch mir die 2 Zuweisungen schräg auf.
Allerdings sehe ich auch hier noch
Log 2, readingsBeginUpdate($Device");
ein Problem.
a) entweder ein " zuviel oder ein " zuwenig
b) was soll readingsBeginUpdate ins Log schreiben?
Ok, b verwende ich nicht daher ist das eher eine Frage als ein Hinweis.

Allerdings bekomme ich diese Zeile
Log 1, ("check_if_alive: $Device dead,  is alive, letztes state war $age_in_hours Stunden her");
mit dieser
Zitat2016.12.01 14:57:58 1 : check_if_alive: MYSENSORS_03 is alive, letztes state war 0 Stunden her
nicht zusammen.
Irgendwie fehlt mir hier das dead aus der Log-Anweisung.
$Device beinhaltet MYSENSORS_03 - das ist mir klar aber wo verschwindet das dead  ???
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

kevkolb

Erstmal danke für eure Rückmeldungen.
ZitatIch hoffe Du meinst 99_myUtils.pm  ;)
Wozu diese Folge:
Code: [Auswählen]
  my ($Device,$zeit) = @_;
  my ($Device) = @_;
???
Ist gar die zweite Zeile das Problem?
Habe es auch ohne der zweiten Zuweisung ausprobiert. Leider keine Änderung im Ergebnis.
Das Problem ist, ich kann von mir auch nicht behaupten ich könnt Perl! ???
ZitatWie Otto schon geschrieben hat stossen auch mir die 2 Zuweisungen schräg auf.
Allerdings sehe ich auch hier noch
Code: [Auswählen]
Log 2, readingsBeginUpdate($Device");
ein Problem.
a) entweder ein " zuviel oder ein " zuwenig
b) was soll readingsBeginUpdate ins Log schreiben?
Ok, b verwende ich nicht daher ist das eher eine Frage als ein Hinweis.
a) Da ist ein " zuviel. Hatte da mal "MYSENSOR_03" drin stehen gehabt um zu probieren ob dann die Readings geupdatet werden.
b) War auch nur so eine Idee um vielleicht meiner Lösung ein Stück näher zu kommen. Was ich jetzt weiss ist das der Fehler genau in der Zeile kommt.
ZitatAllerdings bekomme ich diese Zeile
Code: [Auswählen]
Log 1, ("check_if_alive: $Device dead,  is alive, letztes state war $age_in_hours Stunden her");
mit dieser
Zitat
2016.12.01 14:57:58 1 : check_if_alive: MYSENSORS_03 is alive, letztes state war 0 Stunden her
nicht zusammen.
Irgendwie fehlt mir hier das dead aus der Log-Anweisung.
Das liegt daran ich hatte den else-Teil nicht gepostet:
else {
    Log 1, ("check_if_alive: $Device is alive, is alive, letztes state war  $age_in_hours Stunden her");
    Log 1, readingsBeginUpdate(&$Device);
    readingsBulkUpdate("$Device", "battery", "ok");
    readingsEndUpdate("$Device", 1);
    return 1;
  }


Aber nochmal zurück zu meiner Problemstellung. Vielleicht kann man das auch anders lösen.
Ich habe Sensoren die ihre Daten an Fhem weiterleiten. Es wird z.B. das Reading temperature geupdatet. Ich möchte falls bei einem Sensor kein update des Readings seit einer Zeitspanne X bekommen hat ein neues Reading battery auf "low" gesetzt wird.

Danke im Voraus für euere Unterstützung

MadMax-FHEM

Hi,

ich habe etwas ähnliches (oder genau das) für meine Wasserstandsanzeige gebaut.

Kann aber grad nicht nachsehen, mache ich sobald ich zuhause bin...

Aus dem Kopf habe ich es in etwa so gemacht (bzw. schon mal für dich "angepasst"):

sub my_CheckWasserstandsSensor($$)
{
my ($Device,$zeit) = @_;

if(ReadingsAge($Device, "humidity", 0) > ($zeit*60*60))
{
   {fhem "setreading $Device battery dead"}
}
else
{
   {fhem "setreading $Device battery ok"}
}
}


Zur Sicherheit schau ich aber noch mal nach, wenn ich wieder zuhause bin...

Habe auch im Kopf, dass es ein Modul gibt (vgl.bar bei HM den ActionDetector) welches allgemein (also für jedes "Gerät") genau das tut.
Wollte schon umstellen, hatte nur keine Zeit.

Vielleicht hilft die Forensuche...
...bzw. vielleicht war es das:

https://forum.fhem.de/index.php/topic,8821.msg46651.html#msg46651

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)

Bennemannc

Hallo,

mal so am Rande gefragt - genau das macht doch das watchdog Modul
Zitatdefine <name> watchdog <regexp1> <timespec> <regexp2> <command>

Startet einen beliebigen FHEM Befehl wenn nach dem Empfang des Ereignisses <regexp1> nicht innerhalb von <timespec> ein <regexp2> Ereignis empfangen wird.
Der Syntax für <regexp1> und <regexp2> ist der gleiche wie regexp für notify.
<timespec> ist HH:MM[:SS]
<command> ist ein gewöhnlicher fhem Befehl wie z.B. in at oderr notify

Gruß Christoph
Cubietruck, Fhem 5.8
CC-RT-DN|LC-SW2-FM|RC-12|RC-19|LC-SW4-BA-PCB|LCp-SW1-BA-PCB|ES-PMSw1-Pl|LC-Bl1PBU-FM|PBI-4-FM|CC-VD|CC-TC|SEC-SC(2)|RC-KEY3-B|LC-Sw1PBU-FM|PB-2-FM|WDS100-C6-O|WDC7000|LC-Bl1-FM
Module: Dewpoint,FB_Callmonitor,HCS,Panstamp,at,notify,THRESHOLD,average,DOIF

kevkolb

@MadMax-FHEM

Danke schön, das war genau die Lösung die ich gesucht habe!!!
:D

MadMax-FHEM

Gerne!

Was jetzt:

die Lösung aus dem Kopf

oder

das Modul??

Nur für den der hier drüber stolpert und auch die Lösung sucht...

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)

kevkolb

Ja klar. Hier die Lösung die für mich super funktioniert:

sub check_if_alive($$) {
  my ($Device,$zeit) = @_;
  my $Age = ReadingsAge($Device,"humidity",0);
  if (ReadingsAge($Device,"humidity",13) > ($zeit)) {
    Log 1, ("check_if_alive: $Device dead, last state was $Age hours ago");
   {fhem "setreading $Device battery low"};
  } else {
    Log 1, ("check_if_alive: $Device is alive, last state was $Age hours ago");
    {fhem "setreading $Device battery ok"};
  }}


Sobald ein Sensor länger als 12 Stunden nichts gesendet hat wird das reading battery auf low gesetzt.
Hier noch der at Befehl für Fhem:
*05:55:55 {check_if_alive("1F_MYSENSOR", 12);;check_if_alive("SZ_MYSENSOR", 12);;check_if_alive("WZ_MYSENSOR", 12);;}

Jetzt wird jeden Tag um 05:55:55 Uhr alle Sensoren überprüft ob sie ausgefallen sind.