def on_mqtt_message(self, client, userdata, msg): try: logger.info("mqtt msg %s %s", msg.topic, msg.payload) data = json.loads(msg.payload) charge_info = None if msg.topic.startswith(MQTT_RESP_TOPIC): if "return_code" not in data: logger.debug("mqtt msg hasn't return code") elif data["return_code"] == "400": self.refresh_remote_token(force=True) logger.error("retry last request, token was expired") elif data["return_code"] == "300": logger.error('%d', data["return_code"]) elif data["return_code"] != "0": logger.error('%s : %s', data["return_code"], data["reason"]) if msg.topic.endswith("/VehicleState"): charge_info = data["resp_data"]["charging_state"] self.precond_programs[data["vin"]] = data["resp_data"][ "precond_state"]["programs"] elif msg.topic.startswith(MQTT_EVENT_TOPIC): charge_info = data["charging_state"] if charge_info is not None and charge_info[ 'remaining_time'] != 0 and charge_info['rate'] == 0: # fix a psa server bug where charge beginning without status api being properly updated logger.warning("charge begin but API isn't updated") sleep(60) self.wakeup(data["vin"]) except KeyError: logger.error(traceback.format_exc())
def control_charge_with_ack(self, charge: bool): self.psacc.charge_now(self.vin, charge) self.retry_count += 1 sleep(ChargeControl.MQTT_TIMEOUT) vehicle_status = self.psacc.get_vehicle_info(self.vin) status = vehicle_status.get_energy('Electric').charging.status if status in (FINISHED, DISCONNECTED): logger.warning("Car state isn't compatible with charging %s", status) if (status == INPROGRESS) != charge: logger.warning("retry to control the charge of %s", self.vin) self.psacc.charge_now(self.vin, charge) self.retry_count += 1 return False self.retry_count = 0 return True
def start_app(title, base_path, debug: bool, host, port): global app, dash_app, dispatcher try: lang = locale.getlocale()[0].split("_")[0] locale.setlocale(locale.LC_TIME, ".".join(locale.getlocale())) #make sure LC_TIME is set locale_url = [f"https://cdn.plot.ly/plotly-locale-{lang}-latest.js"] except (IndexError, locale.Error): locale_url = None logger.warning("Can't get language") app = Flask(__name__) app.config["DEBUG"] = debug if base_path == "/": application = DispatcherMiddleware(app) requests_pathname_prefix = None else: application = DispatcherMiddleware(Flask('dummy_app'), {base_path: app}) requests_pathname_prefix = base_path + "/" dash_app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP], external_scripts=locale_url, title=title, server=app, requests_pathname_prefix=requests_pathname_prefix) # keep this line import web.views return run_simple(host, port, application, use_reloader=False, use_debugger=debug)
def set_energy_capacity(self, battery_power=None, fuel_capacity=None, max_elec_consumption=None, max_fuel_consumption=None): if battery_power is not None and fuel_capacity is not None: self.battery_power = battery_power self.fuel_capacity = fuel_capacity elif self.label in ENERGY_CAPACITY: self.battery_power = ENERGY_CAPACITY[self.label]["BATTERY_POWER"] self.fuel_capacity = ENERGY_CAPACITY[self.label]["FUEL_CAPACITY"] else: logger.warning("Can't get car model please check %s", CARS_FILE) self.battery_power = DEFAULT_BATTERY_POWER self.fuel_capacity = DEFAULT_FUEL_CAPACITY if self.is_electric(): self.max_fuel_consumption = 0 else: self.max_fuel_consumption = max_fuel_consumption or DEFAULT_MAX_FUEL_CONSUMPTION if self.is_thermal(): self.max_elec_consumption = 0 else: self.max_elec_consumption = max_elec_consumption or DEFAULT_MAX_ELEC_CONSUMPTION
def on_mqtt_disconnect(self, client, userdata, rc): logger.warning("Disconnected with result code %d", rc) if rc == 1: self.refresh_remote_token(force=True) else: logger.warning(mqtt.error_string(rc))
def serve_layout(): global cached_layout if cached_layout is None: 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'}) ]), ], id="tabs", active_tab="summary", ), html.Div(id="tab-content", className="p-4"), ]) ]) except (IndexError, TypeError, NameError): logger.warning( "Failed to generate figure, there is probably not enough data yet" ) logger.debug(traceback.format_exc()) data_div = ERROR_DIV cached_layout = dbc.Container( fluid=True, children=[html.H1('My car info'), data_div]) return cached_layout