• Willkommen im Forum „Wetterstationsforum.info - Archiv“.
 

Neuigkeiten:

Dieses Forum dient ausschließlich zu Archivzwecken.
Für Fragen nutze bitte unser aktuelles Forum, welches du unter https://wetterstationsforum.info findest.

Hauptmenü

TFA KlimaLogg Pro - Wie entschlüsselt man die Binärdaten in der \"0_history.dat\"?

Begonnen von alexis, 14.02.2016, 15:44:19

⏪ vorheriges - nächstes ⏩

alexis

Als Neuling hier (habe mich eben gerade erst angemeldet) erstmal ein Hallo an alle Forenmitglieder!

Kaum angemeldet und schon habe ich ein ziemlich kniffeliges Problem für das ich etwas länger ausholen muss. Der Hintergrund ist, dass ich mir kürzlich zwei KlimaLogg Pro gekauft habe von denen beide voll bestückt sind mit Temperatur-/Luftfeuchtigkeitsfühlern. Die Geräte und vor allen die Möglichkeiten, die sich bei der Datenauswertung ergeben begeistern mich sehr! Im Moment habe ich die Klimalogger so konfiguriert, dass mit einem Intervall von 1 Minute Daten aufgezeichnet werden.

Die Software für den KlimaLogg Pro speichert (bei Synchronisation) die Daten in der binären Datei "0_history.dat" bzw. bei mir auch in der "1_history.dat" für den zweiten Logger.

Da mir die Funktionalitäten der o. g. Software nicht ausreichen, möchte ich mir unter MS Access bzw. Excel (Office 2016 Plus) ein Programm für ganz spezielle Datenanalysen schreiben. Als ersten Schritt möchte ich hierfür mittels VBA-Programmierung die Möglichkeit schaffen auf die Daten der "0_history.dat" zuzugreifen und diese für die Weiterverarbeitung in MS Access (als eigene Tabelle) importieren. Sicherlich könnte man dies auch über die *.csv-Datei, die man theoretisch exportieren kann. Eleganter und langfristig nicht so zeitaufwendig wäre es direkt auf die Binärdaten zuzugreifen. Der (einfachere) Weg über die *.csv-Datei wäre meine Notlösung.

Mein Problem ist, dass ich es nach mehreren Stunden Tüftelarbeit nicht geschafft habe die Daten zu entschlüsseln und vielleicht hat sich ja einer von euch schonmal mit der Thematik beschäftigt und kann mir den entscheidenden Tipp geben.

Was ich (aus einem anderen Forenbeitrag) schon weiß ist, dass in der Binärdatei (0_history.dat) die einzelnen Messreihen direkt nacheinander abgelegt werden und kein "Header", etc. eingetragen ist. Eine Messreihe = alle Messwerte je Zeitintervall (1 min). Also

Zeitstempel
Temp (interner Sensor)
Luftfeuchtigkeit (interner Sensor)
Temp (Kanal 1)
Luftfeuchtigkeit (Kanal 1)
Temp (Kanal 2)
Luftfeuchtigkeit (Kanal 2)
...
...
...
Temp (Kanal 8)
Luftfeuchtigkeit (Kanal 8)

In meinem Fall erhalte ich für Kanal 7 + 8 keine Luftfeuchtigkeitswerte (oder nur Nullwerte), da ich einen Kabelfühler (ohne LF) angeschlossen habe.

Schaut man sich mit einem Hex-Editor die Daten in der "0_history.dat" an so sieht eine Messreihe beispielhaft so aus:

00530BD6 ED51F202 9A99A541 00005042
30333340 0000A642 3433A341 00005442
CCCC5441 00008A42 66668A41 00008242
00009041 00006C42 34339341 00007042
3433EF41 0000DC42 CCCCAC41 0000DC42
00000000

Wie ich in einem anderen Forumsbeitrag gelesen habe, hat die Messreihe insgesamt 84 Byte, die sich anscheinend wie folgt aufteilen:

