diff --git a/packages/control/chargepoint/chargepoint.py b/packages/control/chargepoint/chargepoint.py index a26b402769..6e3bcee1a9 100644 --- a/packages/control/chargepoint/chargepoint.py +++ b/packages/control/chargepoint/chargepoint.py @@ -731,13 +731,18 @@ def update(self, ev_list: Dict[str, Ev]) -> None: if self.data.get.plug_state and self.data.set.plug_state_prev is False: self.data.control_parameter.timestamp_chargemode_changed = create_timestamp() # SoC nach Anstecken aktualisieren + soc_update_target_ev = vehicle if vehicle != -1 else self.data.config.ev if ((self.data.get.plug_state and self.data.set.plug_state_prev is False) or (self.data.get.plug_state is False and self.data.set.plug_state_prev) or (self.data.get.soc_timestamp and self.data.set.charging_ev_data.data.get.soc_timestamp and - self.data.get.soc_timestamp > self.data.set.charging_ev_data.data.get.soc_timestamp)): - Pub().pub( - f"openWB/set/vehicle/{vehicle if vehicle != -1 else self.data.config.ev}/get/force_soc_update", - True) + self.data.get.soc_timestamp > self.data.set.charging_ev_data.data.get.soc_timestamp and + # nicht jeden Zyklus erneut anstoßen, wenn der EV-SoC dauerhaft veraltet bleibt + # (zB API-Fehler); nur bei neuem CP-SoC oder EV-Wechsel am LP erneut auslösen + (self.data.get.soc_timestamp != self.data.set.soc_timestamp_force_update_prev or + soc_update_target_ev != self.data.set.soc_timestamp_force_update_prev_ev))): + Pub().pub(f"openWB/set/vehicle/{soc_update_target_ev}/get/force_soc_update", True) + self.data.set.soc_timestamp_force_update_prev = self.data.get.soc_timestamp + self.data.set.soc_timestamp_force_update_prev_ev = soc_update_target_ev log.debug("SoC nach Anstecken") self.set_state_and_log(message) except Exception: @@ -766,6 +771,9 @@ def _get_charging_ev(self, vehicle: int, ev_list: Dict[str, Ev]) -> Ev: self.update_charge_template(charging_ev.charge_template) if self.data.config.ev != vehicle: Pub().pub(f"openWB/set/vehicle/{charging_ev.num}/get/force_soc_update", True) + # verhindert doppeltes Pub in der "SoC nach Anstecken"-Prüfung im selben update()-Zyklus + self.data.set.soc_timestamp_force_update_prev = self.data.get.soc_timestamp + self.data.set.soc_timestamp_force_update_prev_ev = vehicle log.debug("SoC nach EV-Wechsel") self.data.config.ev = vehicle self.data.set.charging_ev_data = charging_ev diff --git a/packages/control/chargepoint/chargepoint_data.py b/packages/control/chargepoint/chargepoint_data.py index 429d20bdc3..f13d121353 100644 --- a/packages/control/chargepoint/chargepoint_data.py +++ b/packages/control/chargepoint/chargepoint_data.py @@ -174,6 +174,13 @@ class Set: charging_ev_data: Ev = field(default_factory=ev_factory) ocpp_transaction_id: Optional[int] = field(default=None, metadata={"topic": "set/ocpp_transaction_id"}) charge_state_prev: bool = field(default=False, metadata={"topic": "set/charge_state_prev"}) + # letzter CP-SoC-Timestamp, für den bereits ein force_soc_update ausgelöst wurde, und das zugehörige EV, + # um bei dauerhaft veraltetem EV-SoC (zB API-Fehler) nicht jeden Zyklus erneut ein Update anzustoßen, + # aber bei einem EV-Wechsel am selben Ladepunkt trotzdem einmal neu auszulösen + soc_timestamp_force_update_prev: Optional[int] = field( + default=None, metadata={"topic": "set/soc_timestamp_force_update_prev"}) + soc_timestamp_force_update_prev_ev: Optional[int] = field( + default=None, metadata={"topic": "set/soc_timestamp_force_update_prev_ev"}) @dataclass diff --git a/packages/helpermodules/setdata.py b/packages/helpermodules/setdata.py index 665ff72fb9..25d0a5b5a1 100644 --- a/packages/helpermodules/setdata.py +++ b/packages/helpermodules/setdata.py @@ -505,6 +505,8 @@ def process_chargepoint_topic(self, msg: mqtt.MQTTMessage): self._validate_value(msg, float) elif "/set/ocpp_transaction_id" in msg.topic: self._validate_value(msg, int) + elif "/set/soc_timestamp_force_update_prev" in msg.topic: + self._validate_value(msg, int) elif "/set/log" in msg.topic: self._validate_value(msg, "json") elif "/set/ev_prev" in msg.topic: diff --git a/packages/modules/common/store/_chargepoint.py b/packages/modules/common/store/_chargepoint.py index 292887f31b..e3cb5ce8ef 100644 --- a/packages/modules/common/store/_chargepoint.py +++ b/packages/modules/common/store/_chargepoint.py @@ -37,8 +37,10 @@ def update(self): if self.state.rfid_timestamp is not None: pub_to_broker("openWB/set/chargepoint/" + str(self.num) + "/get/rfid_timestamp", self.state.rfid_timestamp) pub_to_broker("openWB/set/chargepoint/" + str(self.num) + "/get/serial_number", self.state.serial_number) - pub_to_broker("openWB/set/chargepoint/" + str(self.num) + "/get/soc", self.state.soc) - pub_to_broker("openWB/set/chargepoint/" + str(self.num) + "/get/soc_timestamp", self.state.soc_timestamp) + if self.state.soc is not None: + pub_to_broker("openWB/set/chargepoint/" + str(self.num) + "/get/soc", self.state.soc) + if self.state.soc_timestamp is not None: + pub_to_broker("openWB/set/chargepoint/" + str(self.num) + "/get/soc_timestamp", self.state.soc_timestamp) pub_to_broker("openWB/set/chargepoint/" + str(self.num) + "/get/evse_current", self.state.evse_current) pub_to_broker("openWB/set/chargepoint/" + str(self.num) + "/get/vehicle_id", self.state.vehicle_id) pub_to_broker("openWB/set/chargepoint/" + str(self.num) + "/get/max_evse_current", self.state.max_evse_current)