Repository navigation
Feature/bmw cardata #3322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/bmw cardata #3322
Changes from all commits
8077c6f
9311857
96b1804
395d82b
f4e1208
c9823e7
e6f09f2
e5f37b4
13ce119
4ce8597
9f2ef63
2dc1e30
93aff36
f034f26
6f3eee5
58e4abe
4c92233
2237d53
09ea5c6
83e57ca
70efc85
d2dabbd
1a54611
ac6b597
2422882
a405d04
5eab873
cfdede0
ce42a0a
5604736
65f2387
4ed95d8
0ce1c04
292589f
d465524
256275a
c8c68d2
32277ee
b47ab7b
1d6898e
ed3d33e
83dcb77
df94045
99a39ab
9354012
2b9e0d4
4e39fd2
9a5c2d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,9 @@ | |
|
|
||
| from requests.exceptions import RequestException | ||
|
|
||
| from control import data as control_data | ||
| from dataclass_utils import asdict | ||
| from helpermodules.pub import Pub | ||
| from modules.common import req | ||
| from modules.common.abstract_device import DeviceDescriptor | ||
| from modules.common.abstract_vehicle import VehicleUpdateData | ||
|
|
@@ -19,6 +22,7 @@ | |
| FIELD_SOC = "vehicle.drivetrain.electricEngine.charging.level" | ||
| FIELD_SOC_ALT = "vehicle.drivetrain.batteryManagement.header" | ||
| FIELD_RANGE = "vehicle.drivetrain.electricEngine.remainingElectricRange" | ||
| FIELD_RANGE_ALT = "vehicle.drivetrain.electricEngine.kombiRemainingElectricRange" | ||
| FIELD_STATUS = "vehicle.drivetrain.electricEngine.charging.status" | ||
| FIELD_ODOMETER_CANDIDATES = [ | ||
| "vehicle.vehicle.travelledDistance", | ||
|
|
@@ -32,6 +36,7 @@ | |
| "vehicle.drivetrain.electricEngine.charging.level", | ||
| "vehicle.drivetrain.batteryManagement.header", | ||
| "vehicle.drivetrain.electricEngine.remainingElectricRange", | ||
| "vehicle.drivetrain.electricEngine.kombiRemainingElectricRange", | ||
| "vehicle.vehicle.travelledDistance", | ||
| ] | ||
|
|
||
|
|
@@ -119,7 +124,7 @@ def _fetch_telematic_data(token: str, vin: str, container_id: str): | |
| return _get_json(url, token) | ||
|
|
||
|
|
||
| def get_valid_token(cfg: BmwCardataConfiguration) -> str: | ||
| def get_valid_token(cfg: BmwCardataConfiguration, vehicle: int, config: BmwCardataSetup) -> str: | ||
| if not cfg.access_token: | ||
| raise Exception("BMW CarData: Keine Tokens gefunden. Bitte BMW-Kopplung in der UI durchführen.") | ||
|
|
||
|
|
@@ -146,6 +151,34 @@ def get_valid_token(cfg: BmwCardataConfiguration) -> str: | |
| cfg.expires_at = time.time() + new.get("expires_in", 3600) - 60 | ||
|
|
||
| log.info("BMW CarData: Token-Refresh erfolgreich.") | ||
|
|
||
| # Neuen Token zurück in MQTT schreiben – auch für alle anderen BMW CarData | ||
| # Fahrzeuge mit derselben Client ID damit diese nicht invalidiert werden | ||
| try: | ||
| for ev_key, ev in control_data.data.ev_data.items(): | ||
| try: | ||
| soc_module = ev.soc_module | ||
| if soc_module is None: | ||
| continue | ||
| other_config = soc_module.vehicle_config | ||
| if (hasattr(other_config, 'type') and | ||
| other_config.type == "bmw_cardata" and | ||
| other_config.configuration.client_id == cfg.client_id): | ||
| other_config.configuration.access_token = cfg.access_token | ||
| other_config.configuration.refresh_token = cfg.refresh_token | ||
| other_config.configuration.expires_at = cfg.expires_at | ||
| Pub().pub( | ||
| f"openWB/set/vehicle/{ev.num}/soc_module/config", | ||
| asdict(other_config) | ||
| ) | ||
|
benderl marked this conversation as resolved.
Resolved
|
||
| log.info( | ||
| "BMW CarData: Token in MQTT aktualisiert für Fahrzeug %s.", ev.num | ||
| ) | ||
| except Exception as e: | ||
| log.warning("BMW CarData: Token-Sync für Fahrzeug %s fehlgeschlagen: %s", ev_key, e) | ||
| except Exception as e: | ||
| log.warning("BMW CarData: Token-Sync fehlgeschlagen: %s", e) | ||
|
|
||
| return cfg.access_token | ||
|
|
||
|
|
||
|
|
@@ -175,15 +208,15 @@ def get_container_id(cfg: BmwCardataConfiguration, token: str) -> str: | |
| return container_id | ||
|
|
||
|
|
||
| def fetch_soc(config: BmwCardataSetup) -> CarState: | ||
| def fetch_soc(config: BmwCardataSetup, vehicle: int = 0) -> CarState: | ||
| cfg = config.configuration | ||
|
|
||
| if not cfg.client_id: | ||
| raise Exception("BMW CarData: client_id nicht konfiguriert!") | ||
| if not cfg.vin: | ||
| raise Exception("BMW CarData: VIN nicht konfiguriert!") | ||
|
|
||
| token = get_valid_token(cfg) | ||
| token = get_valid_token(cfg, vehicle, config) | ||
| container_id = get_container_id(cfg, token) | ||
|
|
||
| try: | ||
|
|
@@ -212,6 +245,8 @@ def fetch_soc(config: BmwCardataSetup) -> CarState: | |
| soc_raw = _extract_value(td, FIELD_SOC_ALT) | ||
|
|
||
| range_raw = _extract_value(td, FIELD_RANGE) | ||
| if range_raw is None: | ||
| range_raw = _extract_value(td, FIELD_RANGE_ALT) | ||
|
benderl marked this conversation as resolved.
Resolved
Comment on lines
247
to
+249
|
||
| status = _extract_value(td, FIELD_STATUS) | ||
| odometer_raw = _extract_first_value(td, FIELD_ODOMETER_CANDIDATES) | ||
|
|
||
|
|
@@ -222,6 +257,13 @@ def fetch_soc(config: BmwCardataSetup) -> CarState: | |
| if soc is None: | ||
| raise Exception("BMW CarData: Kein SoC-Wert in API-Antwort gefunden!") | ||
|
|
||
| if vehicle_range is None and cfg.container_id: | ||
| log.warning( | ||
| "BMW CarData: Kein Reichweitenwert im Container gefunden – " | ||
| "Container wird neu erstellt um fehlende Datenpunkte zu ergänzen." | ||
| ) | ||
| cfg.container_id = "" | ||
|
|
||
| log.info( | ||
| "BMW CarData: SoC=%s%%, Reichweite=%s km, Status=%s, Odometer=%s km", | ||
| soc, | ||
|
|
@@ -234,7 +276,7 @@ def fetch_soc(config: BmwCardataSetup) -> CarState: | |
|
|
||
| def create_vehicle(vehicle_config: BmwCardataSetup, vehicle: int): | ||
| def updater(vehicle_update_data: VehicleUpdateData) -> CarState: | ||
| return fetch_soc(vehicle_config) | ||
| return fetch_soc(vehicle_config, vehicle) | ||
|
|
||
| return ConfigurableVehicle( | ||
| vehicle_config=vehicle_config, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.