Zeitstempel: 1x 8 Byte (im Beispiel oben also: 00530BD6 ED51F202)
je Messwert: 18x 4 Byte (im Beispiel oben also: 9A99A541 = Temp interner Sensor, LF interner Sensor = 00005042, --> weiter bis Kanal 8)
Schluss-Tag: 1x 4 Byte (im Beispiel oben also: 00000000)

Soweit so gut. An den beiden oben zu erkennenden identischen Werten "0000DC42" kann man auch die beiden Nullwerte für die LF auf Kanal 7 + 8 erkennen (= Kabelsensor ohne Luftfeuchtigkeit).

Meine Vorstellung wäre es nun in VBA diese Binärdaten in einer Schleife auszulesen, dabei auf die Einzelwerte zuzugreifen (1x 8 Byte + 18x 4 Byte), die Einzelwerte wieder in eine (verwendbare) Zeit bzw. Dezimalzahl umzuwandeln und in einer Access-Tabelle abzulegen. Das wäre die Theorie. Bei der Umsetzung in die Praxis hakt es bei mir, also konkret bei der Umwandlung des Hex-Wertes zu einer Dezimalzahl (= Messwert). Anscheinend sind die Binärdaten nach dem System "IEEE 754" codiert und ich weiß nicht wie man dies entschlüsseln kann. Leider gibt auch ein Online-Konverter nur unplausible Werte zurück, siehe z. B.

http://www.binaryconvert.com/index.html

so dass ich mir nicht sicher bin, ob es tatsächlich das System "IEEE 754" ist.

Weiß eventuell von euch jemand Rat, wie man konkret nach IEEE 754 die Daten entschlüsselt, eventuell mit den entsprechenden VBA-Befehlen? Wenn ich das mit euch hinkriegen würde, wäre der erste Schritt für mein Analyse-Tool getan.

Eventuell noch zur Info: Der Zeitstempel soll anscheinend ein numerischer Wert sein, der von einem definierten Startzeitpunkt (Beginn des julianischen Kalenders?) die Zeit in Sekunden (?) bis zum Realdatum angibt. Eine Umrechnung in das Date/Time-Format in MS Access müsste also möglich sein.

Ich habe mal eine "0_history.dat" als Testdatensatz angehängt. Vielen Dank schonmal für eure Unterstützung.

VG
alexis






Beiträge zusammengeführt, weil der Autor sich selbst geantwortet hat statt seinen letzten Beitrag zu ändern: 14.02.2016, 17:08:58

Hier mal noch ein Ansatz in VBA (Umrechnungs-Code, den ich im Netz gefunden habe):

Die Umrechnung scheint grundsätzlich zu funktionieren (im Vergleich mit den Online Konvertern im Netz). Jedoch ergeben die Hex-Werte in meiner 0_history.dat keine sinnvollen Werte, z. B.

"9A99A541" liefert -6,35463E-23

Das ist der dritte Hex-Wert in meinem Beispiel oben, also wohl für die Temperatur des internen Sensors. Erwartet hätte ich einen Wert, der z. B. "22,6" ist.

Wisst ihr wo das Problem ist?

Option Compare Database

Type MyHex
Lng As Long
End Type

Type MySingle
sng As Single
End Type

Sub HexToIEEE754Converter()

'Beispiel "9A99A541" liefert -6,35463E-23
Debug.Print HexToIEEE754("9A", "99", "A5", "41")

End Sub

Function HexToIEEE754(b1, b2, b3, b4)

Dim h As MyHex
Dim s As MySingle

h.Lng = Val("&H" & b1 & b2 & b3 & b4 & "&")
LSet s = h
HexToIEEE754 = s.sng

End Function


[gelöscht durch Administrator]

TheWeather

Hallo Alexis,

schau Dir auch mal diesen Beitrag an.

Um nochmal auf die 84 Byte einzugehen: Es sind 8 Byte, für das Datum (int64, Julianisches Datum, aber auf µsec aufgelöst), dann folgen für jeden Sensor 0 bis 8 jeweils 4 Byte für Temperatur und 4 Byte für Feuchte (jeweils im Format float), abschließend am Ende des Datensatzes jeweils 4 Byte, die aber immer "0x00" sind, zusammen also 84 Byte.

