diff --git a/openevsehttp/__main__.py b/openevsehttp/__main__.py index 21438d9..7fb6e31 100644 --- a/openevsehttp/__main__.py +++ b/openevsehttp/__main__.py @@ -1119,6 +1119,8 @@ def has_limit(self) -> bool | None: assert self._status is not None if "has_limit" in self._status: return self._status["has_limit"] + if "limit" in self._status: + return self._status["limit"] return None @property @@ -1286,3 +1288,44 @@ def mqtt_connected(self) -> bool: if self._status is not None and "mqtt_connected" in self._status: return self._status["mqtt_connected"] return False + + @property + def emoncms_connected(self) -> bool | None: + """Return the status of the emoncms connection.""" + if self._status is not None and "emoncms_connected" in self._status: + return self._status["emoncms_connected"] + return None + + @property + def ocpp_connected(self) -> bool | None: + """Return the status of the ocpp connection.""" + if self._status is not None and "ocpp_connected" in self._status: + return self._status["ocpp_connected"] + return None + + @property + def uptime(self) -> int | None: + """Return the unit uptime.""" + if self._status is not None and "uptime" in self._status: + return self._status["uptime"] + return None + + @property + def freeram(self) -> int | None: + """Return the unit freeram.""" + if self._status is not None and "freeram" in self._status: + return self._status["freeram"] + return None + + # Safety counts + @property + def checks_count(self) -> dict | None: + """Return the saftey checks counts.""" + attributes = ("gfcicount", "nogndcount", "stuckcount") + 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 diff --git a/tests/fixtures/v4_json/config-new.json b/tests/fixtures/v4_json/config-new.json index 4a0fb4a..87162df 100644 --- a/tests/fixtures/v4_json/config-new.json +++ b/tests/fixtures/v4_json/config-new.json @@ -1,67 +1,108 @@ { - "firmware": "7.1.3", - "protocol": "-", - "espflash": 4194304, - "wifi_serial": "1234567890AB", - "version": "4.1.8", - "diodet": 0, - "gfcit": 0, - "groundt": 0, - "relayt": 0, - "ventt": 0, - "tempt": 0, - "service": 2, - "scale": 220, - "offset": 0, - "max_current_soft": 48, - "min_current_hard": 6, - "max_current_hard": 48, - "mqtt_supported_protocols": [ + "mqtt_supported_protocols": [ "mqtt", "mqtts" - ], - "http_supported_protocols": [ - "http", - "https" - ], - "ssid": "Datanode-IoT", - "pass": "_DUMMY_PASSWORD", - "www_username": "", - "www_password": "", - "hostname": "openevse-7b2c", - "sntp_hostname": "0.us.pool.ntp.org", - "time_zone": "America/Phoenix|MST7", - "emoncms_server": "https://emoncms.collective.lan/", - "emoncms_node": "openevse", - "emoncms_apikey": "_DUMMY_PASSWORD", - "emoncms_fingerprint": "", - "mqtt_server": "192.168.1.198", - "mqtt_port": 1883, - "mqtt_topic": "openevse", - "mqtt_user": "devices", - "mqtt_pass": "_DUMMY_PASSWORD", - "mqtt_solar": "", - "mqtt_grid_ie": "home-assistant/power/watts", - "mqtt_vrms": "home-assistant/solar/watts", - "mqtt_announce_topic": "openevse/announce/7b2c", - "ohm": "", - "divert_PV_ratio": 1.1, - "divert_attack_smoothing_factor": 0.4, - "divert_decay_smoothing_factor": 0.05, - "divert_min_charge_time": 600, - "tesla_username": "", - "tesla_password": "", - "tesla_vehidx": -1, - "led_brightness": 128, - "flags": 522, - "emoncms_enabled": false, - "mqtt_enabled": true, - "mqtt_reject_unauthorized": true, - "ohm_enabled": false, - "sntp_enabled": true, - "tesla_enabled": false, - "divert_enabled": false, - "pause_uses_disabled": false, - "mqtt_protocol": "mqtt", - "charge_mode": "fast" - } + ], + "http_supported_protocols": [ + "http" + ], + "buildenv": "openevse_wifi_v1", + "version": "v5.1.2", + "wifi_serial": "9C9C1FE57B2C", + "protocol": "-", + "espinfo": "ESP32r1 2 core WiFi BLE BT", + "espflash": 4194304, + "firmware": "7.1.3", + "evse_serial": "", + "diode_check": true, + "gfci_check": true, + "ground_check": true, + "relay_check": true, + "vent_check": true, + "temp_check": true, + "max_current_soft": 48, + "service": 2, + "scale": 220, + "offset": 0, + "min_current_hard": 6, + "max_current_hard": 48, + "ssid": "Datanode-IoT", + "pass": "_DUMMY_PASSWORD", + "ap_ssid": "", + "ap_pass": "", + "lang": "en", + "www_username": "", + "www_password": "", + "www_certificate_id": "", + "hostname": "openevse-7b2c", + "sntp_hostname": "0.us.pool.ntp.org", + "time_zone": "America/Phoenix|MST7", + "limit_default_type": "", + "limit_default_value": 0, + "emoncms_server": "http://emoncms.collective.lan/", + "emoncms_node": "openevse", + "emoncms_apikey": "_DUMMY_PASSWORD", + "emoncms_fingerprint": "", + "mqtt_server": "192.168.1.198", + "mqtt_port": 1883, + "mqtt_topic": "openevse", + "mqtt_user": "devices", + "mqtt_pass": "_DUMMY_PASSWORD", + "mqtt_certificate_id": "", + "mqtt_solar": "", + "mqtt_grid_ie": "home-assistant/power/watts", + "mqtt_vrms": "", + "mqtt_live_pwr": "", + "mqtt_vehicle_soc": "", + "mqtt_vehicle_range": "", + "mqtt_vehicle_eta": "", + "mqtt_announce_topic": "openevse/announce/7b2c", + "ocpp_server": "", + "ocpp_chargeBoxId": "", + "ocpp_authkey": "", + "ocpp_idtag": "DefaultIdTag", + "ohm": "", + "divert_type": 1, + "divert_PV_ratio": 1.1, + "divert_attack_smoothing_time": 20, + "divert_decay_smoothing_time": 600, + "divert_min_charge_time": 600, + "current_shaper_max_pwr": 0, + "current_shaper_smoothing_time": 60, + "current_shaper_min_pause_time": 300, + "current_shaper_data_maxinterval": 120, + "vehicle_data_src": 0, + "tesla_access_token": "", + "tesla_refresh_token": "", + "tesla_created_at": 18446744073709551615, + "tesla_expires_in": 18446744073709551615, + "tesla_vehicle_id": "", + "rfid_storage": "", + "led_brightness": 125, + "scheduler_start_window": 600, + "flags": 102761482, + "flags_changed": 48242178, + "emoncms_enabled": false, + "mqtt_enabled": true, + "mqtt_reject_unauthorized": true, + "mqtt_retained": false, + "ohm_enabled": false, + "sntp_enabled": true, + "tesla_enabled": false, + "divert_enabled": false, + "current_shaper_enabled": false, + "pause_uses_disabled": false, + "mqtt_vehicle_range_miles": false, + "ocpp_enabled": false, + "ocpp_auth_auto": false, + "ocpp_auth_offline": false, + "ocpp_suspend_evse": false, + "ocpp_energize_plug": false, + "rfid_enabled": false, + "factory_write_lock": true, + "is_threephase": false, + "wizard_passed": true, + "default_state": true, + "mqtt_protocol": "mqtt", + "charge_mode": "eco" +} \ No newline at end of file diff --git a/tests/fixtures/v4_json/status-new.json b/tests/fixtures/v4_json/status-new.json index 291f32e..11c0860 100644 --- a/tests/fixtures/v4_json/status-new.json +++ b/tests/fixtures/v4_json/status-new.json @@ -1,60 +1,80 @@ { - "mode": "STA", - "wifi_client_connected": 1, - "eth_connected": 0, - "net_connected": 1, - "ipaddress": "192.168.21.10", - "emoncms_connected": 0, - "packets_sent": 0, - "packets_success": 0, - "mqtt_connected": 1, - "ohm_hour": "NotConnected", - "free_heap": 223464, - "comm_sent": 345660, - "comm_success": 332432, - "rapi_connected": 1, - "evse_connected": 1, - "amp": 32.2, - "voltage": 240, - "pilot": 48, - "wh": 64582, - "temp": 503, - "temp1": false, - "temp2": 503, - "temp3": false, - "temp4": 560, - "state": 254, - "vehicle": 1, - "colour": 6, - "freeram": 223464, - "divertmode": 0, - "srssi": -61, - "elapsed": 246, - "wattsec": 992549, - "watthour": 64582, - "gfcicount": 1, - "nogndcount": 0, - "stuckcount": 0, - "solar": 0, - "grid_ie": 2891, - "charge_rate": 0, - "divert_update": 11, - "ota_update": 0, - "time": "2021-08-10T23:00:11Z", - "offset": "-0700", - "shaper": 1, - "shaper_live_pwr": 2299, - "shaper_max_pwr": 4000, - "shaper_cur": 21, - "vehicle_soc": 75, - "vehicle_range": 468, - "vehicle_eta": 18000, - "session_energy": 7004, - "has_limit": false, - "total_day": 1234, - "total_week": 12345, - "total_month": 123456, - "total_year": 1234567, - "total_energy": 12345678, - "max_current": 48 - } + "mode": "STA", + "wifi_client_connected": 1, + "eth_connected": 0, + "net_connected": 1, + "ipaddress": "192.168.21.19", + "macaddress": "9C:9C:1F:E5:7B:2C", + "emoncms_connected": 0, + "packets_sent": 0, + "packets_success": 0, + "mqtt_connected": 1, + "ocpp_connected": 0, + "rfid_failure": 0, + "ohm_hour": "NotConnected", + "free_heap": 167436, + "comm_sent": 677216, + "comm_success": 677214, + "rapi_connected": 1, + "evse_connected": 1, + "amp": 0, + "voltage": 220, + "power": 0, + "pilot": 48, + "max_current": 48, + "temp": 440, + "temp_max": 588, + "temp1": false, + "temp2": 440, + "temp3": false, + "temp4": 542.5, + "state": 254, + "status": "disabled", + "flags": 512, + "vehicle": 0, + "colour": 5, + "manual_override": 0, + "freeram": 167436, + "divertmode": 1, + "srssi": -59, + "time": "2024-11-14T20:53:35Z", + "local_time": "2024-11-14T13:53:35-0700", + "offset": "-0700", + "uptime": 1208725, + "session_elapsed": 0, + "session_energy": 0, + "total_energy": 20127.22817, + "total_day": 0, + "total_week": 1.567628635, + "total_month": 37.21857071, + "total_year": 2155.219982, + "total_switches": 1159, + "elapsed": 0, + "wattsec": 0, + "watthour": 2.012722817e7, + "gfcicount": 1, + "nogndcount": 0, + "stuckcount": 0, + "solar": 0, + "grid_ie": -2489, + "charge_rate": 15, + "divert_update": 6, + "divert_active": false, + "shaper": 0, + "shaper_live_pwr": 0, + "shaper_cur": 0, + "shaper_updated": false, + "service_level": 2, + "limit": false, + "ota_update": 0, + "config_version": 6, + "claims_version": 36, + "override_version": 4, + "schedule_version": 1, + "schedule_plan_version": 30, + "limit_version": 1, + "vehicle_state_update": 1208725, + "tesla_vehicle_count": false, + "tesla_vehicle_id": false, + "tesla_vehicle_name": false +} \ No newline at end of file diff --git a/tests/test_main.py b/tests/test_main.py index 309824a..48e5510 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -376,7 +376,7 @@ async def test_get_current_capacity(fixture, expected, request): [ ("test_charger", 64582), ("test_charger_v2", 1585443), - ("test_charger_new", 12345678), + ("test_charger_new", 20127.22817), ], ) async def test_get_usage_total(fixture, expected, request): @@ -448,7 +448,7 @@ async def test_get_time(fixture, expected, request): [ ("test_charger", 275.71), ("test_charger_v2", 7003.41), - ("test_charger_new", 7004), + ("test_charger_new", 0), ], ) async def test_get_usage_session(fixture, expected, request): @@ -1427,7 +1427,7 @@ async def test_get_has_limit(fixture, expected, request): @pytest.mark.parametrize( "fixture, expected", - [("test_charger", None), ("test_charger_v2", None), ("test_charger_new", 1234)], + [("test_charger", None), ("test_charger_v2", None), ("test_charger_new", 0)], ) async def test_get_total_day(fixture, expected, request): """Test total_day reply.""" @@ -1439,7 +1439,11 @@ async def test_get_total_day(fixture, expected, request): @pytest.mark.parametrize( "fixture, expected", - [("test_charger", None), ("test_charger_v2", None), ("test_charger_new", 12345)], + [ + ("test_charger", None), + ("test_charger_v2", None), + ("test_charger_new", 1.567628635), + ], ) async def test_get_total_week(fixture, expected, request): """Test total_week reply.""" @@ -1451,7 +1455,11 @@ async def test_get_total_week(fixture, expected, request): @pytest.mark.parametrize( "fixture, expected", - [("test_charger", None), ("test_charger_v2", None), ("test_charger_new", 123456)], + [ + ("test_charger", None), + ("test_charger_v2", None), + ("test_charger_new", 37.21857071), + ], ) async def test_get_total_month(fixture, expected, request): """Test total_month reply.""" @@ -1463,7 +1471,11 @@ async def test_get_total_month(fixture, expected, request): @pytest.mark.parametrize( "fixture, expected", - [("test_charger", None), ("test_charger_v2", None), ("test_charger_new", 1234567)], + [ + ("test_charger", None), + ("test_charger_v2", None), + ("test_charger_new", 2155.219982), + ], ) async def test_get_total_year(fixture, expected, request): """Test total_year reply.""" @@ -1763,3 +1775,62 @@ async def test_max_current(fixture, expected, request): await charger.update() status = charger.max_current assert status == expected + + +@pytest.mark.parametrize( + "fixture, expected", [("test_charger_new", 0), ("test_charger_v2", 0)] +) +async def test_emoncms_connected(fixture, expected, request): + """Test emoncms_connected reply.""" + charger = request.getfixturevalue(fixture) + await charger.update() + status = charger.emoncms_connected + assert status == expected + + +@pytest.mark.parametrize( + "fixture, expected", [("test_charger_new", 0), ("test_charger_v2", None)] +) +async def test_ocpp_connected(fixture, expected, request): + """Test ocpp_connected reply.""" + charger = request.getfixturevalue(fixture) + await charger.update() + status = charger.ocpp_connected + assert status == expected + + +@pytest.mark.parametrize( + "fixture, expected", [("test_charger_new", 1208725), ("test_charger_v2", None)] +) +async def test_uptime(fixture, expected, request): + """Test uptime reply.""" + charger = request.getfixturevalue(fixture) + await charger.update() + status = charger.uptime + assert status == expected + + +@pytest.mark.parametrize( + "fixture, expected", [("test_charger_new", 167436), ("test_charger_v2", None)] +) +async def test_freeram(fixture, expected, request): + """Test freeram reply.""" + charger = request.getfixturevalue(fixture) + await charger.update() + status = charger.freeram + assert status == expected + + +@pytest.mark.parametrize( + "fixture, expected", + [ + ("test_charger_new", {"gfcicount": 1, "nogndcount": 0, "stuckcount": 0}), + ("test_charger_v2", {"gfcicount": 0, "nogndcount": 0, "stuckcount": 0}), + ], +) +async def test_checks_count(fixture, expected, request): + """Test checks_count reply.""" + charger = request.getfixturevalue(fixture) + await charger.update() + status = charger.checks_count + assert status == expected