DOIF, wie an Readings via regex kommen?

Begonnen von Sidey, 10 August 2018, 22:48:40

Vorheriges Thema - Nächstes Thema

Sidey

Hi,


ich stehe gerade auf dem Schlauch und komme nicht drauf.

Ich will mit einem DOIF mehrere Operationen ausführen. Genauer gesagt, immer den gleichen set Befehl, aber auf mehrere Geräte.
Das ganze möchte ich sequentiell machen und nicht über ein Zeitraster oder so.

Ich habe dazu ein paar Geräte definiert und frage diese mittels devspec(<regex>) ab. Dann habe ich eine Liste der Devices.
Jetzt möchte ich mir im DOIF speichern, welche Geräte das sind. Dazu habe ich mir Readings im DOIF angelegt:



foreach $dev (@devices)
  {
      fhem("setreading $SELF job_$dev pending");;
  },


Jetzt frage ich mich, wie ich in einem DOELSEIF Zweig, die Readings, deren Namen ich nicht kenne suchen kann.

Grüße Sidey
Signalduino, Homematic, Raspberry Pi, Mysensors, MQTT, Alexa, Docker, AlexaFhem

Maintainer von: SIGNALduino, fhem-docker, alexa-fhem-docker, fhempy-docker

Ellert

Genau habe ich das nicht verstanden, aber vielleicht lohnt es sich das Beispiel mit den Batteriereadings anzusehen. Im DOIF steht dann eine Liste von Readings mit dem aktuellen Batteriezustand die auch abgefragt wird.

Unter https://fhem.de/commandref_DE.html#DOIF_Ereignissteuerung_ueber_Auswertung_von_Events das Beispiel
"Batteriewarnung per E-Mail verschicken"

Sidey

#2
Hi Ellert,

ja, so ein bisschen in die Richtung habe ich auch gedacht.



Ich hab jetzt aktuell folgendes:

cmd_1 startet zu einer festen Uhrzeit. Hier im Beispiel 0:14 Uhr.
cmd_1 legt nun Readings im doif an nach dem Schema job_<devicename>
cmd_1 würde dann noch einen der jobs starten, das habe ich zum Testen aktuell entfernt.


cmd_2 soll nun auslösen, wenn bei einem der Devices die mit dem Namen ^DBRep beginnen das EVENT done empfangen wird.
cmd_2 sucht dann die Readings mit Namen job_ und extrahiert den Gerätenamen um damit ein set befehl aufzurufen.

Seltsamer weise, funktionieren die Befehle in cmd_2 nicht, solange der Trigger ["^DBRep:done"]  konfiguriert ist.


Ich habe es jetzt funktionsfähig wie folgt am Laufen:

([00:14]) (
{ my @devices= devspec2array("DBRep.*");;
  my $dev;;
  if (@devices)
  {
  foreach $dev (@devices)
  {
       fhem("setreading $SELF job_$dev pending");;
  }
  }
},
set $SELF cmd_2
)
DOELSEIF (["^DBRep.*:^done$"] and [?$SELF:job_$DEVICE] eq "pending")
(
setreading $SELF job_$DEVICE $EVENT,
deletereading $SELF job_,
{
 
  my @jobreadings;;
  my $di_readings;;
  use Data::Dumper;;
 
  $di_readings = $defs{"$SELF"}{READINGS};
  @jobreadings =grep { $_ =~ "^job_.+" && ReadingsVal("$SELF",$_,"done") eq "pending"}  keys %{$di_readings};;
  if (@jobreadings) {
Log 3, "Job readings from $SELF ".Dumper(\@jobreadings);;
  my $nextjob=substr(pop(@jobreadings),4);;
  Log 3, "Job started $nextjob " if ($nextjob);;
fhem("set $nextjob countEntries history") if ($nextjob);;
  }
},
)

Signalduino, Homematic, Raspberry Pi, Mysensors, MQTT, Alexa, Docker, AlexaFhem

Maintainer von: SIGNALduino, fhem-docker, alexa-fhem-docker, fhempy-docker

Damian

Du führst aus cmd_1 set cmd_2 auf, wo $EVENT und $DEVICE genutzt wird. Ich bin mir nicht sicher, ob das gut geht.

Da du schon recht tief in Perl programmierst, würde ich es komplett in DOIF-Perl programmieren. Ich werde bald die neue Version einchecken: https://forum.fhem.de/index.php/topic,84969.msg822560.html#msg822560. Prinzipiell ist die Nutzung von $EVENT und $DEVICE etwas für FHEM-Befehle. In Perl würde ich eher mit echten Perlvariablen $event und $device arbeiten. Allerdings ist es nicht immer unproblematisch, je nach dem wie viele Events zu einem Trigger dazugehören: siehe https://forum.fhem.de/index.php/topic,68892.msg821100.html#msg821100
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Sidey

Zitat von: Damian am 12 August 2018, 22:05:48
Du führst aus cmd_1 set cmd_2 auf, wo $EVENT und $DEVICE genutzt wird. Ich bin mir nicht sicher, ob das gut geht.


Das aufrufen von CMD_2 führt tatsächlich dazu, das $DEVICE und $EVENT nicht belegt sind.

