-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog-bin2txt
executable file
·92 lines (77 loc) · 2.64 KB
/
log-bin2txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python3
import argparse
import sys
import struct
import time
TEXT_LOG_HEADER = 'datetime,temperature,humidity'
LOG_PREAMBLE = 'Log_v'
PREAMBLE_END_TOKEN = b'\n'
ENDIANNESS_BYTES = (78 << 24) | (185 << 16) | (219 << 8) | (110)
def get_cli_args():
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, description="Convert an optimized binary log to a readable, text log.")
parser.add_argument('binary_logfile', help="Path to the log file in binary format.")
parser.add_argument('output_filepath', help="Path to write the text output to.")
return parser.parse_args()
def readcheck(binfile, numbytes, exit=False):
b = binfile.read(numbytes)
if len(b) < numbytes:
if exit:
print("Log data corrupted.")
sys.exit(-1)
else:
return b''
return b
def v1_conversion(binfile, txtfile):
b = readcheck(binfile, 4, True)
signature = struct.unpack('<I', b)[0]
if signature == ENDIANNESS_BYTES:
endianness = '<'
else:
signature = struct.unpack('>I', b)[0]
if signature == ENDIANNESS_BYTES:
endianness = '>'
else:
print("Invalid log file endianness. Exiting.")
sys.exit(-1)
b = readcheck(binfile, 4, True)
int_size = struct.unpack(f'{endianness}I', b)[0]
int_format = 'I' if int_size == 4 else 'Q'
b = readcheck(binfile, 4, True)
float_size = struct.unpack(f'{endianness}I', b)[0]
float_format = 'f' if float_size == 4 else 'd'
print(TEXT_LOG_PREAMBLE + '1', file=txtfile)
print(TEXT_LOG_HEADER, file=txtfile)
while True:
b = binfile.read(4)
if len(b) < 4: break
unixtime = struct.unpack(f'{endianness}I', b)[0]
b = binfile.read(4)
if len(b) < 4:
print("Log data corrupted.")
sys.exit(-1)
temp = struct.unpack(f'{endianness}{float_format}', b)[0]
#b = binfile.read(4)
#if len(b) < 4:
# print("Log data corrupted.")
# sys.exit(-1)
#hum = struct.unpack(f'{endianness}{float_format}', b)[0]
timestr = time.strftime("%Y-%m-%d,%H:%M:%S", time.gmtime(unixtime))
print(f"{timestr},{temp}", file=txtfile)
conversion_table = {
1 : v1_conversion
}
if __name__ == "__main__":
cli_args = get_cli_args()
with open(cli_args.binary_logfile, 'rb') as binfile, open(cli_args.output_filepath, 'w') as txtfile:
header = ''
while True:
b = binfile.read(1)
if b == b'\x00' or b == b'': break
header += b.decode()
if b == PREAMBLE_END_TOKEN: break
if header.startswith(LOG_PREAMBLE):
version = int(header[len(LOG_PREAMBLE):])
conversion_table[version](binfile, txtfile)
else:
print("Invalid or unknown log preamble. Exiting.")
sys.exit(-1)