From c5b174def8aff45dce0f185dcf6d88b32290b3b6 Mon Sep 17 00:00:00 2001 From: Florian Bezannier Date: Thu, 19 Nov 2020 10:52:19 +0100 Subject: [PATCH] improve charge control and logging --- ChargeControl.py | 28 ++++++++++++++++++---------- MyPSACC.py | 21 +++++++++++++-------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/ChargeControl.py b/ChargeControl.py index d275fde..df30a51 100644 --- a/ChargeControl.py +++ b/ChargeControl.py @@ -1,13 +1,16 @@ import json import threading +import traceback from copy import copy from datetime import datetime, timedelta from hashlib import md5 from time import sleep from MyPSACC import MyPSACC from MyLogger import logger +from psa_connectedcar.rest import ApiException class ChargeControls: + def __init__(self): self.list: dict = {} self._confighash = None @@ -44,13 +47,15 @@ class ChargeControls: class ChargeControl: + periodicity = 120 + MQTT_TIMEOUT = 60 def __init__(self, psacc:MyPSACC, vin, percentage_threshold, stop_hour): self.vin = vin self.percentage_threshold = percentage_threshold self.set_stop_hour(stop_hour) self.psacc = psacc self.retry_count = 0 - self.thread = None + self.thread:threading.Timer = None def set_stop_hour(self,stop_hour): if stop_hour == [0, 0]: @@ -63,33 +68,36 @@ class ChargeControl: self._next_stop_hour += timedelta(days=1) def start(self): - periodicity = 60 * 1 + periodicity = ChargeControl.periodicity now = datetime.now() if self._next_stop_hour is not None and self._next_stop_hour < now: stop_charge = True self._next_stop_hour += timedelta(days=1) - print("stop charge") + logger.info("it's time to stop the charge") else : stop_charge = False if self.percentage_threshold != 100 or stop_charge: - res = self.psacc.get_vehicle_info(self.vin) + res = None + try: + res = self.psacc.get_vehicle_info(self.vin) + except ApiException: + logger.error(traceback.format_exc()) if res is not None: status = res.energy[0]['charging']['status'] - print(f"charging status of {self.vin} is {status}") + level = res.energy[0]["level"] + logger.info(f"charging status of {self.vin} is {status}, battery level: {level}") if status == "InProgress": - level = res.energy[0]["level"] if (level >= self.percentage_threshold and self.retry_count < 2) or stop_charge: self.psacc.charge_now(self.vin,False) self.retry_count += 1 - sleep(45) + sleep(ChargeControl.MQTT_TIMEOUT) res = self.psacc.get_vehicle_info(self.vin) status = res.energy[0]['charging']['status'] if status == "InProgress": - print(f"retry to stop the charge of {self.vin}") + logger.warn(f"retry to stop the charge of {self.vin}") self.psacc.charge_now(self.vin, False) self.retry_count += 1 - periodicity = 60 * 1 if self._next_stop_hour is not None: next_in_second = (self._next_stop_hour- now).total_seconds() if next_in_second < periodicity: @@ -97,7 +105,7 @@ class ChargeControl: else: self.retry_count = 0 else: - print(f"error when get vehicle info of {self.vin}") + logger.error(f"error when get vehicle info of {self.vin}") self.thread = threading.Timer(periodicity, self.start) self.thread.start() diff --git a/MyPSACC.py b/MyPSACC.py index 6abcbcf..64fb464 100644 --- a/MyPSACC.py +++ b/MyPSACC.py @@ -19,7 +19,7 @@ oauhth_url = "https://idpcvs.peugeot.com/am/oauth2/access_token" remote_url = "https://api.groupe-psa.com/connectedcar/v4/virtualkey/remoteaccess/token?client_id=" scopes = ['openid profile'] realm = "clientsB2CPeugeot" - +MQTT_SERVER = "mwa.mpsa.com" class OpenIdCredentialManager(CredentialManager): def _grant_password_request(self, login: str, password: str, realm: str) -> dict: @@ -146,6 +146,7 @@ class MyPSACC: res = self.api().get_vehicle_status(self.get_vehicle_id_with_vin(vin)) return res + # monitor doesn't seem to work def newMonitor(self, vin, body): res = self.manager.post("https://api.groupe-psa.com/connectedcar/v4/user/vehicles/" + self.vehicles_list[vin][ "id"] + "/status?client_id=" + self.client_id, headers=MyPSACC.headers, data=body) @@ -202,23 +203,27 @@ class MyPSACC: def on_mqtt_disconnect(self, client, userdata, rc): try: - logger.info("Disconnected with result code " + str(rc)) + logger.warn("Disconnected with result code " + str(rc)) # Subscribing in on_connect() means that if we lose the connection and # reconnect then subscriptions will be renewed. - logger.info(mqtt.error_string(rc)) + logger.warn(mqtt.error_string(rc)) except: traceback.print_exc() def on_mqtt_message(self, client, userdata, msg): - logger.info(msg.topic + " " + str(msg.payload)) + logger.info(f"mqtt msg {msg.topic} {str(msg.payload)}") try: data = json.loads(msg.payload) - if data["return_code"] == 400: + if data["return_code"] == "0": + return + elif data["return_code"] == "400": self.manager._refresh_token() self.refresh_remote_token() logger.info("retry last request") + else: + logger.error(f'{data["return_code"]} : {data["reason"]}') except: - logger.info("mqtt msg hasn't return code") + logger.debug("mqtt msg hasn't return code") def start_mqtt(self): self.refresh_remote_token() @@ -228,7 +233,7 @@ class MyPSACC: self.mqtt_client.on_message = self.on_mqtt_message self.mqtt_client.on_disconnect = self.on_mqtt_disconnect self.mqtt_client.username_pw_set("IMA_OAUTH_ACCESS_TOKEN", self.remote_access_token) - self.mqtt_client.connect("mwa.mpsa.com", 8885, 60) + self.mqtt_client.connect(MQTT_SERVER, 8885, 60) self.mqtt_client.loop_start() return self.mqtt_client.is_connected() @@ -239,7 +244,7 @@ class MyPSACC: data = {"access_token": self.remote_access_token, "customer_id": self.customer_id, "correlation_id": correlation_id(date), "req_date": date_str, "vin": vin, "req_parameters": req_parameters} - logger.info(f"send mqtt msg: {data}") + return json.dumps(data) def get_charge_hour(self, vin):