mirror of
https://github.com/Dielee/volvo2mqtt.git
synced 2026-08-13 19:29:52 +02:00
Add door sensors
This commit is contained in:
+8
-4
@@ -8,7 +8,7 @@ VEHICLE_DETAILS_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles/{
|
|||||||
WINDOWS_STATE_URL = "https://api.volvocars.com/connected-vehicle/v2/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_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"
|
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"
|
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_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"
|
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"
|
RECHARGE_STATE_URL = "https://api.volvocars.com/energy/v1/vehicles/{0}/recharge-status"
|
||||||
@@ -28,7 +28,11 @@ supported_sensors = [
|
|||||||
{"name": "Window Front Left", "id": "window_front_left", "icon": "car-door-lock", "url": WINDOWS_STATE_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 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 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}
|
{"name": "Window Rear Right", "id": "window_rear_right", "icon": "car-door-lock", "url": WINDOWS_STATE_URL},
|
||||||
|
{"name": "Door Front Left", "id": "door_front_left", "icon": "car-door-lock", "url": LOCK_STATE_URL},
|
||||||
|
{"name": "Door Front Right", "id": "door_front_right", "icon": "car-door-lock", "url": LOCK_STATE_URL},
|
||||||
|
{"name": "Door Rear Left", "id": "door_rear_left", "icon": "car-door-lock", "url": LOCK_STATE_URL},
|
||||||
|
{"name": "Door Rear Right", "id": "door_rear_right", "icon": "car-door-lock", "url": LOCK_STATE_URL}
|
||||||
]
|
]
|
||||||
|
|
||||||
supported_switches = [
|
supported_switches = [
|
||||||
@@ -36,9 +40,9 @@ supported_switches = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
supported_locks = [
|
supported_locks = [
|
||||||
{"name": "Lock state", "id": "lock_status", "icon": "lock", "url": CAR_LOCK_STATE_URL}
|
{"name": "Lock state", "id": "lock_status", "icon": "lock", "url": LOCK_STATE_URL}
|
||||||
]
|
]
|
||||||
|
|
||||||
supported_buttons = [
|
supported_buttons = [
|
||||||
{"name": "Update Data", "id": "update_data", "icon": "update", "url": ""}
|
{"name": "Force Update Data", "id": "update_data", "icon": "update", "url": ""}
|
||||||
]
|
]
|
||||||
|
|||||||
+4
-4
@@ -72,7 +72,7 @@ def on_message(client, userdata, msg):
|
|||||||
update_car_data()
|
update_car_data()
|
||||||
elif "update_data" in msg.topic:
|
elif "update_data" in msg.topic:
|
||||||
if payload == "PRESS":
|
if payload == "PRESS":
|
||||||
update_car_data()
|
update_car_data(True)
|
||||||
|
|
||||||
|
|
||||||
def update_loop():
|
def update_loop():
|
||||||
@@ -84,12 +84,12 @@ def update_loop():
|
|||||||
time.sleep(settings["updateInterval"])
|
time.sleep(settings["updateInterval"])
|
||||||
|
|
||||||
|
|
||||||
def update_car_data():
|
def update_car_data(force_update=False):
|
||||||
global last_data_update
|
global last_data_update
|
||||||
last_data_update = format_datetime(datetime.now(), format="medium", locale=settings["babelLocale"])
|
last_data_update = format_datetime(datetime.now(), format="medium", locale=settings["babelLocale"])
|
||||||
for vin in volvo.vins:
|
for vin in volvo.vins:
|
||||||
for lock in supported_locks:
|
for lock in supported_locks:
|
||||||
state = volvo.api_call(lock["url"], "GET", vin, lock["id"])
|
state = volvo.api_call(lock["url"], "GET", vin, lock["id"], force_update)
|
||||||
mqtt_client.publish(
|
mqtt_client.publish(
|
||||||
f"homeassistant/lock/{vin}_{lock['id']}/state",
|
f"homeassistant/lock/{vin}_{lock['id']}/state",
|
||||||
state
|
state
|
||||||
@@ -110,7 +110,7 @@ def update_car_data():
|
|||||||
if sensor["id"] == "last_data_update":
|
if sensor["id"] == "last_data_update":
|
||||||
state = last_data_update
|
state = last_data_update
|
||||||
else:
|
else:
|
||||||
state = volvo.api_call(sensor["url"], "GET", vin, sensor["id"])
|
state = volvo.api_call(sensor["url"], "GET", vin, sensor["id"], force_update)
|
||||||
mqtt_client.publish(
|
mqtt_client.publish(
|
||||||
f"homeassistant/sensor/{vin}_{sensor['id']}/state",
|
f"homeassistant/sensor/{vin}_{sensor['id']}/state",
|
||||||
state
|
state
|
||||||
|
|||||||
+42
-8
@@ -5,7 +5,7 @@ from config import settings
|
|||||||
from babel.dates import format_datetime
|
from babel.dates import format_datetime
|
||||||
from const import charging_system_states, CLIMATE_START_URL, \
|
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
|
WINDOWS_STATE_URL, LOCK_STATE_URL
|
||||||
|
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
session.headers = {
|
session.headers = {
|
||||||
@@ -21,6 +21,8 @@ recharge_cached_api_response = {}
|
|||||||
recharge_api_last_update = {}
|
recharge_api_last_update = {}
|
||||||
window_cached_api_response = {}
|
window_cached_api_response = {}
|
||||||
window_api_last_update = {}
|
window_api_last_update = {}
|
||||||
|
door_cached_api_response = {}
|
||||||
|
door_api_last_update = {}
|
||||||
|
|
||||||
|
|
||||||
def authorize():
|
def authorize():
|
||||||
@@ -141,17 +143,20 @@ def disable_climate(vin):
|
|||||||
mqtt.update_car_data()
|
mqtt.update_car_data()
|
||||||
|
|
||||||
|
|
||||||
def api_call(url, method, vin, sensor_id=None):
|
def api_call(url, method, vin, sensor_id=None, force_update=False):
|
||||||
global token_expires_at
|
global token_expires_at
|
||||||
if datetime.now() >= token_expires_at:
|
if datetime.now() >= token_expires_at:
|
||||||
refresh_auth()
|
refresh_auth()
|
||||||
|
|
||||||
if url == RECHARGE_STATE_URL:
|
if url == RECHARGE_STATE_URL:
|
||||||
# Minimize API calls for recharge state
|
# Minimize API calls for recharge state
|
||||||
response = pull_recharge_api(url, method, vin)
|
response = pull_recharge_api(url, method, vin, force_update)
|
||||||
elif url == WINDOWS_STATE_URL:
|
elif url == WINDOWS_STATE_URL:
|
||||||
# Minimize API calls for window state
|
# Minimize API calls for window state
|
||||||
response = pull_window_api(url, method, vin)
|
response = pull_window_api(url, method, vin, force_update)
|
||||||
|
elif url == LOCK_STATE_URL:
|
||||||
|
# Minimize API calls for door state
|
||||||
|
response = pull_door_api(url, method, vin, force_update)
|
||||||
elif method == "GET":
|
elif method == "GET":
|
||||||
print("Starting " + method + " call against " + url)
|
print("Starting " + method + " call against " + url)
|
||||||
response = session.get(url.format(vin), timeout=15)
|
response = session.get(url.format(vin), timeout=15)
|
||||||
@@ -178,9 +183,30 @@ def api_call(url, method, vin, sensor_id=None):
|
|||||||
return parse_api_data(data, sensor_id)
|
return parse_api_data(data, sensor_id)
|
||||||
|
|
||||||
|
|
||||||
def pull_window_api(url, method, vin):
|
def pull_door_api(url, method, vin, force_update=False):
|
||||||
|
global door_cached_api_response, door_api_last_update
|
||||||
|
if not vin in door_cached_api_response or force_update:
|
||||||
|
# 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)
|
||||||
|
door_cached_api_response[vin] = response
|
||||||
|
door_api_last_update[vin] = datetime.now()
|
||||||
|
else:
|
||||||
|
if (datetime.now() - door_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)
|
||||||
|
door_cached_api_response[vin] = response
|
||||||
|
door_api_last_update[vin] = datetime.now()
|
||||||
|
else:
|
||||||
|
# Data is up do date, returning cached data
|
||||||
|
response = door_cached_api_response[vin]
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def pull_window_api(url, method, vin, force_update=False):
|
||||||
global window_cached_api_response, window_api_last_update
|
global window_cached_api_response, window_api_last_update
|
||||||
if not vin in window_cached_api_response:
|
if not vin in window_cached_api_response or force_update:
|
||||||
# No API Data for vin cached, get fresh data from API
|
# No API Data for vin cached, get fresh data from API
|
||||||
print("Starting " + method + " call against " + url)
|
print("Starting " + method + " call against " + url)
|
||||||
response = session.get(url.format(vin), timeout=15)
|
response = session.get(url.format(vin), timeout=15)
|
||||||
@@ -199,9 +225,9 @@ def pull_window_api(url, method, vin):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def pull_recharge_api(url, method, vin):
|
def pull_recharge_api(url, method, vin, force_update=False):
|
||||||
global recharge_cached_api_response, recharge_api_last_update
|
global recharge_cached_api_response, recharge_api_last_update
|
||||||
if not vin in recharge_cached_api_response:
|
if not vin in recharge_cached_api_response or force_update:
|
||||||
# No API Data for vin cached, get fresh data from API
|
# No API Data for vin cached, get fresh data from API
|
||||||
print("Starting " + method + " call against " + url)
|
print("Starting " + method + " call against " + url)
|
||||||
response = session.get(url.format(vin), timeout=15)
|
response = session.get(url.format(vin), timeout=15)
|
||||||
@@ -268,5 +294,13 @@ def parse_api_data(data, sensor_id=None):
|
|||||||
return data["data"]["rearLeftWindowOpen"]["value"]
|
return data["data"]["rearLeftWindowOpen"]["value"]
|
||||||
elif sensor_id == "window_rear_right":
|
elif sensor_id == "window_rear_right":
|
||||||
return data["data"]["rearRightWindowOpen"]["value"]
|
return data["data"]["rearRightWindowOpen"]["value"]
|
||||||
|
elif sensor_id == "door_front_left":
|
||||||
|
return data["data"]["frontLeftDoorOpen"]["value"]
|
||||||
|
elif sensor_id == "door_front_right":
|
||||||
|
return data["data"]["frontRightDoorOpen"]["value"]
|
||||||
|
elif sensor_id == "door_rear_left":
|
||||||
|
return data["data"]["rearLeftDoorOpen"]["value"]
|
||||||
|
elif sensor_id == "door_rear_right":
|
||||||
|
return data["data"]["rearRightDoorOpen"]["value"]
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
Reference in New Issue
Block a user