From 8803f9ff1d8d0f3e22115a264de764fdbfe0f3ff Mon Sep 17 00:00:00 2001 From: Linus Dietz <45101649+Dielee@users.noreply.github.com> Date: Mon, 20 Nov 2023 19:33:27 +0100 Subject: [PATCH] Add api backend state sensor --- src/CHANGELOG.md | 6 ++++++ src/config.yaml | 2 +- src/const.py | 4 +++- src/mqtt.py | 2 ++ src/volvo.py | 24 +++++++++++++++++++++--- 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/CHANGELOG.md b/src/CHANGELOG.md index 377513b..43d9711 100644 --- a/src/CHANGELOG.md +++ b/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## v1.8.15 +### 🚀 Features: + +- Move `batteryChargeLevel` to the new v2 fuel endpoint +- Add api backend status sensor + ## v1.8.14 ### 🐛 Bug Fixes: diff --git a/src/config.yaml b/src/config.yaml index a499734..fd190c8 100644 --- a/src/config.yaml +++ b/src/config.yaml @@ -1,6 +1,6 @@ name: "Volvo2Mqtt" description: "Volvo AAOS MQTT bridge" -version: "1.8.14" +version: "1.8.15" slug: "volvo2mqtt" init: false url: "https://github.com/Dielee/volvo2mqtt" diff --git a/src/const.py b/src/const.py index 3fc1e3f..9718789 100644 --- a/src/const.py +++ b/src/const.py @@ -21,6 +21,7 @@ STATISTICS_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/statistics" ENGINE_DIAGNOSTICS_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/engine" VEHICLE_DIAGNOSTICS_URL = "https://api.volvocars.com/connected-vehicle/v2/vehicles/{0}/diagnostics" +API_BACKEND_STATUS = "https://oip-dev-bff.euwest1.production.volvo.care/api/v1/backend-status" units = { "en_GB": { @@ -115,7 +116,8 @@ {"name": "Hours to Service", "domain": "sensor", "id": "hours_to_service", "unit": "hour", "icon": "wrench-clock", "url": VEHICLE_DIAGNOSTICS_URL}, {"name": "Distance to Service", "domain": "sensor", "id": "km_to_service", "unit": "km" if not units.get(settings["babelLocale"]) else units[settings["babelLocale"]]["distance_to_service"]["unit"], "icon": "wrench-clock", "url": VEHICLE_DIAGNOSTICS_URL}, {"name": "Time to Service", "domain": "sensor", "id": "time_to_service", "icon": "wrench-clock", "url": VEHICLE_DIAGNOSTICS_URL}, - {"name": "Service warning status", "domain": "sensor", "id": "service_warning_status", "icon": "alert-outline", "url": VEHICLE_DIAGNOSTICS_URL} + {"name": "Service warning status", "domain": "sensor", "id": "service_warning_status", "icon": "alert-outline", "url": VEHICLE_DIAGNOSTICS_URL}, + {"name": "API Backend status", "domain": "sensor", "id": "api_backend_status", "icon": "alert"} ] old_entity_ids = ["months_to_service", "service_warning_trigger"] diff --git a/src/mqtt.py b/src/mqtt.py index 475f63a..5d23425 100644 --- a/src/mqtt.py +++ b/src/mqtt.py @@ -243,6 +243,8 @@ def update_car_data(force_update=False, overwrite={}): state = last_data_update elif entity["id"] == "active_schedules": state = active_schedules[vin] + elif entity["id"] == "api_backend_status": + state = volvo.backend_status else: if entity["id"] == ov_entity_id and vin == ov_vin: state = ov_state diff --git a/src/volvo.py b/src/volvo.py index 84e27e6..e113535 100644 --- a/src/volvo.py +++ b/src/volvo.py @@ -4,7 +4,7 @@ import util import time import re -from threading import current_thread +from threading import current_thread, Thread from datetime import datetime, timedelta from config import settings from babel.dates import format_datetime @@ -12,7 +12,7 @@ from const import charging_system_states, charging_connection_states, door_states, window_states, \ OAUTH_URL, VEHICLES_URL, VEHICLE_DETAILS_URL, RECHARGE_STATE_URL, CLIMATE_START_URL, \ WINDOWS_STATE_URL, LOCK_STATE_URL, TYRE_STATE_URL, supported_entities, BATTERY_CHARGE_STATE_URL, \ - STATISTICS_URL, ENGINE_DIAGNOSTICS_URL, engine_states + STATISTICS_URL, ENGINE_DIAGNOSTICS_URL, API_BACKEND_STATUS, engine_states session = requests.Session() session.headers = { @@ -27,6 +27,7 @@ supported_endpoints = {} cached_requests = {} vcc_api_keys = [] +backend_status = "" def authorize(): @@ -54,6 +55,7 @@ def authorize(): get_vcc_api_keys() get_vehicles() check_supported_endpoints() + Thread(target=get_backend_status).start() else: message = auth.json() raise Exception(message["error_description"]) @@ -314,6 +316,20 @@ def check_engine_status(vin): time.sleep(5) +def get_backend_status(): + global backend_status + while True: + response = session.get(API_BACKEND_STATUS, timeout=15) + try: + data = response.json() + backend_status = data["message"] if util.keys_exists(data, "message") else "No warnings" + except JSONDecodeError as e: + backend_status = "No warnings" + + # Update every hour + time.sleep(3600) + + def api_call(url, method, vin, sensor_id=None, force_update=False, key_change=False): if datetime.now(util.TZ) >= token_expires_at: refresh_auth() @@ -411,7 +427,9 @@ def cached_request(url, method, vin, force_update=False, key_change=False): def parse_api_data(data, sensor_id=None): - data = data["data"] + if sensor_id != "api_backend_status": + data = data["data"] + if sensor_id == "battery_charge_level": return data["batteryChargeLevel"]["value"] if util.keys_exists(data, "batteryChargeLevel") else None elif sensor_id == "electric_range":