Skip to content

Commit 3c059ca

Browse files
authored
Merge pull request #2914 from openWB/add-simpleAPI-topics
Add readable mqtt topics simpleAPI
2 parents 19c2ab3 + 6674e4c commit 3c059ca

1 file changed

Lines changed: 105 additions & 5 deletions

File tree

‎simpleAPI/simpleAPI_mqtt.py‎

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ def _on_connect(self, client, userdata, flags, rc):
9191
"""Callback for successful MQTT connection."""
9292
if rc == 0:
9393
log.info(f"Connected to MQTT broker at {self.host}:{self.port}")
94+
95+
# Publish API revision
96+
self._publish_revision()
97+
9498
# Subscribe to specific openWB component topics
9599
client.subscribe("openWB/bat/#", qos=0)
96100
client.subscribe("openWB/pv/#", qos=0)
@@ -271,7 +275,11 @@ def _transform_chargepoint_topic(self, simple_base: str) -> Optional[str]:
271275
log.debug(f"DEBUG: Found vehicle name pattern, transforming: {simple_base}")
272276
simple_base = re.sub(r'/get/connected_vehicle/info/name$', '/vehicle_name', simple_base)
273277
simple_base = re.sub(r'/connected_vehicle/info/name$', '/vehicle_name', simple_base)
274-
278+
elif '/connected_vehicle/soc' in simple_base:
279+
log.debug(f"DEBUG: Found connected_vehicle soc pattern, transforming: {simple_base}")
280+
simple_base = re.sub(r'/get/connected_vehicle/soc$', '/soc', simple_base)
281+
simple_base = re.sub(r'/connected_vehicle/soc$', '/soc', simple_base)
282+
275283
# Keep only config topics that are in the allowed list
276284
if '/config/' in simple_base and not re.search(r'/(chargemode|vehicle_name)$', simple_base):
277285
allowed_config_paths = [
@@ -304,11 +312,17 @@ def _transform_chargepoint_topic(self, simple_base: str) -> Optional[str]:
304312
# Handle get topics - remove /get/ prefix
305313
if '/get/' in simple_base:
306314
simple_base = simple_base.replace('/get/', '/')
307-
315+
316+
# Special handling for soc-related topics
317+
if re.search(r'/soc$', simple_base):
318+
simple_base = re.sub(r'/soc$', '/pro_soc', simple_base)
319+
elif re.search(r'/soc_timestamp$', simple_base):
320+
simple_base = re.sub(r'/soc_timestamp$', '/pro_soc_timestamp', simple_base)
321+
308322
# Filter out unwanted topics - but exclude already transformed ones
309-
if not re.search(r'/(chargemode|vehicle_name)$', simple_base):
323+
if not re.search(r'/(chargemode|vehicle_name|soc|pro_soc|pro_soc_timestamp)$', simple_base):
310324
unwanted_patterns = [
311-
r'/connected_vehicle/(info|config|soc)/',
325+
r'/connected_vehicle/(info|config)/',
312326
r'/max_evse_current$',
313327
r'/current_branch$',
314328
r'/current_commit$'
@@ -320,7 +334,7 @@ def _transform_chargepoint_topic(self, simple_base: str) -> Optional[str]:
320334
else:
321335
# For non-get topics, also filter out remaining connected_vehicle topics
322336
# but exclude the ones we already transformed
323-
if not re.search(r'/(chargemode|vehicle_name)$', simple_base):
337+
if not re.search(r'/(chargemode|vehicle_name|soc)$', simple_base):
324338
if re.search(r'/connected_vehicle/', simple_base):
325339
log.debug(f"DEBUG: Filtering out connected_vehicle topic: {simple_base}")
326340
return None
@@ -424,12 +438,88 @@ def _cache_charge_template(self, topic: str, payload: str):
424438
charge_template = json.loads(payload)
425439
self.charge_template_cache[chargepoint_id] = charge_template
426440
log.debug(f"Cached charge_template for chargepoint {chargepoint_id}")
441+
442+
# Publish read topics for charge_template values
443+
self._publish_charge_template_read_topics(chargepoint_id, charge_template)
427444

428445
except json.JSONDecodeError as e:
429446
log.warning(f"Failed to parse charge_template JSON for {topic}: {e}")
430447
except Exception as e:
431448
log.error(f"Error caching charge_template for {topic}: {e}")
432449

450+
def _publish_charge_template_read_topics(self, chargepoint_id: str, charge_template: Dict[str, Any]):
451+
"""Publish readable topics for charge_template values."""
452+
try:
453+
chargemode = charge_template.get('chargemode', {})
454+
455+
# Extract min_current from pv_charging
456+
pv_charging = chargemode.get('pv_charging', {})
457+
if 'min_current' in pv_charging:
458+
topic = f"openWB/simpleAPI/chargepoint/{chargepoint_id}/minimal_permanent_current"
459+
self._publish_if_changed(topic, pv_charging['min_current'])
460+
461+
# Also publish for lowest ID if this is it
462+
if 'chargepoint' in self.lowest_ids and self.lowest_ids['chargepoint'] == int(chargepoint_id):
463+
simple_topic = "openWB/simpleAPI/chargepoint/minimal_permanent_current"
464+
self._publish_if_changed(simple_topic, pv_charging['min_current'])
465+
466+
# Extract min_soc from pv_charging (minimal_pv_soc)
467+
if 'min_soc' in pv_charging:
468+
topic = f"openWB/simpleAPI/chargepoint/{chargepoint_id}/minimal_pv_soc"
469+
self._publish_if_changed(topic, pv_charging['min_soc'])
470+
471+
# Also publish for lowest ID if this is it
472+
if 'chargepoint' in self.lowest_ids and self.lowest_ids['chargepoint'] == int(chargepoint_id):
473+
simple_topic = "openWB/simpleAPI/chargepoint/minimal_pv_soc"
474+
self._publish_if_changed(simple_topic, pv_charging['min_soc'])
475+
476+
# Extract max_price from eco_charging
477+
eco_charging = chargemode.get('eco_charging', {})
478+
if 'max_price' in eco_charging:
479+
topic = f"openWB/simpleAPI/chargepoint/{chargepoint_id}/max_price_eco"
480+
self._publish_if_changed(topic, eco_charging['max_price'])
481+
482+
# Also publish for lowest ID if this is it
483+
if 'chargepoint' in self.lowest_ids and self.lowest_ids['chargepoint'] == int(chargepoint_id):
484+
simple_topic = "openWB/simpleAPI/chargepoint/max_price_eco"
485+
self._publish_if_changed(simple_topic, eco_charging['max_price'])
486+
487+
# Extract instant_charging_limit values
488+
instant_charging = chargemode.get('instant_charging', {})
489+
limit = instant_charging.get('limit', {})
490+
491+
if 'selected' in limit:
492+
topic = f"openWB/simpleAPI/chargepoint/{chargepoint_id}/instant_charging_limit"
493+
self._publish_if_changed(topic, limit['selected'])
494+
495+
# Also publish for lowest ID if this is it
496+
if 'chargepoint' in self.lowest_ids and self.lowest_ids['chargepoint'] == int(chargepoint_id):
497+
simple_topic = "openWB/simpleAPI/chargepoint/instant_charging_limit"
498+
self._publish_if_changed(simple_topic, limit['selected'])
499+
500+
if 'amount' in limit:
501+
# Convert from internal value (Wh) to kWh for display
502+
amount_kwh = limit['amount'] / 1000
503+
topic = f"openWB/simpleAPI/chargepoint/{chargepoint_id}/instant_charging_limit_amount"
504+
self._publish_if_changed(topic, amount_kwh)
505+
506+
# Also publish for lowest ID if this is it
507+
if 'chargepoint' in self.lowest_ids and self.lowest_ids['chargepoint'] == int(chargepoint_id):
508+
simple_topic = "openWB/simpleAPI/chargepoint/instant_charging_limit_amount"
509+
self._publish_if_changed(simple_topic, amount_kwh)
510+
511+
if 'soc' in limit:
512+
topic = f"openWB/simpleAPI/chargepoint/{chargepoint_id}/instant_charging_limit_soc"
513+
self._publish_if_changed(topic, limit['soc'])
514+
515+
# Also publish for lowest ID if this is it
516+
if 'chargepoint' in self.lowest_ids and self.lowest_ids['chargepoint'] == int(chargepoint_id):
517+
simple_topic = "openWB/simpleAPI/chargepoint/instant_charging_limit_soc"
518+
self._publish_if_changed(simple_topic, limit['soc'])
519+
520+
except Exception as e:
521+
log.error(f"Error publishing charge_template read topics: {e}")
522+
433523
def _handle_write_operation(self, topic: str, payload: str):
434524
"""Handle write operations from simpleAPI set topics."""
435525
try:
@@ -777,6 +867,16 @@ def _publish_json(self, topic: str, data: Dict[str, Any]):
777867
except Exception as e:
778868
log.error(f"Failed to publish JSON to {topic}: {e}")
779869

870+
def _publish_revision(self):
871+
"""Publish API revision number."""
872+
try:
873+
revision_topic = "openWB/simpleAPI/revision"
874+
revision_value = "2"
875+
self.client.publish(revision_topic, revision_value, qos=0, retain=True)
876+
log.info(f"Published API revision: {revision_value}")
877+
except Exception as e:
878+
log.error(f"Failed to publish revision: {e}")
879+
780880
def connect(self):
781881
"""Establish connection to MQTT broker."""
782882
try:

0 commit comments

Comments
 (0)