Da das Datum nach Umrechnung aus den 8 Byte als UTC vorliegt, musst Du zuguterletzt auch Zeitzone und ggfs. Winterzeit/Sommerzeit addieren, falls Du in die lokale Zeit umrechnen willst.

Gruß Hans 
2xTFA Nexus, Sinus, Duo, EOS Max, Klima-Logger, Mebus TE923

Die Titanic wurde von Profis gebaut, die Arche Noah von einem Amateur. ...

alexis

So, nach zahlreichen Stunden Programmierarbeit funktioniert es nun, dass ich die Daten der "0_history.dat" in MS Access importieren kann. Es war ganz schön kniffelig die Daten zu entschlüssel, aber jetzt passt es!

Falls es jemanden interessiert gebe ich mal ein paar Hinweise was zu beachten ist, wenn man die Sensordaten direkt aus der "0_history.dat" nutzen will:

Jeder in der "0_history.dat" eingetragene Datensatz hat 84 Byte. Der jüngste Datensatz (neuster Datensatz) steht unten am Ende der Binärdaten. Jeder Datensatz ist wie folgt aufgebaut:

Zeitstempel = Datentyp = Int64 (8 Byte, als 64 bit Ganzzahl)
Temp (interner Sensor) = Gleitkommazahl (4 Byte, nach IEEE754 codiert)
Luftfeuchtigkeit (interner Sensor)  = Gleitkommazahl (4 Byte, nach IEEE754 codiert)
Temp (Kanal 1)  = Gleitkommazahl (4 Byte, nach IEEE754 codiert)
Luftfeuchtigkeit (Kanal 1)  = Gleitkommazahl (4 Byte, nach IEEE754 codiert)
Temp (Kanal 2)  = Gleitkommazahl (4 Byte, nach IEEE754 codiert)
Luftfeuchtigkeit (Kanal 2)  = Gleitkommazahl (4 Byte, nach IEEE754 codiert)
... bis ...
Temp (Kanal 8)  = Gleitkommazahl (4 Byte, nach IEEE754 codiert)
Luftfeuchtigkeit (Kanal 8)  = Gleitkommazahl (4 Byte, nach IEEE754 codiert)
Schlussmarker= Nullwert (4 Byte, als Hex-Wert: "00000000")

Für die Int64 Ganzzahl des Zeitstempels gibt es in VBA den Datentyp "LongLong" (nur für 64 bit Systeme). Ansonsten reicht die Genauigkeit beim Verarbeiten dieses Zahlenwertes nicht aus.

Wofür ich recht lange gebraucht habe ist die Sache, dass man die Hexadezimalwerte rückwärts, also von rechts nach links (arabisch) einlesen muss, damit sie richtig verarbeitet werden können. Beispiel für Zeitstempel + Temp (interner Sensor) + LF (interner Sensor):

Darstellung im Hex-Editor:
00530BD6 ED51F202 9A99A541 00005042

erforderliche Umstellung für Verarbeitung:
Zeitstempel: 02F251EDD60B5300
Temp (interner Sensor): 41A5999A
LF (interner Sensor): 42500000

Dann die Sache mit dem Zeitstempel. Wandelt man den Zeitstempel in eine Ganzzahl um, so erhält man zum Beispiel einen Wert "212322852000000000". Dieser Beispielwert entspricht dem 21.02.2016 10:00:00 Uhr. Die Ganzzahl (Timestamp) ist die vergangene Zeit in µsec nach dem Julianischen Kalender (Startpunkt: 1. Januar 4713 v. Chr.). Um daraus eine in MS Access oder Excel verwertbare Zeit zu bekommen sind folgende Schritte notwendig:

Umwandlung µsec --> sec = 212322852000000000 / 1000000 = 212322852000
Umwandlung in Tage --> 212322852000 / 86400 = 2457440,41667

