diff --git a/web/figures.py b/web/figures.py
index 088ce0c..2dcc436 100644
--- a/web/figures.py
+++ b/web/figures.py
@@ -62,6 +62,12 @@ info = ""
battery_info = ERROR_DIV
battery_table = None
+SUMMARY_CARDS = {"Average consumption": {"text": None, "src": "static/images/consumption.svg"},
+ "Average emission": {"text": None, "src": "static/images/pollution.svg"},
+ "Average charge speed": {"text": None, "src": "static/images/battery-charge-line.svg"},
+ "Electricity consumption": {"text": None, "src": "static/images/electricity bill.svg"}
+ }
+
# pylint: disable=too-many-locals
def get_figures(trips: Trips, charging: List[dict]):
@@ -115,7 +121,8 @@ def get_figures(trips: Trips, charging: List[dict]):
)
# consumption_fig
consumption_df = DataFrame.from_records(trips.get_long_trips())
- consumption_fig = px.line(consumption_df, x="date", y="consumption", title='Consumption of the car')
+ consumption_fig = px.histogram(consumption_df, x="date", y="consumption", title='Consumption of the car',
+ histfunc="avg")
consumption_fig.update_layout(yaxis_title="Consumption kWh/100Km")
consumption_fig_by_speed = px.histogram(consumption_df, x="speed", y="consumption_km", histfunc="avg",
@@ -143,38 +150,11 @@ def get_figures(trips: Trips, charging: List[dict]):
price_kw = 0
total_elec = 0
- battery_info = html.Div(children=[
- html.Tr(
- [
- html.Td('Average emission:', rowSpan=2),
- html.Td("{:.1f} g/km".format(co2_per_km))]),
- html.Tr(
- [
- "{:.1f} g/kWh".format(co2_per_kw),
- ]
- ),
- html.Tr([
- html.Td("Average charge speed:", style=PADDING_TOP),
- html.Td("{:.3f} kW".format(charge_speed))
- ]),
- html.Tr(html.Td(" ", colSpan=2)),
- html.Tr([
- html.Td('Average Price:', rowSpan=2, style=PADDING_TOP),
- html.Td("{:.2f} {}/100km".format(price_kw * kw_per_km, ElecPrice.currency)),
- ]),
- html.Tr([
- "{:.2f} {}/kWh".format(price_kw, ElecPrice.currency),
- ]),
- html.Tr(html.Td(" ", colSpan=2)),
- html.Tr([
- html.Td('Electricity consumption:', rowSpan=2, style=PADDING_TOP),
- html.Td("{:.0f} kWh".format(total_elec)),
- ]),
- html.Tr([
- "{:.0f} {}".format(total_elec * price_kw, ElecPrice.currency),
- ]),
- ])
-
+ SUMMARY_CARDS["Average charge speed"]["text"] = f"{charge_speed:.2f} kW"
+ SUMMARY_CARDS["Average emission"]["text"] = [html.P(f"{co2_per_km:.1f} g/km"), html.P(f"{co2_per_kw:.1f} g/kWh")]
+ SUMMARY_CARDS["Electricity consumption"]["text"] = [f"{total_elec:.0f} kWh", html.Br(), \
+ f"{total_elec * price_kw:.0f} {ElecPrice.currency}"]
+ SUMMARY_CARDS["Average consumption"]["text"] = f"{consumption_df['consumption_km'].mean():.1f} kWh/100km"
battery_table = dash_table.DataTable(
id='battery-table',
sort_action='native',
@@ -220,6 +200,7 @@ def get_figures(trips: Trips, charging: List[dict]):
consumption_graph_by_temp = html.Div(Graph(style={'display': 'none'}), id="consumption_graph_by_temp")
return True
+
def __calculate_co2_per_kw(charging_data):
try:
co2_data = charging_data[charging_data["co2"] > 0]
diff --git a/web/static/images/battery-charge-line.svg b/web/static/images/battery-charge-line.svg
new file mode 100644
index 0000000..a763347
--- /dev/null
+++ b/web/static/images/battery-charge-line.svg
@@ -0,0 +1,54 @@
+
+
diff --git a/web/static/images/consumption.svg b/web/static/images/consumption.svg
new file mode 100644
index 0000000..e9b18db
--- /dev/null
+++ b/web/static/images/consumption.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/web/static/images/electricity bill.svg b/web/static/images/electricity bill.svg
new file mode 100644
index 0000000..93ed62c
--- /dev/null
+++ b/web/static/images/electricity bill.svg
@@ -0,0 +1,224 @@
+
+
diff --git a/web/static/images/pollution.svg b/web/static/images/pollution.svg
new file mode 100644
index 0000000..fbe0761
--- /dev/null
+++ b/web/static/images/pollution.svg
@@ -0,0 +1,77 @@
+
+
diff --git a/web/views.py b/web/views.py
index d3f6f20..f18cac0 100644
--- a/web/views.py
+++ b/web/views.py
@@ -4,6 +4,7 @@ from typing import List
import dash_bootstrap_components as dbc
from dash.dependencies import Output, Input, MATCH, State
+from dash.development.base_component import Component
from dash.exceptions import PreventUpdate
import dash_core_components as dcc
import dash_html_components as html
@@ -61,9 +62,8 @@ def create_callback(): # noqa: MC0001
Output('consumption_fig', 'figure'),
Output('consumption_fig_by_speed', 'figure'),
Output('consumption_graph_by_temp', 'children'),
- Output('consumption', 'children'),
+ Output('summary-cards', 'children'),
Output('tab_trips_fig', 'children'),
- Output('tab_battery_fig', 'children'),
Output('tab_charge', 'children'),
Output('date-slider', 'max'),
Output('date-slider', 'step'),
@@ -78,11 +78,9 @@ def create_callback(): # noqa: MC0001
filtered_trips.append(trip)
filtered_chargings = Charging.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, \
- figures.consumption_graph_by_temp, consumption, figures.table_fig, figures.battery_info, \
- figures.battery_table, max_millis, step, marks
+ figures.consumption_graph_by_temp, create_card(figures.SUMMARY_CARDS), \
+ figures.table_fig, figures.battery_table, max_millis, step, marks
@dash_app.callback(Output(EMPTY_DIV, "children"),
[Input("battery-table", "data_timestamp")],
@@ -268,7 +266,7 @@ def update_trips():
return
# update for slider
try:
- logger.debug("min_date:%s - max_date:%s",min_date, max_date)
+ logger.debug("min_date:%s - max_date:%s", min_date, max_date)
min_millis = figures.unix_time_millis(min_date)
max_millis = figures.unix_time_millis(max_date)
step = (max_millis - min_millis) / 100
@@ -280,6 +278,7 @@ def update_trips():
logger.debug("position table is probably empty :", exc_info=True)
return
+
def __get_control_tabs():
tabs = []
for car in myp.vehicles_list:
@@ -299,14 +298,35 @@ def __get_control_tabs():
return tabs
+def create_card(card: dict):
+ res = []
+ for tile, value in card.items():
+ text = value["text"]
+ # if isinstance(text, str):
+ # text = html.H3(text)
+ res.append(html.Div(
+ dbc.Card([
+ html.H4(tile, className="card-title text-center"),
+ dbc.Row([
+ dbc.Col(dbc.CardBody(text, style={"white-space": "nowrap", "font-size": "160%"}),
+ className="text-center"),
+ dbc.Col(dbc.CardImg(src=value.get("src", Component.UNDEFINED), style={"max-height": "7rem"}))
+ ],
+ className="align-items-center flex-nowrap")
+ ], className="h-100 p-2"),
+ className="col-sm-12 col-md-6 col-lg-3 py-2"
+ ))
+ return res
+
+
def serve_layout():
global cached_layout
if cached_layout is None:
logger.debug("Create new layout")
try:
figures.get_figures(trips, chargings)
- summary_tab = [html.H2(id="consumption",
- children=figures.info),
+ summary_tab = [dbc.Container(dbc.Row(id="summary-cards",
+ children=create_card(figures.SUMMARY_CARDS)), fluid=True),
dcc.Graph(figure=figures.consumption_fig, id="consumption_fig"),
dcc.Graph(figure=figures.consumption_fig_by_speed, id="consumption_fig_by_speed"),
figures.consumption_graph_by_temp]
@@ -323,7 +343,7 @@ def serve_layout():
except (IndexError, TypeError, NameError):
summary_tab = figures.ERROR_DIV
maps = figures.ERROR_DIV
- logger.warning("Failed to generate figure, there is probably not enough data yet")
+ logger.warning("Failed to generate figure, there is probably not enough data yet", exc_info_debug=True)
range_slider = html.Div()
data_div = html.Div([
range_slider,
@@ -347,20 +367,24 @@ def serve_layout():
size="xl",
)
]),
- dbc.Tab(label="Battery", tab_id="battery", id="tab_battery",
- children=[html.Div(id="tab_battery_fig", children=[figures.battery_info]),
+ dbc.Tab(label="Charge", tab_id="charge", id="tab_charge",
+ children=[figures.battery_table,
dbc.Modal(
[
- dbc.ModalHeader("Charging speed"),
- dbc.ModalBody(html.Div(id="tab_battery_popup_graph")),
+ dbc.ModalHeader(
+ "Charging speed"),
+ dbc.ModalBody(html.Div(
+ id="tab_battery_popup_graph")),
dbc.ModalFooter(
- dbc.Button("Close", id="tab_battery_popup-close", className="ml-auto")
+ dbc.Button("Close",
+ id="tab_battery_popup-close",
+ className="ml-auto")
),
],
id="tab_battery_popup",
size="xl",
- )]),
- dbc.Tab(label="Charge", tab_id="charge", id="tab_charge", children=[figures.battery_table]),
+ )
+ ]),
dbc.Tab(label="Map", tab_id="map", children=[maps]),
dbc.Tab(label="Control", tab_id="control", children=dbc.Tabs(id="control-tabs",
children=__get_control_tabs()))],