FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: MichaelO am 15 November 2015, 13:25:34

Titel: String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: MichaelO am 15 November 2015, 13:25:34
Moin,

ich bekomme beim Verlassen der Wohnung eine Warnung, wenn noch Fenster offen sind. Kann mir wer einen Hinweis geben, wie ich meine Meldung derart ergänze, dass die Geräte bennant werden, die die Meldung auslösten (quasi Liste der offenen Fenster)?

## Wenn beim Verlassen des Hauses nicht alle
## (kontrollierten) Fenster/Türen zu sind
( ([Mittelstr:residentsTotalOwnersPresent] == 0) and
  ([?WZ_FK_Fenster_links] eq "open" or [?GZ_FK_Fenster_rechts] eq "open") )

     ## Nachricht schicken.
     (set pushmsg msg 'Hinweis!' 'Es sind noch Fenster offen.'  '' 2 '' 30 3600)

## ansonsten Modul umschalten
DOELSE


Meine Sensoren enthalten alle im Namen _FK_Fenster_ , aber ich bekomme es nicht hin, einen String für die Meldung ereignisgesteuert zusammenzubauen.

Danke
Michael
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: kumue am 15 November 2015, 13:56:33
ich übergebe bei meinem Tür-Alarm-DOIF das Device-Reading
meinst Du sowas ?


(set Pushover msg 'TÜR-ALARM' '[DO_TK_Alarm:Device] ist offen' '' 1 'siren')
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: MichaelO am 15 November 2015, 15:10:20
Zitat von: kumue am 15 November 2015, 13:56:33
ich übergebe bei meinem Tür-Alarm-DOIF das Device-Reading
meinst Du sowas ?


(set Pushover msg 'TÜR-ALARM' '[DO_TK_Alarm:Device] ist offen' '' 1 'siren')

Ja, prima... im Prinzip schon. War mir nicht klar, dass ich im set Pushover... das so benutzen kann. Nun vielleicht noch eine Frage. Es werden ja mehrere Sensoren in meinem DOIF abgefragt. Damit ich nun nicht für jeden Sensor eine eigene Meldung bekomme, wie würde der Syntax lauten, mit dem ich quasi einen String erstelle, der in einer letzten Anweisung im set Pushover... verwendet wird? Grob ins Unreine gesprochen quasi so etwas:

DOIF (Bedingung)
     (Nachricht = 'Es sind Fenster offen: ')
     (IF (Sensor1 ist offen) (Nachricht = Nachricht + '[Sensorname1] '))
     (IF (Sensor2 ist offen) (Nachricht = Nachricht + '[Sensorname2] '))
     (...)
     (set Pushover msg 'Hinweis' Nachricht 1 'siren')
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: kumue am 16 November 2015, 08:54:21
Beim Schreiben meiner Antwort wusste ich schon, daß die Frage aufkommen wird...   :D
Ich weiß es aber selber (noch) nicht, wie das umgesetzt werden kann....
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: Laffer72 am 16 November 2015, 09:42:25
Hallo,

ich habe das ganze als sub in den 99_myUtils.pm wie folgt gelöst:

sub
FensterKontrolle()
{
my $Fensteroffen="";
if ( ReadingsVal("sensor_fenster_bad","state","") ne "closed" ) {$Fensteroffen=$Fensteroffen." Badezimmer"};
if ( ReadingsVal("sensor_fenster_ankleide","state","") ne "closed") {$Fensteroffen=$Fensteroffen." Ankleide"};
if ( ReadingsVal("sensor_fenster_sz","state","") ne "closed" ) {$Fensteroffen=$Fensteroffen." Schlafzimmer"};
if ( ReadingsVal("sensor_fenster_wz_rechts","state","") ne "closed" || ReadingsVal("sensor_fenster_wz_links","state","") ne "closed") {$Fensteroffen=$Fensteroffen." Wohnzimmer"};
if ( ReadingsVal("sensor_fenster_ki_links","state","") ne "closed" || ReadingsVal("sensor_fenster_ki_mitte","state","") ne "closed" ||  ReadingsVal("sensor_fenster_ki_rechts","state","") ne "closed") {$Fensteroffen=$Fensteroffen." Kinderzimmer"};

fhem("set Sonos_Wohnzimmer Speak 20 de Fenster offen in $Fensteroffen");
fhem("set PushNotifyReinhard message \"$Fensteroffen\" \"Fenster-Alarm\" \"\" \"\" \"\" True False");
}


