Wie mach ich das mit modifyTimeSpec richtig ?

Begonnen von TomLee, 25 Februar 2023, 11:48:36

Vorheriges Thema - Nächstes Thema

TomLee

Hallo,

gegegen ist ein von Rudi hier vorgeschlagenes at, welches ich leicht angepasst habe.

defmod at_goertztest at *11:35:00 {\
  HttpUtils_NonblockingGet({\
    url=>'https://www.google.com/search?q=B%C3%A4cker+G%C3%B6rtz+GmbH%2C+Wormser+Landstra%C3%9Fe%2C+Speyer',\
    callback=>sub($$$){\
      return readingsSingleUpdate($defs{'0000026c4e813b12'}, "open_times", "Fehler: $_[1]", 1) if($_[1]);;\
      my $ret = Encode::encode("UTF-8", Encode::decode("ISO-LATIN-1", $_[2]));;\
      $ret =~ m,.*ffnungszeiten<.*?: <span><span.*?>(.*?)</span>,s;;\
  my $v= $1;;\
  #Debug $v;;\
  $v =~ s/.⋅../\n/g;;\
  #Debug $v;;\
      #readingsSingleUpdate($defs{'0000026c4e813b12'}, "open_times", "$v", 1);;\
  readingsSingleUpdate($defs{'0000026c4e813b12'}, "open_times", "12:00", 1);;\
    }\
  });;\
    #system('/opt/fhem/www/scripts/epaper/tmp/epap_goertz.sh &');;\
  my $t = ReadingsVal('0000026c4e813b12','next_time','00:00:00');;\
  return fhem("sleep 5;;set at_goertztest modifyTimeSpec ".$t);;\
}


Die Öffnungszeiten schreibe ich erst mal zum_testen/zur Sicherheit in ein anderes Device (eigentlich hätte ich die gerne in dem at).
Das setreading der ausgelesenen Öffnungszeiten hab ich auskommentiert, weil ich zum testen/nachvollziehen mit execNow fix vorgegebene Zeiten (readingsSingleUpdate($defs{'0000026c4e813b12'}, "open_times", "12:00", 1);;\) verwende.
Das sleep 5 ist auch nur zum Test, um sicher zu sein das das Reading auch 100 % schon geschrieben ist.

Mit Hilfe eines userreadings hol ich mir aus dem Text der "Öffnungszeiten" die Zeit (next_time), die ich mit modifyTimeSpec verwenden möchte:

defmod 0000026c4e813b12 RSS png 192.168.188.26 ./FHEM/0000026c4e813b12.layout
attr 0000026c4e813b12 alias rss_goertz
attr 0000026c4e813b12 comment wget http://bla:bla@bla:8083/fhem/rss/0000026c4e813b12.png\
convert -rotate 90  0000026c4e813b12.png 0000026c4e813b12.png
attr 0000026c4e813b12 size 296x128
attr 0000026c4e813b12 userReadings next_time {ReadingsVal($name,'open_times','na')=~m/(\d\d:\d\d)/g ? timeAdd($1,-1500) : ''}


Das modifyTimeSpec greift aber immer nur bei jedem zweiten ausführen von execNow und ich komm bisher einfach in der Sache nicht weiter/sehe den Grund dafür nicht.
Versteht mich jemand und kann mir bitte zeigen wie man das richtig umsetzt ?

Gruß

Thomas

rudolfkoenig

ZitatVersteht mich jemand und kann mir bitte zeigen wie man das richtig umsetzt ?
Dazu muesste man wissen, wozu modifyTimestamp dienen soll.

Ansonsten:
- modifyTimestamp wuerde ich im callback, ohne sleep aufrufen. Ausserhalb vom callback ist nicht sichergestellt, dass die 5 Sekunden reichen.
- at wird nicht von einem Event aufgerufen, das Verlagern der Berechnung in andere Geraete ist sinnfrei.
- falls ich was nicht verstehe, dann fuege ich solange Log Ausgaben mit den verwendeten Werten in den Code ein, bis die Sache klarer wird. HIer ist mir z.Bsp. nicht klar, mit welchen Werten wann modifyTimeSpec aufgerufen wird.
- in der Regexp Pruefung (=~ m/(\d\d:\d\d)/g) ist das g modifier meiner Ansicht nach sinnfrei.

