From 9dd0bd8a653c78063d8f9c4d6fa2939222f14800 Mon Sep 17 00:00:00 2001 From: Andreas Lemke Date: Mon, 18 May 2026 18:20:31 +0200 Subject: [PATCH 1/3] Introduce session and retries for http --- .../devices/kostal/kostal_steca/inverter.py | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/packages/modules/devices/kostal/kostal_steca/inverter.py b/packages/modules/devices/kostal/kostal_steca/inverter.py index b2158a2edd..773bcf4334 100644 --- a/packages/modules/devices/kostal/kostal_steca/inverter.py +++ b/packages/modules/devices/kostal/kostal_steca/inverter.py @@ -5,6 +5,8 @@ import xml.etree.ElementTree as ET from math import isnan +from requests.adapters import HTTPAdapter + from modules.common import req from modules.common.abstract_device import AbstractInverter from modules.common.component_state import InverterState @@ -47,26 +49,28 @@ def get_values(self) -> Tuple[float, Optional[float]]: # DetMoerk 20210323: Anpassung für ein- und dreiphasige WR der Serie. Anstatt eine feste Zeile aus # dem Ergebnis zu schneiden wird nach der Zeile mit AC_Power gesucht. - # call for XML file and parse it for current PV power - measurements = req.get_http_session().get("http://" + self.ip_address + "/measurements.xml", timeout=2).text - power_raw = ET.fromstring(measurements).find(".//Measurement[@Type='AC_Power']").get("Value") - power = 0 if power_raw is None else float(power_raw) * -1 - power = 0 if isnan(power) else power + with req.get_http_session() as session: + session.default_timeout = 2 + session.mount("http://", HTTPAdapter(max_retries=3)) + # call for XML file and parse it for current PV power + measurements = session.get("http://" + self.ip_address + "/measurements.xml").text + power_raw = ET.fromstring(measurements).find(".//Measurement[@Type='AC_Power']").get("Value") + power = 0 if power_raw is None else float(power_raw) * -1 + power = 0 if isnan(power) else power - if self.component_config.configuration.variant_steca: - # call for XML file and parse it for total produced kwh - yields = req.get_http_session().get("http://" + self.ip_address + "/yields.xml", timeout=2).text - exported = float(ET.fromstring(yields).find(".//Yield[@Type='Produced']/YieldValue").get("Value")) - else: - # call for .js file and parse it for total produced Wh - yields = req.get_http_session().get("http://" + self.ip_address + "/gen.yield.total.chart.js", - timeout=2).text - match = re.search(r'"data":\s*\[\s*([^\]]*)\s*]', yields) - try: - exported = sum(float(s) * 1e6 for s in match.group(1).split(',')) - except AttributeError: - log.debug("PVkWh: Could not find 'data' in gen.yield.total.chart.js.") - exported = None + if self.component_config.configuration.variant_steca: + # call for XML file and parse it for total produced kwh + yields = session.get("http://" + self.ip_address + "/yields.xml").text + exported = float(ET.fromstring(yields).find(".//Yield[@Type='Produced']/YieldValue").get("Value")) + else: + # call for .js file and parse it for total produced Wh + yields = session.get("http://" + self.ip_address + "/gen.yield.total.chart.js").text + match = re.search(r'"data":\s*\[\s*([^\]]*)\s*]', yields) + try: + exported = sum(float(s) * 1e6 for s in match.group(1).split(',')) + except AttributeError: + log.debug("PVkWh: Could not find 'data' in gen.yield.total.chart.js.") + exported = None _, exported = self.peak_filter.check_values(power, None, exported) return power, exported From 2eb6c78745ae080b7c933e0de11359185da1a888 Mon Sep 17 00:00:00 2001 From: Andreas Lemke Date: Thu, 21 May 2026 17:13:32 +0200 Subject: [PATCH 2/3] Reduce retries --- packages/modules/devices/kostal/kostal_steca/inverter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modules/devices/kostal/kostal_steca/inverter.py b/packages/modules/devices/kostal/kostal_steca/inverter.py index 773bcf4334..c7db6bcaf2 100644 --- a/packages/modules/devices/kostal/kostal_steca/inverter.py +++ b/packages/modules/devices/kostal/kostal_steca/inverter.py @@ -51,7 +51,7 @@ def get_values(self) -> Tuple[float, Optional[float]]: with req.get_http_session() as session: session.default_timeout = 2 - session.mount("http://", HTTPAdapter(max_retries=3)) + session.mount("http://", HTTPAdapter(max_retries=1)) # call for XML file and parse it for current PV power measurements = session.get("http://" + self.ip_address + "/measurements.xml").text power_raw = ET.fromstring(measurements).find(".//Measurement[@Type='AC_Power']").get("Value") From 05d9a24fd9f93f8b0124a97cc9c8b65bc07f2baf Mon Sep 17 00:00:00 2001 From: Andreas Lemke Date: Thu, 21 May 2026 17:14:23 +0200 Subject: [PATCH 3/3] Increase retries --- packages/modules/devices/kostal/kostal_steca/inverter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/modules/devices/kostal/kostal_steca/inverter.py b/packages/modules/devices/kostal/kostal_steca/inverter.py index c7db6bcaf2..afe90f9fa1 100644 --- a/packages/modules/devices/kostal/kostal_steca/inverter.py +++ b/packages/modules/devices/kostal/kostal_steca/inverter.py @@ -51,7 +51,7 @@ def get_values(self) -> Tuple[float, Optional[float]]: with req.get_http_session() as session: session.default_timeout = 2 - session.mount("http://", HTTPAdapter(max_retries=1)) + session.mount("http://", HTTPAdapter(max_retries=2)) # call for XML file and parse it for current PV power measurements = session.get("http://" + self.ip_address + "/measurements.xml").text power_raw = ET.fromstring(measurements).find(".//Measurement[@Type='AC_Power']").get("Value")