aufgerufen wird das ganze einfach durch {FensterKontrolle()}.

Hoffe es hilft Die etwas weiter.

Viele Grüße

Reinhard
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: MichaelO am 16 November 2015, 09:50:20
Klasse, das sollte funktionieren, werde es die Tage testen. Ich hatte gehofft, es auch direkt im DOIF lösen zu können, aber wenn es so klappt, ist es auch gut!

Nochmals danke
Gruß
Michael
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: Laffer72 am 16 November 2015, 10:02:05
Du kannst natürlich den Meldungsteil (Sonos,Push) auch auf die DOIF-Ebene heben, indem Du den Wert $Fensteroffen beim return wieder mit zurückgibst.

return $Fensteroffen;

als letzte Zeile, vor der geschweiften Klammer.

Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: viegener am 16 November 2015, 13:41:53
Hi,
nur zur Ergänzung, ich habe mir Routinen gebaut, die die Überprüfung anhand des typs oder wenn das nicht passt eine Gruppe (es ist natürlich auch möglich andere Auswahlkriterien machen). Ziel ist es die Routinen nicht immer anpassen zu müssen, wenn ein Gerät dazukommt oder umbenannt wird. Das ist mir wichtig, da ich plane auch weiterhin Sensoren nachzurüsten und schon jetzt verschiedene Sensoren im Einsatz habe.

Durch Übergabe des parameters "msg" wird eine komplette nachricht (mit Timestamp) zusammengebaut, die auch gepushed werden kann


##############################################
# Check state of Windows and return list (undef if nothing open) or message (cmd = msg / might be empty string)
sub checkWindowOpen($) {

my ($cmd) = @_;


  my $wOpen = "";
  my @list;
  my $sdev;
 
  # Log 1, "checkWindowOpen called :$cmd:";

  # PT_2262
  @list = devspec2array("group=IT_F_SENSOR");

    foreach $sdev (@list) {
    if($defs{$sdev}) {
      $wOpen = $wOpen."$sdev " if (ReadingsVal($sdev,"state","unknown") !~ "off");
    }
  }
 
  # HM threestate
  @list = devspec2array("subType=threeStateSensor:FILTER=TYPE=CUL_HM");

  foreach $sdev (@list) {
    if($defs{$sdev}) {
      $wOpen = $wOpen."$sdev " if (ReadingsVal($sdev,"state","unknown") !~ "closed");
    }
  }

  #Log 1, "checkWindowOpen returned :$wOpen:";

  if ( ! defined( $cmd ) || ( $cmd eq "" ) ) {
    $wOpen = undef if ( $wOpen eq "" );
  } elsif ( $cmd eq "msg" ) {
    my ($seconds, $microseconds) = gettimeofday();
    my @t = localtime($seconds);
    my $tim = sprintf("%02d.%02d %02d:%02d:%02d",
            $t[3],$t[4]+1, $t[2],$t[1],$t[0]);

    $wOpen = "Es sind nicht alle Fenster geschlossen ($wOpen) - [$tim]" if ( $wOpen ne "" );
    Log 1, "checkWindowOpen result :$wOpen:";
  } else {
    $wOpen = "unknwown cmd :$cmd: in checkWindowOpen";
  }
 
  return $wOpen;

}


Ich bin dabei mehrere solche Routinen (Batteriewarnung, Tempsensor meldet sich länger nicht, etc) zubauen und an mein Benachrichtigungssystem anzuschliessen, je nach Wichtigkeit.

Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: devil77 am 21 Juni 2016, 14:07:27
Hallo,

versuche gerade die Routine zu verstehen aber begreife noch nicht ganz wie ich das ganze zu einer Meldung bewegen kann?
Grob gesagt möchte ich gerne das ganze verwenden um zu einer festgelegten Uhrzeit alle Fensterkontakte abzufragen und die offenen zu melden.
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: viegener am 21 Juni 2016, 19:48:53
Generell muss die Methode in einem notify oder DOIF oder at eingebaut werden zum Beispiel so:



define alarm_test DOIF ([dummy_test:?on]) ( set telegrambot message {(checkWindowOpen("msg"))} )


