@@ -166,14 +166,17 @@ def _transform_and_publish(self, original_topic: str, payload: str):
166166 """Transform original topic to simpleAPI format and publish if value changed."""
167167 try :
168168 log .debug (f"DEBUG: Processing original topic: { original_topic } " )
169-
169+
170170 # Parse the payload
171171 parsed_payload = self ._parse_payload (payload )
172172
173173 # Generate transformed topics
174174 transformed_topics = self ._generate_simple_topics (original_topic , parsed_payload )
175-
176- log .debug (f"DEBUG: Generated { len (transformed_topics )} transformed topics: { list (transformed_topics .keys ())} " )
175+
176+ log .debug (
177+ f"DEBUG: Generated { len (transformed_topics )} transformed topics: "
178+ f"{ list (transformed_topics .keys ())} "
179+ )
177180
178181 # Publish each transformed topic if value changed
179182 for topic , value in transformed_topics .items ():
@@ -250,9 +253,9 @@ def _generate_simple_topics(self, original_topic: str, parsed_value: Any) -> Dic
250253
251254 def _transform_chargepoint_topic (self , simple_base : str ) -> Optional [str ]:
252255 """Transform chargepoint topics according to simplified structure."""
253-
256+
254257 log .debug (f"DEBUG: _transform_chargepoint_topic input: { simple_base } " )
255-
258+
256259 # FIRST: Handle connected_vehicle transformations (both /get/ and direct)
257260 # This must happen BEFORE any other filtering
258261 if '/connected_vehicle/config/chargemode' in simple_base :
@@ -263,45 +266,45 @@ def _transform_chargepoint_topic(self, simple_base: str) -> Optional[str]:
263266 simple_base = re .sub (r'/connected_vehicle/config/chargemode$' , '/chargemode' , simple_base )
264267 log .debug (f"DEBUG: After second regex: { simple_base } " )
265268 if original != simple_base :
266- log .debug (f"DEBUG: Chargemode transformation successful: { original } -> { simple_base } " )
269+ log .debug (f"DEBUG: Charge mode transformation successful: { original } -> { simple_base } " )
267270 elif '/connected_vehicle/info/name' in simple_base :
268271 log .debug (f"DEBUG: Found vehicle name pattern, transforming: { simple_base } " )
269272 simple_base = re .sub (r'/get/connected_vehicle/info/name$' , '/vehicle_name' , simple_base )
270273 simple_base = re .sub (r'/connected_vehicle/info/name$' , '/vehicle_name' , simple_base )
271-
274+
272275 # Keep only config topics that are in the allowed list
273276 if '/config/' in simple_base and not re .search (r'/(chargemode|vehicle_name)$' , simple_base ):
274277 allowed_config_paths = [
275- 'configuration/ip_address' , 'configuration/duo_num' , 'ev' , 'name' ,
276- 'type' , 'template' , 'connected_phases' , 'phase_1' ,
278+ 'configuration/ip_address' , 'configuration/duo_num' , 'ev' , 'name' ,
279+ 'type' , 'template' , 'connected_phases' , 'phase_1' ,
277280 'auto_phase_switch_hw' , 'control_pilot_interruption_hw' , 'id' , 'ocpp_chargebox_id'
278281 ]
279-
282+
280283 # Extract the config path part
281284 config_match = re .search (r'/config/(.+)$' , simple_base )
282285 if config_match :
283286 config_path = config_match .group (1 )
284287 if config_path in allowed_config_paths :
285288 return simple_base # Keep this config topic
286-
289+
287290 return None # Filter out other config topics
288-
291+
289292 # Handle set topics with special mappings
290293 if '/set/' in simple_base :
291294 # set/manual_lock -> manual_lock
292295 simple_base = re .sub (r'/set/manual_lock$' , '/manual_lock' , simple_base )
293-
296+
294297 # set/current -> evse_current
295298 simple_base = re .sub (r'/set/current$' , '/evse_current' , simple_base )
296-
299+
297300 # Filter out all other set topics (like charge_template, log, etc.)
298301 if '/set/' in simple_base :
299302 return None
300-
303+
301304 # Handle get topics - remove /get/ prefix
302305 if '/get/' in simple_base :
303306 simple_base = simple_base .replace ('/get/' , '/' )
304-
307+
305308 # Filter out unwanted topics - but exclude already transformed ones
306309 if not re .search (r'/(chargemode|vehicle_name)$' , simple_base ):
307310 unwanted_patterns = [
@@ -310,7 +313,7 @@ def _transform_chargepoint_topic(self, simple_base: str) -> Optional[str]:
310313 r'/current_branch$' ,
311314 r'/current_commit$'
312315 ]
313-
316+
314317 for pattern in unwanted_patterns :
315318 if re .search (pattern , simple_base ):
316319 return None
@@ -321,7 +324,7 @@ def _transform_chargepoint_topic(self, simple_base: str) -> Optional[str]:
321324 if re .search (r'/connected_vehicle/' , simple_base ):
322325 log .debug (f"DEBUG: Filtering out connected_vehicle topic: { simple_base } " )
323326 return None
324-
327+
325328 log .debug (f"DEBUG: _transform_chargepoint_topic output: { simple_base } " )
326329 return simple_base
327330
@@ -361,7 +364,7 @@ def _expand_value_to_topics(self, base_topic: str, value: Any, result: Dict[str,
361364 final_topic = transformed
362365 else :
363366 return # Topic should be filtered out
364-
367+
365368 result [final_topic ] = value
366369
367370 def _generate_simplified_topics (self , simple_topic : str , parsed_value : Any ) -> Dict [str , Any ]:
@@ -380,13 +383,13 @@ def _generate_simplified_topics(self, simple_topic: str, parsed_value: Any) -> D
380383 # Check if this is the lowest ID for this component type
381384 if component_type in self .lowest_ids and self .lowest_ids [component_type ] == component_id :
382385 simplified_base = f"openWB/simpleAPI/{ component_type } /{ remaining_path } "
383-
386+
384387 # Apply chargepoint transformations to simplified topics as well
385388 if component_type == 'chargepoint' :
386389 simplified_base = self ._transform_chargepoint_topic (simplified_base )
387390 if simplified_base is None :
388391 return result
389-
392+
390393 self ._expand_value_to_topics (simplified_base , parsed_value , result )
391394
392395 return result
@@ -434,12 +437,12 @@ def _handle_write_operation(self, topic: str, payload: str):
434437 if not payload or payload .strip () == "" :
435438 log .debug (f"Skipping empty set topic: { topic } " )
436439 return
437-
440+
438441 log .info (f"Write operation: { topic } = { payload } " )
439442
440443 # Parse the set topic to extract operation details
441444 topic_remainder = topic .replace ('openWB/simpleAPI/set/' , '' )
442-
445+
443446 # Check for instant_charging_limit operations first (can be with or without chargepoint ID)
444447 if 'instant_charging_limit_soc' in topic_remainder :
445448 success = self ._handle_instant_charging_limit_soc_operation (payload )
@@ -456,9 +459,9 @@ def _handle_write_operation(self, topic: str, payload: str):
456459 if success :
457460 self ._clear_set_topic (topic )
458461 return
459-
462+
460463 topic_parts = topic_remainder .split ('/' )
461-
464+
462465 if len (topic_parts ) < 1 :
463466 log .error (f"Invalid set topic format: { topic } " )
464467 return
@@ -506,7 +509,7 @@ def _handle_chargepoint_operation(self, topic_parts: list, payload: str) -> bool
506509 log .error (f"Invalid chargepoint topic format: { '/' .join (topic_parts )} " )
507510 return False
508511
509- log .debug (f"Chargepoint operation: ID={ chargepoint_id } , parameter={ parameter } , value={ payload } " )
512+ log .debug (f"Charge point operation: ID={ chargepoint_id } , parameter={ parameter } , value={ payload } " )
510513
511514 if parameter == 'chargemode' :
512515 self ._set_chargemode (chargepoint_id , payload )
@@ -523,7 +526,7 @@ def _handle_chargepoint_operation(self, topic_parts: list, payload: str) -> bool
523526 else :
524527 log .error (f"Unknown chargepoint parameter: { parameter } " )
525528 return False
526-
529+
527530 return True
528531
529532 def _get_charge_template (self , chargepoint_id : str ) -> Optional [Dict [str , Any ]]:
@@ -664,26 +667,26 @@ def _handle_bat_mode_operation(self, payload: str) -> bool:
664667 def _handle_instant_charging_limit_operation (self , payload : str ) -> bool :
665668 """Handle instant charging limit type operation."""
666669 valid_limits = ['none' , 'soc' , 'amount' ]
667-
670+
668671 if payload not in valid_limits :
669672 log .error (f"Invalid instant_charging_limit: { payload } . Valid values: { valid_limits } " )
670673 return False
671-
674+
672675 # Get chargepoint ID (use lowest if not specified)
673676 if 'chargepoint' in self .lowest_ids :
674677 chargepoint_id = str (self .lowest_ids ['chargepoint' ])
675678 else :
676679 log .error ("No chargepoint ID found for instant_charging_limit operation" )
677680 return False
678-
681+
679682 charge_template = self ._get_charge_template (chargepoint_id )
680683 if charge_template is None :
681684 log .error (f"No charge_template available for chargepoint { chargepoint_id } " )
682685 return False
683-
686+
684687 # Modify the instant_charging.limit.selected value
685688 charge_template ['chargemode' ]['instant_charging' ]['limit' ]['selected' ] = payload
686-
689+
687690 # Publish the modified template
688691 target_topic = f"openWB/set/chargepoint/{ chargepoint_id } /set/charge_template"
689692 self ._publish_json (target_topic , charge_template )
@@ -700,22 +703,22 @@ def _handle_instant_charging_limit_soc_operation(self, payload: str) -> bool:
700703 except ValueError :
701704 log .error (f"Invalid SoC value: { payload } . Must be an integer" )
702705 return False
703-
706+
704707 # Get chargepoint ID (use lowest if not specified)
705708 if 'chargepoint' in self .lowest_ids :
706709 chargepoint_id = str (self .lowest_ids ['chargepoint' ])
707710 else :
708711 log .error ("No chargepoint ID found for instant_charging_limit_soc operation" )
709712 return False
710-
713+
711714 charge_template = self ._get_charge_template (chargepoint_id )
712715 if charge_template is None :
713716 log .error (f"No charge_template available for chargepoint { chargepoint_id } " )
714717 return False
715-
718+
716719 # Modify the instant_charging.limit.soc value
717720 charge_template ['chargemode' ]['instant_charging' ]['limit' ]['soc' ] = soc_value
718-
721+
719722 # Publish the modified template
720723 target_topic = f"openWB/set/chargepoint/{ chargepoint_id } /set/charge_template"
721724 self ._publish_json (target_topic , charge_template )
@@ -729,32 +732,35 @@ def _handle_instant_charging_limit_amount_operation(self, payload: str) -> bool:
729732 if amount_value < 1 or amount_value > 50 :
730733 log .error (f"Invalid amount value: { amount_value } . Must be between 1 and 50" )
731734 return False
732-
735+
733736 # Convert to internal value (multiply by 1000)
734737 internal_amount = amount_value * 1000
735738 except ValueError :
736739 log .error (f"Invalid amount value: { payload } . Must be an integer" )
737740 return False
738-
741+
739742 # Get chargepoint ID (use lowest if not specified)
740743 if 'chargepoint' in self .lowest_ids :
741744 chargepoint_id = str (self .lowest_ids ['chargepoint' ])
742745 else :
743746 log .error ("No chargepoint ID found for instant_charging_limit_amount operation" )
744747 return False
745-
748+
746749 charge_template = self ._get_charge_template (chargepoint_id )
747750 if charge_template is None :
748751 log .error (f"No charge_template available for chargepoint { chargepoint_id } " )
749752 return False
750-
753+
751754 # Modify the instant_charging.limit.amount value
752755 charge_template ['chargemode' ]['instant_charging' ]['limit' ]['amount' ] = internal_amount
753-
756+
754757 # Publish the modified template
755758 target_topic = f"openWB/set/chargepoint/{ chargepoint_id } /set/charge_template"
756759 self ._publish_json (target_topic , charge_template )
757- log .info (f"Set instant_charging_limit_amount to { amount_value } kWh ({ internal_amount } Wh) for chargepoint { chargepoint_id } " )
760+ log .info (
761+ f"Set instant_charging_limit_amount to { amount_value } kWh "
762+ f"({ internal_amount } Wh) for chargepoint { chargepoint_id } "
763+ )
758764 return True
759765
760766 def _publish_json (self , topic : str , data : Dict [str , Any ]):
0 commit comments