Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/modules/vehicles/json/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ def __init__(
soc_pattern: Optional[str] = None,
range_pattern: Optional[str] = None,
timestamp_pattern: Optional[str] = None,
odometer_pattern: Optional[str] = None,
timeout: Optional[int] = None,
calculate_soc: bool = False
):
self.url = url
self.soc_pattern = soc_pattern
self.range_pattern = range_pattern
self.timestamp_pattern = timestamp_pattern
self.odometer_pattern = odometer_pattern
self.timeout = timeout
self.calculate_soc = calculate_soc

Expand Down
14 changes: 11 additions & 3 deletions packages/modules/vehicles/json/soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ def fetch_soc(config: JsonSocSetup, compiled_queries: Dict) -> CarState:
compiled_queries["timestamp"],
config.configuration.timestamp_pattern))
if compiled_queries["timestamp"] is not None else None)
return CarState(soc=soc, range=range, soc_timestamp=timestamp)
odometer = (float(parse_data(raw_data, compiled_queries["odometer"], config.configuration.odometer_pattern))
if compiled_queries["odometer"] is not None else None)
return CarState(soc=soc, range=range, soc_timestamp=timestamp, odometer=odometer)


def initialize_vehicle(vehicle_config: JsonSocSetup, compiled_queries: Dict) -> None:
Expand All @@ -71,13 +73,16 @@ def initialize_vehicle(vehicle_config: JsonSocSetup, compiled_queries: Dict) ->
compiled_queries["range"] = jq.compile(config.range_pattern) if config.range_pattern is not None else None
compiled_queries["timestamp"] = (jq.compile(config.timestamp_pattern)
if config.timestamp_pattern is not None else None)
compiled_queries["odometer"] = (jq.compile(config.odometer_pattern)
if config.odometer_pattern is not None else None)


def create_vehicle(vehicle_config: JsonSocSetup, vehicle: int):
compiled_queries = {
'soc': None,
'range': None,
'timestamp': None
'timestamp': None,
'odometer': None
}

def initializer() -> None:
Expand All @@ -97,14 +102,17 @@ def json_update(charge_point: int,
soc_pattern: str,
range_pattern: Optional[str] = None,
timestamp_pattern: Optional[str] = None,
odometer_pattern: Optional[str] = None,
calculate_soc: Optional[bool] = False):
log.debug(f'json-soc: charge_point={charge_point} url="{url}" soc-pattern="{soc_pattern}" '
f'range-pattern="{range_pattern}" timestamp-pattern="{timestamp_pattern}" calculate-soc={calculate_soc}')
f'range-pattern="{range_pattern}" timestamp-pattern="{timestamp_pattern}" '
f'odometer-pattern="{odometer_pattern}" calculate-soc={calculate_soc}')
store.get_car_value_store(charge_point).store.set(
fetch_soc(JsonSocSetup(configuration=JsonSocConfiguration(url=url,
soc_pattern=soc_pattern,
range_pattern=range_pattern,
timestamp_pattern=timestamp_pattern,
odometer_pattern=odometer_pattern,
calculate_soc=calculate_soc))))
Comment on lines 110 to 116
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

json_update calls fetch_soc(...) without passing a compiled_queries dict, but fetch_soc requires it and indexes keys like compiled_queries["soc"]/["odometer"]. This will raise a TypeError at runtime. Consider creating a local compiled_queries dict in json_update, calling initialize_vehicle(...), and then calling fetch_soc(config, compiled_queries) (or alternatively adjust fetch_soc to compile queries internally when none are provided).

Suggested change
store.get_car_value_store(charge_point).store.set(
fetch_soc(JsonSocSetup(configuration=JsonSocConfiguration(url=url,
soc_pattern=soc_pattern,
range_pattern=range_pattern,
timestamp_pattern=timestamp_pattern,
odometer_pattern=odometer_pattern,
calculate_soc=calculate_soc))))
vehicle_config = JsonSocSetup(configuration=JsonSocConfiguration(url=url,
soc_pattern=soc_pattern,
range_pattern=range_pattern,
timestamp_pattern=timestamp_pattern,
odometer_pattern=odometer_pattern,
calculate_soc=calculate_soc))
compiled_queries = {
'soc': None,
'range': None,
'timestamp': None,
'odometer': None
}
initialize_vehicle(vehicle_config, compiled_queries)
store.get_car_value_store(charge_point).store.set(fetch_soc(vehicle_config, compiled_queries))

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Der Code funktioniert. Anmerkung kann ignoriert werden.



Expand Down
34 changes: 30 additions & 4 deletions packages/modules/vehicles/json/test_json_soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ def setUp(self):
'soc_pattern': '.energy[0].level',
'range_pattern': '.energy[0].autonomy',
'timestamp_pattern': '.energy[0].updated_at',
'odometer_pattern': None,
'expected_soc': 69,
'expected_range': 214,
'expected_timestamp': 1735984813
'expected_timestamp': 1735984813,
'expected_odometer': None
},
{
'sample_data': {
Expand All @@ -46,9 +48,30 @@ def setUp(self):
'soc_pattern': '.response.value',
'range_pattern': None,
'timestamp_pattern': '.response.timestamp',
'odometer_pattern': None,
'expected_soc': 20.2,
'expected_range': None,
'expected_timestamp': 1736108141
'expected_timestamp': 1736108141,
'expected_odometer': None
},
{
'sample_data': {
"response": {
"soc": "45.5",
"range": 300,
"timestamp": 1736108141,
"odometer": 12345.67
}
},
'url': "http://example.com/soc3",
'soc_pattern': '.response.soc',
'range_pattern': '.response.range',
'timestamp_pattern': '.response.timestamp',
'odometer_pattern': '.response.odometer',
'expected_soc': 45.5,
'expected_range': 300,
'expected_timestamp': 1736108141,
'expected_odometer': 12345.67
}
]

Expand All @@ -62,17 +85,20 @@ def test_fetch_soc(self, mock_get_http_session):
compiled_queries = {
'soc': None,
'range': None,
'timestamp': None
'timestamp': None,
'odometer': None
}
vehicle_config = JsonSocSetup(configuration=JsonSocConfiguration(
url=case['url'],
soc_pattern=case['soc_pattern'],
range_pattern=case['range_pattern'],
timestamp_pattern=case['timestamp_pattern']
timestamp_pattern=case['timestamp_pattern'],
odometer_pattern=case['odometer_pattern']
))
initialize_vehicle(vehicle_config, compiled_queries)
car_state = fetch_soc(vehicle_config, compiled_queries)

self.assertEqual(car_state.soc, case['expected_soc'])
self.assertEqual(car_state.range, case['expected_range'])
self.assertEqual(car_state.soc_timestamp, case['expected_timestamp'])
self.assertEqual(car_state.odometer, case['expected_odometer'])
1 change: 1 addition & 0 deletions packages/modules/vehicles/psacc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def __init__(self,
super().__init__(soc_pattern=prf + "level",
range_pattern=prf + "autonomy",
timestamp_pattern=prf + "updated_at",
odometer_pattern=".timed_odometer.mileage",
timeout=10,
calculate_soc=True)

Expand Down
Loading