In diesem Fall wird auf die Änderung eines Dummies reagiert, aber das lässt sich natürlich analog in einem at einbauen.

Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: automatisierer am 21 Juli 2016, 19:06:24
So hab ich mir den Code von Viegener umgebaut:

# Check state of Windows and return list (undef if nothing open) or message (cmd = msg / might be empty string)
sub checkWindowOpen($) {

my ($cmd) = @_;


  my $wOpen = "";
  my @list;
  my $sdev;

  # Log 1, "checkWindowOpen called :$cmd:";

  # PT_2262
  #@list = devspec2array("group=IT_F_SENSOR");

  #  foreach $sdev (@list) {
  #  if($defs{$sdev}) {
  #    $wOpen = $wOpen."$sdev " if (ReadingsVal($sdev,"state","unknown") !~ "off");
  #  }
  #}

  # HM threestate
  @list = devspec2array("subType=threeStateSensor:FILTER=winOpenMsg=1");

  foreach $sdev (@list) {
    if($defs{$sdev}) {
      $wOpen = $wOpen."$sdev " if (ReadingsVal($sdev,"state","unknown") !~ "closed");
    }
  }

  #Log 1, "checkWindowOpen returned :$wOpen:";

  if ( ! defined( $cmd ) || ( $cmd eq "" ) ) {
    $wOpen = undef if ( $wOpen eq "" );
  } elsif ( $cmd eq "msg" ) {
    my ($seconds, $microseconds) = gettimeofday();
    my @t = localtime($seconds);
    my $tim = sprintf("%02d.%02d %02d:%02d:%02d",
            $t[3],$t[4]+1, $t[2],$t[1],$t[0]);

    $wOpen = "Es sind nicht alle Fenster geschlossen ($wOpen) - [$tim]" if ( $wOpen ne "" );
    Log 1, "checkWindowOpen result :$wOpen:";
  } else {
    $wOpen = "unknwown cmd :$cmd: in checkWindowOpen";
  }

  return $wOpen;

}

und bei mir werden die Geräte nur mit einbezogen, wenn ich denen ein 'attr <dev> winOpenMsg 1' gebe.

Da ich die Meldung nochmal nach einbruchgefährdeten und nicht einbruchgefährdeten Fenstern teile, also einmal Pushover mit bestätigung und einmal ohne...

Was ich noch gerne hätte, aber mangels Perlkenntnis noch nicht umgesetzt habe, ist das nicht die Device-Namen, sondern der alias Name oder sonst ein Wunschname übergeben wird.
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: viegener am 22 Juli 2016, 01:22:37
Probiers doch mal mit dieser Veränderung, auch wenn das jetzt nur ein Schnellschuss ist:


# Check state of Windows and return list (undef if nothing open) or message (cmd = msg / might be empty string)
sub checkWindowOpen($) {

my ($cmd) = @_;


  my $wOpen = "";
  my @list;
  my $sdev;

  # Log 1, "checkWindowOpen called :$cmd:";

  # PT_2262
  #@list = devspec2array("group=IT_F_SENSOR");

  #  foreach $sdev (@list) {
  #  if($defs{$sdev}) {
  #    $wOpen = $wOpen."$sdev " if (ReadingsVal($sdev,"state","unknown") !~ "off");
  #  }
  #}

  # HM threestate
  @list = devspec2array("subType=threeStateSensor:FILTER=winOpenMsg=1");

  my @openList = ();
  foreach $sdev (@list) {
    if($defs{$sdev}) {
      push (@openList,$sdev) if (ReadingsVal($sdev,"state","unknown") !~ "closed");
      $wOpen = $wOpen."$sdev " if (ReadingsVal($sdev,"state","unknown") !~ "closed");
      }
  }

  #Log 1, "checkWindowOpen returned :$wOpen:";

  if ( ! defined( $cmd ) || ( $cmd eq "" ) ) {
    $wOpen = undef if ( $wOpen eq "" );
  } elsif ( $cmd eq "msg" ) {
    my ($seconds, $microseconds) = gettimeofday();
    my @t = localtime($seconds);
    my $tim = sprintf("%02d.%02d %02d:%02d:%02d",
            $t[3],$t[4]+1, $t[2],$t[1],$t[0]);

    if ( scalar(@openList) > 0 ) {
      $wOpen = "";
      foreach $sdev (@openList) {
        $wOpen .= ", " if ( length($wOpen) > 0 );
        $wOpen .= $sdev;
      }
      $wOpen = "Es sind nicht alle Fenster geschlossen ($wOpen) - [$tim]";
    }
    Log 1, "checkWindowOpen result :$wOpen:";
  } else {
    $wOpen = "unknwown cmd :$cmd: in checkWindowOpen";
  }

  return $wOpen;

}
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: automatisierer am 23 Juli 2016, 14:22:53
das hat nicht geklappt (Gott sei Dank), ich wollte das ja mal selber hin fuckeln... quasi als Lernprojekt.

# Check state of Windows and return list (undef if nothing open) or message (cmd = msg / might be empty string)
sub checkWindowOpen($) {

my ($cmd) = @_;


  my $wOpen = "";
  my @list;
  my $sdev;

  #Log 1, "checkWindowOpen called :$cmd:";

    # HM threestate
  @list = devspec2array("subType=threeStateSensor:FILTER=winOpenMsg=1");
  #Log 1, "Zeile 15 at list: @list";
  foreach $sdev (@list)
    {
    if($defs{$sdev})
        {
        $wOpen = $wOpen.(AttrVal($sdev,"winOpenName",$sdev)) if (ReadingsVal($sdev,"state","unknown") !~ "closed");
        }
    }

# Log 1, "Zeile 24 checkWindowOpen returned :$wOpen:";

  if ( ! defined( $cmd ) || ( $cmd eq "" ) ) {
    $wOpen = undef if ( $wOpen eq "" );
  } elsif ( $cmd eq "msg" ) {
    my ($seconds, $microseconds) = gettimeofday();
    my @t = localtime($seconds);
    my $tim = sprintf("%02d.%02d %02d:%02d:%02d",
            $t[3],$t[4]+1, $t[2],$t[1],$t[0]);

    $wOpen = "Es sind nicht alle Fenster geschlossen ($wOpen) - [$tim]" if ( $wOpen ne "" );
    Log 1, "checkWindowOpen result :$wOpen:";
  } else {
    $wOpen = "unknwown cmd :$cmd: in checkWindowOpen";
  }

  return $wOpen;


}


so hats geklappt, was allerdings noch fehlt ist ein Leerzeichen oder ein ',' zwischen den Devices. Da muss ich mal noch ein wenig studieren, wie das geht...

Mit dem 'attr winOpenMsg 1' wird das Device nun hinzugefügt und mit dem 'attr winOpenName Wunschname' kann man einen Namen bestimmen, ohne das wird der Device-Name genommen.
Titel: Antw:String für Push-Message in DOIF erzeugen (Liste von Geräten)?
Beitrag von: automatisierer am 23 Juli 2016, 23:48:44
nochmal aufgehübscht...

# Check state of Windows and return list (undef if nothing open) or message (cmd = msg / might be empty string)
sub checkWindowOpen($)
{

my ($cmd) = @_;

my $wOpen = "";
my @list;
my $sdev;
   
# HM threestate
@list = devspec2array("subType=threeStateSensor:FILTER=winOpenMsg=1");
foreach $sdev (@list)
        {
        if($defs{$sdev})
            {
            my $devname=AttrVal($sdev,'winOpenName',AttrVal($sdev,'alias',$sdev));
            $wOpen = $wOpen."$devname\n" if (ReadingsVal($sdev,"state","unknown") !~ "closed");
            }
        }

if ( ! defined( $cmd ) || ( $cmd eq "" ) )
{
    $wOpen = undef if ( $wOpen eq "" );
    } elsif ( $cmd eq "msg" )
{
        my ($seconds, $microseconds) = gettimeofday();
        my @t = localtime($seconds);
        my $tim = sprintf("%02d.%02d %02d:%02d:%02d",
                $t[3],$t[4]+1, $t[2],$t[1],$t[0]);
        $wOpen = "Fenster nicht geschlossen:\n$wOpen [$tim]" if ( $wOpen ne "" );
    } else
{
    $wOpen = "unknwown cmd :$cmd: in checkWindowOpen";
    }
   
return $wOpen;

}



Jetzt wird erst der Wunschname wenn vorhanden, dann der Alias und sonst der Dev-Name genommen. Dann noch mit Zeilenumbruch statt dem Leerzeichen zwischen einzelnen Namen - macht es besser lesbar.