From a2858f47a0590869868d5bd1ed14cc6a1edab31a Mon Sep 17 00:00:00 2001 From: MartinRinas Date: Sun, 5 Jan 2025 15:32:19 +0000 Subject: [PATCH 1/3] fix timestamp --- packages/modules/vehicles/json/soc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/modules/vehicles/json/soc.py b/packages/modules/vehicles/json/soc.py index d988c862ce..4bedb8473b 100644 --- a/packages/modules/vehicles/json/soc.py +++ b/packages/modules/vehicles/json/soc.py @@ -31,7 +31,7 @@ def extract_to_epoch(input_string: str) -> float: return None -def parse_data(data: Dict[str, Any], pattern: str) -> float: +def parse_data(data: Dict[str, Any], pattern: str) -> any: log.debug(f"parse_data: data='{data}' pattern='{pattern}'") if pattern == "": @@ -42,7 +42,7 @@ def parse_data(data: Dict[str, Any], pattern: str) -> float: raise ValueError(f"Pattern {pattern} hat keine Ergebnisse in '{data}' geliefert.") log.debug(f"result='{result}'") - return float(result) + return result def fetch_soc(config: JsonSocSetup) -> CarState: @@ -58,7 +58,7 @@ def fetch_soc(config: JsonSocSetup) -> CarState: else: raw_data: Dict[str, Any] = req.get_http_session().get(url, timeout=timeout).json() - soc = parse_data(raw_data, soc_pattern) + soc = float(parse_data(raw_data, soc_pattern)) if range_pattern is None or range_pattern == "": log.debug("Kein Pattern für Range angegeben, setze Range auf None.") From 3e32aa757b48901042dc77217b79df12695f48e2 Mon Sep 17 00:00:00 2001 From: MartinRinas Date: Sun, 5 Jan 2025 21:04:54 +0000 Subject: [PATCH 2/3] add unittest for json soc module --- packages/modules/vehicles/json/test_soc.py | 72 ++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 packages/modules/vehicles/json/test_soc.py diff --git a/packages/modules/vehicles/json/test_soc.py b/packages/modules/vehicles/json/test_soc.py new file mode 100644 index 0000000000..4f8ea1c0af --- /dev/null +++ b/packages/modules/vehicles/json/test_soc.py @@ -0,0 +1,72 @@ +import unittest +from unittest.mock import patch, MagicMock +from soc import fetch_soc, JsonSocSetup, JsonSocConfiguration + + +class TestSoc(unittest.TestCase): + + def setUp(self): + self.test_cases = [ + { + 'sample_data': { + 'energy': [{ + 'updated_at': '2025-01-04 10:00:13+00:00', + 'autonomy': 214.0, + 'battery': None, + 'charging': { + 'charging_mode': 'No', + 'charging_rate': 0, + 'next_delayed_time': 'PT9H1M', + 'plugged': True, + 'remaining_time': 'PT0S', + 'status': 'Disconnected' + }, + 'consumption': None, + 'level': 69.0, + 'residual': None, + 'type': 'Electric' + }] + }, + 'url': "http://example.com/soc1", + 'soc_pattern': '.energy[0].level', + 'range_pattern': '.energy[0].autonomy', + 'timestamp_pattern': '.energy[0].updated_at', + 'expected_soc': 69, + 'expected_range': 214, + 'expected_timestamp': 1735984813 + }, + { + 'sample_data': { + "response": { + "value": "20.2", + "timestamp": 1736108141 + } + }, + 'url': "http://example.com/soc2", + 'soc_pattern': '.response.value', + 'range_pattern': None, + 'timestamp_pattern': '.response.timestamp', + 'expected_soc': 20.2, + 'expected_range': None, + 'expected_timestamp': 1736108141 + } + ] + + @patch('soc.req.get_http_session') + def test_fetch_soc(self, mock_get_http_session): + for case in self.test_cases: + mock_response = MagicMock() + mock_response.json.return_value = case['sample_data'] + mock_get_http_session.return_value.get.return_value = mock_response + + vehicle_config = JsonSocSetup(configuration=JsonSocConfiguration( + url=case['url'], + soc_pattern=case['soc_pattern'], + range_pattern=case['range_pattern'], + timestamp_pattern=case['timestamp_pattern'] + )) + car_state = fetch_soc(vehicle_config) + + 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']) From e43536c80a6605b6df22d52eff67eedccb0613b4 Mon Sep 17 00:00:00 2001 From: MartinRinas Date: Mon, 6 Jan 2025 19:17:48 +0000 Subject: [PATCH 3/3] raise exception for invalid config --- packages/modules/vehicles/json/soc.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/modules/vehicles/json/soc.py b/packages/modules/vehicles/json/soc.py index 4bedb8473b..95ababf601 100644 --- a/packages/modules/vehicles/json/soc.py +++ b/packages/modules/vehicles/json/soc.py @@ -53,10 +53,9 @@ def fetch_soc(config: JsonSocSetup) -> CarState: timeout = config.configuration.timeout if isinstance(config.configuration.timeout, int) else None if url is None or url == "": - log.warning("URL nicht definiert, setze SOC auf 0") - return CarState(0, 0) - else: - raw_data: Dict[str, Any] = req.get_http_session().get(url, timeout=timeout).json() + raise ValueError("Keine URL zum Abrufen der Daten definiert. Bitte in der Konfiguration aktualisieren.") + + raw_data: Dict[str, Any] = req.get_http_session().get(url, timeout=timeout).json() soc = float(parse_data(raw_data, soc_pattern))