From aeab825f5a5326a59b8f3fc37e014378d13bcdd9 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 4 Feb 2022 14:24:34 -0700 Subject: [PATCH 1/2] fix: bug in toggle_override for older firmware --- openevsehttp/__init__.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openevsehttp/__init__.py b/openevsehttp/__init__.py index 96304f6..6588ab4 100644 --- a/openevsehttp/__init__.py +++ b/openevsehttp/__init__.py @@ -430,7 +430,7 @@ async def toggle_override(self) -> None: else: # Older firmware use RAPI commands _LOGGER.debug("Toggling manual override via RAPI") - command = "$FE" if self._status["state"] == "sleeping" else "$FS" + command = "$FE" if self._status["state"] == 254 else "$FS" response = await self.send_command(command) _LOGGER.debug("Toggle response: %s", response[1]) diff --git a/setup.py b/setup.py index 02f11fd..5c03e23 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ PROJECT_DIR = Path(__file__).parent.resolve() README_FILE = PROJECT_DIR / "README.md" -VERSION = "0.1.14" +VERSION = "0.1.15" setup( From 838a343abb438e36a7cbf818729f8adc06c4bef3 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 16 Mar 2022 10:25:13 -0700 Subject: [PATCH 2/2] feat: add support for max_current_soft (#37) --- openevsehttp/__init__.py | 32 ++++++++++++++++++++++++ setup.py | 2 +- tests/fixtures/v4_json/config.json | 4 +++ tests/test_init.py | 39 +++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/openevsehttp/__init__.py b/openevsehttp/__init__.py index 6588ab4..8d3f2f3 100644 --- a/openevsehttp/__init__.py +++ b/openevsehttp/__init__.py @@ -442,6 +442,25 @@ async def clear_override(self) -> None: response = await self.process_request(url=url, method="delete") _LOGGER.debug("Toggle response: %s", response["msg"]) + async def set_current(self, amps: int = 6) -> None: + """Set the soft current limit.""" + url = f"{self.url}config" + + if amps < self._config["min_current_hard"] or amps > self._config["max_current_hard"]: + _LOGGER.error("Invalid value for max_current_soft: %s", amps) + raise ValueError + + data = {"max_current_soft": amps} + + _LOGGER.debug("Setting max_current_soft to %s", amps) + response = await self.process_request( + url=url, method="post", data=data + ) # noqa: E501 + if response["msg"] != "done": + _LOGGER.error("Problem issuing command: %s", response["msg"]) + raise UnknownError + + @property def hostname(self) -> str: """Return charger hostname.""" @@ -597,6 +616,8 @@ def charging_current(self) -> float: def current_capacity(self) -> int: """Return the current capacity.""" assert self._status is not None + if self._config is not None and "max_current_soft" in self._config: + return self._config["max_current_soft"] return self._status["pilot"] @property @@ -724,14 +745,25 @@ def divert_active(self) -> bool: assert self._status is not None return self._status["divert_active"] + @property + def wifi_serial(self) -> str: + """Return wifi serial.""" + if self._config is not None and "wifi_serial" in self._config: + return self._config["wifi_serial"] + return None + # There is currently no min/max amps JSON data # available via HTTP API methods @property def min_amps(self) -> int: """Return the minimum amps.""" + if self._config is not None and "min_current_hard" in self._config: + return self._config["min_current_hard"] return MIN_AMPS @property def max_amps(self) -> int: """Return the maximum amps.""" + if self._config is not None and "max_current_hard" in self._config: + return self._config["max_current_hard"] return MAX_AMPS diff --git a/setup.py b/setup.py index 5c03e23..df73e8e 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ PROJECT_DIR = Path(__file__).parent.resolve() README_FILE = PROJECT_DIR / "README.md" -VERSION = "0.1.15" +VERSION = "0.1.16" setup( diff --git a/tests/fixtures/v4_json/config.json b/tests/fixtures/v4_json/config.json index ba48934..44d64af 100644 --- a/tests/fixtures/v4_json/config.json +++ b/tests/fixtures/v4_json/config.json @@ -2,6 +2,7 @@ "firmware": "7.1.3", "protocol": "-", "espflash": 4194304, + "wifi_serial": "1234567890AB", "version": "4.0.0", "diodet": 0, "gfcit": 0, @@ -12,6 +13,9 @@ "service": 2, "scale": 220, "offset": 0, + "max_current_soft": 6, + "min_current_hard": 6, + "max_current_hard": 48, "mqtt_supported_protocols": [ "mqtt", "mqtts" diff --git a/tests/test_init.py b/tests/test_init.py index 0de1e62..7fd380c 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -11,6 +11,7 @@ TEST_URL_RAPI = "http://openevse.test.tld/r" TEST_URL_OVERRIDE = "http://openevse.test.tld/override" +TEST_URL_CONFIG = "http://openevse.test.tld/config" async def test_get_status_auth(test_charger_auth): @@ -307,7 +308,7 @@ async def test_get_charging_current(fixture, expected, request): @pytest.mark.parametrize( - "fixture, expected", [("test_charger", 48), ("test_charger_v2", 25)] + "fixture, expected", [("test_charger", 6), ("test_charger_v2", 25)] ) async def test_get_current_capacity(fixture, expected, request): """Test v4 Status reply""" @@ -610,3 +611,39 @@ async def test_toggle_override_v2(test_charger_v2, mock_aioclient, caplog): with caplog.at_level(logging.DEBUG): await test_charger_v2.toggle_override() assert "Toggling manual override via RAPI" in caplog.text + +@pytest.mark.parametrize( + "fixture, expected", [("test_charger", "1234567890AB"), ("test_charger_v2", None)] +) +async def test_wifi_serial(fixture, expected, request): + """Test wifi_serial reply""" + charger = request.getfixturevalue(fixture) + await charger.update() + status = charger.wifi_serial + assert status == expected + +async def test_set_current(test_charger, mock_aioclient, caplog): + """Test v4 Status reply""" + await test_charger.update() + value = {"msg": "done"} + mock_aioclient.post( + TEST_URL_CONFIG, + status=200, + body=json.dumps(value), + ) + with caplog.at_level(logging.DEBUG): + await test_charger.set_current(12) + assert "Setting max_current_soft to 12" in caplog.text + +async def test_set_current_error(test_charger, mock_aioclient, caplog): + """Test v4 Status reply""" + await test_charger.update() + mock_aioclient.post( + TEST_URL_CONFIG, + status=200, + body="OK", + ) + with caplog.at_level(logging.DEBUG): + with pytest.raises(ValueError): + await test_charger.set_current(60) + assert "Invalid value for max_current_soft: 60" in caplog.text \ No newline at end of file