mirror of
https://github.com/flobz/psa_car_controller.git
synced 2026-08-22 09:26:16 +00:00
enable access to control tab when no data & improve style
This commit is contained in:
+33
-41
@@ -46,15 +46,17 @@ def get_marks_from_start_end(start, end):
|
||||
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
consumption_fig = None
|
||||
consumption_df = None
|
||||
trips_map = None
|
||||
consumption_fig_by_speed = None
|
||||
consumption_graph_by_temp = None
|
||||
table_fig = None
|
||||
ERROR_DIV = dbc.Alert("No data to show, there is probably no trips recorded yet", color="danger")
|
||||
PADDING_TOP = {"padding-top": "1em"}
|
||||
consumption_fig = ERROR_DIV
|
||||
consumption_df = ERROR_DIV
|
||||
trips_map = ERROR_DIV
|
||||
consumption_fig_by_speed = ERROR_DIV
|
||||
consumption_graph_by_temp = ERROR_DIV
|
||||
table_fig = ERROR_DIV
|
||||
pandas_options.display.float_format = '${:.2f}'.format
|
||||
info = ""
|
||||
battery_info = dbc.Alert("No data to show", color="danger")
|
||||
battery_info = ERROR_DIV
|
||||
battery_table = None
|
||||
|
||||
|
||||
@@ -130,42 +132,32 @@ def get_figures(trips: Trips, charging: List[dict]):
|
||||
html.Tr(
|
||||
[
|
||||
html.Td('Average emission:', rowSpan=2),
|
||||
html.Td("{:.1f} g/km".format(co2_per_km)),
|
||||
]
|
||||
),
|
||||
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:"),
|
||||
html.Td("{:.3f} kW".format(charge_speed))
|
||||
]
|
||||
),
|
||||
html.Tr(
|
||||
[
|
||||
html.Td('Average Price:', rowSpan=2),
|
||||
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('Electricity consumption:', rowSpan=2),
|
||||
html.Td("{:.0f} kWh".format(total_elec)),
|
||||
]
|
||||
),
|
||||
html.Tr(
|
||||
[
|
||||
"{:.0f} {}".format(total_elec*price_kw, ElecPrice.currency),
|
||||
]
|
||||
),
|
||||
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),
|
||||
]),
|
||||
])
|
||||
|
||||
battery_table = dash_table.DataTable(
|
||||
@@ -181,9 +173,9 @@ def get_figures(trips: Trips, charging: List[dict]):
|
||||
{'id': 'kw', 'name': 'consumption', 'type': 'numeric',
|
||||
'format': deepcopy(nb_format).symbol_suffix(" kWh").precision(2)},
|
||||
{'id': 'price', 'name': 'price', 'type': 'numeric',
|
||||
'format': deepcopy(nb_format).symbol_suffix(" " + ElecPrice.currency).precision(2)}],
|
||||
data=charging,
|
||||
editable=True
|
||||
'format': deepcopy(nb_format).symbol_suffix(" " + ElecPrice.currency).precision(2), 'editable': True}
|
||||
],
|
||||
data=charging
|
||||
)
|
||||
consumption_by_temp_df = consumption_df[consumption_df["consumption_by_temp"].notnull()]
|
||||
if len(consumption_by_temp_df) > 0:
|
||||
|
||||
+84
-75
@@ -27,8 +27,8 @@ from web.db import set_chargings_price, get_db, set_db_callback
|
||||
RESPONSE = "-response"
|
||||
EMPTY_DIV = "empty-div"
|
||||
ABRP_SWITCH = 'abrp-switch'
|
||||
CALLBACK_CREATED = False
|
||||
|
||||
ERROR_DIV = dbc.Alert("No data to show, there is probably no trips recorded yet", color="danger")
|
||||
trips: Trips
|
||||
chargings: List[dict]
|
||||
min_date = max_date = min_millis = max_millis = step = marks = cached_layout = None
|
||||
@@ -57,50 +57,56 @@ def diff_dashtable(data, data_previous, row_id_name="row_id"):
|
||||
return changes
|
||||
|
||||
|
||||
@dash_app.callback(Output('trips_map', 'figure'),
|
||||
Output('consumption_fig', 'figure'),
|
||||
Output('consumption_fig_by_speed', 'figure'),
|
||||
Output('consumption_graph_by_temp', 'children'),
|
||||
Output('consumption', 'children'),
|
||||
Output('tab_trips', 'children'),
|
||||
Output('tab_battery', 'children'),
|
||||
Output('tab_charge', 'children'),
|
||||
Output('date-slider', 'max'),
|
||||
Output('date-slider', 'step'),
|
||||
Output('date-slider', 'marks'),
|
||||
Input('date-slider', 'value'))
|
||||
def display_value(value):
|
||||
mini = datetime.fromtimestamp(value[0], tz=timezone.utc)
|
||||
maxi = datetime.fromtimestamp(value[1], tz=timezone.utc)
|
||||
filtered_trips = Trips()
|
||||
for trip in trips:
|
||||
if mini <= trip.start_at <= maxi:
|
||||
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
|
||||
def create_callback():
|
||||
global CALLBACK_CREATED
|
||||
if not CALLBACK_CREATED:
|
||||
# pylint: disable=unused-variable
|
||||
@dash_app.callback(Output('trips_map', 'figure'),
|
||||
Output('consumption_fig', 'figure'),
|
||||
Output('consumption_fig_by_speed', 'figure'),
|
||||
Output('consumption_graph_by_temp', 'children'),
|
||||
Output('consumption', 'children'),
|
||||
Output('tab_trips', 'children'),
|
||||
Output('tab_battery', 'children'),
|
||||
Output('tab_charge', 'children'),
|
||||
Output('date-slider', 'max'),
|
||||
Output('date-slider', 'step'),
|
||||
Output('date-slider', 'marks'),
|
||||
Input('date-slider', 'value'))
|
||||
def display_value(value):
|
||||
mini = datetime.fromtimestamp(value[0], tz=timezone.utc)
|
||||
maxi = datetime.fromtimestamp(value[1], tz=timezone.utc)
|
||||
filtered_trips = Trips()
|
||||
for trip in trips:
|
||||
if mini <= trip.start_at <= maxi:
|
||||
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
|
||||
|
||||
@dash_app.callback(
|
||||
Output(EMPTY_DIV, "children"),
|
||||
[Input("battery-table", "data_timestamp")],
|
||||
[
|
||||
State("battery-table", "data"),
|
||||
State("battery-table", "data_previous"),
|
||||
],
|
||||
)
|
||||
def capture_diffs(timestamp, data, data_previous):
|
||||
if timestamp is None:
|
||||
raise PreventUpdate
|
||||
diff_data = diff_dashtable(data, data_previous, "start_at")
|
||||
for changed_line in diff_data:
|
||||
if changed_line['column_name'] == 'price':
|
||||
if not set_chargings_price(get_db(), changed_line['start_at'], changed_line['current_value']):
|
||||
logger.error("Can't find line to update in the database")
|
||||
return ""
|
||||
|
||||
@dash_app.callback(
|
||||
Output(EMPTY_DIV, "children"),
|
||||
[Input("battery-table", "data_timestamp")],
|
||||
[
|
||||
State("battery-table", "data"),
|
||||
State("battery-table", "data_previous"),
|
||||
],
|
||||
)
|
||||
def capture_diffs(timestamp, data, data_previous):
|
||||
if timestamp is None:
|
||||
raise PreventUpdate
|
||||
diff_data = diff_dashtable(data, data_previous, "start_at")
|
||||
for changed_line in diff_data:
|
||||
if changed_line['column_name'] == 'price':
|
||||
if not set_chargings_price(get_db(), changed_line['start_at'], changed_line['current_value']):
|
||||
logger.error("Can't find line to update in the database")
|
||||
return ""
|
||||
CALLBACK_CREATED = True
|
||||
|
||||
|
||||
@dash_app.callback(Output({'role': ABRP_SWITCH + RESPONSE, 'vin': MATCH}, 'children'),
|
||||
@@ -267,41 +273,44 @@ def serve_layout():
|
||||
logger.debug("Create new layout")
|
||||
try:
|
||||
figures.get_figures(trips, chargings)
|
||||
data_div = html.Div([
|
||||
dcc.RangeSlider(
|
||||
id='date-slider',
|
||||
min=min_millis,
|
||||
max=max_millis,
|
||||
step=step,
|
||||
marks=marks,
|
||||
value=[min_millis, max_millis],
|
||||
),
|
||||
html.Div([
|
||||
dbc.Tabs([
|
||||
dbc.Tab(label="Summary", tab_id="summary",
|
||||
children=[
|
||||
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"),
|
||||
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]),
|
||||
dbc.Tab(label="Charge", tab_id="charge", id="tab_charge", children=[figures.battery_table]),
|
||||
dbc.Tab(label="Map", tab_id="map", children=[
|
||||
dcc.Graph(figure=figures.trips_map, id="trips_map", style={"height": '90vh'})]),
|
||||
dbc.Tab(label="Control", tab_id="control", children=dbc.Tabs(id="control-tabs",
|
||||
children=__get_control_tabs()))
|
||||
],
|
||||
id="tabs",
|
||||
active_tab="summary"),
|
||||
html.Div(id=EMPTY_DIV),
|
||||
])])
|
||||
summary_tab = [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"),
|
||||
figures.consumption_graph_by_temp]
|
||||
maps = dcc.Graph(figure=figures.trips_map, id="trips_map", style={"height": '90vh'})
|
||||
create_callback()
|
||||
range_slider = dcc.RangeSlider(
|
||||
id='date-slider',
|
||||
min=min_millis,
|
||||
max=max_millis,
|
||||
step=step,
|
||||
marks=marks,
|
||||
value=[min_millis, max_millis],
|
||||
)
|
||||
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.debug(traceback.format_exc())
|
||||
data_div = ERROR_DIV
|
||||
range_slider = html.Div()
|
||||
data_div = html.Div([
|
||||
range_slider,
|
||||
html.Div([
|
||||
dbc.Tabs([
|
||||
dbc.Tab(label="Summary", tab_id="summary", children=summary_tab),
|
||||
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]),
|
||||
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()))
|
||||
],
|
||||
id="tabs",
|
||||
active_tab="summary",
|
||||
persistence=True),
|
||||
html.Div(id=EMPTY_DIV),
|
||||
])])
|
||||
cached_layout = dbc.Container(fluid=True, children=[html.H1('My car info'), data_div])
|
||||
return cached_layout
|
||||
|
||||
|
||||
Reference in New Issue
Block a user