mirror of
https://github.com/Dielee/volvo2mqtt.git
synced 2026-07-22 02:13:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7db02b5dc6 | ||
|
|
7c87c71ac8 | ||
|
|
3482a5f893 | ||
|
|
3f1f793c1b | ||
|
|
1039eab649 | ||
|
|
47bd726ebb | ||
|
|
0397d05522 | ||
|
|
f0628e6a26 | ||
|
|
0f89258718 |
@@ -19,6 +19,7 @@ If you like my work:<br>
|
||||
[](https://ko-fi.com/U7U8MFXCF)
|
||||
|
||||
## Confirmed working with
|
||||
- XC40 BEV (2024)
|
||||
- XC40 BEV (2023)
|
||||
- XC40 BEV (2022)
|
||||
- XC40 PHEV (2021)
|
||||
@@ -26,6 +27,7 @@ If you like my work:<br>
|
||||
- C40 BEV (2023)
|
||||
- C40 BEV (2022)
|
||||
- XC90 T8 PHEV (2023)
|
||||
- XC60 PHEV (2024)
|
||||
- XC60 PHEV (2023)
|
||||
- XC60 PHEV (2022)
|
||||
- XC90 PHEV T8 (2023)
|
||||
@@ -53,6 +55,12 @@ Please let me know if your car works with this addon so I can expand the list!<b
|
||||
- Sensor "Fuel Status"
|
||||
- Sensor "Average Fuel Consumption"
|
||||
- Sensor "Average Speed"
|
||||
- Sensor "Distance to Empty"
|
||||
- Sensor "Hours to Service"
|
||||
- Sensor "Distance to Service"
|
||||
- Sensor "Months to Service"
|
||||
- Sensor "Service warning status"
|
||||
- Sensor "Service warning trigger"
|
||||
- Car Device Tracker
|
||||
- Multiple cars
|
||||
|
||||
@@ -64,7 +72,7 @@ NOTE: Energy status currently available only for cars in the Europe / Middle Eas
|
||||
Just install this addon with the following command.
|
||||
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>
|
||||
|
||||
@@ -90,74 +98,6 @@ Here is what every option means:
|
||||
| `CONF_debug` | `string` | | optional | Debug option (true/false). Normally you don't need this. |
|
||||
| `TZ` | `string` | | **required** | Container timezone eg "Europe/Berlin" from [here](https://docs.diladele.com/docker/timezones.html)|
|
||||
|
||||
## Lovelace sample card
|
||||
<details>
|
||||
<summary>Show me more!</summary><blockquote>
|
||||
<br>
|
||||
|
||||
<br>
|
||||
|
||||
<details>
|
||||
<summary>Lovelace card sample</summary>
|
||||
|
||||
```
|
||||
type: vertical-stack
|
||||
title: Autostatus
|
||||
cards:
|
||||
- type: custom:vertical-stack-in-card
|
||||
cards:
|
||||
- type: custom:mushroom-lock-card
|
||||
entity: lock.volvo_<your vin>_lock_status
|
||||
name: Verrigelungsstatus
|
||||
- type: horizontal-stack
|
||||
cards:
|
||||
- type: custom:mushroom-entity-card
|
||||
entity: sensor.volvo_<your vin>_electric_range
|
||||
name: Reichweite
|
||||
layout: vertical
|
||||
- type: custom:mushroom-entity-card
|
||||
entity: sensor.volvo_<your vin>_battery_charge_level
|
||||
name: Batteriestatus
|
||||
layout: vertical
|
||||
- type: custom:mushroom-entity-card
|
||||
entity: sensor.volvo_<your vin>_estimated_charging_time
|
||||
layout: vertical
|
||||
name: Ladezeit
|
||||
- type: horizontal-stack
|
||||
cards:
|
||||
- type: custom:mushroom-entity-card
|
||||
entity: switch.volvo_<your vin>_climate_status
|
||||
tap_action:
|
||||
action: toggle
|
||||
layout: vertical
|
||||
name: Klimatisieren/Heizen
|
||||
- type: custom:mushroom-template-card
|
||||
primary: Daten aktualisieren
|
||||
secondary: '{{ states(''sensor.volvo_<your vin>_last_data_update'')}}'
|
||||
icon: mdi:update
|
||||
layout: vertical
|
||||
entity: button.volvo_<your vin>_update_data
|
||||
- type: conditional
|
||||
conditions:
|
||||
- entity: sensor.volvo_<your vin>_estimated_charging_time
|
||||
state_not: '0'
|
||||
card:
|
||||
type: custom:mushroom-entity-card
|
||||
entity: sensor.volvo_<your vin>_estimated_charging_finish_time
|
||||
name: Ladung vorraussichtlich abgeschlossen
|
||||
show_name: true
|
||||
- type: map
|
||||
entities:
|
||||
- entity: device_tracker.volvo_<your vin>_location
|
||||
default_zoom: 16
|
||||
dark_mode: false
|
||||
hours_to_show: 0
|
||||
auto_fit: true
|
||||
aspect_ratio: '16:9'
|
||||
```
|
||||
|
||||
</details>
|
||||
</blockquote></details>
|
||||
|
||||
|
||||
[aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
## 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
|
||||
### 🐛 Bug Fixes:
|
||||
|
||||
- Fix app crash if `debug` is not set #86
|
||||
|
||||
## v1.8.0
|
||||
### 🚀 Features:
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
name: "Volvo2Mqtt"
|
||||
description: "Volvo AAOS MQTT bridge"
|
||||
version: "1.8.0"
|
||||
version: "1.8.2"
|
||||
slug: "volvo2mqtt"
|
||||
init: false
|
||||
url: "https://github.com/Dielee/volvo2mqtt"
|
||||
@@ -29,7 +29,7 @@ options:
|
||||
averageSpeedDivider: 1
|
||||
averageFuelConsumptionMultiplier: 1
|
||||
schema:
|
||||
updateInterval: int(10,)
|
||||
updateInterval: int(60,)
|
||||
babelLocale: str
|
||||
TZ: str
|
||||
debug: bool
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
from config import settings
|
||||
|
||||
VERSION = "v1.8.0"
|
||||
VERSION = "v1.8.2"
|
||||
|
||||
OAUTH_URL = "https://volvoid.eu.volvocars.com/as/token.oauth2"
|
||||
VEHICLES_URL = "https://api.volvocars.com/connected-vehicle/v1/vehicles"
|
||||
|
||||
+4
-3
@@ -2,14 +2,15 @@ import logging
|
||||
from volvo import authorize
|
||||
from mqtt import update_loop, connect
|
||||
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__':
|
||||
set_tz()
|
||||
set_mqtt_settings()
|
||||
setup_logging()
|
||||
logging.info("Starting volvo2mqtt version " + VERSION)
|
||||
validate_settings()
|
||||
set_tz()
|
||||
set_mqtt_settings()
|
||||
connect()
|
||||
authorize()
|
||||
update_loop()
|
||||
|
||||
+16
-3
@@ -50,9 +50,10 @@ def setup_logging():
|
||||
'%b %d %H:%M:%S')
|
||||
file_log_handler.setFormatter(formatter)
|
||||
|
||||
if settings["debug"]:
|
||||
sensitive_data_filter = SensitiveDataFilter(SENSITIVE_PATTERNS)
|
||||
file_log_handler.addFilter(sensitive_data_filter)
|
||||
if "debug" in settings:
|
||||
if settings["debug"]:
|
||||
sensitive_data_filter = SensitiveDataFilter(SENSITIVE_PATTERNS)
|
||||
file_log_handler.addFilter(sensitive_data_filter)
|
||||
|
||||
console_log_handler = logging.StreamHandler(sys.stdout)
|
||||
console_log_handler.setFormatter(formatter)
|
||||
@@ -135,3 +136,15 @@ def set_mqtt_settings():
|
||||
config.settings["mqtt"]["port"] = broker_port
|
||||
config.settings["mqtt"]["username"] = broker_user
|
||||
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
@@ -119,28 +119,32 @@ def get_vehicles():
|
||||
|
||||
|
||||
def get_vcc_api_keys(used_key=None):
|
||||
setting_keys = settings.volvoData["vccapikey"]
|
||||
if isinstance(setting_keys, str):
|
||||
set_key_state(setting_keys)
|
||||
elif isinstance(setting_keys, list):
|
||||
for key in setting_keys:
|
||||
set_key_state(key)
|
||||
working_keys = None
|
||||
|
||||
logging.debug(str(vcc_api_keys))
|
||||
working_keys = [key["key"] for key in vcc_api_keys if not key.get("extended") and key.get('key') != used_key]
|
||||
if len(working_keys) < 1:
|
||||
logging.warning("No working VCCAPIKEY found, waiting 10 minutes. Then trying again!")
|
||||
mqtt.send_offline()
|
||||
time.sleep(600)
|
||||
get_vcc_api_keys(used_key=None)
|
||||
return None
|
||||
while not working_keys:
|
||||
setting_keys = settings.volvoData["vccapikey"]
|
||||
if isinstance(setting_keys, str):
|
||||
set_key_state(setting_keys)
|
||||
elif isinstance(setting_keys, list):
|
||||
for key in setting_keys:
|
||||
set_key_state(key)
|
||||
|
||||
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))
|
||||
working_keys = [key["key"] for key in vcc_api_keys if not key.get("extended") and key.get('key') != used_key]
|
||||
if len(working_keys) < 1:
|
||||
used_key = None
|
||||
logging.warning("No working VCCAPIKEY found, waiting 10 minutes. Then trying again!")
|
||||
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):
|
||||
@@ -160,6 +164,8 @@ def set_key_state(key):
|
||||
def check_vcc_api_key(test_key, extended_until=None):
|
||||
if extended_until:
|
||||
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
|
||||
|
||||
if datetime.now(util.TZ) >= token_expires_at:
|
||||
|
||||
Reference in New Issue
Block a user