TomLee

#2
ZitatDazu muesste man wissen, wozu modifyTimestamp dienen soll.

Das at soll am Ende zu der Zeit, die ausgelesen wird, wieder ausgeführt werden +/- (das ist mir noch nicht ganz klar  ::), denke eher kurz danach ist sinnvoll, nicht 25 Minuten vorher )
Ich möchte mal testen wie lange die Batterien eines Displays halten, wenn mehrfach am Tag eine Aktualisierung statfindet (das teste ich nicht mit den Öffnungszeiten von Görtz).

Die aufgeführten Punkte geh ich später durch, jetzt bin ich kurz einkaufen.

TomLee

#3
ZitatDie aufgeführten Punkte geh ich später durch ...

Danke, alle genannten Punkte hab ich angepasst, mit der Angabe in dem callback klappt das dann auch wie ich mir das vorgestellt hatte:


defmod at_goertztest at *17:00:30 {\
  HttpUtils_NonblockingGet({\
    url=>'https://www.google.com/search?q=B%C3%A4cker+G%C3%B6rtz+GmbH%2C+Wormser+Landstra%C3%9Fe%2C+Speyer',\
    callback=>sub($$$){\
      return readingsSingleUpdate($defs{$SELF}, "open_times", "Fehler: $_[1]", 1) if($_[1]);;\
      my $ret = Encode::encode("UTF-8", Encode::decode("ISO-LATIN-1", $_[2]));;\
      $ret =~ m,.*ffnungszeiten<.*?: <span><span.*?>(.*?)</span>,s;;\
  my $v= $1;;\
  $v =~ s/.⋅../\n/g;;\
  readingsSingleUpdate($defs{$SELF}, "open_times", $v, 1);;\
  my $t = ReadingsVal($SELF,'next_time','00:00:00');;\
  fhem("set at_goertztest modifyTimeSpec ".$t);;\
  system('/opt/fhem/www/scripts/epaper/tmp/epap_goertz.sh &');;\
    }\
  });;\
}
attr at_goertztest userReadings next_time {ReadingsVal($name,'open_times','na')=~m/(\d\d:\d\d)/ ? timeAdd($1,+30) : '00:00:15'}

setstate at_goertztest Next: 17:00:30
setstate at_goertztest 2023-02-25 14:51:28 next_time 17:00:30
setstate at_goertztest 2023-02-25 14:51:28 open_times Geöffnet\
Schließt um 17:00
setstate at_goertztest 2023-02-25 14:51:28 state Next: 17:00:30


Wo ich immer noch nicht durchblicke ist die Angabe eines triggers bei dem userreadings.
mit next_time:open_times.* löst das userreadings einfach nicht aus ?

rudolfkoenig

ZitatDas at soll am Ende zu der Zeit, die ausgelesen wird, wieder ausgeführt werden [...]
Ok, gelesen habe ich es, das wozu aber immer noch nicht verstanden.

Zitatmit next_time:open_times.* löst das userreadings einfach nicht aus ?
Ich kann das Problem nicht nachstellen:
fhem> define d dummy
fhem> attr d userReadings next_time:open_times.* { "Event: $event" }
fhem> setreading d open_times TestMe
fhem> l d next_time
d                    2023-02-26 10:15:35    Event: open_times: TestMe

TomLee

#5
ZitatOk, gelesen habe ich es, das wozu aber immer noch nicht verstanden.

Hmm, das auf dem Display halt immer die nächste Öffnungs/Schließungszeit dargestellt wird ?
(In dem Screenshot steht 17 Uhr weil ich eine andere Görtz-Filale im RSS darstelle, Speyer ist bloss für hier im Forum)


