diff --git a/MyPSACC.py b/MyPSACC.py index 46a1726..3b99997 100644 --- a/MyPSACC.py +++ b/MyPSACC.py @@ -580,7 +580,7 @@ class MyPSACC: return geo_dumps(feature_collection, sort_keys=True) @staticmethod - def get_chargings(mini=None, maxi=None): + def get_chargings(mini=None, maxi=None) -> tuple[dict]: conn = get_db() if mini is not None: if maxi is not None: diff --git a/Trip.py b/Trip.py index a6e4c82..4e8b7de 100644 --- a/Trip.py +++ b/Trip.py @@ -1,5 +1,6 @@ from __future__ import annotations +from statistics import mean from typing import List from dateutil import tz @@ -34,10 +35,19 @@ class Trip: self.duration = None self.mileage = None self.car: Car = None + self.temperatures = [] def add_points(self, latitude, longitude): self.positions.append(Points(latitude, longitude)) + def add_temperature(self, temp): + self.temperatures.append(temp) + + def get_temperature(self): + if len(self.temperatures) > 0: + return float(mean(self.temperatures)) + return None + def set_consumption(self, diff_level: float) -> float: if self.distance is None: raise ValueError("Distance not set") @@ -98,7 +108,7 @@ class Trips(list): for tr in self: if tr.consumption > 1.8: res.append({"speed": tr.speed_average, "consumption_km": tr.consumption_km, "date": tr.start_at, - "consumption": tr.consumption}) + "consumption": tr.consumption, "consumption_by_temp": tr.get_temperature()}) return res def check_and_append(self, tr: Trip): @@ -178,6 +188,8 @@ class Trips(list): tr.start_at = start["Timestamp"] tr.end_at = end["Timestamp"] tr.add_points(end["longitude"], end["latitude"]) + if end["temperature"] is not None and start["temperature"] is not None: + tr.add_temperature(end["temperature"]) tr.duration = (end["Timestamp"] - start["Timestamp"]).total_seconds() / 3600 tr.speed_average = tr.distance / tr.duration diff_level, diff_level_fuel = trip_parser.get_level_consumption(start, end) diff --git a/web/figures.py b/web/figures.py index 501edae..c9fd9ac 100644 --- a/web/figures.py +++ b/web/figures.py @@ -4,6 +4,7 @@ from typing import List import dash_bootstrap_components as dbc import dash_table import numpy as np +from dash_core_components import Graph from dash_table.Format import Format, Scheme, Symbol from dateutil.relativedelta import relativedelta from pandas import DataFrame @@ -46,6 +47,7 @@ consumption_fig = None consumption_df = None trips_map = None consumption_fig_by_speed = None +consumption_graph_by_temp = None table_fig = None pandas_options.display.float_format = '${:.2f}'.format info = "" @@ -53,9 +55,9 @@ battery_info = dbc.Alert("No data to show", color="danger") battery_table = None -def get_figures(trips: Trips, charging: List[dict]): +def get_figures(trips: Trips, charging: tuple[dict]): global consumption_fig, consumption_df, trips_map, consumption_fig_by_speed, table_fig, info, battery_info, \ - battery_table + battery_table, consumption_graph_by_temp lats = [] lons = [] names = [] @@ -164,3 +166,18 @@ def get_figures(trips: Trips, charging: List[dict]): 'format': deepcopy(nb_format).symbol_suffix(" kWh").precision(3)}], data=charging, ) + consumption_by_temp_df = consumption_df[consumption_df["consumption_by_temp"].notnull()] + if len(consumption_by_temp_df) > 0: + consumption_fig_by_temp = px.histogram(consumption_by_temp_df, x="consumption_by_temp", y="consumption_km", + histfunc="avg", title="Consumption by temperature") + consumption_fig_by_temp.update_traces(xbins_size=2) + consumption_fig_by_temp.update_layout(bargap=0.05) + consumption_fig_by_temp.add_trace( + go.Scatter(mode="markers", x=consumption_by_temp_df["consumption_by_temp"], + y=consumption_by_temp_df["consumption_km"], name="Trips")) + consumption_fig_by_temp.update_layout(xaxis_title="average temperature in °C", + yaxis_title="Consumption kWh/100Km") + consumption_graph_by_temp = Graph(figure=consumption_fig_by_temp, id="consumption_fig_by_temp") + + else: + consumption_graph_by_temp = Graph(style={'display': 'none'}) diff --git a/web/views.py b/web/views.py index f429786..4f6b4d2 100644 --- a/web/views.py +++ b/web/views.py @@ -24,6 +24,7 @@ min_date = max_date = min_millis = max_millis = step = marks = None @dash_app.callback(Output('trips_map', 'figure'), Output('consumption_fig', 'figure'), Output('consumption_fig_by_speed', 'figure'), + Output('consumption_fig_by_temp', 'graph'), Output('consumption', 'children'), Output('tab_trips', 'children'), Output('tab_battery', 'children'), @@ -42,13 +43,14 @@ def display_value(value): filtered_chargings = MyPSACC.get_chargings(mini, maxi) figures.get_figures(filtered_trips, filtered_chargings) consumption = "Average consumption: {:.1f} kWh/100km".format(float(figures.consumption_df["consumption_km"].mean())) - return figures.trips_map, figures.consumption_fig, figures.consumption_fig_by_speed, consumption, figures.table_fig, \ - figures.battery_info, figures.battery_table, max_millis, step, marks + return figures.trips_map, figures.consumption_fig, figures.consumption_fig_by_speed,\ + figures.consumption_graph_by_temp, consumption, figures.table_fig, figures.battery_info, \ + figures.battery_table, max_millis, step, marks @app.route('/getvehicles') def get_vehicules(): - return jsonify(myp.getVIN()) + return jsonify(myp.get_vehicles()) @app.route('/get_vehicleinfo/') @@ -166,7 +168,8 @@ try: html.H2(id="consumption", children=figures.info), dcc.Graph(figure=figures.consumption_fig, id="consumption_fig"), - dcc.Graph(figure=figures.consumption_fig_by_speed, id="consumption_fig_by_speed") + dcc.Graph(figure=figures.consumption_fig_by_speed, id="consumption_fig_by_speed"), + figures.consumption_graph_by_temp ]), dbc.Tab(label="Trips", tab_id="trips", id="tab_trips", children=[figures.table_fig]), dbc.Tab(label="Battery", tab_id="battery", id="tab_battery", children=[figures.battery_info]),