From 038c0f9aa622a923bd3fdafa43b82a6e97fcd82d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Br=C3=BCggemann?= Date: Sat, 2 Apr 2022 18:28:03 +0200 Subject: [PATCH] WIP: Multi Day Charge Control --- psa_car_controller/psa/RemoteClient.py | 4 ++-- .../psacc/application/charge_control.py | 24 ++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/psa_car_controller/psa/RemoteClient.py b/psa_car_controller/psa/RemoteClient.py index 2d17f78..cb68554 100644 --- a/psa_car_controller/psa/RemoteClient.py +++ b/psa_car_controller/psa/RemoteClient.py @@ -272,12 +272,12 @@ class RemoteClient: charge_type = IMMEDIATE_CHARGE else: charge_type = DELAYED_CHARGE - hour, minute = self.__get_charge_hour(vin) + hour, minute = self.get_charge_hour(vin) res = self.veh_charge_request(vin, hour, minute, charge_type) logger.info("charge_now: %s", res) return True - def __get_charge_hour(self, vin): + def get_charge_hour(self, vin): hour_str = self.vehicles_list.get_car_by_vin(vin).status.get_energy('Electric').charging.next_delayed_time try: return parse_hour(hour_str)[:2] diff --git a/psa_car_controller/psacc/application/charge_control.py b/psa_car_controller/psacc/application/charge_control.py index a2035e1..de648dc 100644 --- a/psa_car_controller/psacc/application/charge_control.py +++ b/psa_car_controller/psacc/application/charge_control.py @@ -8,7 +8,7 @@ from time import sleep import pytz -from psa_car_controller.psa.constants import DISCONNECTED, INPROGRESS, FINISHED +from psa_car_controller.psa.constants import DISCONNECTED, INPROGRESS, FINISHED, STOPPED from psa_car_controller.common.utils import RateLimitException from .psa_client import PSAClient @@ -55,7 +55,10 @@ class ChargeControl: self.retry_count = 0 return True - def force_update(self, quick_refresh): + def force_update(self, vehicle_status): + charging_mode = vehicle_status.get_energy('Electric').charging.charging_mode + quick_refresh = isinstance(charging_mode, str) and charging_mode == "Quick" + # force update if the car doesn't send info during 10 minutes last_update = self.psacc.vehicles_list.get_car_by_vin(self.vin).get_status().get_energy('Electric').updated_at if quick_refresh: @@ -68,17 +71,21 @@ class ChargeControl: except RateLimitException: logger.exception("force_update:") + def __is_approaching_scheduled_time(self, now: datetime): + scheduled_hour, scheduled_minute = self.psacc.remote_client.get_charge_hour(self.vin) + minutes_passed = now.hour * 60 + now.minute + scheduled_minute = scheduled_hour * 60 + scheduled_minute + return minutes_passed < scheduled_minute and scheduled_minute - minutes_passed < 30 + def process(self): now = datetime.now() try: vehicle_status = self.psacc.vehicles_list.get_car_by_vin(self.vin).get_status() status = vehicle_status.get_energy('Electric').charging.status level = vehicle_status.get_energy('Electric').level - if status == "InProgress" and self.percentage_threshold < 100: + if status == INPROGRESS and self.percentage_threshold < 100: logger.info("charging status of %s is %s, battery level: %d", self.vin, status, level) - charging_mode = vehicle_status.get_energy('Electric').charging.charging_mode - quick_refresh = isinstance(charging_mode, str) and charging_mode == "Quick" - self.force_update(quick_refresh) + self.force_update(vehicle_status) if level >= self.percentage_threshold and self.retry_count < 2: logger.info("Charge threshold is reached, stop the charge") self.control_charge_with_ack(False) @@ -94,6 +101,11 @@ class ChargeControl: thread = threading.Timer(periodicity, self.process) thread.setDaemon(True) thread.start() + elif status == STOPPED and self.percentage_threshold < 100 and level >= self.percentage_threshold and self.__is_approaching_scheduled_time(now): + logger.info("Approaching scheduled charging time, but should not charge. Postponing charge hour!") + self.force_update(vehicle_status) + hour = now.hour - 1 if now.hour > 0 else 23 + self.psacc.remote_client.change_charge_hour(self.vin, hour, 0) else: if self._next_stop_hour is not None and self._next_stop_hour < now: self._next_stop_hour += timedelta(days=1)