diff --git a/packages/helpermodules/setdata.py b/packages/helpermodules/setdata.py index 69403d20ff..ef6ad9d90c 100644 --- a/packages/helpermodules/setdata.py +++ b/packages/helpermodules/setdata.py @@ -794,6 +794,8 @@ def process_mqtt_topic(self, msg: mqtt.MQTTMessage): self.process_bat_topic(msg) elif "openWB/set/mqtt/pv/" in msg.topic: self.process_pv_topic(msg) + elif "openWB/set/mqtt/vehicle/" in msg.topic: + self.process_vehicle_topic(msg) def process_optional_topic(self, msg: mqtt.MQTTMessage): """ Handler für die Optionalen-Topics diff --git a/packages/helpermodules/update_config.py b/packages/helpermodules/update_config.py index ff1b73d209..a55883a1d8 100644 --- a/packages/helpermodules/update_config.py +++ b/packages/helpermodules/update_config.py @@ -304,6 +304,9 @@ class UpdateConfig: "^openWB/mqtt/inverter/[0-9]+/get/power$", "^openWB/mqtt/inverter/[0-9]+/get/exported$", "^openWB/mqtt/inverter/[0-9]+/get/dc_power$", + "^openWB/mqtt/vehicle/[0-9]+/get/range$", + "^openWB/mqtt/vehicle/[0-9]+/get/soc$", + "^openWB/mqtt/vehicle/[0-9]+/get/soc_timestamp$", "^openWB/set/log/request", "^openWB/set/log/data", diff --git a/packages/modules/common/configurable_vehicle.py b/packages/modules/common/configurable_vehicle.py index e94917632c..297d4832e5 100644 --- a/packages/modules/common/configurable_vehicle.py +++ b/packages/modules/common/configurable_vehicle.py @@ -71,6 +71,9 @@ def update(self, vehicle_update_data: VehicleUpdateData): log.debug("No soc update necessary.") return car_state = self._get_carstate_by_source(vehicle_update_data, source) + if isinstance(self.vehicle_config, MqttSocSetup) and car_state is None: + log.debug("Mqtt uses legacy topics.") + return log.debug(f"Requested start soc from {source.value}: {car_state.soc}%") if (source != SocSource.CALCULATION or @@ -90,8 +93,6 @@ def update(self, vehicle_update_data: VehicleUpdateData): log.debug("Not updating SoC, because timestamp is older.") def _get_carstate_source(self, vehicle_update_data: VehicleUpdateData) -> SocSource: - if isinstance(self.vehicle_config, MqttSocSetup): - return SocSource.NO_UPDATE # Kein SoC vom LP vorhanden oder erwünscht if (vehicle_update_data.soc_from_cp is None or self.general_config.use_soc_from_cp is False or # oder aktueller manueller SoC vorhanden (ausgelesenen SoC während der Ladung korrigieren) diff --git a/packages/modules/common/configurable_vehicle_test.py b/packages/modules/common/configurable_vehicle_test.py index 98e71dff49..f31bcf6603 100644 --- a/packages/modules/common/configurable_vehicle_test.py +++ b/packages/modules/common/configurable_vehicle_test.py @@ -120,7 +120,7 @@ def conf_vehicle_mqtt(): pytest.param(conf_vehicle_api_while_charging(), False, VehicleUpdateData(plug_state=True, charge_state=True), CalculatedSocState(), SocSource.CALCULATION, id="API mit Berechnung, Ladung"), pytest.param(conf_vehicle_mqtt(), False, VehicleUpdateData(plug_state=True), - CalculatedSocState(), SocSource.NO_UPDATE, id="Kein Update, da Werte per MQTT"), + CalculatedSocState(), SocSource.API, id="MQTT-Werte werden vom Broker abgerufen"), ]) def test_get_carstate_source(conf_vehicle: ConfigurableVehicle, use_soc_from_cp, diff --git a/packages/modules/vehicles/mqtt/soc.py b/packages/modules/vehicles/mqtt/soc.py index 4441c9494e..23be6ee2ba 100644 --- a/packages/modules/vehicles/mqtt/soc.py +++ b/packages/modules/vehicles/mqtt/soc.py @@ -1,6 +1,8 @@ #!/usr/bin/env python3 import logging +from helpermodules.broker import BrokerClient +from helpermodules.utils.topic_parser import decode_payload from modules.vehicles.mqtt.config import MqttSocSetup from modules.common.abstract_device import DeviceDescriptor from modules.common.abstract_vehicle import VehicleUpdateData @@ -12,8 +14,31 @@ def create_vehicle(vehicle_config: MqttSocSetup, vehicle: int): def updater(vehicle_update_data: VehicleUpdateData) -> CarState: - log.debug("MQTT-Fahrzeuge müssen nicht ausgelesen werden.") - return ConfigurableVehicle(vehicle_config=vehicle_config, component_updater=updater, vehicle=vehicle) + def on_connect(client, userdata, flags, rc): + client.subscribe(f"openWB/mqtt/vehicle/{vehicle}/get/#") + + def on_message(client, userdata, message): + received_topics.update({message.topic: decode_payload(message.payload)}) + + received_topics = {} + BrokerClient(f"subscribeMqttVehicle{vehicle}", + on_connect, on_message).start_finite_loop() + + if received_topics: + log.debug(f"Empfange MQTT Daten für Fahrzeug {vehicle}: {received_topics}") + topic_prefix = f"openWB/mqtt/vehicle/{vehicle}/get/" + return CarState(soc=received_topics.get(f"{topic_prefix}soc"), + range=received_topics.get(f"{topic_prefix}range"), + soc_timestamp=received_topics.get(f"{topic_prefix}soc_timestamp")) + else: + configurable_vehicle.fault_state.warning( + f"Keine MQTT-Daten für Fahrzeug {vehicle_config.name} empfangen oder es werden " + "veraltete, abwärtskompatible Topics verwendet. Bitte die Doku in den " + "Einstellungen beachten.") + return None + configurable_vehicle = ConfigurableVehicle(vehicle_config=vehicle_config, + component_updater=updater, vehicle=vehicle) + return configurable_vehicle device_descriptor = DeviceDescriptor(configuration_factory=MqttSocSetup)