Probleme mit $hour in Funktion

Begonnen von CoolTux, 19 Januar 2018, 17:16:21

Vorheriges Thema - Nächstes Thema

CoolTux

Hallo Rudi,

Es gab vor kurzem einen User der Probleme mit $hour in einem Notify hate.
Ich habe aktuell das selbe Problem in einer Funktion von mir. $hour wird falsch ausgegeben.

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time());

sub wakeUpHeating() {
    printf "\n\nWakeUp in der Heizfunktion - Stunde ist: $hour\n\n";
    if (ReadingsVal( "AnniKraussStr", "residentsTotalWakeup", 0 ) < 2 and Value( "AnniKraussStr" ) eq "asleep" and Value( "setTemperaturTemplateDummy" ) ne "Sommer"
        and Value( "setTemperaturTemplateDummy" ) ne "HeizungAUS" and $hour < 6 ) {
        printf "\n\nWakeUp Heizen JA - Stunde ist: $hour\n\n";
        fhem "set (WandThermostatWohnzimmer_Climate|HeizungsThermostatBadezimmer_Clima):FILTER=desired-temp!=6:FILTER=measured-temp<20.0 desired-temp 20.0";
    }
}


Heute morgen um 5 Uhr sprang die Heizung nicht an, aber dafür um 10 Uhr. Anbei mal ein Auszug meines logs

2018.01.19 10:00:01 3: (Sub systemCommand - notifyFirewall_IsabelHandy) - Zugriff verboten für notifyFirewall_IsabelHandy
2018.01.19 10:00:01 3: (Sub systemCommand_Done - notifyFirewall_IsabelHandy) - Abschluss vom Systemkommandoaufruf im nonBlocking Mode. Auswertungsteil beginnt.
2018.01.19 10:08:38 3: UWZ Unwetterzentrale: Run.1049 Done fetching data
2018.01.19 10:38:38 3: UWZ Unwetterzentrale: Run.1049 Done fetching data
2018.01.19 11:00:00 3: Macro_rr_Nadin_wakeuptimer1: Wake-up program started for rr_Nadin with target time 12:00


WakeUp in der Heizfunktion - Stunde ist: 5



WakeUp Heizen JA - Stunde ist: 5

2018.01.19 11:00:00 3: CUL_HM set HeizungsThermostatBadezimmer_Clima desired-temp 20.0
2018.01.19 11:00:00 3: CUL_HM set WandThermostatWohnzimmer_Climate desired-temp 20.0
2018.01.19 11:08:38 3: UWZ Unwetterzentrale: Run.1049 Done fetching data
2018.01.19 11:38:38 3: UWZ Unwetterzentrale: Run.1049 Done fetching data


Was kann ich tun um Dich/uns bei der Fehlersuche zu unterstützen?



Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

JoWiemann

Hm, ich kenne den Aufruf nur mit: localtime(time) und nicht mit localtime(time())

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

CoolTux

Beides sind ja Funktionen. Man ruft also eine Funktion in einer zweiten auf. Übergeben werden aber keine Parameter bei beiden aufrufen, daher ()
Der Aufruf an sich funktioniert ja. Zu mindest bekomme ich eine vernünftige Ausgabe.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

rudolfkoenig

printf koennte auch Schuld an deinem Problem sein, weil es potentiell nicht geflusht wird, und ueber einen separaten Puffer (STDIN) zwischengespeichert wird  (gibts fuer flush eine "richtige" deutsche Uebersetzung? Spuelen hoert sich komisch an).
Im FHEM-Kontext wuerde ich immer Log verwenden, auch weil es im Event-Monitor oder notify verwendbar ist.
Sonst solltest du time() ausgeben und nochmal localtime, ohne Argument (default ist die aktuelle Uhrzeit), in etwa so:
Log 1, localtime()."/".time();

betateilchen

Zitat von: rudolfkoenig am 19 Januar 2018, 20:12:04
(gibts fuer flush eine "richtige" deutsche Uebersetzung? Spuelen hoert sich komisch an).

Kommt auf den Kontext an. Im Bereich Software/Programmierung passt meistens "leeren" am Besten.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

CoolTux

Danke Rudi. Baue ich gleich ein und schaue morgen.
Printf wäre dann aber ja nur ein Anzeigefehler wenn da was ist, erklärt aber immer noch nicht wieso er um 11 Uhr schaltet obwohl $hour < 6 als Bedingung steht.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

CoolTux

Guten Morgen Rudi,

Hier einmal meine heutige Logausgabe

2018.01.20 06:00:00 3: Macro_rr_Marko_wakeuptimer1: Wake-up program started for rr_Marko with target time 07:00
2018.01.20 06:00:00 1: WakeUp - Stunde ist: 5
2018.01.20 06:00:00 1: Sat Jan 20 06:00:00 2018/1516424400.06751



Localtime sagt es ist Stunde 6 aber meine $hour Variable sagt es ist 5, und time sagt Realzeit: 20.01.2018 - 06:00:00. Also auch Stunde 6.

Falls es relevant ist hier meine 99_myUtils_HeatingControl.pm

##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;

use strict;
use warnings;
use POSIX;

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time());


sub myUtils_HeatingControl_Initialize($$) {

  my ($hash) = @_;

}



