Skip to content

Commit 59abd69

Browse files
authored
Merge pull request #2923 from benderl/fix-simpleapi
Fix simpleapi
2 parents f582276 + 1c96233 commit 59abd69

8 files changed

Lines changed: 301 additions & 253 deletions

File tree

.editorconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ charset = utf-8
66
end_of_line = lf
77
insert_final_newline = true
88

9+
[simpleAPI/**.php]
10+
indent_style = space
11+
indent_size = 4
12+
913
[*.{py,yml,lock}]
1014
indent_style = space
1115
indent_size = 4

simpleAPI/config/config.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
'auth' => [
2121
'enabled' => false,
2222
'require_https' => false,
23-
23+
2424
// Gültige Tokens
2525
'tokens' => [
2626
// 'your-secret-token-here'
2727
],
28-
28+
2929
// Benutzer (Username => Passwort/Hash)
3030
'users' => [
3131
// 'admin' => password_hash('admin123', PASSWORD_DEFAULT),

simpleAPI/simpleAPI_mqtt.py

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)