Forum: PC-Programmierung Python, korrektes Speichern der aktuellen Zeit in Binärdatei


von Michael (Gast)


Lesenswert?

Hallo zusammen,

vielleicht kann mit jemand hier weiterhelfen, ich möchte eingehende 
UDP-Daten  (4Bytes je Minute) zusammen mit der aktuellen Systemzeit in 
eine Datei speichern. Aus dieser Datei sollen z.b. alle 3 Stunden die 
Einträge der letzten 2 Tage ausgelesen und dann grafisch als Bild 
angezeigt werden.

Hier habe ich das Problem, die Systemzeit wohl nicht korrekt in die 
Datei Speichern zu können. Bei den 4 Eingangsbytes gibt es das Problem 
nicht.

Dazu hier der Code, welcher die Zeit in die Datei speichern soll:
1
import time
2
import socket
3
import struct
4
port = 80
5
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
6
s.bind(("", port))
7
print ("waiting on port:", port)
8
is_negative = 0
9
temp = 0
10
temp_float = 1.0
11
datatype='ff'
12
while(1):
13
        
14
        data, addr = s.recvfrom(1024)
15
        temp=int.from_bytes(data, "big", signed=False)
16
        temp_float = temp/10.0
17
        wr=struct.pack('ff',time.time(),temp_float)
18
        print("Type of wr : " + str(type(wr)))
19
        print("wr: " + str(wr))
20
        print("Original value of time.time() : " + str(time.time()))
21
        print("Type of time.time() : " + str(type(time.time())))
22
        local=time.localtime(time.time())
23
        #print("Read entry[0].localtime : " + str(local))
24
        print("Decoded Time entry[0].localtime.asciitime: " + str(time.asctime(local)))
25
        f=open("tempdaten.bin","ab+")
26
        f.write(wr)
27
        f.close()
28
        print(str(temp_float))
29
        print()

Hier das gegenstück zum Auslesen:
1
import time
2
import struct
3
4
dataset = []                                #declare empty list
5
with open('tempdaten.bin', 'ab+') as f:
6
    print("A")
7
    pos=f.tell()                            #actual file position ist last
8
    #f.seek(pos-20)                         #get last 20 entrys
9
    i=3*8
10
    print("B")
11
    while i > 0:                            #20 times
12
        print("Round-NR : " + str(i))
13
        f.seek(pos-i)
14
        print("Actual last pos : " + str(pos))
15
        print("Actual adderssed pos : " + str(pos-i))
16
        entry = f.read(8)                   #read one entry
17
        print("Unpacked-Entry " + str(struct.unpack('ff',entry)))
18
        print("Read-Entry : " + str(entry))
19
        print("Length of Entry : " + str(len(entry)))
20
        print("Type of entry[0] : " + str(type(entry[0])))
21
        local=time.localtime(float(entry[0]))
22
        print("Read entry[0].localtime : " + str(local))
23
        print("Decoded Time entry[0].localtime.asciitime: " + str(time.asctime(local)))
24
        i = i - 8

Schaue ich mir nun die Debug-Ausgaben an, so bekomme ich beim Schreiben:
1
Type of wr : <class 'bytes'>
2
wr: b'iB\xc1N33\xafA'
3
Original value of time.time() : 1621177533.532084
4
Type of time.time() : <class 'float'>
5
Decoded Time entry[0].localtime.asciitime: Sun May 16 17:05:33 2021
6
21.9
7
8
Type of wr : <class 'bytes'>
9
wr: b'jB\xc1Nff\xaeA'
10
Original value of time.time() : 1621177544.1373923
11
Type of time.time() : <class 'float'>
12
Decoded Time entry[0].localtime.asciitime: Sun May 16 17:05:44 2021
13
21.8
14
15
Type of wr : <class 'bytes'>
16
wr: b'jB\xc1N33\xafA'
17
Original value of time.time() : 1621177554.720464
18
Type of time.time() : <class 'float'>
19
Decoded Time entry[0].localtime.asciitime: Sun May 16 17:05:54 2021
20
21.9

