Compare commits

...
6 Commits
Author SHA1 Message Date
Linus DietzandGitHub 781e1da8e8 Fix #104 (#107)
* Catch Volvo API not returning a valid json string #104

* Update changelog
2023-09-21 14:31:21 +02:00
6b419cfe3a Fix regex for some emails #98 // Add option to disable log completely #96 (#99)
* Update volovData.username regex (#98)

* Add option to disable log completely #96

---------

Co-authored-by: Gert-jan Theunissen <gurtjun@users.noreply.github.com>
2023-09-08 11:40:21 +02:00
Linus Dietz e5ece2116b Add option to use multiple docker containers (with different logins) #93 2023-08-28 15:09:01 +02:00
Linus Dietz 23246a464f Allow phone number as username #91 2023-08-25 15:08:25 +02:00
Linus Dietz 1a5cc3db7a Optimize addon configuration 2023-08-25 09:08:58 +02:00
Linus Dietz 974ad0e454 Add "device_class: battery" for battery state sensors from BEV and PHEV 2023-08-18 15:44:13 +02:00
8 changed files with 70 additions and 15 deletions
+34
View File
@@ -1,3 +1,37 @@
## v1.8.8
### 🐛 Bug Fixes:
- Fix json decode error, if volvo API returns a simple string #104
## v1.8.7
### 🚀 Features:
- Add option to disable log completely #96
### 🐛 Bug Fixes:
- Fix regex error for some mailaddresses #97
## v1.8.6
### 🚀 Features:
- Add option to use multiple docker containers (with different logins) #93
## v1.8.5
### 🚀 Features:
- Allow phone number as username #91
## v1.8.4
### 🚀 Features:
- Optimize Addon configuration #90
## v1.8.3
### 🚀 Features:
- Add `device_class: battery` for battery state sensors from BEV and PHEV
## v1.8.2 ## v1.8.2
### 🚀 Features: ### 🚀 Features:
+8 -5
View File
@@ -1,6 +1,6 @@
name: "Volvo2Mqtt" name: "Volvo2Mqtt"
description: "Volvo AAOS MQTT bridge" description: "Volvo AAOS MQTT bridge"
version: "1.8.2" version: "1.8.7"
slug: "volvo2mqtt" slug: "volvo2mqtt"
init: false init: false
url: "https://github.com/Dielee/volvo2mqtt" url: "https://github.com/Dielee/volvo2mqtt"
@@ -15,6 +15,7 @@ options:
babelLocale: null babelLocale: null
TZ: null TZ: null
debug: false debug: false
disable_logging: false
mqtt: mqtt:
broker: "auto_broker" broker: "auto_broker"
port: "auto_port" port: "auto_port"
@@ -24,26 +25,28 @@ options:
username: null username: null
password: null password: null
vin: "" vin: ""
vccapikey: null vccapikey:
- null
odometerMultiplier: 1 odometerMultiplier: 1
averageSpeedDivider: 1 averageSpeedDivider: 1
averageFuelConsumptionMultiplier: 1 averageFuelConsumptionMultiplier: 1
schema: schema:
updateInterval: int(60,) updateInterval: int(60,)
babelLocale: str babelLocale: str
TZ: str TZ: match(^.+/.+$)
debug: bool debug: bool
disable_logging: bool
mqtt: mqtt:
broker: str broker: str
port: str port: str
username: str? username: str?
password: str? password: str?
volvoData: volvoData:
username: str username: match(^([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)|(\+\d{5,20})$)
password: str password: str
vin: str? vin: str?
vccapikey: vccapikey:
- str - match(^\b\w{32}\b$)
odometerMultiplier: int(1,) odometerMultiplier: int(1,)
averageSpeedDivider: int(1,) averageSpeedDivider: int(1,)
averageFuelConsumptionMultiplier: int(1,) averageFuelConsumptionMultiplier: int(1,)
+3 -3
View File
@@ -1,6 +1,6 @@
from config import settings from config import settings
VERSION = "v1.8.2" VERSION = "v1.8.8"
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"
@@ -77,8 +77,8 @@ icon_states = {
} }
supported_entities = [ supported_entities = [
{"name": "Battery Charge Level", "domain": "sensor", "id": "battery_charge_level", "unit": "%", "icon": "car-battery", "url": RECHARGE_STATE_URL, "state_class": "measurement"}, {"name": "Battery Charge Level", "domain": "sensor", "device_class": "battery", "id": "battery_charge_level", "unit": "%", "icon": "car-battery", "url": RECHARGE_STATE_URL, "state_class": "measurement"},
{"name": "Battery Charge Level", "domain": "sensor", "id": "battery_charge_level", "unit": "%", "icon": "car-battery", "url": BATTERY_CHARGE_STATE_URL, "state_class": "measurement"}, {"name": "Battery Charge Level", "domain": "sensor", "device_class": "battery", "id": "battery_charge_level", "unit": "%", "icon": "car-battery", "url": BATTERY_CHARGE_STATE_URL, "state_class": "measurement"},
{"name": "Electric Range", "domain": "sensor", "id": "electric_range", "unit": "km" if not units.get(settings["babelLocale"]) else units[settings["babelLocale"]]["electric_range"]["unit"], "icon": "map-marker-distance", "url": RECHARGE_STATE_URL, "state_class": "measurement"}, {"name": "Electric Range", "domain": "sensor", "id": "electric_range", "unit": "km" if not units.get(settings["babelLocale"]) else units[settings["babelLocale"]]["electric_range"]["unit"], "icon": "map-marker-distance", "url": RECHARGE_STATE_URL, "state_class": "measurement"},
{"name": "Estimated Charging Time", "domain": "sensor", "id": "estimated_charging_time", "unit": "minutes", "icon": "timer-sync-outline", "url": RECHARGE_STATE_URL, "state_class": "measurement"}, {"name": "Estimated Charging Time", "domain": "sensor", "id": "estimated_charging_time", "unit": "minutes", "icon": "timer-sync-outline", "url": RECHARGE_STATE_URL, "state_class": "measurement"},
{"name": "Charging System Status", "domain": "sensor", "id": "charging_system_status", "icon": "ev-station", "url": RECHARGE_STATE_URL}, {"name": "Charging System Status", "domain": "sensor", "id": "charging_system_status", "icon": "ev-station", "url": RECHARGE_STATE_URL},
+10 -6
View File
@@ -4,6 +4,7 @@ import paho.mqtt.client as mqtt
import json import json
import volvo import volvo
import util import util
import os
from threading import Thread, Timer from threading import Thread, Timer
from datetime import datetime from datetime import datetime
from babel.dates import format_datetime from babel.dates import format_datetime
@@ -23,7 +24,9 @@ active_schedules = {}
def connect(): def connect():
client = mqtt.Client("volvoAAOS2mqtt") client = mqtt.Client("volvoAAOS2mqtt") if os.environ.get("IS_HA_ADDON") \
else mqtt.Client("volvoAAOS2mqtt_" + settings.volvoData["username"])
client.will_set(availability_topic, "offline", 0, False) client.will_set(availability_topic, "offline", 0, False)
if settings["mqtt"]["username"] and settings["mqtt"]["password"]: if settings["mqtt"]["username"] and settings["mqtt"]["password"]:
client.username_pw_set(settings["mqtt"]["username"], settings["mqtt"]["password"]) client.username_pw_set(settings["mqtt"]["username"], settings["mqtt"]["password"])
@@ -252,11 +255,12 @@ def update_car_data(force_update=False, overwrite={}):
else: else:
topic = f"homeassistant/{entity['domain']}/{vin}_{entity['id']}/state" topic = f"homeassistant/{entity['domain']}/{vin}_{entity['id']}/state"
mqtt_client.publish( if state:
topic, mqtt_client.publish(
json.dumps(state) if isinstance(state, dict) or isinstance(state, list) else state topic,
) json.dumps(state) if isinstance(state, dict) or isinstance(state, list) else state
update_ha_device(entity, vin, state) )
update_ha_device(entity, vin, state)
def update_ha_device(entity, vin, state): def update_ha_device(entity, vin, state):
+2
View File
@@ -2,6 +2,8 @@
"updateInterval": 300, "updateInterval": 300,
"babelLocale": "de", "babelLocale": "de",
"TZ": "Europe/Berlin", "TZ": "Europe/Berlin",
"debug": false,
"disable_logging": false,
"mqtt": { "mqtt": {
"broker": "", "broker": "",
"port": 1883, "port": 1883,
+3
View File
@@ -11,6 +11,9 @@ configuration:
debug: debug:
name: API debug mode name: API debug mode
description: Enable Volvo API debug, normaly this can stay off. If enabled, the complete log file can be found under \\<Your HA Host IP>\addons\volvo2mqtt\log\volvo2mqtt.log. description: Enable Volvo API debug, normaly this can stay off. If enabled, the complete log file can be found under \\<Your HA Host IP>\addons\volvo2mqtt\log\volvo2mqtt.log.
disable_logging:
name: Disable logging
description: Disable logging completely to reduce IO and SD card access.
mqtt: mqtt:
name: MQTT Broker settings name: MQTT Broker settings
description: Leave the settings as they are if you are using the MQTT Mosquitto Addon. If not, take a look at the readme from volvo2mqtt. description: Leave the settings as they are if you are using the MQTT Mosquitto Addon. If not, take a look at the readme from volvo2mqtt.
+4
View File
@@ -68,6 +68,10 @@ def setup_logging():
if settings["debug"]: if settings["debug"]:
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
if "disable_logging" in settings:
if settings["disable_logging"]:
logger.setLevel(logging.ERROR)
def check_existing_folder(): def check_existing_folder():
Path("/addons/volvo2mqtt/log/").mkdir(parents=True, exist_ok=True) Path("/addons/volvo2mqtt/log/").mkdir(parents=True, exist_ok=True)
+6 -1
View File
@@ -8,6 +8,7 @@ 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 json import JSONDecodeError
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, \
@@ -347,7 +348,11 @@ def api_call(url, method, vin, sensor_id=None, force_update=False, key_change=Fa
return None return None
logging.debug("Response status code: " + str(response.status_code)) logging.debug("Response status code: " + str(response.status_code))
data = response.json() try:
data = response.json()
except JSONDecodeError as e:
logging.error("Fetched json decode error, Volvo API seems to return garbage. Skipping update. Error: " + str(e))
return None
if response.status_code == 200: if response.status_code == 200:
logging.debug(response.text) logging.debug(response.text)