From cd3ec2a1a93d16a917787198c2861a9b32b4b096 Mon Sep 17 00:00:00 2001 From: mdkeil Date: Fri, 24 Nov 2023 12:10:12 +0100 Subject: [PATCH 1/9] fixed ApiException 400 fix #678 fix #674 --- psa_car_controller/psacc/application/psa_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psa_car_controller/psacc/application/psa_client.py b/psa_car_controller/psacc/application/psa_client.py index 331e652..8df313f 100644 --- a/psa_car_controller/psacc/application/psa_client.py +++ b/psa_car_controller/psacc/application/psa_client.py @@ -102,7 +102,7 @@ class PSAClient: else: for _ in range(0, 2): try: - res = self.api().get_vehicle_status(car.vehicle_id, extension=["odometer"]) + res = self.api().get_vehicle_status(car.vehicle_id) if res is not None: car.status = res if self._record_enabled: From d9799726a5b44b3e7f558954258f960807ac930c Mon Sep 17 00:00:00 2001 From: Mikado8231 <18015877+Mikado8231@users.noreply.github.com> Date: Wed, 15 Nov 2023 21:02:05 +0100 Subject: [PATCH 2/9] [FIX] Dash battery_table typing --- psa_car_controller/web/figures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psa_car_controller/web/figures.py b/psa_car_controller/web/figures.py index 847914d..9ec1513 100644 --- a/psa_car_controller/web/figures.py +++ b/psa_car_controller/web/figures.py @@ -147,7 +147,7 @@ def get_figures(car: Car): 'format': deepcopy(nb_format).symbol_suffix(" kWh").precision(2)}, {'id': 'price', 'name': 'price', 'type': 'numeric', 'format': deepcopy(nb_format).symbol_suffix(" " + CURRENCY).precision(2), 'editable': True}, - {'id': 'charging_mode', 'name': 'charging mode', 'type': 'string'}, + {'id': 'charging_mode', 'name': 'charging mode', 'type': 'text'}, {'id': 'mileage', 'name': 'mileage', 'type': 'numeric', 'format': nb_format}, ], data=[], From 26df9f35a974a186f564089ead545200576b354a Mon Sep 17 00:00:00 2001 From: Mikado8231 <18015877+Mikado8231@users.noreply.github.com> Date: Sun, 12 Nov 2023 12:10:33 +0100 Subject: [PATCH 3/9] [ENH] Add duration in Charge table - Add 2 new columns duration (string + min) in Charge tab - Data calculated on the fly to display in the table (No fields in DB) --- .../psacc/application/charging.py | 20 +++++++++++++++---- psa_car_controller/psacc/repository/db.py | 7 +++++++ psa_car_controller/web/figures.py | 3 +++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/psa_car_controller/psacc/application/charging.py b/psa_car_controller/psacc/application/charging.py index 70f59a3..d75dadc 100644 --- a/psa_car_controller/psacc/application/charging.py +++ b/psa_car_controller/psacc/application/charging.py @@ -20,10 +20,10 @@ class Charging: @staticmethod def get_chargings() -> List[dict]: - conn = Database.get_db() - res = conn.execute("select * from battery ORDER BY start_at").fetchall() - conn.close() - return list(map(dict, res)) + charge_db = Database.get_all_charge() + charge_list = list(map(dict, charge_db)) + Charging._calculated_fields(charge_list) + return charge_list @staticmethod def get_battery_curve(conn, charge, car) -> List[BatteryChargeCurve]: @@ -97,3 +97,15 @@ class Charging: Charging.update_chargings(conn, last_charge, car) conn.commit() conn.close() + + @staticmethod + def _calculated_fields(charge_list: list): + for c in charge_list: + if c.get("stop_at") and c.get("start_at"): + c.update( + { + "duration_min": (c.get("stop_at") - c.get("start_at")).seconds + / 60, + "duration_str": str((c.get("stop_at") - c.get("start_at"))), + } + ) \ No newline at end of file diff --git a/psa_car_controller/psacc/repository/db.py b/psa_car_controller/psacc/repository/db.py index 65b94b1..78c9750 100644 --- a/psa_car_controller/psacc/repository/db.py +++ b/psa_car_controller/psacc/repository/db.py @@ -321,6 +321,13 @@ class Database: charges.append(Charge(**dict_key_to_lower_case(**row))) return charges + @staticmethod + def get_all_charge() -> List[Charge]: + conn = Database.get_db() + res = conn.execute("select * from battery ORDER BY start_at").fetchall() + conn.close() + return res + @staticmethod def update_charge(charge: Charge): # we don't need to update mileage, since it should be inserted at beginning of charge, diff --git a/psa_car_controller/web/figures.py b/psa_car_controller/web/figures.py index 9ec1513..1216a6b 100644 --- a/psa_car_controller/web/figures.py +++ b/psa_car_controller/web/figures.py @@ -139,6 +139,9 @@ def get_figures(car: Car): sort_by=[{'column_id': 'start_at_str', 'direction': 'desc'}], columns=[{'id': 'start_at_str', 'name': 'start at', 'type': 'datetime'}, {'id': 'stop_at_str', 'name': 'stop at', 'type': 'datetime'}, + {'id': 'duration_str', 'name': 'duration', 'type': 'text'}, + {'id': 'duration_min', 'name': 'duration (min)', 'type': 'numeric', + 'format': deepcopy(nb_format).symbol_suffix(" min").precision(0)}, {'id': 'start_level', 'name': 'start level', 'type': 'numeric'}, {'id': 'end_level', 'name': 'end level', 'type': 'numeric'}, {'id': 'co2', 'name': 'CO2', 'type': 'numeric', From dfa4e8fb8dd2ee9a41cd1b72f5bec4463b2939a5 Mon Sep 17 00:00:00 2001 From: Mikado8231 <18015877+Mikado8231@users.noreply.github.com> Date: Sun, 12 Nov 2023 23:22:28 +0100 Subject: [PATCH 4/9] [ENH] Add duration in Charge table - tests --- tests/test_unit.py | 4 +++- tests/utils.py | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_unit.py b/tests/test_unit.py index 5ee580c..38699aa 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -33,7 +33,7 @@ from psa_car_controller.psacc.repository.trips import Trips from psa_car_controller.psacc.utils.utils import get_temp from tests.data.car_status import FUEL_CAR_STATUS, ELECTRIC_CAR_STATUS, ELECTRIC_CAR_STATUS_V2 from tests.utils import DATA_DIR, record_position, latitude, longitude, date0, date1, date2, date3, record_charging, \ - vehicule_list, get_new_test_db, get_date, date4, compare_dict + vehicule_list, get_new_test_db, get_date, date4, compare_dict, duration_min, duration_str from psa_car_controller.web.figures import get_figures, get_battery_curve_fig, get_altitude_fig dummy_value = 0 @@ -237,6 +237,8 @@ class TestUnit(unittest.TestCase): assert isinstance(co2, float) assert compare_dict(chargings, [{'start_at': date0, 'stop_at': date3, + 'duration_str': duration_str, + 'duration_min' :duration_min, 'VIN': 'VR3UHZKX', 'start_level': 40, 'end_level': 85, diff --git a/tests/utils.py b/tests/utils.py index 530e109..f8a0dc6 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -21,6 +21,8 @@ date2 = date3 - timedelta(minutes=20) date1 = date3 - timedelta(minutes=40) date0 = date3 - timedelta(minutes=60) date4 = date3 + timedelta(minutes=1) +duration_min = (date3 - date0).seconds / 60 +duration_str = str(date3 - date0) vehicule_list = Cars() vehicule_list.extend( From e63dfd3ef5cbc13ea41bf0ccce3c32091c7c445e Mon Sep 17 00:00:00 2001 From: Mikado8231 <18015877+Mikado8231@users.noreply.github.com> Date: Mon, 13 Nov 2023 21:00:17 +0100 Subject: [PATCH 5/9] [FIX] Chargings duration bad conversion + dash type --- psa_car_controller/psacc/application/charging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psa_car_controller/psacc/application/charging.py b/psa_car_controller/psacc/application/charging.py index d75dadc..e58d649 100644 --- a/psa_car_controller/psacc/application/charging.py +++ b/psa_car_controller/psacc/application/charging.py @@ -104,7 +104,7 @@ class Charging: if c.get("stop_at") and c.get("start_at"): c.update( { - "duration_min": (c.get("stop_at") - c.get("start_at")).seconds + "duration_min": (c.get("stop_at") - c.get("start_at")).total_seconds() / 60, "duration_str": str((c.get("stop_at") - c.get("start_at"))), } From b158373eec8f901e8db992510961a129a94f9a07 Mon Sep 17 00:00:00 2001 From: Mikado8231 <18015877+Mikado8231@users.noreply.github.com> Date: Wed, 15 Nov 2023 23:46:21 +0100 Subject: [PATCH 6/9] [ENH] Display version + link to github --- .gitignore | 4 ++++ psa_car_controller/web/app.py | 3 ++- psa_car_controller/web/view/views.py | 15 +++++++++++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 58906f4..43438d8 100644 --- a/.gitignore +++ b/.gitignore @@ -148,3 +148,7 @@ config.json test.json charge_config.json cars.json +certs/ +*.log.* + +.vscode/ \ No newline at end of file diff --git a/psa_car_controller/web/app.py b/psa_car_controller/web/app.py index 977933f..7479390 100644 --- a/psa_car_controller/web/app.py +++ b/psa_car_controller/web/app.py @@ -76,7 +76,8 @@ def config_flask(title, base_path, debug: bool, host, port, reloader=False, # p else: application = DispatcherMiddleware(Flask('dummy_app'), {base_path: app}) requests_pathname_prefix = base_path + "/" - dash_app = DashCustom(external_stylesheets=[dbc.themes.BOOTSTRAP], external_scripts=locale_url, title=title, + dash_app = DashCustom(external_stylesheets=[dbc.themes.BOOTSTRAP, dbc.icons.BOOTSTRAP], + external_scripts=locale_url, title=title, server=app, requests_pathname_prefix=requests_pathname_prefix, suppress_callback_exceptions=True, serve_locally=False) dash_app.enable_dev_tools(debug) diff --git a/psa_car_controller/web/view/views.py b/psa_car_controller/web/view/views.py index 8fa49c8..f826ade 100644 --- a/psa_car_controller/web/view/views.py +++ b/psa_car_controller/web/view/views.py @@ -30,6 +30,7 @@ from psa_car_controller.web.view.config_views import log_layout, config_layout from psa_car_controller.web.tools.figurefilter import FigureFilter from psa_car_controller.web.view.control import get_control_tabs +from psa_car_controller import __version__ logger = CustomLogger.getLogger(__name__) EMPTY_DIV = "empty-div" @@ -46,11 +47,21 @@ def get_default_car() -> Car: def add_header(el): + version = "v" + __version__ + github_url= "https://github.com/flobz/psa_car_controller/releases/tag/"+version + dbc_version = dbc.Button(html.I(version, className="m-1"), + size='sm', + color="secondary", + className="me-1 bi bi-github", + external_link =True, href=github_url) return dbc.Row([dbc.Col(dcc.Link(html.H1('My car info'), href=dash_app.requests_pathname_external_prefix, style={"TextDecoration": "none"})), - dbc.Col(dcc.Link(html.Img(src="assets/images/settings.svg", width="30veh"), + dbc.Col(html.Div([dbc_version, + dcc.Link(html.Img(src="assets/images/settings.svg", width="30veh"), href=dash_app.requests_pathname_external_prefix + "config", - className="float-end"))]), el + className="float-end")], + className="d-grid gap-2 d-md-flex justify-content-md-end",))], + className='align-items-center'), el @dash_app.callback(Output('page-content', 'children'), From 26800679c03fcaa7b3d3c208b220d2102734a933 Mon Sep 17 00:00:00 2001 From: Mikado8231 <18015877+Mikado8231@users.noreply.github.com> Date: Mon, 20 Nov 2023 21:51:53 +0100 Subject: [PATCH 7/9] [ENH] Display in log at startup --- psa_car_controller/psacc/application/car_controller.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/psa_car_controller/psacc/application/car_controller.py b/psa_car_controller/psacc/application/car_controller.py index 5ab478f..7c2906f 100644 --- a/psa_car_controller/psacc/application/car_controller.py +++ b/psa_car_controller/psacc/application/car_controller.py @@ -15,6 +15,7 @@ from psa_car_controller.psacc.utils.utils import Singleton from .psa_client import PSAClient from psa_car_controller.common.mylogger import my_logger from psa_car_controller.psa.otp.otp import CONFIG_NAME as OTP_CONFIG_NAME, ConfigException +from psa_car_controller import __version__ DEFAULT_NAME = "config.json" @@ -75,6 +76,8 @@ class PSACarController(metaclass=Singleton): def load_app(self) -> bool: # pylint: disable=too-many-branches my_logger(handler_level=int(self.args.debug)) + + logger.info("App version %s", __version__) if self.args.config: self.config_name = self.args.config if path.isfile(self.config_name): From 56374202a134dc56ab9923bc2149b7de21dbe2e8 Mon Sep 17 00:00:00 2001 From: matteusz88 <80220568+matteusz88@users.noreply.github.com> Date: Fri, 24 Nov 2023 16:16:22 +0000 Subject: [PATCH 8/9] Update car_models.yml Added Peugeot Rifter - hope correctly! --- psa_car_controller/psacc/resources/car_models.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/psa_car_controller/psacc/resources/car_models.yml b/psa_car_controller/psacc/resources/car_models.yml index 4a089c8..601270b 100644 --- a/psa_car_controller/psacc/resources/car_models.yml +++ b/psa_car_controller/psacc/resources/car_models.yml @@ -459,3 +459,11 @@ abrp_name: reg: W0VEAZKXZP.* max_elec_consumption: 46 +- !CarModel + name: Peugeot Rifter + battery_power: 0 + fuel_capacity: 45 + abrp_name: + reg: VR3ECYHYCK.* + max_elec_consumption: 0 + max_fuel_consumption: 50 From 9bcc83ca35e27c7fd177dac4c498230129463617 Mon Sep 17 00:00:00 2001 From: matteusz88 <80220568+matteusz88@users.noreply.github.com> Date: Fri, 24 Nov 2023 16:23:55 +0000 Subject: [PATCH 9/9] Update car_models.yml --- psa_car_controller/psacc/resources/car_models.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/psa_car_controller/psacc/resources/car_models.yml b/psa_car_controller/psacc/resources/car_models.yml index 601270b..ef5d7e7 100644 --- a/psa_car_controller/psacc/resources/car_models.yml +++ b/psa_car_controller/psacc/resources/car_models.yml @@ -462,8 +462,8 @@ - !CarModel name: Peugeot Rifter battery_power: 0 - fuel_capacity: 45 + fuel_capacity: 50 abrp_name: reg: VR3ECYHYCK.* max_elec_consumption: 0 - max_fuel_consumption: 50 + max_fuel_consumption: 30