Probleme bei notify mit ausgelagerter Funktion in 99_myUtils.pm

Begonnen von s3bi, 21 Januar 2016, 21:45:15

Vorheriges Thema - Nächstes Thema

s3bi

Hallo,

ich versuche mich gerade an einer Funktion in der 99_myUtils.pm - ausgelöst über ein notify.

Folgendes habe ich vor:

Ich prüfe per LAN-Ping auf eine IP-Adresse, ob ein bestimmtes Smartphone "anwesend" ist (=PRESENCE)

define Sebi PRESENCE lan-ping 10.100.100.21

Ein notify soll nun eine Funktion aufrufen (99_myUtils.pm) um einige Prüfungen durchzuführen und dann einen Status im Typ ROOMMATE zu ändern.

define n.SetHomeStatusSebi notify Sebi:state:.* { SetHomeStatusSebi($EVENT) }

Nun die Funktion:

sub SetHomeStatusSebi($)
{
my $SetStatus = @_;
my $NewStatus = '';
my $CurrentStatus = ReadingsVal("rr_Sebi", "state", "");

  if ( ( $CurrentStatus == "gotosleep") && ($SetStatus == "home") ){
    my $NewStatus = "gotosleep";
  }
  if ( ( $CurrentStatus == "gone") && ($NewStatus == "home") ){
    my $NewStatus = "home";
  }
  if ( ( $CurrentStatus == "absent") && ($NewStatus == "home") ){
    my $NewStatus = "home";
  }
  if ( ( $CurrentStatus == "home") && ($NewStatus == "home") ){
    my $NewStatus = "home";
  }

  if ( ( $CurrentStatus == "absent" ) && ($NewStatus == "absent") ){
    my $absentTime = ReadingsVal("rr_Sebi", "durTimerAbsence_cr", "");
    if ( ( $absentTime > 0 ) && ($absentTime <= 15 ) ) {
      my $NewStatus = "absent";
    }
    if ( $absentTime > 15 ) {
      my $NewStatus = "gone";
    }
  }

  set rr_Sebi $NewStatus;

}


Was soll passieren? Nun, wenn das Handy anwesend ist, soll auch der Homestatus von rr_Sebi auf "home" gesetzt werden, aber nur dann, wenn der Status nicht "gotosleep" ist.
Wenn das Handy nicht anwesend ist wird der Homestatus auf "absent" gesetzt, ist der Satus bereits "absent" und das schon länger als 15 min, soll der Homestatus auf "gone" gesetzt werden.

Irgendwo habe ich einen Fehler, nur wo finde ich nicht. Vielleicht kann mir ja jemand einen Schups in die Richtige Richtung geben?

Danke für Eure Unterstützung.

drhirn

Sollte das am Schluss nicht

fhem "set rr_Sebi $NewStatus";

heißen?

s3bi

Das war auf jeden Fall einer der Fehler. Danke!


Ich habe die Vermutung dass meine Variablen nicht gefüllt sind. Kann ich denn durch eine Anweisung debuggen welcher Wert gerade in welcher Variable steckt?
so alá print($var) und im Log (oder irgendwo anders) sehe ich dann den aktuellen Wert?

Ich glaube hier liegt der Fehler:
my $SetStatus = @_;
my $CurrentStatus = ReadingsVal("rr_Sebi", "state", "");



Hans Franz

Log 1,"SetStatus: ".$SetStatus."  CurrentStatus: ".$CurrentStatus;

Gruß
Hans
Raspi
CUL, Nano-CUL
FHT8V, FHT80B, S300TH
WM1000WZ, ELRO
LW12, LD382,DS18B20

s3bi

Danke Hans! Das bringt mich weiter.

Mein Log sagt jetzt:
2016.01.22 12:26:22 1: SetStatus: presence: absent  CurrentStatus: home

Sprich, die Variable SetStaus enthällt momentan "presence: absent"
Ich möchte aber nur "absent" in der Variable haben.

Wie bekomme ich den Wert aus:
my $SetStatus = @_;
ohne "presence: " ?

Versucht  habe ich nun folgendes:
my ($SetStatusTmp1) = @_;
my @SetStatusTmp2 = split(/: /,$SetStatusTmp1);
my $SetStatus = @SetStatusTmp2[2];


jedoch ohne Erfolg, die Variable $SetStatus is nun leer.

marvin78

commandref zu notify lesen und dich mit den Events beschäftigen. Teile eines Events erhält man über $EVTPARTX (siehe commandref).

Hans Franz

Die Indexierung beginnt bei 0:
my $SetStatus = @SetStatusTmp2[1];