Access und auch Excel verwenden für Datums-/Zeitangaben nicht den Julianischen Kalender als Zeit-Bezugssystem, sondern die vergangene Zeit seit dem 1.1.1900 als Zahlenwert, z. B. 42421,41667 (21.02.2016 10:00:00 Uhr). Die Differenz zwischen den beiden Zeit-Bezugssystemen beträgt exakt 2415019 Tage, also für das obige Beispiel 2457440,41667 - 2415019 = 42421,41667.

Wenn man's weiß ist alles einfach. Aber das alles muss man erstmal verstehen und anschließend 'ne Möglichkeit finden die Sache in VBA umzusetzen. Danke an dich Hans, für den Link zum anderen Post. Die ganzen Beiträge haben mir geholfen auf die richtige Fährte zu kommen.

Falls Interesse besteht, kann ich meinen VBA-Quellcode zum Importieren der Messdaten in eine Access-DB hier bereitstellen. Als nächsten Schritt kann ich mich jetzt mit der Verarbeitung der Sensordaten in Access bzw. Excel beschäftigen. Damit kennen ich mich wieder besser aus als mit Binärdaten und Hexadezimalzahlen. Trotzdem ein interessanter Exkurs!

Viele Grüße
Martin

TheWeather

Hallo Martin,

:top: Respekt. Die bislang knappen Angaben hast Du präzisiert und sowohl treffend als auch richtig herausgefunden und im letzten Beitrag auch sehr anschaulich dokumentiert.

Da ich mich in VBA nicht auskenne, vielleicht noch eine kleine Frage (interessehalber) zur Umwandlung der 4-Byte-Hexwerte (Temperatur/Feuchte) in eine Gleitkommazahl (gemäß IEEE754):

Bei C++ (da bin ich eher zu Hause), kann man einen Datentyp union definieren, z.B. in der Form: union{
Byte B[4];
float Dezimalwert;
} BytesToFloat;


Dann liest man den Stream von 4 Hex-Werten über BytesToFloat.B[0] (Startbyte) ein und kann ihn über BytesToFloat.Dezimalwert direkt als gewandelten Gleitkommawert (gemäß IEEE754) wieder abholen - oder umgekehrt.

Gibt's das in VBA auch oder war's da (weil Du anscheinend mit der Reihenfolge LoByte/HighByte kämpfen musstest) komplizierter? Die Vorgabe LoByte->HighByte entspricht meines Wissens der beim 6502-Prozessor (einem der ersten industriell eingesetzten µCs überhaupt) von Motorola festgelegten Standard, Bytes in dieser Reihenfolge abzulegen. Dem hat sich auch die IEEE754 angeschlossen und deswegen ist das anscheinend bis heute auch Standard beblieben.

Auf jeden Fall hast Du das Vorgehen bestens beschrieben und damit dürfte für weitere Generationen, welche sich mit dem Thema noc h beschäftigen möchten, eine sehr gute Grundlage geschaffen.

Falls Du den VBA-Code veröffentlichen möchtest, gerne. Je nach Umfang kannst Du dazu eventuell auch die Funktion "#" "Code einfügen" hier im Forums-Editor verwenden, um die Lösung vorzustellen. Alles in Allem eine schöne Analyse, die anscheinend auch erfolgreich war.

Gruß Hans

P.S.: Was mir im Nachhinein eingefallen ist, ich hätte Dir auch einen Link hierhin schicken können. Unter "Programminternes" war das Thema (nicht so schön wie bei Dir) bezüglich des Zeitstempels schon mal behandelt. Sorry - habe ich nicht dran gedacht ... Es gab auch noch einen anderen Beitrag, der diesen "julianischen" Zeitstempel als Eigenschaft von Linux-Systemen beschrieben hat und wie man den in den z.B. bei Excel gebräuchlichen (oder den in MS-basierten, meist verwendeten) TimeStamp (auch DateTime) umrechnet - den habe ich aber leider nicht mehr gefunden - wahrscheinlich falsch gesucht - irgendwo im Forum gibt's den bestimmt noch ...
2xTFA Nexus, Sinus, Duo, EOS Max, Klima-Logger, Mebus TE923

