Compare commits

...
7 Commits
7 changed files with 70 additions and 33 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ NOTE: Energy status currently available only for cars in the Europe / Middle Eas
Just install this addon with the following command. Just install this addon with the following command.
Please note to fill in your settings inside the environment variables. Please note to fill in your settings inside the environment variables.
`docker run -d --pull=always -e CONF_updateInterval=300 -e CONF_babelLocale='de' -e CONF_mqtt='@json {"broker": "", "username": "", "password": "", "port": 1883}' -e CONF_volvoData='@json {"username": "", "password": "", "vin": "", "vccapikey": "", "backupvccapikey": "", "odometerMultiplier": 1, "averageSpeedDivider": 1, "averageFuelConsumptionMultiplier": 1}' -e TZ='Europe/Berlin' --name volvo2mqtt ghcr.io/dielee/volvo2mqtt:latest` `docker run -d --pull=always -e CONF_updateInterval=300 -e CONF_babelLocale='de' -e CONF_mqtt='@json {"broker": "", "username": "", "password": "", "port": 1883}' -e CONF_volvoData='@json {"username": "", "password": "", "vin": "", "vccapikey": ["key1", "key2"], "odometerMultiplier": 1, "averageSpeedDivider": 1, "averageFuelConsumptionMultiplier": 1}' -e TZ='Europe/Berlin' --name volvo2mqtt ghcr.io/dielee/volvo2mqtt:latest`
<b>HA Add-On:</b><br> <b>HA Add-On:</b><br>
+17
View File
@@ -1,3 +1,20 @@
## 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
### 🚀 Features:
- Add `updateInterval` limit to prevent abuse (60 Seconds)
- Add `vccapikey` limit to prevent abuse (3 Keys)
- Optimize vcc api key change behaviour
## v1.8.1 ## v1.8.1
### 🐛 Bug Fixes: ### 🐛 Bug Fixes:
+7 -6
View File
@@ -1,6 +1,6 @@
name: "Volvo2Mqtt" name: "Volvo2Mqtt"
description: "Volvo AAOS MQTT bridge" description: "Volvo AAOS MQTT bridge"
version: "1.8.1" version: "1.8.4"
slug: "volvo2mqtt" slug: "volvo2mqtt"
init: false init: false
url: "https://github.com/Dielee/volvo2mqtt" url: "https://github.com/Dielee/volvo2mqtt"
@@ -24,14 +24,15 @@ 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(10,) updateInterval: int(60,)
babelLocale: str babelLocale: str
TZ: str TZ: match(^.+/.+$)
debug: bool debug: bool
mqtt: mqtt:
broker: str broker: str
@@ -39,11 +40,11 @@ schema:
username: str? username: str?
password: str? password: str?
volvoData: volvoData:
username: str username: match(^[\w+\.]+@([\w-]+\.)+[\w-]{2,4}$)
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.1" VERSION = "v1.8.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"
@@ -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},
+4 -3
View File
@@ -2,14 +2,15 @@ import logging
from volvo import authorize from volvo import authorize
from mqtt import update_loop, connect from mqtt import update_loop, connect
from const import VERSION from const import VERSION
from util import set_tz, setup_logging, set_mqtt_settings from util import set_tz, setup_logging, set_mqtt_settings, validate_settings
if __name__ == '__main__': if __name__ == '__main__':
set_tz()
set_mqtt_settings()
setup_logging() setup_logging()
logging.info("Starting volvo2mqtt version " + VERSION) logging.info("Starting volvo2mqtt version " + VERSION)
validate_settings()
set_tz()
set_mqtt_settings()
connect() connect()
authorize() authorize()
update_loop() update_loop()
+12
View File
@@ -136,3 +136,15 @@ def set_mqtt_settings():
config.settings["mqtt"]["port"] = broker_port config.settings["mqtt"]["port"] = broker_port
config.settings["mqtt"]["username"] = broker_user config.settings["mqtt"]["username"] = broker_user
config.settings["mqtt"]["password"] = broker_pass config.settings["mqtt"]["password"] = broker_pass
def validate_settings():
if not os.environ.get("DEV_MODE"):
setting_keys = settings.volvoData["vccapikey"]
if isinstance(setting_keys, list):
if len(setting_keys) > 3:
raise Exception("Settings invalid! Maximum allowed vccapikeys are three!")
update_interval = settings["updateInterval"]
if update_interval < 60:
raise Exception("Settings invalid! Minimum allowed update interval is 60 seconds!")
+26 -20
View File
@@ -119,28 +119,32 @@ def get_vehicles():
def get_vcc_api_keys(used_key=None): def get_vcc_api_keys(used_key=None):
setting_keys = settings.volvoData["vccapikey"] working_keys = None
if isinstance(setting_keys, str):
set_key_state(setting_keys)
elif isinstance(setting_keys, list):
for key in setting_keys:
set_key_state(key)
logging.debug(str(vcc_api_keys)) while not working_keys:
working_keys = [key["key"] for key in vcc_api_keys if not key.get("extended") and key.get('key') != used_key] setting_keys = settings.volvoData["vccapikey"]
if len(working_keys) < 1: if isinstance(setting_keys, str):
logging.warning("No working VCCAPIKEY found, waiting 10 minutes. Then trying again!") set_key_state(setting_keys)
mqtt.send_offline() elif isinstance(setting_keys, list):
time.sleep(600) for key in setting_keys:
get_vcc_api_keys(used_key=None) set_key_state(key)
return None
mqtt.send_heartbeat() logging.debug(str(vcc_api_keys))
session.headers.update({"vcc-api-key": working_keys[0]}) working_keys = [key["key"] for key in vcc_api_keys if not key.get("extended") and key.get('key') != used_key]
logging.info("Using VCCAPIKEY: " + working_keys[0]) if len(working_keys) < 1:
for key_dict in vcc_api_keys: used_key = None
if key_dict["key"] == working_keys[0]: logging.warning("No working VCCAPIKEY found, waiting 10 minutes. Then trying again!")
key_dict["in_use"] = True mqtt.send_offline()
time.sleep(600)
else:
mqtt.send_heartbeat()
session.headers.update({"vcc-api-key": working_keys[0]})
logging.info("Using VCCAPIKEY: " + working_keys[0])
for key_dict in vcc_api_keys:
if key_dict["key"] == working_keys[0]:
key_dict["in_use"] = True
logging.debug(str(vcc_api_keys))
def set_key_state(key): def set_key_state(key):
@@ -160,6 +164,8 @@ def set_key_state(key):
def check_vcc_api_key(test_key, extended_until=None): def check_vcc_api_key(test_key, extended_until=None):
if extended_until: if extended_until:
if extended_until >= datetime.now(): if extended_until >= datetime.now():
logging.warning("VCCAPIKEY " + test_key + " is extended and will be reusable at: "
+ format_datetime(extended_until, format="medium", locale=settings["babelLocale"]))
return True, extended_until return True, extended_until
if datetime.now(util.TZ) >= token_expires_at: if datetime.now(util.TZ) >= token_expires_at: