202 lines
4.9 KiB
Python
202 lines
4.9 KiB
Python
import json
|
|
import os
|
|
import numpy as np
|
|
import dateutil.parser as dup
|
|
from jay_diff import jay_merge_full
|
|
from matplotlib import pyplot as plot
|
|
|
|
BASE = "/media/jens/cifs/jens@moon/projects/we_collect/results"
|
|
VIN = 'WVWZZZE1ZMP010760'
|
|
USER = 'alex'
|
|
YEAR = 2024
|
|
MONTH = 10
|
|
DAYS = [15, 16, 17, 18, 19, 20, 21, 22, 23]
|
|
|
|
|
|
def has_diff_entries(diff):
|
|
handled = False
|
|
if "update" in diff:
|
|
handled = True
|
|
if "update_add" in diff:
|
|
handled = True
|
|
if "add" in diff:
|
|
handled = True
|
|
if "delete" in diff:
|
|
handled = True
|
|
|
|
return handled
|
|
|
|
|
|
class Endpoint:
|
|
def __init__(self, _ep_path: str, _ts_path: str, _ts_format='%Y-%m-%dT%H:%M:%S.%f%z'):
|
|
self._ep_path = _ep_path
|
|
self._ep_path_keys = self.to_keys(_ep_path)
|
|
self._timestamps = []
|
|
self._values = []
|
|
|
|
self._ts_format = _ts_format
|
|
self._ts_path_keys = self.to_keys(_ts_path)
|
|
|
|
def timestamps_str(self):
|
|
return f"{self._ep_path}:{len(self._timestamps)}: {self._timestamps}"
|
|
|
|
@property
|
|
def timestamps(self):
|
|
return self._timestamps
|
|
|
|
@property
|
|
def values(self):
|
|
return self._values
|
|
|
|
@property
|
|
def path(self):
|
|
return self._ep_path
|
|
|
|
def assign(self, _record: dict):
|
|
value = self.deref_multi(_record, self._ep_path_keys)
|
|
self._values += [value]
|
|
|
|
# Extract timestamp
|
|
capture_time = self.deref_multi(_record, self._ts_path_keys)
|
|
timestamp_int = convert(capture_time)
|
|
self._timestamps += [timestamp_int]
|
|
|
|
def remove_dups(self):
|
|
new_dict = {}
|
|
index = 0
|
|
unique_indices = []
|
|
for ts in self._timestamps:
|
|
if ts not in new_dict:
|
|
new_dict[ts] = index
|
|
unique_indices.append(index)
|
|
index += 1
|
|
|
|
t_list = self._timestamps
|
|
v_list = self._values
|
|
self._timestamps = []
|
|
self._values = {}
|
|
|
|
self._timestamps = [t_list[i] for i in unique_indices]
|
|
self._values = [v_list[i] for i in unique_indices]
|
|
|
|
@staticmethod
|
|
def to_keys(key_path: str):
|
|
keys = key_path.split('/')
|
|
return keys
|
|
|
|
@staticmethod
|
|
def deref_multi(data, keys):
|
|
return Endpoint.deref_multi(data[keys[0]], keys[1:]) if keys else data
|
|
|
|
|
|
end_points = {
|
|
'odo': Endpoint('data/measurements/odometerStatus/value/odometer', 'data/measurements/odometerStatus/value/carCapturedTimestamp'),
|
|
'soc': Endpoint('data/measurements/fuelLevelStatus/value/currentSOC_pct', 'data/measurements/fuelLevelStatus/value/carCapturedTimestamp'),
|
|
}
|
|
|
|
|
|
def convert(_filename: str):
|
|
name = _filename
|
|
if "records_" in _filename:
|
|
name = os.path.splitext(_filename)[0].split("_")[1]
|
|
date_str = name.split("T")[0]
|
|
time_str = name.split("T")[1]
|
|
if "-" in time_str:
|
|
time_str = time_str.replace("-", ":")
|
|
|
|
timestamp_str = f"{date_str}T{time_str}"
|
|
ts = dup.parse(timestamp_str)
|
|
result = ts.year
|
|
result = 100*result + ts.month
|
|
result = 100*result + ts.day
|
|
result = 100*result + ts.hour
|
|
result = 100*result + ts.minute
|
|
result = 100*result + ts.second
|
|
result = 1000000*result + ts.microsecond
|
|
|
|
return result
|
|
|
|
|
|
path = os.path.join(BASE, USER)
|
|
path = os.path.join(path, VIN)
|
|
path = os.path.join(path, str(YEAR))
|
|
path = os.path.join(path, str(MONTH))
|
|
|
|
day_list = sorted(os.listdir(path), key=lambda f: int(f))
|
|
print("Days in '", path, "' :")
|
|
# prints all files
|
|
print(day_list)
|
|
|
|
month_path = path
|
|
record_list = []
|
|
last = {}
|
|
|
|
for _day in DAYS:
|
|
day = str(_day)
|
|
if day not in day_list:
|
|
continue
|
|
day_path = os.path.join(month_path, day)
|
|
|
|
# Sort out files with unknown nickname
|
|
file_list = os.listdir(day_path)
|
|
file_list_sorted = sorted(file_list, key=lambda f: convert(f))
|
|
print("Files in '", day_path, "' :")
|
|
# prints all files
|
|
print(file_list_sorted)
|
|
|
|
for filename in file_list_sorted:
|
|
file_path = os.path.join(day_path, filename)
|
|
print(f"Open file: {filename}")
|
|
with open(file_path, "r") as fp:
|
|
records = json.load(fp)
|
|
print(f"Found {len(records)} records")
|
|
for record in records:
|
|
try:
|
|
vehicle_diff = record['data']
|
|
is_header = True
|
|
if 'is_delta' in record['info']:
|
|
if record['info']['is_delta']:
|
|
is_header = False
|
|
|
|
if is_header:
|
|
last = {}
|
|
|
|
except KeyError as e:
|
|
print(f"KeyError: {e}")
|
|
|
|
if not has_diff_entries(vehicle_diff):
|
|
vehicle_diff = {'update_add': vehicle_diff}
|
|
|
|
vehicle_data = jay_merge_full(last, vehicle_diff)
|
|
last = vehicle_data
|
|
try:
|
|
for k in end_points.keys():
|
|
end_points[k].assign({'info': record['info'], 'data': vehicle_data})
|
|
except KeyError:
|
|
pass
|
|
|
|
for k in end_points.keys():
|
|
end_points[k].remove_dups()
|
|
|
|
speed = [0]
|
|
for i in range(1, len(end_points['odo'].timestamps)):
|
|
dt = float(end_points['odo'].timestamps[i] - end_points['odo'].timestamps[i-1])/(60*100000000)
|
|
dv = end_points['odo'].values[i] - end_points['odo'].values[i-1]
|
|
_speed = dv/dt
|
|
speed.append(_speed)
|
|
|
|
plot.subplot(3, 1, 1)
|
|
plot.plot(end_points['odo'].timestamps, np.array(end_points['odo'].values) - end_points['odo'].values[0])
|
|
plot.title("Kilometerstand")
|
|
plot.grid()
|
|
plot.subplot(3, 1, 2)
|
|
plot.plot(end_points['odo'].timestamps, speed)
|
|
plot.title("Speed")
|
|
plot.grid()
|
|
plot.subplot(3, 1, 3)
|
|
plot.plot(end_points['soc'].timestamps, end_points['soc'].values)
|
|
plot.title("Akkustand")
|
|
plot.grid()
|
|
|
|
plot.show()
|