mirror of
https://github.com/Dielee/volvo2mqtt.git
synced 2026-08-12 18:59:53 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6e423839a | ||
|
|
044e71d862 | ||
|
|
444579316b | ||
|
|
e9ae0037dc | ||
|
|
4ab08ab4df | ||
|
|
48cae3eee1 | ||
|
|
57a0451fda | ||
|
|
86fbb08dcb | ||
|
|
5e59c49608 | ||
|
|
5729bf06ba | ||
|
|
8fdfa269c4 | ||
|
|
71b6cd269a | ||
|
|
4cb729beb5 |
@@ -3,28 +3,29 @@ name: Bug report
|
|||||||
about: Create a report to help us improve
|
about: Create a report to help us improve
|
||||||
title: ''
|
title: ''
|
||||||
labels: ''
|
labels: ''
|
||||||
assignees: Dielee
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Describe the bug**
|
**Describe the bug**
|
||||||
A clear and concise description of what the bug is.
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
**To Reproduce**
|
**To Reproduce**:<br>
|
||||||
Steps to reproduce the behavior:
|
Steps to reproduce the behavior:
|
||||||
1. Go to '...'
|
1. Go to '...'
|
||||||
2. Click on '....'
|
2. Click on '....'
|
||||||
3. Scroll down to '....'
|
3. Scroll down to '....'
|
||||||
4. See error
|
4. See error
|
||||||
|
|
||||||
**Expected behavior**
|
**Expected behavior**:<br>
|
||||||
A clear and concise description of what you expected to happen.
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
**Screenshots**
|
**Screenshots**:<br>
|
||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Version info**
|
**Version info**:<br>
|
||||||
The version you are using and the method you are using (Docker container/HA Addon/Cloned repo)
|
The version you are using and the method you are using (Docker container/HA Addon/Cloned repo)
|
||||||
|
|
||||||
**Additional context**
|
**Logs**:<br>
|
||||||
Add any other context about the problem here.
|
Enable the debug option and upload your logfile here. <br>
|
||||||
|
<b>If you are using the HA Addon the log location is `\\<Your HA Host IP>\addons\volvo2mqtt\log\volvo2mqtt.log`
|
||||||
|
|||||||
@@ -15,13 +15,16 @@ Maybe this component works also with other Volvo cars. Please try out the native
|
|||||||
|
|
||||||
Home Assistant thread can be found [here](https://community.home-assistant.io/t/volvo2mqtt-connect-your-aaos-volvo/585699).
|
Home Assistant thread can be found [here](https://community.home-assistant.io/t/volvo2mqtt-connect-your-aaos-volvo/585699).
|
||||||
|
|
||||||
|
If you like my work:<br>
|
||||||
|
[](https://ko-fi.com/U7U8MFXCF)
|
||||||
|
|
||||||
## Confirmed working with
|
## Confirmed working with
|
||||||
- XC40 BEV (2023)
|
- XC40 BEV (2023)
|
||||||
- XC40 BEV (2022)
|
- XC40 BEV (2022)
|
||||||
- XC40 PHEV (2021)
|
- XC40 PHEV (2021)
|
||||||
- V60 T8 PHEV (2023)
|
- V60 T8 PHEV (2023)
|
||||||
- C40 PHEV (2023)
|
- C40 BEV (2023)
|
||||||
- C40 PHEV (2022)
|
- C40 BEV (2022)
|
||||||
- XC90 T8 PHEV (2023)
|
- XC90 T8 PHEV (2023)
|
||||||
- XC60 PHEV (2023)
|
- XC60 PHEV (2023)
|
||||||
- XC60 PHEV (2022)
|
- XC60 PHEV (2022)
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
## v1.7.4
|
||||||
|
### 🐛 Bug Fixes:
|
||||||
|
|
||||||
|
- Fixed undocumented charging connection state `CONNECTION_STATUS_FAULT` '#57
|
||||||
|
|
||||||
|
## v1.7.3
|
||||||
|
### 🐛 Bug Fixes:
|
||||||
|
|
||||||
|
- Fixed API changes from Volvo #53
|
||||||
|
|
||||||
|
<b>ATTENTION: Volvo optimized their API. Maybe you have to set your odometer multiplier to 1.
|
||||||
|
Also check all the other multipliers!</b>
|
||||||
|
## v1.7.2
|
||||||
|
### 🐛 Bug Fixes:
|
||||||
|
|
||||||
|
- Fixed "Engine State" can be "true" or "false", not "RUNNING" or "STOPPED" #47
|
||||||
|
|
||||||
|
## v1.7.1
|
||||||
|
### 🚀 Features:
|
||||||
|
|
||||||
|
- Moved "Engine State" from "sensor" to the "binary_sensor" domain
|
||||||
|
- Improved HA Add-On security level to 7
|
||||||
|
|
||||||
|
<b>NOTE: The old "sensor" entity will be not deleted automatically. If you want to clean up your mqtt device, just delete it and restart the volvo2mqtt addon.
|
||||||
|
</b>
|
||||||
|
|
||||||
|
## v1.7.0
|
||||||
|
### 🚀 Features:
|
||||||
|
|
||||||
|
- Added MQTT autodiscovery for HA Add-On users
|
||||||
|
- Added "Engine State" fallback endpoint for some cars (BEVs)
|
||||||
|
- Added dynamic icons for "Engine State"
|
||||||
|
- Turn off the pre-climate switch if "Engine State" changes to "RUNNING"
|
||||||
|
|
||||||
|
<b>NOTE: The mqtt broker port is now a string. Just quote your port like this `port: "1883"`</b><br>
|
||||||
|
<b>NOTE: If you want to switch to MQTT autodiscovery for the HA Add-On change your settings to: <br>
|
||||||
|
</b>
|
||||||
|
|
||||||
|
## v1.6.5
|
||||||
|
### 🐛 Bug Fixes:
|
||||||
|
|
||||||
|
- Fixed missing key in unit mappings for `en_US` and `en_GB` mapping
|
||||||
|
|
||||||
|
## v1.6.4
|
||||||
|
### 🚀 Features:
|
||||||
|
|
||||||
|
- Added dynamic icons for lock, battery and window state #43
|
||||||
|
|
||||||
|
## v1.6.3
|
||||||
|
### 🚀 Features:
|
||||||
|
|
||||||
|
- Moved data source for "Distance to empty" from extended api to connected api
|
||||||
|
|
||||||
|
## v1.6.2
|
||||||
|
### 🚀 Features:
|
||||||
|
|
||||||
|
- Moved print statements to logger
|
||||||
|
- Added more debug logging
|
||||||
|
- The full HA Addon log can now be found at your addon smb share `\\<Your HA IP>\addons\volvo2mqtt\log\volvo2mqtt.log`
|
||||||
|
|
||||||
|
## v1.6.1
|
||||||
|
### 🚀 Features:
|
||||||
|
|
||||||
|
- Added "Washer Fluid Level" and "Distance to Empty" sensors #37
|
||||||
|
- Expanded climate control for better state sync with HA
|
||||||
|
|
||||||
|
### 🐛 Bug Fixes:
|
||||||
|
|
||||||
|
- Fixed wrong return values for not working endpoints
|
||||||
|
- Fixed app crash on credential renewal timeout #39
|
||||||
|
|
||||||
|
## v1.6.0
|
||||||
|
### 🚀 Features:
|
||||||
|
|
||||||
|
- Added conversion from metric to imperial system for `en_US` and `en_GB` locale
|
||||||
+2
-1
@@ -1,10 +1,11 @@
|
|||||||
name: "Volvo2Mqtt"
|
name: "Volvo2Mqtt"
|
||||||
description: "Volvo AAOS MQTT bridge"
|
description: "Volvo AAOS MQTT bridge"
|
||||||
version: "1.7.0"
|
version: "1.7.4"
|
||||||
slug: "volvo2mqtt"
|
slug: "volvo2mqtt"
|
||||||
init: false
|
init: false
|
||||||
url: "https://github.com/Dielee/volvo2mqtt"
|
url: "https://github.com/Dielee/volvo2mqtt"
|
||||||
apparmor: true
|
apparmor: true
|
||||||
|
codenotary: notary@home-assistant.io
|
||||||
services:
|
services:
|
||||||
- 'mqtt:need'
|
- 'mqtt:need'
|
||||||
map:
|
map:
|
||||||
|
|||||||
+7
-5
@@ -1,6 +1,6 @@
|
|||||||
from config import settings
|
from config import settings
|
||||||
|
|
||||||
VERSION = "v1.7.0"
|
VERSION = "v1.7.4"
|
||||||
|
|
||||||
OAUTH_URL = "https://volvoid.eu.volvocars.com/as/token.oauth2"
|
OAUTH_URL = "https://volvoid.eu.volvocars.com/as/token.oauth2"
|
||||||
VEHICLES_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles"
|
VEHICLES_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles"
|
||||||
@@ -44,10 +44,12 @@ charging_system_states = {"CHARGING_SYSTEM_CHARGING": "Charging", "CHARGING_SYST
|
|||||||
"CHARGING_SYSTEM_FAULT": "Fault", "CHARGING_SYSTEM_UNSPECIFIED": "Unspecified"}
|
"CHARGING_SYSTEM_FAULT": "Fault", "CHARGING_SYSTEM_UNSPECIFIED": "Unspecified"}
|
||||||
|
|
||||||
charging_connection_states = {"CONNECTION_STATUS_DISCONNECTED": "Disconnected", "CONNECTION_STATUS_UNSPECIFIED": "Unspecified",
|
charging_connection_states = {"CONNECTION_STATUS_DISCONNECTED": "Disconnected", "CONNECTION_STATUS_UNSPECIFIED": "Unspecified",
|
||||||
"CONNECTION_STATUS_CONNECTED_DC": "Connected DC", "CONNECTION_STATUS_CONNECTED_AC": "Connected AC"}
|
"CONNECTION_STATUS_CONNECTED_DC": "Connected DC", "CONNECTION_STATUS_CONNECTED_AC": "Connected AC",
|
||||||
|
"CONNECTION_STATUS_FAULT": "Fault"}
|
||||||
|
|
||||||
window_states = {"CLOSED": "OFF", "OPEN": "ON"}
|
window_states = {"CLOSED": "OFF", "OPEN": "ON"}
|
||||||
door_states = {"CLOSED": "OFF", "OPEN": "ON"}
|
door_states = {"CLOSED": "OFF", "OPEN": "ON"}
|
||||||
|
engine_states = {"RUNNING": "ON", "STOPPED": "OFF", "true": "ON", "false": "OFF"}
|
||||||
|
|
||||||
icon_states = {
|
icon_states = {
|
||||||
"lock_status": {"UNLOCKED": "lock-open-alert", "LOCKED": "lock"},
|
"lock_status": {"UNLOCKED": "lock-open-alert", "LOCKED": "lock"},
|
||||||
@@ -55,7 +57,7 @@ icon_states = {
|
|||||||
"door_front_right": {"ON": "car-door", "OFF": "car-door-lock"},
|
"door_front_right": {"ON": "car-door", "OFF": "car-door-lock"},
|
||||||
"door_rear_left": {"ON": "car-door", "OFF": "car-door-lock"},
|
"door_rear_left": {"ON": "car-door", "OFF": "car-door-lock"},
|
||||||
"door_rear_right": {"ON": "car-door", "OFF": "car-door-lock"},
|
"door_rear_right": {"ON": "car-door", "OFF": "car-door-lock"},
|
||||||
"engine_state": {"RUNNING": "engine-outline", "STOPPED": "engine-off-outline"},
|
"engine_state": {"ON": "engine-outline", "OFF": "engine-off-outline"},
|
||||||
"battery_charge_level": [
|
"battery_charge_level": [
|
||||||
{"from": 100, "to": 100, "icon": "battery"},
|
{"from": 100, "to": 100, "icon": "battery"},
|
||||||
{"from": 99, "to": 90, "icon": "battery-90"},
|
{"from": 99, "to": 90, "icon": "battery-90"},
|
||||||
@@ -101,8 +103,8 @@ supported_entities = [
|
|||||||
{"name": "Tire Front Right", "domain": "sensor", "id": "tyre_front_right", "icon": "car-tire-alert", "url": TYRE_STATE_URL},
|
{"name": "Tire Front Right", "domain": "sensor", "id": "tyre_front_right", "icon": "car-tire-alert", "url": TYRE_STATE_URL},
|
||||||
{"name": "Tire Rear Left", "domain": "sensor", "id": "tyre_rear_left", "icon": "car-tire-alert", "url": TYRE_STATE_URL},
|
{"name": "Tire Rear Left", "domain": "sensor", "id": "tyre_rear_left", "icon": "car-tire-alert", "url": TYRE_STATE_URL},
|
||||||
{"name": "Tire Rear Right", "domain": "sensor", "id": "tyre_rear_right", "icon": "car-tire-alert", "url": TYRE_STATE_URL},
|
{"name": "Tire Rear Right", "domain": "sensor", "id": "tyre_rear_right", "icon": "car-tire-alert", "url": TYRE_STATE_URL},
|
||||||
{"name": "Engine State", "domain": "sensor", "id": "engine_state", "icon": "engine", "url": ENGINE_STATE_URL},
|
{"name": "Engine State", "domain": "binary_sensor", "device_class": "running", "id": "engine_state", "icon": "engine", "url": ENGINE_STATE_URL},
|
||||||
{"name": "Engine State", "domain": "sensor", "id": "engine_state", "icon": "engine", "url": ENGINE_DIAGNOSTICS_URL},
|
{"name": "Engine State", "domain": "binary_sensor", "device_class": "running", "id": "engine_state", "icon": "engine", "url": ENGINE_DIAGNOSTICS_URL},
|
||||||
{"name": "Fuel Level", "domain": "sensor", "id": "fuel_level", "unit": "liters", "icon": "fuel", "url": FUEL_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 Fuel Consumption", "domain": "sensor", "id": "average_fuel_consumption", "unit": "liters", "icon": "fuel", "url": STATISTICS_URL},
|
||||||
{"name": "Distance to Empty", "domain": "sensor", "id": "distance_to_empty", "unit": "km" if not units.get(settings["babelLocale"]) else units[settings["babelLocale"]]["distance_to_empty"]["unit"], "icon": "map-marker-distance", "url": STATISTICS_URL},
|
{"name": "Distance to Empty", "domain": "sensor", "id": "distance_to_empty", "unit": "km" if not units.get(settings["babelLocale"]) else units[settings["babelLocale"]]["distance_to_empty"]["unit"], "icon": "map-marker-distance", "url": STATISTICS_URL},
|
||||||
|
|||||||
+6
-6
@@ -3,14 +3,14 @@ import requests
|
|||||||
import mqtt
|
import mqtt
|
||||||
import util
|
import util
|
||||||
import time
|
import time
|
||||||
from threading import Thread, currentThread
|
from threading import currentThread
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from config import settings
|
from config import settings
|
||||||
from babel.dates import format_datetime
|
from babel.dates import format_datetime
|
||||||
from const import charging_system_states, charging_connection_states, door_states, window_states, \
|
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, \
|
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, \
|
WINDOWS_STATE_URL, LOCK_STATE_URL, TYRE_STATE_URL, supported_entities, BATTERY_CHARGE_STATE_URL, \
|
||||||
STATISTICS_URL, CLIMATE_STOP_URL, ENGINE_DIAGNOSTICS_URL
|
STATISTICS_URL, ENGINE_DIAGNOSTICS_URL, engine_states
|
||||||
|
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
session.headers = {
|
session.headers = {
|
||||||
@@ -194,7 +194,7 @@ def check_engine_status(vin):
|
|||||||
t = currentThread()
|
t = currentThread()
|
||||||
while getattr(t, "do_run", True):
|
while getattr(t, "do_run", True):
|
||||||
engine_state = api_call(endpoint_url, "GET", vin, "engine_state", True)
|
engine_state = api_call(endpoint_url, "GET", vin, "engine_state", True)
|
||||||
if engine_state == "RUNNING":
|
if engine_state == "ON":
|
||||||
mqtt.assumed_climate_state[vin] = "OFF"
|
mqtt.assumed_climate_state[vin] = "OFF"
|
||||||
mqtt.update_car_data()
|
mqtt.update_car_data()
|
||||||
break
|
break
|
||||||
@@ -366,10 +366,10 @@ def parse_api_data(data, sensor_id=None):
|
|||||||
elif sensor_id == "tyre_rear_right":
|
elif sensor_id == "tyre_rear_right":
|
||||||
return data["rearRightTyrePressure"]["value"] if util.keys_exists(data, "rearRightTyrePressure") else None
|
return data["rearRightTyrePressure"]["value"] if util.keys_exists(data, "rearRightTyrePressure") else None
|
||||||
elif sensor_id == "engine_state":
|
elif sensor_id == "engine_state":
|
||||||
return data["engineRunning"]["value"] if util.keys_exists(data, "engineRunning") else None
|
return engine_states[data["engineRunning"]["value"]] if util.keys_exists(data, "engineRunning") else None
|
||||||
elif sensor_id == "fuel_level":
|
elif sensor_id == "fuel_level":
|
||||||
if util.keys_exists(data, "fuelAmount"):
|
if util.keys_exists(data, "fuelAmount"):
|
||||||
fuel_amount = int(data["fuelAmount"]["value"])
|
fuel_amount = float(data["fuelAmount"]["value"])
|
||||||
if fuel_amount > 0:
|
if fuel_amount > 0:
|
||||||
return fuel_amount
|
return fuel_amount
|
||||||
return None
|
return None
|
||||||
@@ -388,7 +388,7 @@ def parse_api_data(data, sensor_id=None):
|
|||||||
return None
|
return None
|
||||||
elif sensor_id == "average_speed":
|
elif sensor_id == "average_speed":
|
||||||
if util.keys_exists(data, "averageSpeed"):
|
if util.keys_exists(data, "averageSpeed"):
|
||||||
average_speed = int(data["averageSpeed"]["value"])
|
average_speed = float(data["averageSpeed"]["value"])
|
||||||
if average_speed > 1:
|
if average_speed > 1:
|
||||||
divider = 1
|
divider = 1
|
||||||
if util.keys_exists(settings["volvoData"], "averageSpeedDivider"):
|
if util.keys_exists(settings["volvoData"], "averageSpeedDivider"):
|
||||||
|
|||||||
Reference in New Issue
Block a user