set time als UTC oder Lokalzeit

Begonnen von Pseudex, 10 April 2019, 11:11:55

Vorheriges Thema - Nächstes Thema

Pseudex

Hi,

ich habe ein kleines Problem mit der receiveTime funktion auf der Arduino Seite.

Laut Mysensors.org sollte der Controller die Zeit nicht als UTC schicken, sondern als Local Time und die Konvertierung machen

ZitatFetching time from controller
Requests time from controller. Answer will be delivered to your receiveTime()-function function in sketch.

void requestTime();

void receiveTime(uint32_t ts);
ts - Time in seconds since 1970. Adjusted for timezone by controller.

Im Code von 10_MYSENSORS_DEVICE.pm kann ich aber nur das Senden als UTC finden
https://perldoc.perl.org/functions/time.html

    COMMAND_HANDLER: {
    $command eq "time" and do {
        sendClientMessage($hash, childId => 255, cmd => C_INTERNAL, ack => 0, subType => I_TIME, payload => time);
        last;
    };



Schön wäre, wenn ich beim set time befehl noch ein UTC oder Local mit geben könnte. Oder man ein Attribut am MY_SENSOR_DEVICE angeben kann, welche Zeit gesendet werden soll.

Beta-User

Hallo Pseudex,

da ich eh' wegen der SetExtensions grad an dem Modul rumschraube:
Kannst du mal testen, ob es klappt, wenn du
vor den beiden Sendebefehlen (ca. Zeilen 741 und 257) folgendes einfügst:
my $t = localtime(time);
und dann statt "time" "$t" versendest?

Generell neige ich dazu, das Verhalten entsprechend Spec zu machen, also "adjusted for timezone".

Wenn es da Bedarf geben sollte, das rückwärtskompatibel zu halten, würde ich dazu lieber jeder Node ein bool-Attribut spendieren wollen; m.E. macht es wenig Sinn, unter derselben Kennung unterschiedliche Informationen senden zu können. Aber wenn es mehr Wünsche in die Richtung geben sollte: dürfte auch nicht das Problem sein...

Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Pseudex

#2
sehr gut. ich habe nichts dagegen, dass immer die lokale zeit verschickt wird.
dein Code wird aber wahrscheinlich nicht funktionieren.

Es wird ein uint32 in den Sensor geschickt.
Time liefert einen uint32 in Sekunden seit 1970 (UTC).
Localtime liefert ein array oder string des Datums.

Ich habe mal ein Beispiel ausprobiert.

use Time::Local;

my $utctime = time;
my ($sec, $min, $hour, $day,$month,$year) = (localtime(time))[0,1,2,3,4,5];
my $localTime  = timegm($sec,$min,$hour,$day,$month,$year);
print "UTC:   $utctime\n";
print "LOCAL: $localTime\n";
my $diff = $localTime-$utctime;
print "Diff: $diff\n";
my $t = gmtime($utctime);
print "$t\n";
my $t = gmtime($localTime);
print "$t\n";


Hier wird nur das aktuelle lokale Datum in Sekunden umgewandelt.
Dabei muss aber use Time::Local; ins Modul.
Da bin ich mir aber sicher, ob man das evtl. installieren muss. Ich mache leider zu wenig mit perl.

my ($sec, $min, $hour, $day,$month,$year) = (localtime(time))[0,1,2,3,4,5];
my $localTime  = timegm($sec,$min,$hour,$day,$month,$year);


Ich hoffe die mögliche Lösung übersteht auch das Ende der Zeitumstellung die uns bald endlich bevorsteht!


Update:

Ich habe versucht meine Lösung einzubauen:
Hier die komplette Datei: https://kaiserflur.de/index.php/s/C2fm43eaH6WM5Rq

patch
69a70
> use Time::Local;
259c260,262
<         sendClientMessage($hash, childId => 255, cmd => C_INTERNAL, ack => 0, subType => I_TIME, payload => time);
---
> my ($sec, $min, $hour, $day,$month,$year) = (localtime(time))[0,1,2,3,4,5];
>         my $localTime  = timegm($sec,$min,$hour,$day,$month,$year);
>         sendClientMessage($hash, childId => 255, cmd => C_INTERNAL, ack => 0, subType => I_TIME, payload => $localTime);
725c728,730
<           sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_TIME, payload => time);
---
>           my ($sec, $min, $hour, $day,$month,$year) = (localtime(time))[0,1,2,3,4,5];
>           my $localTime  = timegm($sec,$min,$hour,$day,$month,$year);
>           sendClientMessage($hash,cmd => C_INTERNAL, childId => 255, subType => I_TIME, payload => $localTime);


Die geänderten Zeilen sind auch als Bilder angehangen.

Beta-User

#3
Danke für die Rückmeldung,

das mit dem Array wäre mir im Leben nicht aufgefallen :( .

In der lib gibt es auch eine Funktion, die z.B. vom WeekdayTimer genutzt wird:
use Time::Local 'timelocal_nocheck';
Der Beschreibung nach müßte das passen.

Hab's jetzt mal so eingebaut:
my $t = timelocal_nocheck(localtime(time));

Anbei mal meine modifizierte 10-er; da sind aber alle Änderungen drin, einschl. der SetExtensions- und heartbeat/state-Umstellung. Beim state iVm. den SetExtensions gibt es in der state-Darstellung noch eine Kleinigkeit, die ich mit Rudi klären muß, sonst ist das aber ein heißer update-Kandidat (wenn es mit der Zeit auch klappt).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Pseudex

danke für die Implementierung.
Leider bekomme ich mit dem Aufruf
my $t = timelocal_nocheck(localtime(time));
immer nur die UTC als Zeitstempel. Leider sind da auch online Konverter keine sehr große Hilfe. Ich habe es in Excel (SCALC) nachgebaut und es will einfach immer die UTC raus kommen.

wenn ich anstatt local gm bei der letzen Wandlung einsetze, kommt der richtige lokale Zeistempel raus
my $t = timegm_nocheck(localtime(time));

Das WeekdayTimer Modul habe ich mir auch angeschaut und die Umwandlung mal raus gezogen und in ein Perl test Skript gesteckt.
Hier kommt als uint32 auch nur UTC raus. Da aber nur intern damit gerechnet wird, ist das kein Problem und der Wert kann immer in die richtige Lokalzeit gewandelt werden.
Da der Arduino aber die Lokalzeit in Sekunden seit 1970 braucht, funktioniert das scheinbar nur mit der timegm Funktion.

Beta-User

Thx für den Hinweis, dann kommt jetzt also an den beiden betreffenden Stellen timegm_nocheck() zum Einsatz ;D .

Eigentlich irgendwie doof, dass man da so '"im Kreis herum" rechnen muß und es nichts direktes zu geben scheint...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files