diff --git a/src/const.py b/src/const.py index 1f02251..60a9c4c 100644 --- a/src/const.py +++ b/src/const.py @@ -5,14 +5,14 @@ VERSION = "v1.1.2" OAUTH_URL = "https://volvoid.eu.volvocars.com/as/token.oauth2" VEHICLES_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles" VEHICLE_DETAILS_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles/{0}" -WINDOW_STATE_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles/{0}/windows" +WINDOWS_STATE_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/windows" CLIMATE_START_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/commands/climatization-start" CLIMATE_STOP_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/commands/climatization-stop" CAR_LOCK_STATE_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/doors" CAR_LOCK_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/commands/lock" CAR_UNLOCK_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/commands/unlock" RECHARGE_STATE_URL = "https://api.volvocars.com/energy/v1/vehicles/{0}/recharge-status" -ODOMETER_STATE_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles/{0}/odometer" +ODOMETER_STATE_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/odometer" charging_system_states = {"CHARGING_SYSTEM_CHARGING": "Charging", "CHARGING_SYSTEM_IDLE": "Idle", "CHARGING_SYSTEM_FAULT": "Fault", "CHARGING_SYSTEM_UNSPECIFIED": "Unspecified"} @@ -24,7 +24,11 @@ supported_sensors = [ {"name": "Charging System Status", "id": "charging_system_status", "icon": "ev-plug-ccs2", "url": RECHARGE_STATE_URL}, {"name": "Estimated Charging Finish Time", "id": "estimated_charging_finish_time", "icon": "timer-sync-outline", "url": RECHARGE_STATE_URL}, {"name": "Odometer", "id": "odometer", "unit": "km" if settings["babelLocale"] != "en_US" else "mi", "icon": "counter", "url": ODOMETER_STATE_URL}, - {"name": "Last Data Update", "id": "last_data_update", "icon": "timer", "url": ""} + {"name": "Last Data Update", "id": "last_data_update", "icon": "timer", "url": ""}, + {"name": "Window Front Left", "id": "window_front_left", "icon": "car-door-lock", "url": WINDOWS_STATE_URL}, + {"name": "Window Front Right", "id": "window_front_right", "icon": "car-door-lock", "url": WINDOWS_STATE_URL}, + {"name": "Window Rear Left", "id": "window_rear_left", "icon": "car-door-lock", "url": WINDOWS_STATE_URL}, + {"name": "Window Rear Right", "id": "window_rear_right", "icon": "car-door-lock", "url": WINDOWS_STATE_URL} ] supported_switches = [ @@ -37,4 +41,4 @@ supported_locks = [ supported_buttons = [ {"name": "Update Data", "id": "update_data", "icon": "update", "url": ""} -] \ No newline at end of file +] diff --git a/src/volvo.py b/src/volvo.py index 4b46188..59ceba5 100644 --- a/src/volvo.py +++ b/src/volvo.py @@ -4,7 +4,8 @@ import mqtt from config import settings from babel.dates import format_datetime from const import charging_system_states, CLIMATE_START_URL, \ - OAUTH_URL, VEHICLES_URL, VEHICLE_DETAILS_URL, RECHARGE_STATE_URL + OAUTH_URL, VEHICLES_URL, VEHICLE_DETAILS_URL, RECHARGE_STATE_URL, \ + WINDOWS_STATE_URL session = requests.Session() session.headers = { @@ -16,8 +17,10 @@ session.headers = { token_expires_at: datetime refresh_token = None vins = [] -recharge_response = {} -recharge_last_update = {} +recharge_cached_api_response = {} +recharge_api_last_update = {} +window_cached_api_response = {} +window_api_last_update = {} def authorize(): @@ -143,25 +146,12 @@ def api_call(url, method, vin, sensor_id=None): if datetime.now() >= token_expires_at: refresh_auth() - global recharge_response, recharge_last_update if url == RECHARGE_STATE_URL: - # Minimize API calls for recharge API - if not vin in recharge_response: - # No API Data for vin cached, get fresh data from API - print("Starting " + method + " call against " + url) - response = session.get(url.format(vin), timeout=15) - recharge_response[vin] = response - recharge_last_update[vin] = datetime.now() - else: - if (datetime.now() - recharge_last_update[vin]).total_seconds() >= settings["updateInterval"]: - # Old Data in Cache, updating - print("Starting " + method + " call against " + url) - response = session.get(url.format(vin), timeout=15) - recharge_response[vin] = response - recharge_last_update[vin] = datetime.now() - else: - # Data is up do date, returning cached data - response = recharge_response[vin] + # Minimize API calls for recharge state + response = pull_recharge_api(url, method, vin) + elif url == WINDOWS_STATE_URL: + # Minimize API calls for window state + response = pull_window_api(url, method, vin) elif method == "GET": print("Starting " + method + " call against " + url) response = session.get(url.format(vin), timeout=15) @@ -188,6 +178,48 @@ def api_call(url, method, vin, sensor_id=None): return parse_api_data(data, sensor_id) +def pull_window_api(url, method, vin): + global window_cached_api_response, window_api_last_update + if not vin in window_cached_api_response: + # No API Data for vin cached, get fresh data from API + print("Starting " + method + " call against " + url) + response = session.get(url.format(vin), timeout=15) + window_cached_api_response[vin] = response + window_api_last_update[vin] = datetime.now() + else: + if (datetime.now() - window_api_last_update[vin]).total_seconds() >= settings["updateInterval"]: + # Old Data in Cache, updating + print("Starting " + method + " call against " + url) + response = session.get(url.format(vin), timeout=15) + window_cached_api_response[vin] = response + window_api_last_update[vin] = datetime.now() + else: + # Data is up do date, returning cached data + response = window_cached_api_response[vin] + return response + + +def pull_recharge_api(url, method, vin): + global recharge_cached_api_response, recharge_api_last_update + if not vin in recharge_cached_api_response: + # No API Data for vin cached, get fresh data from API + print("Starting " + method + " call against " + url) + response = session.get(url.format(vin), timeout=15) + recharge_cached_api_response[vin] = response + recharge_api_last_update[vin] = datetime.now() + else: + if (datetime.now() - recharge_api_last_update[vin]).total_seconds() >= settings["updateInterval"]: + # Old Data in Cache, updating + print("Starting " + method + " call against " + url) + response = session.get(url.format(vin), timeout=15) + recharge_cached_api_response[vin] = response + recharge_api_last_update[vin] = datetime.now() + else: + # Data is up do date, returning cached data + response = recharge_cached_api_response[vin] + return response + + def parse_api_data(data, sensor_id=None): if sensor_id == "battery_charge_level": if "batteryChargeLevel" in data["data"]: @@ -228,5 +260,13 @@ def parse_api_data(data, sensor_id=None): return data["data"]["carLocked"]["value"] elif sensor_id == "odometer": return data["data"]["odometer"]["value"] + elif sensor_id == "window_front_left": + return data["data"]["frontLeftWindowOpen"]["value"] + elif sensor_id == "window_front_right": + return data["data"]["frontRightWindowOpen"]["value"] + elif sensor_id == "window_rear_left": + return data["data"]["rearLeftWindowOpen"]["value"] + elif sensor_id == "window_rear_right": + return data["data"]["rearRightWindowOpen"]["value"] else: return ""