Compare commits

..
6 Commits
Author SHA1 Message Date
Linus Dietz 1e071154c5 Bump version 2023-06-26 08:55:23 +02:00
Linus Dietz 6d938eab7a Filter zero data from volvo api 2023-06-26 08:50:30 +02:00
Linus Dietz 86980408e7 Filter zero data from volvo api 2023-06-26 08:43:20 +02:00
Linus Dietz a0800db907 Change average speed icon 2023-06-26 08:37:41 +02:00
Linus Dietz d5565cd52a Move windows and doors to binary_sensor domain 2023-06-26 08:36:50 +02:00
Linus DietzandGitHub 9f5b4f4017 Only build on new release 2023-06-26 08:17:51 +02:00
5 changed files with 67 additions and 36 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ name: Create and publish a Docker image
on:
release:
types: [created, edited]
types: [created]
workflow_dispatch:
env:
+1 -1
View File
@@ -1,6 +1,6 @@
name: "Volvo2Mqtt"
description: "Volvo AAOS MQTT bridge"
version: "1.5.1"
version: "1.5.2"
slug: "volvo2mqtt"
init: false
url: "https://github.com/Dielee/volvo2mqtt"
+17 -14
View File
@@ -1,6 +1,6 @@
from config import settings
VERSION = "v1.5.1"
VERSION = "v1.5.2"
OAUTH_URL = "https://volvoid.eu.volvocars.com/as/token.oauth2"
VEHICLES_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles"
@@ -28,6 +28,9 @@ charging_system_states = {"CHARGING_SYSTEM_CHARGING": "Charging", "CHARGING_SYST
charging_connection_states = {"CONNECTION_STATUS_DISCONNECTED": "Disconnected", "CONNECTION_STATUS_UNSPECIFIED": "Unspecified",
"CONNECTION_STATUS_CONNECTED_DC": "Connected DC", "CONNECTION_STATUS_CONNECTED_AC": "Connected AC"}
window_states = {"CLOSED": "OFF", "OPEN": "ON"}
door_states = {"CLOSED": "OFF", "OPEN": "ON"}
supported_entities = [
{"name": "Battery Charge Level", "domain": "sensor", "id": "battery_charge_level", "unit": "%", "icon": "car-battery", "url": RECHARGE_STATE_URL},
{"name": "Battery Charge Level", "domain": "sensor", "id": "battery_charge_level", "unit": "%", "icon": "car-battery", "url": BATTERY_CHARGE_STATE_URL},
@@ -38,18 +41,18 @@ supported_entities = [
{"name": "Estimated Charging Finish Time", "domain": "sensor", "id": "estimated_charging_finish_time", "icon": "timer-sync-outline", "url": RECHARGE_STATE_URL},
{"name": "Odometer", "domain": "sensor", "id": "odometer", "unit": "km" if settings["babelLocale"] != "en_US" else "mi", "icon": "counter", "url": ODOMETER_STATE_URL},
{"name": "Last Data Update", "domain": "sensor", "id": "last_data_update", "icon": "timer", "url": ""},
{"name": "Window Front Left", "domain": "sensor", "id": "window_front_left", "icon": "car-door-lock", "url": WINDOWS_STATE_URL},
{"name": "Window Front Right", "domain": "sensor", "id": "window_front_right", "icon": "car-door-lock", "url": WINDOWS_STATE_URL},
{"name": "Window Rear Left", "domain": "sensor", "id": "window_rear_left", "icon": "car-door-lock", "url": WINDOWS_STATE_URL},
{"name": "Window Rear Right", "domain": "sensor", "id": "window_rear_right", "icon": "car-door-lock", "url": WINDOWS_STATE_URL},
{"name": "Door Front Left", "domain": "sensor", "id": "door_front_left", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Door Front Right", "domain": "sensor", "id": "door_front_right", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Door Rear Left", "domain": "sensor", "id": "door_rear_left", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Door Rear Right", "domain": "sensor", "id": "door_rear_right", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Tailgate", "domain": "sensor", "id": "tailgate", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Engine Hood", "domain": "sensor", "id": "engine_hood", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Tank Lid", "domain": "sensor", "id": "tank_lid", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Sunroof", "domain": "sensor", "id": "sunroof", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Window Front Left", "domain": "binary_sensor", "device_class": "window", "id": "window_front_left", "icon": "car-door-lock", "url": WINDOWS_STATE_URL},
{"name": "Window Front Right", "domain": "binary_sensor", "device_class": "window", "id": "window_front_right", "icon": "car-door-lock", "url": WINDOWS_STATE_URL},
{"name": "Window Rear Left", "domain": "binary_sensor", "device_class": "window", "id": "window_rear_left", "icon": "car-door-lock", "url": WINDOWS_STATE_URL},
{"name": "Window Rear Right", "domain": "binary_sensor", "device_class": "window", "id": "window_rear_right", "icon": "car-door-lock", "url": WINDOWS_STATE_URL},
{"name": "Door Front Left", "domain": "binary_sensor", "device_class": "door", "id": "door_front_left", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Door Front Right", "domain": "binary_sensor", "device_class": "door", "id": "door_front_right", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Door Rear Left", "domain": "binary_sensor", "device_class": "door", "id": "door_rear_left", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Door Rear Right", "domain": "binary_sensor", "device_class": "door", "id": "door_rear_right", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Tailgate", "domain": "binary_sensor", "device_class": "door", "id": "tailgate", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Engine Hood", "domain": "binary_sensor", "device_class": "door", "id": "engine_hood", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Tank Lid", "domain": "binary_sensor", "device_class": "door", "id": "tank_lid", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Sunroof", "domain": "binary_sensor", "device_class": "door", "id": "sunroof", "icon": "car-door-lock", "url": LOCK_STATE_URL},
{"name": "Air Conditioning", "domain": "switch", "id": "climate_status", "icon": "air-conditioner"},
{"name": "Lock state", "domain": "lock", "id": "lock_status", "icon": "lock", "url": LOCK_STATE_URL},
{"name": "Force Update Data", "domain": "button", "id": "update_data", "icon": "update", "url": ""},
@@ -61,5 +64,5 @@ supported_entities = [
{"name": "Engine State", "domain": "sensor", "id": "engine_state", "icon": "engine", "url": ENGINE_STATE_URL},
{"name": "Fuel Level", "domain": "sensor", "id": "fuel_level", "unit": "liters", "icon": "fuel", "url": FUEL_STATE_URL},
{"name": "Average Fuel Consumption", "domain": "sensor", "id": "average_fuel_consumption", "unit": "liters", "icon": "fuel", "url": STATISTICS_URL},
{"name": "Average Speed", "domain": "sensor", "id": "average_speed", "unit": "km/h" if settings["babelLocale"] != "en_US" else "mp/h", "icon": "fuel", "url": STATISTICS_URL}
{"name": "Average Speed", "domain": "sensor", "id": "average_speed", "unit": "km/h" if settings["babelLocale"] != "en_US" else "mp/h", "icon": "speedometer", "url": STATISTICS_URL}
]
+6 -3
View File
@@ -150,13 +150,16 @@ def create_ha_devices():
"unique_id": f"volvoAAOS2mqtt_{vin}_{entity['id']}",
"availability_topic": availability_topic
}
if entity.get('unit'):
if entity.get("device_class"):
config["device_class"] = entity["device_class"]
if entity.get("unit"):
config["unit_of_measurement"] = entity["unit"]
if entity.get('domain') == "device_tracker":
if entity.get("domain") == "device_tracker":
config["json_attributes_topic"] = f"homeassistant/{entity['domain']}/{vin}_{entity['id']}/attributes"
if entity.get('domain') in ["switch", "lock", "button"]:
if entity.get("domain") in ["switch", "lock", "button"]:
command_topic = f"homeassistant/{entity['domain']}/{vin}_{entity['id']}/command"
config["command_topic"] = command_topic
subscribed_topics.append(command_topic)
+42 -17
View File
@@ -4,8 +4,8 @@ import util
from datetime import datetime, timedelta
from config import settings
from babel.dates import format_datetime
from const import charging_system_states, charging_connection_states, CLIMATE_START_URL, \
OAUTH_URL, VEHICLES_URL, VEHICLE_DETAILS_URL, RECHARGE_STATE_URL, \
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
@@ -285,29 +285,33 @@ def parse_api_data(data, sensor_id=None):
multiplier = 1
return int(data["odometer"]["value"]) * multiplier if util.keys_exists(data, "odometer") else None
elif sensor_id == "window_front_left":
return data["frontLeftWindowOpen"]["value"] if util.keys_exists(data, "frontLeftWindowOpen") else None
return window_states[data["frontLeftWindowOpen"]["value"]] if util.keys_exists(data, "frontLeftWindowOpen") \
else None
elif sensor_id == "window_front_right":
return data["frontRightWindowOpen"]["value"] if util.keys_exists(data, "frontRightWindowOpen") else None
return window_states[data["frontRightWindowOpen"]["value"]] if util.keys_exists(data, "frontRightWindowOpen") \
else None
elif sensor_id == "window_rear_left":
return data["rearLeftWindowOpen"]["value"] if util.keys_exists(data, "rearLeftWindowOpen") else None
return window_states[data["rearLeftWindowOpen"]["value"]] if util.keys_exists(data, "rearLeftWindowOpen") \
else None
elif sensor_id == "window_rear_right":
return data["rearRightWindowOpen"]["value"] if util.keys_exists(data, "rearRightWindowOpen") else None
return window_states[data["rearRightWindowOpen"]["value"]] if util.keys_exists(data, "rearRightWindowOpen") \
else None
elif sensor_id == "door_front_left":
return data["frontLeftDoorOpen"]["value"] if util.keys_exists(data, "frontLeftDoorOpen") else None
return door_states[data["frontLeftDoorOpen"]["value"]] if util.keys_exists(data, "frontLeftDoorOpen") else None
elif sensor_id == "door_front_right":
return data["frontRightDoorOpen"]["value"] if util.keys_exists(data, "frontRightDoorOpen") else None
return door_states[data["frontRightDoorOpen"]["value"]] if util.keys_exists(data, "frontRightDoorOpen") else None
elif sensor_id == "door_rear_left":
return data["rearLeftDoorOpen"]["value"] if util.keys_exists(data, "rearLeftDoorOpen") else None
return door_states[data["rearLeftDoorOpen"]["value"]] if util.keys_exists(data, "rearLeftDoorOpen") else None
elif sensor_id == "door_rear_right":
return data["rearRightDoorOpen"]["value"] if util.keys_exists(data, "rearRightDoorOpen") else None
return door_states[data["rearRightDoorOpen"]["value"]] if util.keys_exists(data, "rearRightDoorOpen") else None
elif sensor_id == "tailgate":
return data["tailGateOpen"]["value"] if util.keys_exists(data, "tailGateOpen") else None
return door_states[data["tailGateOpen"]["value"]] if util.keys_exists(data, "tailGateOpen") else None
elif sensor_id == "sunroof":
return data["capOpen"]["value"] if util.keys_exists(data, "capOpen") else None
return door_states[data["capOpen"]["value"]] if util.keys_exists(data, "capOpen") else None
elif sensor_id == "engine_hood":
return data["hoodOpen"]["value"] if util.keys_exists(data, "hoodOpen") else None
return door_states[data["hoodOpen"]["value"]] if util.keys_exists(data, "hoodOpen") else None
elif sensor_id == "tank_lid":
return data["tankLidOpen"]["value"] if util.keys_exists(data, "tankLidOpen") else None
return door_states[data["tankLidOpen"]["value"]] if util.keys_exists(data, "tankLidOpen") else None
elif sensor_id == "tyre_front_left":
return data["frontLeftTyrePressure"]["value"] if util.keys_exists(data, "frontLeftTyrePressure") else None
elif sensor_id == "tyre_front_right":
@@ -319,11 +323,32 @@ def parse_api_data(data, sensor_id=None):
elif sensor_id == "engine_state":
return data["engineRunning"]["value"] if util.keys_exists(data, "engineRunning") else None
elif sensor_id == "fuel_level":
return data["fuelAmount"]["value"] if util.keys_exists(data, "fuelAmount") else None
if util.keys_exists(data, "fuelAmount"):
fuel_amount = int(data["fuelAmount"]["value"])
if fuel_amount > 0:
return fuel_amount
else:
return None
else:
return None
elif sensor_id == "average_fuel_consumption":
return data["averageFuelConsumption"]["value"] if util.keys_exists(data, "averageFuelConsumption") else None
if util.keys_exists(data, "averageFuelConsumption"):
average_fuel_con = float(data["averageFuelConsumption"]["value"])
if average_fuel_con > 0:
return average_fuel_con
else:
return None
else:
return None
elif sensor_id == "average_speed":
return data["averageSpeed"]["value"] if util.keys_exists(data, "averageSpeed") else None
if util.keys_exists(data, "averageSpeed"):
average_speed = int(data["averageSpeed"]["value"])
if average_speed > 0:
return average_speed
else:
return None
else:
return None
elif sensor_id == "location":
coordinates = {}
if util.keys_exists(data, "geometry"):