##########################################################
##########################################################
sub wakeUpHeating() {

    Log 1, localtime()."WakeUp - Stunde ist: $hour";
    Log 1, localtime()."/".time();
   
    if (ReadingsVal( "AnniKraussStr", "residentsTotalWakeup", 0 ) < 2 and Value( "AnniKraussStr" ) eq "asleep" and Value( "setTemperaturTemplateDummy" ) ne "Sommer"
        and Value( "setTemperaturTemplateDummy" ) ne "HeizungAUS" and $hour < 6 ) {
       
        Log 1, localtime()."WakeUp Heizen JA - Stunde ist: $hour";
        Log 1, localtime()."/".time();
       
        fhem "set (WandThermostatWohnzimmer_Climate|HeizungsThermostatBadezimmer_Clima):FILTER=desired-temp!=6:FILTER=measured-temp<20.0 desired-temp 20.0";
    }
}


Es sind noch 6 weitere Funktionen in der Datei drin, denke aber mal nicht das dies Relevants hat.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

betateilchen

Spontan würde ich sagen, Du füllst die Zeitvariablen zum falschen Zeitpunkt.
Die Variablen werden einmalig in dem Moment gefüllt, wenn die 99_...Utils.pm geladen wird, danach werden die Variablen aber nicht mehr aktualisiert.

Pack doch mal das

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time());

direkt in die Funktion, in der Du die Daten zur Ausführungszeit brauchst.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

ZitatSpontan würde ich sagen, Du füllst die Zeitvariablen zum falschen Zeitpunkt.
Meinst mich mit "Du"? :) Mit
define at3 at +*00:01 { Log 1, "$hour $min $sec" }
attr at3 alignTime 00:00

habe ich gerade auch 3 mal "XX XX 59" beobachtet innerhalb einer Stunde in 4 parallel laufenden FHEMs. Meine aktuelle Hypothese ist, das unter Linux time() und gettimeofday() nicht synchron sind. Bevor ich was aendere, will ich die Bestaetigung per debug, das Problem will nach dem Einbau des Debug-Codes aber nicht auftreten.
perldoc Time::HiRes verwirrt mich auch noch mit "Notice that the core "time()" maybe rounding rather than truncating.", das passt wiederum nicht zum Phaenomen.

betateilchen

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Zitat von: rudolfkoenig am 20 Januar 2018, 18:30:58
Meine aktuelle Hypothese ist, das unter Linux time() und gettimeofday() nicht synchron sind.

Das ist aber keine neue Erkenntnis.

Zitatgettimeofday() and time() should only be used to get the current time if the current wall-clock time is actually what you want. They should never be used to measure time or schedule an event X time into the future.

Daran nützt auch die Verwendung von Time::Hires vermutlich nichts. Es gibt im Internet einige Diskussion zum Thema (teilweise schon mehrere Jahre alt)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

Das habe ich auch gelesen (Google scheint deterministisch zu sein), aber ich will keine Zetidifferenz messen, haette nur gerne, dass time(), nach gettimeofday() aufgerufen, nicht einen kleineren Wert zurueckliefert.
Bisher dachte ich, dass sowas nur bei einer Schaltsekunde passieren kann.

CoolTux

Zitat von: betateilchen am 20 Januar 2018, 18:07:33
Pack doch mal das

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time());

direkt in die Funktion, in der Du die Daten zur Ausführungszeit brauchst.

Kann ich gerne machen. Wollte ich aber eigentlich vermeiden da ich mehrere in unterschiedlichen Funktionen habe. Werde aber in den sauren Apfel beißen.

@Rudi
Kann ich Dir/Euch irgendwie behilflich sein?



Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

rudolfkoenig

Hab ihn. Folgendes
Zitat2018.01.20 20:34:00.001 1:  1516476840.00072/1516476840 APC:20:33:59 1516476839/1516476840.00104 20 33 59
wurde von
define at3 at +*00:01 { Log 1, "$data{APC} $hour $min $sec" }
attr at3 alignTime 00:00
produziet, wobei $data{APC} in AnalyzePerlCommand, direkt nach Berechnung von $hour mit
$data{APC} = " $data{HT} APC:$hms ".time()."/".gettimeofday();
gesetzt wurde, und $data{HT} in HandlTimeout direkt vor dem Aufruf der ausgefuehrten InternalTimer Funktion mit
$data{HT} = "$now/$tim";


Daraus folgere ich, dass time (und localtime ohne Argument) einen kleineren Wert zurueckliefert als das vorher aufgerufene gettimeofday, in meinem Fall war der Unterschied mehr als 0.00072s. Falls irgendwer dafuer eine Begruendung/Dokumentation findet, dann bin ich dankbar.

Ich habe jetzt time() in fhem.pl ueberall durch gettimeofday (bzw. int(gettimeofday())) ausgetauscht, und eingecheckt.

Es gab auch vor paar Tagen eine aehnliche (identische?) Meldung hier:
https://forum.fhem.de/index.php/topic,82848

rudolfkoenig

@CoolTux: btw: betateilchen hat Recht, und der aktuelle Fix wird dir nicht helfen, da geht es um Unterschiede in Millisekunden Bereich und nicht um 6 Stunden :)