ZitatIch kann das Problem nicht nachstellen:

Dann probiers doch bitte mal mit der at-Definition:

defmod at_goertztest at *18:00:30 {\
  HttpUtils_NonblockingGet({\
    url=>'https://www.google.com/search?q=B%C3%A4cker+G%C3%B6rtz+GmbH%2C+Wormser+Landstra%C3%9Fe%2C+Speyer',\
    callback=>sub($$$){\
      return readingsSingleUpdate($defs{$SELF}, "open_times", "Fehler: $_[1]", 1) if($_[1]);;\
      my $ret = Encode::encode("UTF-8", Encode::decode("ISO-LATIN-1", $_[2]));;\
      $ret =~ m,.*ffnungszeiten<.*?: <span><span.*?>(.*?)</span>,s;;\
  #Debug $v;;\
  $v =~ s/.⋅../\n/g;;\
  readingsSingleUpdate($defs{$SELF}, "open_times", $v, 1);;\
  my $t = ReadingsVal($SELF,'next_time','00:00:15');;\
  fhem("set at_goertztest modifyTimeSpec ".$t);;\
  #system('/opt/fhem/www/scripts/epaper/tmp/epap.sh 0000026dd28c3b1b.png &');;   \
    }\
  })\
}
attr at_goertztest userReadings next_time {ReadingsVal($name,'open_times','na')=~m/(\d\d:\d\d)/ ? timeAdd($1,+30) : '00:00:15'}

rudolfkoenig

Nachdem ich die offensichtlichen Probleme behoben habe (my $v = $1;, timeAdd() definiert) funktioniert das ohne Fehler.

TomLee

Zitat(my $v = $1;, timeAdd() definiert)
Sry deswegen.

Ich will nicht nerven, aber bei mir klappt es nicht, sobald ich den trigger mit rein nehme wird das userreadings nicht mehr geschrieben, sieht man hier auch am Zeitstempel von next_time:
defmod at_goertztest at *18:00:30 {\
  HttpUtils_NonblockingGet({\
    url=>'https://www.google.com/search?q=B%C3%A4cker+G%C3%B6rtz+GmbH%2C+Wormser+Landstra%C3%9Fe%2C+Speyer',\
    callback=>sub($$$){\
      return readingsSingleUpdate($defs{$SELF}, "open_times", "Fehler: $_[1]", 1) if($_[1]);;\
      my $ret = Encode::encode("UTF-8", Encode::decode("ISO-LATIN-1", $_[2]));;\
      $ret =~ m,.*ffnungszeiten<.*?: <span><span.*?>(.*?)</span>,s;;\
  my $v= $1;;\
  #Debug $v;;\
  $v =~ s/.⋅../\n/g;;\
  readingsSingleUpdate($defs{$SELF}, "open_times", $v, 1);;\
  my $t = ReadingsVal($SELF,'next_time','00:00:15');;\
  fhem("set at_goertztest modifyTimeSpec ".$t);;\
  #system('/opt/fhem/www/scripts/epaper/tmp/epap.sh 0000026dd28c3b1b.png &');;   \
    }\
  })\
}
attr at_goertztest userReadings next_time:open_times.* {ReadingsVal($name,'open_times','na')=~m/(\d\d:\d\d)/ ? timeAdd($1,+30) : '00:00:15'}

setstate at_goertztest Next: 18:00:30
setstate at_goertztest 2023-02-26 11:04:24 next_time 18:00:30
setstate at_goertztest 2023-02-26 11:05:07 open_times Geöffnet\
Schließt um 18:00
setstate at_goertztest 2023-02-26 11:05:07 state Next: 18:00:30

rudolfkoenig

Ich bleibe bei meinem Vorschlag:
Zitat- falls ich was nicht verstehe, dann fuege ich solange Log Ausgaben mit den verwendeten Werten in den Code ein, bis die Sache klarer wird. [...]

TomLee

Zitat- falls ich was nicht verstehe, dann fuege ich solange Log Ausgaben mit den verwendeten Werten in den Code ein, bis die Sache klarer wird. [...]