Ich habe den FHEM Befehl jetzt in einen Perl Befehl mit Abfrage der Variable geändert:
  fhem("setreading $SELF job_$DEVICE $EVENT") if("$DEVICE");;


Was ich aber noch nicht hinbekommen habe ist, dass ich den STATE verändere, wenn alle "jobs" gelaufen sind.
Setze ich den state vom DOIF manuell, wird er ja wieder überschrieben, sobald ein Zweig beendet wurde.

Ich habe daran gedacht, ein eigenes DOELSEIF zu erzeugen um dadurch einen eigenen cmdState ausgeben zu können:

Grob habe ich an eine Bedingung wie folgt gedacht,
DOELSEIF ([$SELF:job_.* !~ "pending"])

, aber das wird ja so nicht funktionieren, fürchte ich.


Zitat von: Damian am 12 August 2018, 22:05:48

Da du schon recht tief in Perl programmierst, würde ich es komplett in DOIF-Perl programmieren. Ich werde bald die neue Version einchecken: https://forum.fhem.de/index.php/topic,84969.msg822560.html#msg822560. Prinzipiell ist die Nutzung von $EVENT und $DEVICE etwas für FHEM-Befehle. In Perl würde ich eher mit echten Perlvariablen $event und $device arbeiten. Allerdings ist es nicht immer unproblematisch, je nach dem wie viele Events zu einem Trigger dazugehören: siehe https://forum.fhem.de/index.php/topic,68892.msg821100.html#msg821100

Vermutlich hast Du recht. Erst dachte ich, dass ich es im Fhem DOIF Modus machen kann. Naja, die Suche nach unbekannten Readings
ging dann wirklich nicht mehr.
Ich muss mir dazu wohl mal die commandref durchlesen und es dann umbauen :)

Das mit den subs bei der Definition ersetzt ja dann die 99_myutils (hat mir persönlich auch nie so super gut gefallen).


Hast Du vielleicht auch noch mal eine Idee, wie man einfach Daten im DOIF selbst abspeichern kann (alternativ zu readings) ?


Grüße Sidey
Signalduino, Homematic, Raspberry Pi, Mysensors, MQTT, Alexa, Docker, AlexaFhem

Maintainer von: SIGNALduino, fhem-docker, alexa-fhem-docker, fhempy-docker

Damian

Das Setzen des eigenen Status ist ein Grund mehr die Perlversion zu nutzen, hier ist es normal eigene Readings/Status per Funktion set_Reading zu setzen.

Eine besondere Eigenschaft der Perlversion sind Instanzvariablen (globale Variablen pro definiertes DOIF-Device), allerdings überleben sie nicht einen Neustart, daher ist die Nutzung von Readings schon sinnvoll, wenn die Informationen den Neustart überleben sollen. Ansonsten kannst du natürlich immer Informationen in eigenen Dateien speichern und wieder einlesen.

Eine andere Sache ist, die Möglichkeit Aggregationsfunktionen in DOIF zu nutzen. Damit kann man per Regex nicht nur nach Devices, sondern auch nach Readings zu filtern https://fhem.de/commandref_DE.html#DOIF_aggregation
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Sidey

Zitat von: Damian am 12 August 2018, 22:33:48
Das Setzen des eigenen Status ist ein Grund mehr die Perlversion zu nutzen, hier ist es normal eigene Readings/Status per Funktion set_Reading zu setzen.

Ahh, jetzt machts klick :) Du hast sicher setstate gemeint, steht in der commandref vermutlich auch falsch oder?


Zitat von: Damian am 12 August 2018, 22:33:48
Eine besondere Eigenschaft der Perlversion sind Instanzvariablen (globale Variablen pro definiertes DOIF-Device), allerdings überleben sie nicht einen Neustart, daher ist die Nutzung von Readings schon sinnvoll, wenn die Informationen den Neustart überleben sollen. Ansonsten kannst du natürlich immer Informationen in eigenen Dateien speichern und wieder einlesen.
Okay, das mit den Instanzvariablen ist mir neu, eröffnet aber auch wieder Möglichkeiten. Dass man das DOIF nach einem Neustart quasi betriebsbereit macht, ist kein Problem.

Zitat von: Damian am 12 August 2018, 22:33:48
Eine andere Sache ist, die Möglichkeit Aggregationsfunktionen in DOIF zu nutzen. Damit kann man per Regex nicht nur nach Devices, sondern auch nach Readings zu filtern https://fhem.de/commandref_DE.html#DOIF_aggregation

Die kenne ich, helfen mir aber glaube ich nicht weiter.
Für die Lösung meiner Probleme habe ich jetzt aber ein paar Ansätze.

Danke für die Tips.


Grüße Sidey
Signalduino, Homematic, Raspberry Pi, Mysensors, MQTT, Alexa, Docker, AlexaFhem

Maintainer von: SIGNALduino, fhem-docker, alexa-fhem-docker, fhempy-docker

Damian

setstate ist ein FHEM-Befehl. Auf FHEM-Befehle würde ich im Perlmodus konsequent komplett verzichten und nur noch mit Perlfunktionen hantieren. Um nicht umständlich mit $hash readingsSingleUpdate zu nutzen, habe ich die Perlfunktion set_Reading definiert, die in readingsSingleUpdate intern gewandelt wird.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF