From ee7aff336533ed6da2e8736dc54b2aa0fe2dd4d8 Mon Sep 17 00:00:00 2001 From: Chris <1105672+firstof9@users.noreply.github.com> Date: Wed, 29 Jan 2025 10:06:25 -0700 Subject: [PATCH] feat: add `async_override_state` property (#410) * feat: add `async_override_state` property * formatting * formatting * linting --- openevsehttp/__main__.py | 19 +++++++++--- tests/fixtures/v2_json/config.json | 44 +++++++++++++++++++++++++- tests/fixtures/v2_json/status.json | 36 ++++++++++++++++++++- tests/test_main.py | 50 ++++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 6 deletions(-) diff --git a/openevsehttp/__main__.py b/openevsehttp/__main__.py index cbe6afc..9208bed 100644 --- a/openevsehttp/__main__.py +++ b/openevsehttp/__main__.py @@ -1384,13 +1384,24 @@ def freeram(self) -> int | None: # Safety counts @property - def checks_count(self) -> dict | None: + def checks_count(self) -> dict: """Return the saftey checks counts.""" attributes = ("gfcicount", "nogndcount", "stuckcount") + counts = {} if self._status is not None and set(attributes).issubset(self._status.keys()): - counts = {} counts["gfcicount"] = self._status["gfcicount"] counts["nogndcount"] = self._status["nogndcount"] counts["stuckcount"] = self._status["stuckcount"] - return counts - return None + return counts + + @property + async def async_override_state(self) -> str | None: + """Return the unit override state.""" + try: + override = await self.get_override() + except UnsupportedFeature: + _LOGGER.debug("Override state unavailable on older firmware.") + return None + if "state" in override.keys(): + return override["state"] + return "auto" diff --git a/tests/fixtures/v2_json/config.json b/tests/fixtures/v2_json/config.json index cc666ba..3ff93c4 100644 --- a/tests/fixtures/v2_json/config.json +++ b/tests/fixtures/v2_json/config.json @@ -1 +1,43 @@ -{"firmware":"5.0.1","protocol":"4.0.1","espflash":4194304,"version":"2.9.1","diodet":1,"gfcit":0,"groundt":0,"relayt":0,"ventt":0,"tempt":0,"service":2,"scale":220,"offset":0,"ssid":"nsavanup_IoT","pass":"_DUMMY_PASSWORD","www_username":"mark","www_password":"_DUMMY_PASSWORD","hostname":"openevse","emoncms_server":"data.openevse.com/emoncms","emoncms_node":"0","emoncms_apikey":"_DUMMY_PASSWORD","emoncms_fingerprint":"","mqtt_server":"192.168.1.142","mqtt_port":1883,"mqtt_topic":"openevse","mqtt_user":"mqtt","mqtt_pass":"_DUMMY_PASSWORD","mqtt_solar":"","mqtt_grid_ie":"emon/emonpi/power1","mqtt_vrms":"emon/emonpi/vrms","mqtt_announce_topic":"openevse/announce/0000","ohm":"","divert_attack_smoothing_factor":0.4,"divert_decay_smoothing_factor":0.05,"divert_min_charge_time":600,"flags":3,"emoncms_enabled":true,"mqtt_enabled":true,"ohm_enabled":false,"divert_enabled":false,"charge_mode":"fast"} +{ + "firmware": "5.0.1", + "protocol": "4.0.1", + "espflash": 4194304, + "version": "2.9.1", + "diodet": 1, + "gfcit": 0, + "groundt": 0, + "relayt": 0, + "ventt": 0, + "tempt": 0, + "service": 2, + "scale": 220, + "offset": 0, + "ssid": "nsavanup_IoT", + "pass": "_DUMMY_PASSWORD", + "www_username": "mark", + "www_password": "_DUMMY_PASSWORD", + "hostname": "openevse", + "emoncms_server": "data.openevse.com/emoncms", + "emoncms_node": "0", + "emoncms_apikey": "_DUMMY_PASSWORD", + "emoncms_fingerprint": "", + "mqtt_server": "192.168.1.142", + "mqtt_port": 1883, + "mqtt_topic": "openevse", + "mqtt_user": "mqtt", + "mqtt_pass": "_DUMMY_PASSWORD", + "mqtt_solar": "", + "mqtt_grid_ie": "emon/emonpi/power1", + "mqtt_vrms": "emon/emonpi/vrms", + "mqtt_announce_topic": "openevse/announce/0000", + "ohm": "", + "divert_attack_smoothing_factor": 0.4, + "divert_decay_smoothing_factor": 0.05, + "divert_min_charge_time": 600, + "flags": 3, + "emoncms_enabled": true, + "mqtt_enabled": true, + "ohm_enabled": false, + "divert_enabled": false, + "charge_mode": "fast" +} diff --git a/tests/fixtures/v2_json/status.json b/tests/fixtures/v2_json/status.json index c102739..64176f5 100644 --- a/tests/fixtures/v2_json/status.json +++ b/tests/fixtures/v2_json/status.json @@ -1 +1,35 @@ -{"mode":"STA","wifi_client_connected":1,"net_connected":1,"srssi":-56,"ipaddress":"192.168.1.67","emoncms_connected":0,"packets_sent":2909,"packets_success":0,"mqtt_connected":0,"ohm_hour":"NotConnected","free_heap":12448,"comm_sent":43704,"comm_success":43704,"rapi_connected":1,"amp":0,"voltage":240,"pilot":25,"temp1":340,"temp2":false,"temp3":false,"state":1,"elapsed":8751,"wattsec":25212279,"watthour":1585443,"gfcicount":0,"nogndcount":0,"stuckcount":0,"divertmode":1,"solar":0,"grid_ie":0,"charge_rate":0,"divert_update":87648,"ota_update":0} +{ + "mode": "STA", + "wifi_client_connected": 1, + "net_connected": 1, + "srssi": -56, + "ipaddress": "192.168.1.67", + "emoncms_connected": 0, + "packets_sent": 2909, + "packets_success": 0, + "mqtt_connected": 0, + "ohm_hour": "NotConnected", + "free_heap": 12448, + "comm_sent": 43704, + "comm_success": 43704, + "rapi_connected": 1, + "amp": 0, + "voltage": 240, + "pilot": 25, + "temp1": 340, + "temp2": false, + "temp3": false, + "state": 1, + "elapsed": 8751, + "wattsec": 25212279, + "watthour": 1585443, + "gfcicount": 0, + "nogndcount": 0, + "stuckcount": 0, + "divertmode": 1, + "solar": 0, + "grid_ie": 0, + "charge_rate": 0, + "divert_update": 87648, + "ota_update": 0 +} diff --git a/tests/test_main.py b/tests/test_main.py index 7272c84..3fb55d3 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -2012,3 +2012,53 @@ async def test_async_charge_current( value = await test_charger_v2.async_charge_current assert value == 25 await test_charger_v2.ws_disconnect() + + +async def test_async_override_state( + test_charger, test_charger_v2, mock_aioclient, caplog +): + """Test get override function.""" + await test_charger.update() + value = { + "state": "active", + "charge_current": 0, + "max_current": 0, + "energy_limit": 0, + "time_limit": 0, + "auto_release": True, + } + mock_aioclient.get( + TEST_URL_OVERRIDE, + status=200, + body=json.dumps(value), + ) + with caplog.at_level(logging.DEBUG): + status = await test_charger.async_override_state + assert status == "active" + + value = { + "state": "disabled", + } + mock_aioclient.get( + TEST_URL_OVERRIDE, + status=200, + body=json.dumps(value), + ) + with caplog.at_level(logging.DEBUG): + status = await test_charger.async_override_state + assert status == "disabled" + + value = {} + mock_aioclient.get( + TEST_URL_OVERRIDE, + status=200, + body=json.dumps(value), + ) + with caplog.at_level(logging.DEBUG): + status = await test_charger.async_override_state + assert status == "auto" + + with caplog.at_level(logging.DEBUG): + await test_charger_v2.update() + await test_charger_v2.async_override_state + assert "Override state unavailable on older firmware." in caplog.text