131 lines
4.9 KiB
Python
131 lines
4.9 KiB
Python
|
#!/usr/bin/env python3
|
|||
|
# -*- coding: utf-8 -*-
|
|||
|
|
|||
|
import datetime
|
|||
|
import geopy.distance
|
|||
|
import json
|
|||
|
import math
|
|||
|
import os
|
|||
|
import glob
|
|||
|
import re
|
|||
|
import sys
|
|||
|
|
|||
|
class C2GAnalyse:
|
|||
|
def __init__(self):
|
|||
|
self.state = {}
|
|||
|
self.in_use = []
|
|||
|
self.total_minutes = 0.0
|
|||
|
self.total_money = 0.0
|
|||
|
self.total_distance = 0.0
|
|||
|
self.run()
|
|||
|
|
|||
|
def find_car_type(self, vin):
|
|||
|
# 1..3 = manufacturer code
|
|||
|
# 4..6 = general type
|
|||
|
# 7 = body form
|
|||
|
# 8..9 = engine type
|
|||
|
# 10 = steering (1=left, 2=right)
|
|||
|
# 11 = manufacturing facilty
|
|||
|
seg = vin[0:9]
|
|||
|
typelist = {
|
|||
|
"WDD117342": ["CLA 180", 0.34],
|
|||
|
"WDC156912": ["GLA 180 CDI", 0.34],
|
|||
|
"WDC156942": ["GLA 180", 0.34],
|
|||
|
"WDC156943": ["GLA 200", 0.34],
|
|||
|
"WDD176012": ["A 180 CDI", 0.31],
|
|||
|
"WDD176042": ["A 180", 0.31],
|
|||
|
"WDD176043": ["A 200", 0.31],
|
|||
|
"WDD246242": ["B 180", 0.34],
|
|||
|
"WME451334": ["smart fortwo 451", 0.26],
|
|||
|
"WME451390": ["smart fortwo 451 ed", 0.29],
|
|||
|
"WME451391": ["smart fortwo 451 ed", 0.29],
|
|||
|
"WME453342": ["smart fortwo 453", 0.26],
|
|||
|
}
|
|||
|
|
|||
|
if not seg in typelist:
|
|||
|
print("Missing vehicle type for {} (VIN {})!".format(seg, vin))
|
|||
|
|
|||
|
return typelist[seg]
|
|||
|
|
|||
|
def run(self):
|
|||
|
for f in sorted(glob.glob(os.path.join("../data/", "*.json"))):
|
|||
|
self.scanfile(f)
|
|||
|
print("{} cars seen in total.".format(len(self.state)))
|
|||
|
print("Total kilometres driven: {}".format(self.total_distance))
|
|||
|
print("Total minutes driven: {}".format(self.total_minutes))
|
|||
|
print("Total money made: {}".format(self.total_money))
|
|||
|
|
|||
|
def scanfile(self, filename):
|
|||
|
stamp = re.search(r'(\d{4}-\d\d-\d\d_\d{6})', filename)
|
|||
|
stamp_str = stamp.group(1)
|
|||
|
stamp_dt = datetime.datetime.strptime(stamp_str, "%Y-%m-%d_%H%M%S")
|
|||
|
print("File: {} ({}, Totals: {:.3f}km, {:.1f}mins, {:.2f}€)".format(filename, stamp_str, self.total_distance, self.total_minutes, self.total_money), end="")
|
|||
|
jf = open(filename, "r")
|
|||
|
doc = json.load(jf)
|
|||
|
jf.close()
|
|||
|
root = doc["placemarks"]
|
|||
|
print(" ({} cars available)".format(len(root)))
|
|||
|
self.parse_cars(stamp_dt, root)
|
|||
|
|
|||
|
def parse_cars(self, stamp, placemarks):
|
|||
|
not_in_use = []
|
|||
|
for pm in placemarks:
|
|||
|
self.update_car(stamp, pm)
|
|||
|
not_in_use.append(pm["name"])
|
|||
|
for car_id in self.state:
|
|||
|
if not car_id in not_in_use:
|
|||
|
if not car_id in self.in_use:
|
|||
|
print("{} OCCUPIED!".format(car_id))
|
|||
|
self.state[car_id]["occupied"] = stamp
|
|||
|
self.in_use.append(car_id)
|
|||
|
else:
|
|||
|
if car_id in self.in_use:
|
|||
|
#print("{} RETURNED!".format(car_id))
|
|||
|
if "occupied" in self.state[car_id]:
|
|||
|
del self.state[car_id]["occupied"]
|
|||
|
self.in_use.remove(car_id)
|
|||
|
|
|||
|
def update_car(self, stamp, new_data):
|
|||
|
car_id = new_data["name"]
|
|||
|
if car_id in self.state:
|
|||
|
old_data = self.state[car_id]
|
|||
|
car_type = self.find_car_type(new_data["vin"])
|
|||
|
if new_data["address"] != old_data["address"]:
|
|||
|
## CAR MOVED
|
|||
|
old_spot = (old_data["coordinates"][1], old_data["coordinates"][0])
|
|||
|
new_spot = (new_data["coordinates"][1], new_data["coordinates"][0])
|
|||
|
distance = geopy.distance.distance(old_spot, new_spot).kilometers
|
|||
|
if not "occupied" in old_data:
|
|||
|
old_data["occupied"] = "unknown"
|
|||
|
minutes = -1
|
|||
|
else:
|
|||
|
minutes = (stamp - old_data["occupied"]).total_seconds() / 60
|
|||
|
self.total_minutes += minutes
|
|||
|
self.total_money += math.ceil(minutes) * car_type[1]
|
|||
|
self.total_distance += distance
|
|||
|
|
|||
|
print("{} {} moved for {:.3f}km/{:.1f}mins: {} ({}%, {}, {}) {} -> {} {} ({}%, {}, {})".format(
|
|||
|
car_type[0],
|
|||
|
car_id,
|
|||
|
distance,
|
|||
|
minutes,
|
|||
|
old_data["address"],
|
|||
|
old_data["fuel"],
|
|||
|
old_data["interior"],
|
|||
|
old_data["exterior"],
|
|||
|
old_data["occupied"],
|
|||
|
stamp,
|
|||
|
new_data["address"],
|
|||
|
new_data["fuel"],
|
|||
|
new_data["interior"],
|
|||
|
new_data["exterior"]
|
|||
|
))
|
|||
|
elif new_data["fuel"] != old_data["fuel"]:
|
|||
|
print("{} FUEL CHANGE: {} -> {}".format(car_id, old_data["fuel"], new_data["fuel"]))
|
|||
|
if new_data["vin"] != old_data["vin"]:
|
|||
|
print("{} ################# VIN CHANGE!!!".format(car_id))
|
|||
|
self.state[car_id] = new_data
|
|||
|
|
|||
|
if __name__=="__main__":
|
|||
|
C2GAnalyse()
|