forked from peter/volvo2mqtt
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53114e9d6c | ||
|
|
bbc6ccb840 | ||
|
|
1d07644a9c | ||
|
|
e0152fa82d |
+1
-1
@@ -1,6 +1,6 @@
|
||||
name: "Volvo2Mqtt"
|
||||
description: "Volvo AAOS MQTT bridge"
|
||||
version: "1.2.0"
|
||||
version: "1.2.2"
|
||||
slug: "volvo2mqtt"
|
||||
init: false
|
||||
url: "https://github.com/Dielee/volvo2mqtt"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
from config import settings
|
||||
|
||||
VERSION = "v1.2.0"
|
||||
VERSION = "v1.2.2"
|
||||
|
||||
OAUTH_URL = "https://volvoid.eu.volvocars.com/as/token.oauth2"
|
||||
VEHICLES_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles"
|
||||
|
||||
+5
-6
@@ -133,10 +133,9 @@ def create_ha_devices():
|
||||
for device_tracker in supported_device_trackers:
|
||||
config = {
|
||||
"name": device_tracker['name'],
|
||||
"object_id": device_tracker['id'],
|
||||
"object_id": f"volvo_{vin}_{device_tracker['id']}",
|
||||
"schema": "state",
|
||||
"icon": f"mdi:{device_tracker['icon']}",
|
||||
|
||||
"state_topic": f"homeassistant/device_tracker/{vin}_{device_tracker['id']}/state",
|
||||
"device": device,
|
||||
"unique_id": f"volvoAAOS2mqtt_{vin}_{device_tracker['id']}",
|
||||
@@ -151,7 +150,7 @@ def create_ha_devices():
|
||||
command_topic = f"homeassistant/button/{vin}_{button['id']}/command"
|
||||
config = {
|
||||
"name": button['name'],
|
||||
"object_id": button['id'],
|
||||
"object_id": f"volvo_{vin}_{button['id']}",
|
||||
"schema": "state",
|
||||
"icon": f"mdi:{button['icon']}",
|
||||
"state_topic": f"homeassistant/button/{vin}_{button['id']}/state",
|
||||
@@ -170,7 +169,7 @@ def create_ha_devices():
|
||||
command_topic = f"homeassistant/lock/{vin}_{lock['id']}/command"
|
||||
config = {
|
||||
"name": lock['name'],
|
||||
"object_id": lock['id'],
|
||||
"object_id": f"volvo_{vin}_{lock['id']}",
|
||||
"schema": "state",
|
||||
"icon": f"mdi:{lock['icon']}",
|
||||
"state_topic": f"homeassistant/lock/{vin}_{lock['id']}/state",
|
||||
@@ -190,7 +189,7 @@ def create_ha_devices():
|
||||
command_topic = f"homeassistant/switch/{vin}_{switch['id']}/command"
|
||||
config = {
|
||||
"name": switch['name'],
|
||||
"object_id": switch['id'],
|
||||
"object_id": f"volvo_{vin}_{switch['id']}",
|
||||
"schema": "state",
|
||||
"icon": f"mdi:{switch['icon']}",
|
||||
"state_topic": f"homeassistant/switch/{vin}_{switch['id']}/state",
|
||||
@@ -209,7 +208,7 @@ def create_ha_devices():
|
||||
for sensor in supported_sensors:
|
||||
config = {
|
||||
"name": sensor['name'],
|
||||
"object_id": sensor['id'],
|
||||
"object_id": f"volvo_{vin}_{sensor['id']}",
|
||||
"schema": "state",
|
||||
"icon": f"mdi:{sensor['icon']}",
|
||||
"state_topic": f"homeassistant/sensor/{vin}_{sensor['id']}/state",
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
def keys_exists(element, *keys):
|
||||
""""
|
||||
Check if *keys (nested) exists in `element` (dict).
|
||||
Thanks stackoverflow: https://stackoverflow.com/questions/43491287/elegant-way-to-check-if-a-nested-key-exists-in-a-dict
|
||||
"""
|
||||
if not isinstance(element, dict):
|
||||
raise AttributeError('keys_exists() expects dict as first argument.')
|
||||
if len(keys) == 0:
|
||||
raise AttributeError('keys_exists() expects at least two arguments, one given.')
|
||||
|
||||
_element = element
|
||||
for key in keys:
|
||||
try:
|
||||
_element = _element[key]
|
||||
except KeyError:
|
||||
return False
|
||||
return True
|
||||
+45
-51
@@ -3,6 +3,7 @@ from datetime import datetime, timedelta
|
||||
import mqtt
|
||||
from config import settings
|
||||
from babel.dates import format_datetime
|
||||
from util import keys_exists
|
||||
from const import charging_system_states, CLIMATE_START_URL, \
|
||||
OAUTH_URL, VEHICLES_URL, VEHICLE_DETAILS_URL, RECHARGE_STATE_URL, \
|
||||
WINDOWS_STATE_URL, LOCK_STATE_URL
|
||||
@@ -247,75 +248,68 @@ def pull_recharge_api(url, method, vin, force_update=False):
|
||||
|
||||
|
||||
def parse_api_data(data, sensor_id=None):
|
||||
data = data["data"]
|
||||
if sensor_id == "battery_charge_level":
|
||||
if "batteryChargeLevel" in data["data"]:
|
||||
return data["data"]["batteryChargeLevel"]["value"]
|
||||
else:
|
||||
return ""
|
||||
return data["batteryChargeLevel"]["value"] if keys_exists(data, "batteryChargeLevel") else 0
|
||||
elif sensor_id == "electric_range":
|
||||
if "electricRange" in data["data"]:
|
||||
return data["data"]["electricRange"]["value"]
|
||||
else:
|
||||
return ""
|
||||
return data["electricRange"]["value"] if keys_exists(data, "electricRange") else 0
|
||||
elif sensor_id == "charging_system_status":
|
||||
if "chargingSystemStatus" in data["data"]:
|
||||
return charging_system_states[data["data"]["chargingSystemStatus"]["value"]]
|
||||
else:
|
||||
return ""
|
||||
return charging_system_states[data["chargingSystemStatus"]["value"]] if keys_exists(data, "chargingSystemStatus") else ""
|
||||
elif sensor_id == "estimated_charging_time":
|
||||
if "chargingSystemStatus" in data["data"]:
|
||||
charging_system_state = charging_system_states[data["data"]["chargingSystemStatus"]["value"]]
|
||||
if keys_exists(data, "chargingSystemStatus"):
|
||||
charging_system_state = charging_system_states[data["chargingSystemStatus"]["value"]]
|
||||
if charging_system_state == "Charging":
|
||||
return data["data"]["estimatedChargingTime"]["value"]
|
||||
return data["estimatedChargingTime"]["value"] if keys_exists(data, "estimatedChargingTime") else ""
|
||||
else:
|
||||
return 0
|
||||
else:
|
||||
return ""
|
||||
elif sensor_id == "estimated_charging_finish_time":
|
||||
if "chargingSystemStatus" in data["data"]:
|
||||
charging_system_state = charging_system_states[data["data"]["chargingSystemStatus"]["value"]]
|
||||
if keys_exists(data, "chargingSystemStatus"):
|
||||
charging_system_state = charging_system_states[data["chargingSystemStatus"]["value"]]
|
||||
if charging_system_state == "Charging":
|
||||
charging_time = int(data["data"]["estimatedChargingTime"]["value"])
|
||||
charging_time = int(data["estimatedChargingTime"]["value"] if keys_exists(data, "estimatedChargingTime")
|
||||
else 0)
|
||||
charging_finished = datetime.now() + timedelta(minutes=charging_time)
|
||||
return format_datetime(charging_finished, format="medium", locale=settings["babelLocale"])
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
elif sensor_id == "lock_status":
|
||||
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"]
|
||||
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"]
|
||||
elif sensor_id == "tailgate":
|
||||
return data["data"]["tailGateOpen"]["value"]
|
||||
elif sensor_id == "engine_hood":
|
||||
return data["data"]["hoodOpen"]["value"]
|
||||
elif sensor_id == "tank_lid":
|
||||
if "tankLidOpen" in data["data"]:
|
||||
return data["data"]["tankLidOpen"]["value"]
|
||||
return ""
|
||||
else:
|
||||
return ""
|
||||
elif sensor_id == "lock_status":
|
||||
return data["carLocked"]["value"] if keys_exists(data, "carLocked") else ""
|
||||
elif sensor_id == "odometer":
|
||||
return data["odometer"]["value"] if keys_exists(data, "odometer") else 0
|
||||
elif sensor_id == "window_front_left":
|
||||
return data["frontLeftWindowOpen"]["value"] if keys_exists(data, "frontLeftWindowOpen") else ""
|
||||
elif sensor_id == "window_front_right":
|
||||
return data["frontRightWindowOpen"]["value"] if keys_exists(data, "frontRightWindowOpen") else ""
|
||||
elif sensor_id == "window_rear_left":
|
||||
return data["rearLeftWindowOpen"]["value"] if keys_exists(data, "rearLeftWindowOpen") else ""
|
||||
elif sensor_id == "window_rear_right":
|
||||
return data["rearRightWindowOpen"]["value"] if keys_exists(data, "rearRightWindowOpen") else ""
|
||||
elif sensor_id == "door_front_left":
|
||||
return data["frontLeftDoorOpen"]["value"] if keys_exists(data, "frontLeftDoorOpen") else ""
|
||||
elif sensor_id == "door_front_right":
|
||||
return data["frontRightDoorOpen"]["value"] if keys_exists(data, "frontRightDoorOpen") else ""
|
||||
elif sensor_id == "door_rear_left":
|
||||
return data["rearLeftDoorOpen"]["value"] if keys_exists(data, "rearLeftDoorOpen") else ""
|
||||
elif sensor_id == "door_rear_right":
|
||||
return data["rearRightDoorOpen"]["value"] if keys_exists(data, "rearRightDoorOpen") else ""
|
||||
elif sensor_id == "tailgate":
|
||||
return data["tailGateOpen"]["value"] if keys_exists(data, "tailGateOpen") else ""
|
||||
elif sensor_id == "engine_hood":
|
||||
return data["hoodOpen"]["value"] if keys_exists(data, "hoodOpen") else ""
|
||||
elif sensor_id == "tank_lid":
|
||||
return data["tankLidOpen"]["value"] if keys_exists(data, "tankLidOpen") else ""
|
||||
elif sensor_id == "location":
|
||||
coordinates = {}
|
||||
if "geometry" in data["data"]:
|
||||
raw_data = data["data"]["geometry"]["coordinates"]
|
||||
coordinates = {"longitude": raw_data[0], "latitude": raw_data[1], "gps_accuracy": 1}
|
||||
if keys_exists(data, "geometry"):
|
||||
raw_data = data["geometry"]
|
||||
if keys_exists(raw_data, "coordinates"):
|
||||
coordinates = {"longitude": raw_data["coordinates"][0],
|
||||
"latitude": raw_data["coordinates"][1],
|
||||
"gps_accuracy": 1}
|
||||
return coordinates
|
||||
else:
|
||||
return ""
|
||||
|
||||
Reference in New Issue
Block a user