forked from peter/volvo2mqtt
Add window sensors
This commit is contained in:
+8
-4
@@ -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": ""}
|
||||
]
|
||||
]
|
||||
|
||||
+61
-21
@@ -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 ""
|
||||
|
||||
Reference in New Issue
Block a user