Eleganter und mehr fhem-like ist aber Marvins Vorschlag.

Gruß
Hans
Raspi
CUL, Nano-CUL
FHT8V, FHT80B, S300TH
WM1000WZ, ELRO
LW12, LD382,DS18B20

s3bi

Ich habe mir die ommandref zu notify nochmal genauer angesehen. Mit $EVTPART1 klappt jetzt alles wie gewünscht.
Das mit der Indexierung hätte mir auch gleich auffallen können - ist ja in den meisten Programmiersprachen gleich *schande über mich*. $EVTPART1 ist auf jeden Fall sinnvoller als der Split.

Hier der neue, funktionierende code aus der 99_myUtils.pm (falls es jemanden helfen sollte):

sub SetHomeStatusSebi($)
{
my ($SetStatus) = @_;
my $NewStatus = "";
my $CurrentStatus = Value("rr_Sebi");
my $absentTime = ReadingsVal("rr_Sebi", "durTimerAbsence_cr", 1);

  if ( ( $CurrentStatus eq "gotosleep") && ($SetStatus eq "present") ){
    $NewStatus = "gotosleep";
  }
  if ( ( $CurrentStatus eq "gone") && ($SetStatus eq "present") ){
    $NewStatus = "home";
  }
  if ( ( $CurrentStatus eq "absent") && ($SetStatus eq "present") ){
    $NewStatus = "home";
  }
  if ( ( $CurrentStatus eq "home") && ($SetStatus eq "present") ){
    $NewStatus = "home";
  }
  if ( ( $CurrentStatus eq "home") && ($SetStatus eq "absent") ){
    $NewStatus = "absent";
  }

  if ( ( $CurrentStatus eq "absent" ) && ($SetStatus eq "absent") ){
   
    if ($absentTime < 15 ) {
      $NewStatus = "absent";
    }
    if ( $absentTime >= 15 ) {
      $NewStatus = "gone";
    }
  }

  if($NewStatus ne $CurrentStatus){
    fhem "set rr_Sebi $NewStatus";
    Log 1,"SEBI: SetStatus: ".$SetStatus." CurrentStatus: ".$CurrentStatus." NewStatus: ".$NewStatus." AbsentTime: ".$absentTime;
  }

}


Ich möchte damit verschiedene Dinge steuern:
- Benachrichtung per WhatsApp falls keiner zuhause ist und Fenster oder Türen geöffnet sind
- Heizung herunterregeln wenn keiner zuhause / Hochfahren wenn jemand zuhause
- Alarmanlage scharf stellen, wenn keiner zuhause / deaktivieren wenn jemand zuhause
- Anwesenheitssimulation starten wenn keiner zuhause (Rollos hoch/ runterfahren, Licht an und ausschalten, etc)
- Haustüre abschließen, wenn keiner zuhause

Vielen Dank für Eure Hilfe!

Puschel74

ZitatHier der neue, funktionierende code aus der 99_myUtils.pm (falls es jemanden helfen sollte):
Es würde mit Sicherheit einem Anfänger helfen - nur leider wird dieser dein Beitrag nach hinten rutschen und die Nachkommenden werden nicht suchen.
Also wird auch deine gut gemeinte Dokumentation nichts helfen.

Warum ich das schreiben?
Weil ich vor ca. 2 Wochen grad einen Anfänger "begleitet" habe und ihm auch Log und $EVTPARTx gezeigt habe - es muss nur gesucht und gefunden werden (und es wird selten ersteres gemacht).
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.

s3bi

Da geb ich dir recht, nur ist es nicht immer so leicht (gerade als Anfänger) nach den richtigen Begriffen zu suchen.

Ich hatte z.B. garnicht gewusst das es $EVTPARTx gibt und versucht per perl zu Splitten. Wenn man ein wenig Programmiererfahrung hat geht man eben oft einen Weg der zunächst einfacher erscheint, tatsächlich aber doch einfacher zu Lösen ist.

Manchmal braucht man eben nur einen Schubs in die Richtige Richtung. Vielen dank jedenfalls für deinen Schubs ;)

Puschel74

Dann würde ich dich bitten dir einen "logischen" Titel zu überlegen.
Vielleicht schafft es dein Beitrag dann gefunden zu werden - ob er gesucht wird weiß ja dennoch niemand  ;)
Deine Beiträge kannst du übrigens selbst bearbeiten und wenn deine Frage geklärt ist dann - bitte lies meinen angepinnten Beitrag hier im Anfängerbereich.
Wenn jeder Fragesteller seinem Beitrag einen "logischen" Betreff geben würde wäre die Suche auch einfacher  :P
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.