@@ -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