DOIF zur Heizungssteuerung funktioniert nicht mehr

Begonnen von holgerschlegel, 01 Oktober 2018, 08:58:10

Vorheriges Thema - Nächstes Thema

holgerschlegel

Hallo,

ich verwende ein DOIF mit ein paar Perl Funktionen um meine (Homematic) Raumthermostate manuell aus FHEM zu steuern wenn ich Urlaub habe.
Das ganze hat im letzten Winter - das war der letzte Zeitpunkt an dem diese Steuerung notwendig und das Ergebnis bemerkbar war - auch perfekt funktioniert.

Jetzt funktioniert das aber nicht mehr. Dem Log nach, wird löst das DOIF nicht mehr immer aus.
Weder das DOIF noch die Perl Funktionen wurden seit dem letzten Winter verändert.


So sieht das DOIF in der fhem.cfg Datei aus.
define di_AzThermostatAuto DOIF ([Tagmodus] or [({getHeatingNextSwitchTime('Az.Thermostat')})] or [Az.Thermostat.WindowRec])\
({ applyHeatingProgramToDevice('Az.Thermostat') })
attr di_AzThermostatAuto do always
attr di_AzThermostatAuto room 9_Skripte


Tagmodus ist ein Dummy welches entweder entweder den Wert '1_Arbeit' oder '2_Frei' hat. Ein AT der jeden morgen um 01:00 ausgeführt wird, setzt das Dummy abhängig von Wochentag und Urlaub/Feiertag.
Die Perl-Funktion getHeatingNextSwitchTime ermittelt den nächsten (bezogen auf die aktuelle Uhrzeit) Schaltzeitpunkt aus dem Heizprogramm des angegebenen Raumthermostaten. Genauer aus dem Register 'R_P1_0_tempListSat' des entsprechenden Climate Channels.
Die Perl-Funktion applyHeatingProgramToDevice steuert schlussendlich das Wandthermostat. Je nach Tagmodus und Wochentag wird das Thermostat entweder auf Automatik, oder auf Manuell mit Zieltemperatur aus der oben genannten TempList gesetzt.


In der Log-Datei des Raumthermostat kann ich sehen, das dieser heute Nacht um 01:00 Uhr auf Manuell mit 17.0 Grab gesetzt wurde. Zu dem Zeit hat sich das Dummy Tagmodus geändert und das DOIF daher ausgelöst. Soweit korrekt.
Laut TempList hätte getHeatingNextSwitchTime zu dem Zeit als Uhrzeit 07:00 liefern müssen. Die Funktion enthält leider keine Log-Ausgabe an der ich deren Aufruf ablesen kann. Wenn ich sie jetzt aufrufe, liefert sie aber die korrekte Zeit des nächsten Schaltzeitpunktes.

In der Log-Datei ist aber zu sehen, das die Steuerung des Raumthermostat um 07:00 Uhr nicht ausgeführt wurde. Zu der Zeit hätte die Zieltemperatur auf 21.0 Grad gestellt werden sollen. Hätte sollen, wurde aber nicht.
Es gibt im DOIF ein Reading 'timer_01_c01' welches den nächsten Schaltzeitpunkt enthält. Dort steht heute 21:30 Uhr, was für jetzt (nach 07:00) korrekt ist.

Wie bereits geschrieben, habe ich seit dem letzten Winter (in dem das ganze korrekt funktioniert hat) weder das DOIF noch die Perl Funktionen geändert.
Allerdings habe ich (natürlich) FHEM Updates eingespielt.
Daher versteht ich nicht warum das ganze heute nicht mehr funktioniert.


Jetzt habe gerade in der CommandReference zu DOIF das Attribut 'checkall' gefunden. Soweit ich mich erinnern kann gab es das Attribut vor einem Jahr noch nicht.
Wenn ich dem Befehl 'set di_AzThermostatAuto checkall' ausführe, wird die Steuerfunktion ausgeführt und der Raumthermostat korrekt gesetzt. (Kann es sein, das es den Befehl vor einem Jahr auch noch nicht gab?)

Kann ein verändertes Standardverhalten von DOIF die Ursache sein? Würde es helfen das Attribut 'checkall' auf 'all' zu setzen?

Ich weiß, viel Text. Aber vielleicht hat ja trotzdem jemand eine Idee dazu.

Grüße
Holger

Damian

Das Problem wird vermutlich sein, dass DOIF seit einiger Zeit nur noch einmal am Tag bei absoluten Zeitangaben schaltet, um vermeintliche Wiederholungen zu unterdrücken.

Du müsstest deine Funktion auf relative Zeitangaben [+...] umstellen, die können mehrfach am Tag schalten.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

holgerschlegel

Wo in der CommandReference steht das? Irgendwie finde ich dort keinen entsprechenden Hinweis.

Davon abgesehen:
Da ich die Schaltzeiten direkt aus der TempList auslese, möchte ich die eigentlich nicht noch auf relative Zeitangaben umrechnen.

Kann man dem DOIF (z.B. über ein Attribut) sagen das er das ganze mehrfach am Tag ausführen darf/soll? Also quasi das alte Verhalten wieder aktivieren.

Damian

Zitat von: holgerschlegel am 01 Oktober 2018, 09:53:24
Wo in der CommandReference steht das? Irgendwie finde ich dort keinen entsprechenden Hinweis.

Davon abgesehen:
Da ich die Schaltzeiten direkt aus der TempList auslese, möchte ich die eigentlich nicht noch auf relative Zeitangaben umrechnen.

Kann man dem DOIF (z.B. über ein Attribut) sagen das er das ganze mehrfach am Tag ausführen darf/soll? Also quasi das alte Verhalten wieder aktivieren.

Leider nicht. Das vermeintliche doppelte Schalten bei absoluten Zeiten kann man als Bug ansehen, der jetzt korrigiert ist.

Deine Lösung könnte aber so aussehen:

...[+({getHeatingNextSwitchTime('Az.Thermostat')}-{"$hm"})]) (...

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per

Zitat von: holgerschlegel am 01 Oktober 2018, 08:58:10
define di_AzThermostatAuto DOIF ([Tagmodus] or [({getHeatingNextSwitchTime('Az.Thermostat')})] or [Az.Thermostat.WindowRec])\
({ applyHeatingProgramToDevice('Az.Thermostat') })
attr di_AzThermostatAuto do always
attr di_AzThermostatAuto room 9_Skripte

muss hier
[Az.Thermostat.WindowRec]) xxx ({ applyHeatingProgramToDevice('Az.Thermostat') })
nicht noch was dazwischen?

holgerschlegel

Ich habe das mit dem

Zitat...[+({getHeatingNextSwitchTime('Az.Thermostat')}-{"$hm"})]) (...

mal mit einem Test-DOIF probiert.

Das Timer-Reading zeigt dann die folgenden Fehlermeldung an:
Zitaterror: the function ""$hm"" must return a timespec and not Global symbol "$hm" requires explicit package name at (eval 2813) line 1.

Wenn ich das "$hm" durch strftime("%H:%M", localtime) ersetze, funktioniert es. Aber leider nur wenn die von der Funktion gelieferte Uhrzeit später als die aktuelle Uhrzeit liegt.
Es kommt aber je jeden Tag einmal vor,  das der nächste Schaltzeitpunkt erst am nächsten Tag liegt - und damit rein von der Uhrzeit her vor der aktuellen Uhrzeit.
(Wenn die Funktion um 23:00 aufgerufen wird, liefert sie z.B. "06:00" zurück. Was dann zu der Fehlermeldung führt, das ein negatives Offset nicht erlaubt ist.