Die Titanic wurde von Profis gebaut, die Arche Noah von einem Amateur. ...

alexis

Hallo Hans,

ja, diese Konvertierung nach IEEE754 hat mein Kopf auch etwas zum rauchen gebracht und mich Zeit gekostet. Ich wäre froh gewesen, wenn es in VBA auch so trivial gewesen wäre wie in C++. Doch das ist eine Programmiersprache, mit der ich mich LEIDER überhaupt nicht auskenne  :(

In VBA kann man das so lösen:

Sub convertHexToIEEE754()

Dim hexValueIEEE754 As String
Dim convertValue As Double

Dim ieee754_h As MyHex
Dim ieee754_s As MySingle

'Beispiel für einen 4 Byte Hexadezimalwert
hexValueIEEE754 = "41A5999A"

'Konvertierung nach IEEE754
ieee754_h.Lng = Val("&H" & hexValueIEEE754)
LSet ieee754_s = ieee754_h

'Konvertierung auf Double und Rundung auf eine Nachkommastelle
convertValue = Round(CDbl(ieee754_s.sng), 1)

'Ergebnis ist 20,7 GradC

End Sub


Ist natürlich ne ganze Menge Arbeit die einzelnen Bytes in der Binärdatei auszulesen, byteweise richtig zusammen zu setzen, zu konvertieren und anschließend in Access zu importieren. Aber das funktioniert jetzt ganz gut und für mich sogar unerwartet schnell. Ca. 10000 Datensätze mit allen Sensordaten sind in ca. 15 Sekunden importiert. Mein Code ist aber so aufgebaut, dass (wie bei der Software zum KlimaLogg auch) nur neuere Datensätze ergänzt werden, die noch nicht in der Access-Tabelle sind. Das geht sehr fix, wenn man z. B. nur die Daten von einem Tag ergänzt.

Was ich noch nicht berücksichtigt habe ist die Sommer- und Winterzeit. Das kommt noch. Dann muss ich in der Sommerzeit (die man programmiertechnisch mit der Systemzeit ermitteln kann) noch 1 Stunde zu dem Timestamp addieren.

Viele Grüße und noch schönen Sonntag dir.
Martin

PS: Wenn du denkst , dass mein Betrag an anderer Stelle besser aufgehoben ist kannst du ihn gerne verschieben.

TheWeather

Hallo Martin,

in der "0_histoy.dat" waren die Daten (nach damaligem Wissen) bereits in Lokalzeit (inkl. Zeitzone und Sommerzeit/Winterzeit SZ/WZ) umgerechnet - das habe ich eventuell "durcheinander geworfen". Die notwendige Umrechnung gilt (anscheinend) nur für die fortlaufend aktualisierte Datei "Klimalogg.dat1", in der unter dem Header [LastActualisation] ein Zeitstempel eingetragen ist, der anscheinend UTC ist und mit Zeitzone sowie SZ/WZ für die lokale Zeitangabe nachkalkuliert werden muss. Bei den "x_history.dat" scheint die Lokalzeit schon berücksichtigt. Kann man nochmal nachprüfen, aber ich bin mir recht sicher ...

Das Vorgehen in VBA scheint dem in C++ (der Union-Deklaration) zu entsprechen. Da muss man aber auch erst mal drauf kommen ... Auch bei C++ muss man den Gleitkommawert nochmal runden, z.B. mit String Display= FormatFloat (0#.#, Gleitkommawert), damit (teils unsinnige und nicht beabsichtigte) Nachkommastellen des Float-Formats entfallen.

Gruß Hans

P.S.: Der Beitrag steht hier genau richtig, über den Betreff ist er leicht wieder aufzufinden und  :) da muss nix verschoben werden.
2xTFA Nexus, Sinus, Duo, EOS Max, Klima-Logger, Mebus TE923

Die Titanic wurde von Profis gebaut, die Arche Noah von einem Amateur. ...

datensammler

Hat so was ähnliches schon wer unter Linux probiert bzw. kennt einen Thread dazu? Ich denke statt VBA sollte man auch bash-Befehle verwenden können.