Ich versuchs noch einmal anders, weil wo ich jetzt Log-Ausgaben einbauen soll wo doch alles klappt, nur das mit dem trigger nicht, versteh ich nicht.

Das steht bei mir im Event-Monitor bei einem execNow in dem zuletzt gezeigten at, mit und ohne trigger:

2023-02-26 11:24:12 at at_goertztest execNow #mit trigger next_time:open_times.*
2023-02-26 11:24:13 at at_goertztest open_times: Geöffnet Schließt um 18:00

2023-02-26 11:25:22 at at_goertztest execNow #ohne trigger
2023-02-26 11:25:23 at at_goertztest open_times: Geöffnet Schließt um 18:00
2023-02-26 11:25:23 at at_goertztest next_time: 18:00:30


Ich kann es nicht glauben das es bei dir funzt mit trigger, ich möchte ausschliessen das wir nicht doch irgendwie aneinander vorbeireden, zeig mir bitte mal ein Raw (das aus dem letzten Beispiel, mit trigger) das bei dir klappt, dessen Zeitstempel der Readings zeigen das der trigger bei dir greift.

rudolfkoenig

ZitatIch kann es nicht glauben das es bei dir funzt mit trigger [...] zeig mir bitte mal ein Raw
Klingt nach Erpressung.


Definition:
defmod at_goertztest at *16:00 {\
  HttpUtils_NonblockingGet({\
    url=>'https://www.google.com/search?q=B%C3%A4cker+G%C3%B6rtz+GmbH%2C+Wormser+Landstra%C3%9Fe%2C+Speyer',\
    callback=>sub($$$){\
      return readingsSingleUpdate($defs{$SELF}, "open_times", "Fehler: $_[1]", 1) if($_[1]);;\
      my $ret = Encode::encode("UTF-8", Encode::decode("ISO-LATIN-1", $_[2]));;\
      $ret =~ m,.*ffnungszeiten<.*?: <span><span.*?>(.*?)</span>,s;;\
      my $v = $1;;\
      $v =~ s/.⋅../\n/g;;\
      readingsSingleUpdate($defs{$SELF}, "open_times", $v, 1);;\
      my $t = ReadingsVal($SELF,'next_time','00:00:15');;\
      fhem("set at_goertztest modifyTimeSpec ".$t);;\
    }\
  })\
}
attr at_goertztest userReadings next_time {ReadingsVal($name,'open_times','na')=~m/(\d\d:\d\d)/ ? timeAdd($1,30) : '00:00:15'}


Im telnet:

fhem> info timer
fhem> l at_goertztest STATE
at_goertztest            Next: 16:00:00
fhem> set at_goertztest execNow
2023-02-26 12:44:55 at at_goertztest execNow
2023-02-26 12:44:56 at at_goertztest open_times: Geöffnet
Schließt um 18:00
2023-02-26 12:44:56 at at_goertztest next_time: 18:00:30
2023-02-26 12:44:56 at at_goertztest Next: 18:00:30
2023-02-26 12:44:56 at at_goertztest next_time: 18:00:30
fhem> l at_goertztest STATE
at_goertztest            Next: 18:00:30

TomLee

ZitatKlingt nach Erpressung.

War aber nicht so gemeint.
Die Frage nach dem Raw war aber, wie man jetzt sieht, berechtigt, du hast gar keinen trigger in dem userreadings angegeben ???

rudolfkoenig

ZitatDie Frage nach dem Raw war aber, wie man jetzt sieht, berechtigt, du hast gar keinen trigger in dem userreadings angegeben ???
In der Tat.
open_times.* als trigger funktioniert in userReadings nicht, weil es da per /^$trigger$/ geprueft wird, und . kein \n matcht.
Abhilfe ist z.Bsp. open_times.*\n.*

TomLee

Zitat... kein \n matcht.

Danke dir wieder mal für die Geduld  ;D, der Erläuterung und der fertigen Lösung des "Problems".