Beim Lesen:
1
Round-NR : 24
2
Actual last pos : 14480
3
Actual adderssed pos : 14456
4
Unpacked-Entry (1621177472.0, 21.899999618530273)
5
Read-Entry : b'iB\xc1N33\xafA'
6
Length of Entry : 8
7
Type of entry[0] : <class 'int'>
8
Read entry[0].localtime : time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=1, tm_min=1, tm_sec=45, tm_wday=3, tm_yday=1, tm_isdst=0)
9
Decoded Time entry[0].localtime.asciitime: Thu Jan  1 01:01:45 1970
10
Round-NR : 16
11
Actual last pos : 14480
12
Actual adderssed pos : 14464
13
Unpacked-Entry (1621177600.0, 21.799999237060547)
14
Read-Entry : b'jB\xc1Nff\xaeA'
15
Length of Entry : 8
16
Type of entry[0] : <class 'int'>
17
Read entry[0].localtime : time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=1, tm_min=1, tm_sec=46, tm_wday=3, tm_yday=1, tm_isdst=0)
18
Decoded Time entry[0].localtime.asciitime: Thu Jan  1 01:01:46 1970
19
Round-NR : 8
20
Actual last pos : 14480
21
Actual adderssed pos : 14472
22
Unpacked-Entry (1621177600.0, 21.899999618530273)
23
Read-Entry : b'jB\xc1N33\xafA'
24
Length of Entry : 8
25
Type of entry[0] : <class 'int'>
26
Read entry[0].localtime : time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=1, tm_min=1, tm_sec=46, tm_wday=3, tm_yday=1, tm_isdst=0)
27
Decoded Time entry[0].localtime.asciitime: Thu Jan  1 01:01:46 1970

Wie man sieht sind die gelsenen Bytes z.b. jB\xc1N33\xafA mit den 
geschriebenen identisch.
Im letzten Eintrag wird die Zeit: 1621177600.0 gelesen, jedoch war die 
wahre Sytemzeit: 1621177554.720464

Dies führt dazu, dass demnach Sun May 16 17:05:54 2021 geschrieben 
wurde, jedoch immer eine zeit zu Beginn der Computerzeit: Thu Jan  1 
01:01:46 1970
gelesen wird.

Zumindest denke ich dass es so ist.
Hat jeman vielleicht eine Idee, wie man das beheben kann, oder an was es 
sonst liegt?

Schöne Grüße,
Michael

: Verschoben durch Moderator
von Moskito (Gast)


Lesenswert?

Schreiben/Lesen ist nicht dein Problem, der Unix timestamp taucht ja 
beim Lesen wieder auf.

'entry' ist nicht das, was du erwartest (du unpackst nur für die eine 
Log-Ausgabe).
entry[0] ist deshalb das 'j' (ASCII 106).
Damit landest du 106 Sekunden (1 min 46 sec) nach Unix timestamp 0.

von Michael (Gast)


Lesenswert?

Moskito schrieb:
> Schreiben/Lesen ist nicht dein Problem, der Unix timestamp taucht ja
> beim Lesen wieder auf.
>
> 'entry' ist nicht das, was du erwartest (du unpackst nur für die eine
> Log-Ausgabe).
> entry[0] ist deshalb das 'j' (ASCII 106).
> Damit landest du 106 Sekunden (1 min 46 sec) nach Unix timestamp 0.

Vielen Dank für den Hinweis, nun kommen keine völlig falschen Zeiten 
mehr heraus.

Ein Problem besteht jedoch noch, es wird immer eine ganze Zahl an 
Einträgen mit zwar unterschiedlichen und korrekten 4Bytes, jedoch mit 
falschem (gruppiertem) Zeitstempel ausgelesen. Also haben z.b. 20 Werte 
eine identische Zeit, die nächsten 20 Werte wieder eine identische Zeit, 
in meinem aktuellen Fall mit 10Sec/Nachricht ca. 2Min später haben.

Hier sehe ich noch ein Problem mit der Wandlung/Packung der Zeit durch 
das Struct beim Schreiben.
Prinzipiell sind lese+schreibbytes identisch, jedoch sind die 
Eingabezeiten immer mit Nachkommastellen, die Ausgabezeiten immer mit 
xxxx.0 sozusagen abgeschnitten. Ich denke daher kommt das, werde ich mir 
morgen ansehen.
Oder, wenn jemand da mehr wüsste wäre das auch schon toll :)

Grüße,
Matthias

von Imonbln (Gast)


Lesenswert?

Michael schrieb:
> vielleicht kann mit jemand hier weiterhelfen, ich möchte eingehende
> UDP-Daten  (4Bytes je Minute) zusammen mit der aktuellen Systemzeit in
> eine Datei speichern. Aus dieser Datei sollen z.b. alle 3 Stunden die
> Einträge der letzten 2 Tage ausgelesen und dann grafisch als Bild
> angezeigt werden.

Auch wenn die Antwort, vielleicht ein wenig OT ist, warum willst du das 
selbst machen? Influxdb, ist genau für solche Einsätze erfunden worden 
und es gibt schöne Frontends um die Daten hübsch darzustellen. Grafana 
zum Beispiel (auch wenn das mit Kanonen auf Spatzen schießen ist, wenn 
es nur um diese Messreihe geht)

Im Besten fall musst du nur ein kleines Pythonscript schrieben, was die 
UDP Daten empfängt und an die Influxdb sendet, welche sich um den 
Zeitstempel und die passenden Bilder für dich kümmert.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.