HomeAssist Vehicle add Range and Odometer#3257
Conversation
|
Zugehörige UI: openWB/openwb-ui-settings#939 |
There was a problem hiding this comment.
Pull request overview
Adds optional Home Assistant entities for vehicle range and odometer to the existing HomeAssistant SoC vehicle module, and migrates the configuration key from entity_id to entity_soc via a datastore upgrade.
Changes:
- Rename configuration field
entity_id→entity_soc(incl. datastore migration to version 118). - Extend HomeAssistant fetch logic to optionally read
entity_rangeandentity_odometerand return them inCarState. - Update the HomeAssistant unit test to use
entity_socin the config payload.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| packages/modules/vehicles/homeassistant/test_ha_soc.py | Adjust test config key from entity_id to entity_soc. |
| packages/modules/vehicles/homeassistant/soc.py | Fetch SoC plus optional range/odometer from Home Assistant and return extended CarState; update CLI updater signature/logging. |
| packages/modules/vehicles/homeassistant/config.py | Extend configuration model with entity_soc, entity_range, entity_odometer. |
| packages/helpermodules/update_config.py | Bump datastore version to 118 and migrate HA config entity_id → entity_soc. |
Comments suppressed due to low confidence (1)
packages/modules/vehicles/homeassistant/soc.py:50
- In
fetch_soc()wirdreq.get_http_session()für SoC/Range/Odometer jeweils erneut aufgerufen. Daget_http_session()jedes Mal ein neuesrequests.Session-Objekt erstellt (inkl. Hooks), gehen Connection-Pooling/Keep-Alive verloren und es entsteht unnötiger Overhead. Bitte einmal eine Session am Anfang erzeugen und für alle drei Requests wiederverwenden.
url_soc = url + "/api/states/" + entity_soc
response = req.get_http_session().get(url_soc, timeout=10,
headers={
"authorization": "Bearer " + token,
"content-type": "application/json"}
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if entity_range is None or entity_range == "": | ||
| range = None | ||
| else: |
There was a problem hiding this comment.
Die lokale Variable range überschattet das Python-Builtin range(). Bitte umbenennen (z. B. vehicle_range_km o. ä.), um Verwechslungen und Debugging-Probleme zu vermeiden.
| def json_update(charge_point: int, | ||
| url: str, | ||
| token: str, | ||
| entity_id: str | ||
| entity_soc: str, | ||
| entity_range: str, | ||
| entity_odometer: str | ||
| ): |
There was a problem hiding this comment.
json_update() macht entity_range und entity_odometer als Pflicht-Positional-Args. Da run_using_positional_cli_args nur Optional[...]-Parameter als optional behandelt, ist das ein Breaking Change für bestehende Aufrufe/Configs ohne diese Werte. Bitte als Optional[str] mit Default None (oder "") definieren, damit bestehende CLI-Aufrufe weiter funktionieren.
| entity_range: str, | ||
| entity_odometer: str | ||
| ): | ||
| log.debug(f'homeassistant-soc: charge_point={charge_point} url="{url}" token="{token}" ' |
There was a problem hiding this comment.
In der Debug-Ausgabe wird der Auth-Token im Klartext geloggt. Das kann Secrets in Logs/Support-Bundles/CI-Artefakte leaken. Bitte Token nicht loggen oder mindestens maskieren (z. B. nur Prefix/Suffix).
| log.debug(f'homeassistant-soc: charge_point={charge_point} url="{url}" token="{token}" ' | |
| if token: | |
| masked_token = (token[:4] + '***') if len(token) > 4 else '***' | |
| else: | |
| masked_token = '<none>' | |
| log.debug(f'homeassistant-soc: charge_point={charge_point} url="{url}" token="{masked_token}" ' |
There was a problem hiding this comment.
wird zentral in der logger.py gefiltert
| f'entity_range="{entity_range}"' | ||
| f'entity_odometer="{entity_odometer}"') |
There was a problem hiding this comment.
Die log.debug(...)-F-Strings werden ohne Trennzeichen zusammengesetzt, wodurch im Log z. B. entity_soc="..."entity_range="..." entsteht. Bitte klare Separatoren (Leerzeichen/Kommas) hinzufügen, damit Logs maschinen- und menschenlesbar bleiben.
| f'entity_range="{entity_range}"' | |
| f'entity_odometer="{entity_odometer}"') | |
| f' entity_range="{entity_range}"' | |
| f' entity_odometer="{entity_odometer}"') |
| if entity_range is None or entity_range == "": | ||
| range = None | ||
| else: | ||
| url_range = url + "/api/states/" + entity_range | ||
| response = req.get_http_session().get(url_range, timeout=10, | ||
| headers={ | ||
| "authorization": "Bearer " + token, | ||
| "content-type": "application/json"} | ||
| ) | ||
| json = response.json() | ||
| range = float(json['state']) | ||
| if entity_odometer is None or entity_odometer == "": | ||
| odometer = None | ||
| else: | ||
| url_odometer = url + "/api/states/" + entity_odometer | ||
| response = req.get_http_session().get(url_odometer, timeout=10, | ||
| headers={ | ||
| "authorization": "Bearer " + token, | ||
| "content-type": "application/json"} | ||
| ) | ||
| json = response.json() | ||
| odometer = float(json['state']) | ||
| return CarState(soc=soc, range=range, odometer=odometer, soc_timestamp=soc_timestamp) |
There was a problem hiding this comment.
Für die neu hinzugefügte Logik zum Abruf von entity_range und entity_odometer fehlt Testabdeckung. Bitte Tests ergänzen, die (a) mehrere GET-Calls mit unterschiedlichen Responses abbilden und (b) verifizieren, dass CarState.range und CarState.odometer korrekt gesetzt werden, wenn die Entitäten konfiguriert sind.
| vehicle_config = HaVehicleSocSetup(configuration=HaVehicleSocConfiguration( | ||
| url=case['url'], | ||
| token=case['token'], | ||
| entity_id=case['entity_id'] | ||
| entity_soc=case['entity_soc'] | ||
| )) |
There was a problem hiding this comment.
Der Patch-Target-String referenziert das Modul soc (@patch('soc.req.get_http_session')). Unter dem in CI verwendeten PYTHONPATH=packages ist kein Top-Level-Modul soc vorhanden; dadurch schlägt das Patchen typischerweise mit ModuleNotFoundError fehl oder patched nicht das tatsächlich importierte Modul. Bitte das Target auf den tatsächlichen Importpfad anpassen (z. B. modules.vehicles.homeassistant.soc.req.get_http_session).
Hallo @LKuemmel ,
da dies ein offiziell durch openWB gepflegtes Modul ist, weiß ich nicht, ob Ihr hier auch Änderungen haben wollt.
Ich habe entity_id nach entity_soc umgezogen, da es ja nun mehrere Entitäten gibt, hoffe mit dem upgrade_datastore passt das soweit.
Habe es bei mir getestet, hier tut es, was es soll.
VG
Christoph