From 75b7e94aa5824122f81b029f5a8731411e4accd3 Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Thu, 22 Feb 2024 23:14:31 +0100 Subject: [PATCH] Dump device info - fixtures for HA testing (#494) --- ...IR-1_20230913-113804-v1.14.0-gcb84623.json | 238 ++++++++++++ ...GS-1_20230913-114427-v1.14.0-gcb84623.json | 165 ++++++++ ...LG-S_20230913-113421-v1.14.0-gcb84623.json | 198 ++++++++++ ...IN-1_20230913-111730-v1.14.0-gcb84623.json | 199 ++++++++++ ...W-BT01_20231219-133956-1.1.0-g34b5d4f.json | 137 +++++++ ...W-BT01_20240213-140411-1.2.0-gb1b9aa8.json | 137 +++++++ ...1P16EU_20231219-133934-1.1.0-g34b5d4f.json | 186 +++++++++ ...0110IT_20231219-133948-1.1.0-g34b5d4f.json | 162 ++++++++ ...0112EU_20231219-134003-1.1.0-g34b5d4f.json | 196 ++++++++++ ...3CEBEU_20231219-134001-1.1.0-g34b5d4f.json | 199 ++++++++++ ...XE16EU_20231219-133956-1.1.0-g34b5d4f.json | 225 +++++++++++ ...PE16EU_20230912-082358-1.0.3-g6176478.json | 335 ++++++++++++++++ ...X10EU1_20240115-105444-1.2.8-59063a9a.json | 248 ++++++++++++ tools/{common.py => common/__init__.py} | 15 +- tools/example.py | 30 +- tools/fixture.py | 360 ++++++++++++++++++ 16 files changed, 3013 insertions(+), 17 deletions(-) create mode 100644 fixtures/gen1_Shelly Air_SHAIR-1_20230913-113804-v1.14.0-gcb84623.json create mode 100644 fixtures/gen1_Shelly Gas_SHGS-1_20230913-114427-v1.14.0-gcb84623.json create mode 100644 fixtures/gen1_Shelly Plug S_SHPLG-S_20230913-113421-v1.14.0-gcb84623.json create mode 100644 fixtures/gen1_Shelly Vintage_SHVIN-1_20230913-111730-v1.14.0-gcb84623.json create mode 100644 fixtures/gen2_Shelly BLU Gateway_SNGW-BT01_20231219-133956-1.1.0-g34b5d4f.json create mode 100644 fixtures/gen2_Shelly BLU Gateway_SNGW-BT01_20240213-140411-1.2.0-gb1b9aa8.json create mode 100644 fixtures/gen2_Shelly Plus 1PM_SNSW-001P16EU_20231219-133934-1.1.0-g34b5d4f.json create mode 100644 fixtures/gen2_Shelly Plus Plug IT_SNPL-00110IT_20231219-133948-1.1.0-g34b5d4f.json create mode 100644 fixtures/gen2_Shelly Plus Plug S_SNPL-00112EU_20231219-134003-1.1.0-g34b5d4f.json create mode 100644 fixtures/gen2_Shelly Pro 3EM_SPEM-003CEBEU_20231219-134001-1.1.0-g34b5d4f.json create mode 100644 fixtures/gen2_Shelly Pro 3_SPSW-003XE16EU_20231219-133956-1.1.0-g34b5d4f.json create mode 100644 fixtures/gen2_Shelly Pro 4PM_SPSW-004PE16EU_20230912-082358-1.0.3-g6176478.json create mode 100644 fixtures/gen2_Shelly Wall Display_SAWD-0A1XX10EU1_20240115-105444-1.2.8-59063a9a.json rename tools/{common.py => common/__init__.py} (89%) create mode 100644 tools/fixture.py diff --git a/fixtures/gen1_Shelly Air_SHAIR-1_20230913-113804-v1.14.0-gcb84623.json b/fixtures/gen1_Shelly Air_SHAIR-1_20230913-113804-v1.14.0-gcb84623.json new file mode 100644 index 00000000..156f0381 --- /dev/null +++ b/fixtures/gen1_Shelly Air_SHAIR-1_20230913-113804-v1.14.0-gcb84623.json @@ -0,0 +1,238 @@ +{ + "settings": { + "actions": { + "active": false, + "names": [ + "btn_on_url", + "btn_off_url", + "longpush_url", + "shortpush_url", + "out_on_url", + "out_off_url" + ] + }, + "allow_cross_origin": false, + "ap_roaming": { + "enabled": false, + "threshold": -70 + }, + "build_info": { + "build_id": "20230913-113804/v1.14.0-gcb84623", + "build_timestamp": "2023-09-13T11:38:04Z", + "build_version": "1.0" + }, + "cloud": { + "connected": true, + "enabled": true + }, + "coiot": { + "enabled": true, + "peer": "192.168.1.10:5683", + "update_period": 15 + }, + "debug_enable": false, + "device": { + "hostname": "shellyair-AABBCCDDEEFF", + "mac": "AABBCCDDEEFF", + "num_meters": 1, + "num_outputs": 1, + "type": "SHAIR-1" + }, + "discoverable": false, + "eco_mode_enabled": true, + "ext_humidity": {}, + "ext_sensors": { + "temperature_unit": "C" + }, + "ext_temperature": { + "0": { + "offset_tC": 0.0, + "offset_tF": 0.0, + "overtemp_act": "disabled", + "overtemp_threshold_tC": 0.0, + "overtemp_threshold_tF": 32.0, + "undertemp_act": "disabled", + "undertemp_threshold_tC": 0.0, + "undertemp_threshold_tF": 32.0 + } + }, + "factory_reset_from_switch": true, + "fw": "20230913-113804/v1.14.0-gcb84623", + "hwinfo": { + "batch_id": 0, + "hw_revision": "dev-prototype" + }, + "lat": 45.472198, + "lng": 9.1922, + "login": { + "enabled": false, + "unprotected": false, + "username": "admin" + }, + "longpush_time": 800, + "mode": "relay", + "mqtt": { + "clean_session": true, + "enable": false, + "id": "shellyair-AABBCCDDEEFF", + "keep_alive": 60, + "max_qos": 0, + "reconnect_timeout_max": 60.0, + "reconnect_timeout_min": 2.0, + "retain": false, + "server": "192.168.33.3:1883", + "update_period": 30, + "user": "" + }, + "name": "Test Name", + "pin_code": "", + "pon_wifi_reset": false, + "power_correction": 1.0, + "relays": [ + { + "auto_off": 1800.0, + "auto_on": 0.0, + "btn_reverse": 0, + "btn_type": "toggle", + "default_state": "off", + "has_timer": false, + "ison": false, + "name": null, + "schedule": false, + "schedule_rules": [] + } + ], + "sntp": { + "enabled": true, + "server": "192.168.1.10" + }, + "time": "18:28", + "timezone": "Europe/Rome", + "tz_dst": false, + "tz_dst_auto": true, + "tz_utc_offset": 3600, + "tzautodetect": true, + "unixtime": 1707326928, + "wifi_ap": { + "enabled": false, + "key": "", + "ssid": "shellyair-AABBCCDDEEFF" + }, + "wifi_sta": { + "dns": null, + "enabled": true, + "gw": null, + "ip": null, + "ipv4_method": "dhcp", + "mask": null, + "ssid": "Wifi-Network-Name" + }, + "wifi_sta1": { + "dns": null, + "enabled": false, + "gw": null, + "ip": null, + "ipv4_method": "dhcp", + "mask": null, + "ssid": null + } + }, + "shelly": { + "auth": false, + "discoverable": false, + "fw": "20230913-113804/v1.14.0-gcb84623", + "longid": 1, + "mac": "AABBCCDDEEFF", + "name": "Test Name", + "num_meters": 1, + "num_outputs": 1, + "type": "SHAIR-1" + }, + "status": { + "actions_stats": { + "skipped": 0 + }, + "cfg_changed_cnt": 0, + "cloud": { + "connected": true, + "enabled": true + }, + "ext_humidity": {}, + "ext_sensors": { + "temperature_unit": "C" + }, + "ext_temperature": { + "0": { + "hwID": "2843db970a000011", + "tC": 23.06, + "tF": 73.51 + } + }, + "fs_free": 145831, + "fs_size": 233681, + "has_update": false, + "inputs": [ + { + "event": "", + "event_cnt": 0, + "input": 0 + } + ], + "mac": "AABBCCDDEEFF", + "meters": [ + { + "counters": [ + 0.0, + 0.0, + 0.0 + ], + "is_valid": true, + "overpower": 0.0, + "power": 0.0, + "timestamp": 1707330528, + "total": 0 + } + ], + "mqtt": { + "connected": false + }, + "overtemperature": false, + "ram_free": 38656, + "ram_total": 51536, + "relays": [ + { + "has_timer": false, + "ison": false, + "overpower": false, + "source": "input", + "timer_duration": 0, + "timer_remaining": 0, + "timer_started": 0 + } + ], + "serial": 34491, + "temperature": 33.89, + "time": "18:28", + "tmp": { + "is_valid": true, + "tC": 33.89, + "tF": 93.0 + }, + "total_work_time": 55697, + "unixtime": 1707326928, + "update": { + "beta_version": "20231107-164540/v1.14.1-rc1-g0617c15", + "has_update": false, + "new_version": "20230913-113804/v1.14.0-gcb84623", + "old_version": "20230913-113804/v1.14.0-gcb84623", + "status": "idle" + }, + "uptime": 4572455, + "wifi_sta": { + "connected": true, + "ip": "192.168.1.64", + "rssi": -65, + "ssid": "Wifi-Network-Name" + } + } +} diff --git a/fixtures/gen1_Shelly Gas_SHGS-1_20230913-114427-v1.14.0-gcb84623.json b/fixtures/gen1_Shelly Gas_SHGS-1_20230913-114427-v1.14.0-gcb84623.json new file mode 100644 index 00000000..5b8d8583 --- /dev/null +++ b/fixtures/gen1_Shelly Gas_SHGS-1_20230913-114427-v1.14.0-gcb84623.json @@ -0,0 +1,165 @@ +{ + "settings": { + "actions": { + "active": false, + "names": [ + "alarm_off_url", + "alarm_mild_url", + "alarm_heavy_url" + ] + }, + "allow_cross_origin": false, + "ap_roaming": { + "enabled": true, + "threshold": -70 + }, + "build_info": { + "build_id": "20230913-114427/v1.14.0-gcb84623", + "build_timestamp": "2023-09-13T11:44:27Z", + "build_version": "1.0" + }, + "cloud": { + "connected": true, + "enabled": true + }, + "coiot": { + "enabled": true, + "peer": "192.168.1.10:5683", + "update_period": 15 + }, + "debug_enable": false, + "device": { + "hostname": "shellygas-AABBCCDDEEFF", + "mac": "AABBCCDDEEFF", + "num_inputs": 0, + "num_outputs": 0, + "type": "SHGS-1" + }, + "discoverable": false, + "eco_mode_enabled": true, + "fw": "20230913-114427/v1.14.0-gcb84623", + "hwinfo": { + "batch_id": 1, + "hw_revision": "prod-2020-04-09" + }, + "lat": 45.472198, + "lng": 9.1922, + "login": { + "enabled": false, + "unprotected": false, + "username": "admin" + }, + "mqtt": { + "clean_session": true, + "enable": false, + "id": "shellygas-AABBCCDDEEFF", + "keep_alive": 60, + "max_qos": 0, + "reconnect_timeout_max": 60.0, + "reconnect_timeout_min": 2.0, + "retain": false, + "server": "192.168.33.3:1883", + "update_period": 30, + "user": "" + }, + "name": "Test Name", + "pin_code": "!Y7z@N", + "pon_wifi_reset": false, + "set_volume": 11, + "sntp": { + "enabled": true, + "server": "192.168.1.10" + }, + "time": "18:28", + "timezone": "Europe/Rome", + "tz_dst": false, + "tz_dst_auto": true, + "tz_utc_offset": 3600, + "tzautodetect": true, + "unixtime": 1707326929, + "wifi_ap": { + "enabled": false, + "key": "", + "ssid": "shellygas-AABBCCDDEEFF" + }, + "wifi_sta": { + "dns": null, + "enabled": true, + "gw": null, + "ip": null, + "ipv4_method": "dhcp", + "mask": null, + "ssid": "Wifi-Network-Name" + }, + "wifi_sta1": { + "dns": null, + "enabled": false, + "gw": null, + "ip": null, + "ipv4_method": "dhcp", + "mask": null, + "ssid": null + } + }, + "shelly": { + "auth": false, + "discoverable": false, + "fw": "20230913-114427/v1.14.0-gcb84623", + "longid": 1, + "mac": "AABBCCDDEEFF", + "name": "Test Name", + "num_inputs": 0, + "num_outputs": 0, + "type": "SHGS-1" + }, + "status": { + "actions_stats": { + "skipped": 0 + }, + "cfg_changed_cnt": 0, + "cloud": { + "connected": true, + "enabled": true + }, + "concentration": { + "is_valid": true, + "ppm": 0 + }, + "fs_free": 92117, + "fs_size": 233681, + "gas_sensor": { + "alarm_state": "none", + "self_test_state": "not_completed", + "sensor_state": "normal" + }, + "has_update": false, + "mac": "AABBCCDDEEFF", + "mqtt": { + "connected": false + }, + "ram_free": 40524, + "ram_total": 52528, + "serial": 790, + "time": "18:28", + "unixtime": 1707326929, + "update": { + "beta_version": "20231107-165146/v1.14.1-rc1-g0617c15", + "has_update": false, + "new_version": "20230913-114427/v1.14.0-gcb84623", + "old_version": "20230913-114427/v1.14.0-gcb84623", + "status": "idle" + }, + "uptime": 1468391, + "valves": [ + { + "state": "not_connected" + } + ], + "wifi_sta": { + "connected": true, + "ip": "192.168.1.66", + "rssi": -62, + "ssid": "Wifi-Network-Name" + } + } +} diff --git a/fixtures/gen1_Shelly Plug S_SHPLG-S_20230913-113421-v1.14.0-gcb84623.json b/fixtures/gen1_Shelly Plug S_SHPLG-S_20230913-113421-v1.14.0-gcb84623.json new file mode 100644 index 00000000..6534a3cf --- /dev/null +++ b/fixtures/gen1_Shelly Plug S_SHPLG-S_20230913-113421-v1.14.0-gcb84623.json @@ -0,0 +1,198 @@ +{ + "settings": { + "actions": { + "active": false, + "names": [ + "btn_on_url", + "out_on_url", + "out_off_url" + ] + }, + "allow_cross_origin": false, + "ap_roaming": { + "enabled": false, + "threshold": -70 + }, + "build_info": { + "build_id": "20230913-113421/v1.14.0-gcb84623", + "build_timestamp": "2023-09-13T11:34:21Z", + "build_version": "1.0" + }, + "cloud": { + "connected": false, + "enabled": false + }, + "coiot": { + "enabled": true, + "peer": "192.168.1.10:5683", + "update_period": 15 + }, + "debug_enable": false, + "device": { + "hostname": "shellyplug-s-DDEEFF", + "mac": "AABBCCDDEEFF", + "num_meters": 1, + "num_outputs": 1, + "type": "SHPLG-S" + }, + "discoverable": true, + "eco_mode_enabled": true, + "fw": "20230913-113421/v1.14.0-gcb84623", + "hwinfo": { + "batch_id": 1, + "hw_revision": "prod-190516" + }, + "lat": 45.472198, + "led_power_disable": false, + "led_status_disable": false, + "lng": 9.1922, + "login": { + "enabled": false, + "unprotected": false, + "username": "admin" + }, + "max_power": 1800, + "mqtt": { + "clean_session": true, + "enable": false, + "id": "shellyplug-s-DDEEFF", + "keep_alive": 60, + "max_qos": 0, + "reconnect_timeout_max": 60.0, + "reconnect_timeout_min": 2.0, + "retain": false, + "server": "192.168.33.3:1883", + "update_period": 30, + "user": "" + }, + "name": "Test Name", + "pin_code": "", + "pon_wifi_reset": false, + "relays": [ + { + "appliance_type": "Light", + "auto_off": 0.0, + "auto_on": 0.0, + "default_state": "off", + "has_timer": false, + "ison": false, + "max_power": 1800, + "name": null, + "schedule": false, + "schedule_rules": [] + } + ], + "sntp": { + "enabled": true, + "server": "192.168.1.10" + }, + "time": "19:57", + "timezone": "Europe/Rome", + "tz_dst": false, + "tz_dst_auto": true, + "tz_utc_offset": 3600, + "tzautodetect": true, + "unixtime": 1707332241, + "wifi_ap": { + "enabled": false, + "key": "", + "ssid": "shellyplug-s-DDEEFF" + }, + "wifi_sta": { + "dns": null, + "enabled": true, + "gw": null, + "ip": null, + "ipv4_method": "dhcp", + "mask": null, + "ssid": "Wifi-Network-Name" + }, + "wifi_sta1": { + "dns": null, + "enabled": false, + "gw": null, + "ip": null, + "ipv4_method": "dhcp", + "mask": null, + "ssid": null + } + }, + "shelly": { + "auth": false, + "discoverable": true, + "fw": "20230913-113421/v1.14.0-gcb84623", + "mac": "AABBCCDDEEFF", + "name": "Test Name", + "num_meters": 1, + "num_outputs": 1, + "type": "SHPLG-S" + }, + "status": { + "actions_stats": { + "skipped": 0 + }, + "cfg_changed_cnt": 0, + "cloud": { + "connected": false, + "enabled": false + }, + "fs_free": 166915, + "fs_size": 233681, + "has_update": false, + "mac": "AABBCCDDEEFF", + "meters": [ + { + "counters": [ + 0.0, + 0.0, + 0.0 + ], + "is_valid": true, + "overpower": 0.0, + "power": 0.0, + "timestamp": 1707335841, + "total": 2632 + } + ], + "mqtt": { + "connected": false + }, + "overtemperature": false, + "ram_free": 40428, + "ram_total": 52056, + "relays": [ + { + "has_timer": false, + "ison": false, + "overpower": false, + "source": "http", + "timer_duration": 0, + "timer_remaining": 0, + "timer_started": 0 + } + ], + "serial": 16, + "temperature": 24.14, + "time": "19:57", + "tmp": { + "is_valid": true, + "tC": 24.14, + "tF": 75.45 + }, + "unixtime": 1707332241, + "update": { + "beta_version": "20231107-164219/v1.14.1-rc1-g0617c15", + "has_update": false, + "new_version": "20230913-113421/v1.14.0-gcb84623", + "old_version": "20230913-113421/v1.14.0-gcb84623", + "status": "idle" + }, + "uptime": 2589909, + "wifi_sta": { + "connected": true, + "ip": "192.168.1.91", + "rssi": -76, + "ssid": "Wifi-Network-Name" + } + } +} diff --git a/fixtures/gen1_Shelly Vintage_SHVIN-1_20230913-111730-v1.14.0-gcb84623.json b/fixtures/gen1_Shelly Vintage_SHVIN-1_20230913-111730-v1.14.0-gcb84623.json new file mode 100644 index 00000000..9e3a45a2 --- /dev/null +++ b/fixtures/gen1_Shelly Vintage_SHVIN-1_20230913-111730-v1.14.0-gcb84623.json @@ -0,0 +1,199 @@ +{ + "settings": { + "actions": { + "active": false, + "names": [ + "out_on_url", + "out_off_url" + ] + }, + "allow_cross_origin": false, + "ap_roaming": { + "enabled": true, + "threshold": -70 + }, + "build_info": { + "build_id": "20230913-111730/v1.14.0-gcb84623", + "build_timestamp": "2023-09-13T11:17:30Z", + "build_version": "1.0" + }, + "cloud": { + "connected": true, + "enabled": true + }, + "coiot": { + "enabled": true, + "peer": "192.168.1.10:5683", + "update_period": 15 + }, + "debug_enable": false, + "device": { + "hostname": "ShellyVintage-AABBCCDDEEFF", + "mac": "AABBCCDDEEFF", + "num_outputs": 1, + "type": "SHVIN-1" + }, + "discoverable": false, + "eco_mode_enabled": true, + "fw": "20230913-111730/v1.14.0-gcb84623", + "hwinfo": { + "batch_id": 0, + "hw_revision": "prod-102020" + }, + "lat": 45.472198, + "lights": [ + { + "auto_off": 0.0, + "auto_on": 0.0, + "brightness": 100, + "default_state": "last", + "ison": false, + "name": null, + "night_mode": { + "brightness": 0, + "enabled": false, + "end_time": "00:00", + "start_time": "00:00" + }, + "schedule": false, + "schedule_rules": [], + "transition": 1000 + } + ], + "lng": 9.1922, + "login": { + "enabled": false, + "unprotected": false, + "username": "admin" + }, + "mode": "white", + "mqtt": { + "clean_session": true, + "enable": false, + "id": "ShellyVintage-AABBCCDDEEFF", + "keep_alive": 60, + "max_qos": 0, + "reconnect_timeout_max": 60.0, + "reconnect_timeout_min": 2.0, + "retain": false, + "server": "192.168.33.3:1883", + "update_period": 30, + "user": "" + }, + "name": "Test Name", + "night_mode": { + "brightness": 0, + "enabled": false, + "end_time": "00:00", + "start_time": "00:00" + }, + "pin_code": "", + "pon_wifi_reset": false, + "sntp": { + "enabled": true, + "server": "192.168.1.10" + }, + "time": "18:28", + "timezone": "Europe/Rome", + "transition": 1000, + "tz_dst": false, + "tz_dst_auto": true, + "tz_utc_offset": 3600, + "tzautodetect": true, + "unixtime": 1707326930, + "wifi_ap": { + "enabled": false, + "key": "", + "ssid": "ShellyVintage-AABBCCDDEEFF" + }, + "wifi_sta": { + "dns": null, + "enabled": true, + "gw": null, + "ip": null, + "ipv4_method": "dhcp", + "mask": null, + "ssid": "Wifi-Network-Name" + }, + "wifi_sta1": { + "dns": null, + "enabled": false, + "gw": null, + "ip": null, + "ipv4_method": "dhcp", + "mask": null, + "ssid": null + } + }, + "shelly": { + "auth": false, + "discoverable": false, + "fw": "20230913-111730/v1.14.0-gcb84623", + "longid": 1, + "mac": "AABBCCDDEEFF", + "name": "Test Name", + "num_outputs": 1, + "type": "SHVIN-1" + }, + "status": { + "actions_stats": { + "skipped": 0 + }, + "cfg_changed_cnt": 0, + "cloud": { + "connected": true, + "enabled": true + }, + "fs_free": 163903, + "fs_size": 233681, + "has_update": false, + "lights": [ + { + "brightness": 100, + "has_timer": false, + "ison": false, + "source": "http", + "timer_duration": 0, + "timer_remaining": 0, + "timer_started": 0, + "transition": 0 + } + ], + "mac": "AABBCCDDEEFF", + "meters": [ + { + "counters": [ + 0.0, + 0.0, + 0.0 + ], + "is_valid": true, + "power": 0.0, + "timestamp": 1707330530, + "total": 1 + } + ], + "mqtt": { + "connected": false + }, + "ram_free": 40444, + "ram_total": 52344, + "serial": 19777, + "time": "18:28", + "unixtime": 1707326930, + "update": { + "beta_version": "20231107-162609/v1.14.1-rc1-g0617c15", + "has_update": false, + "new_version": "20230913-111730/v1.14.0-gcb84623", + "old_version": "20230913-111730/v1.14.0-gcb84623", + "status": "idle" + }, + "uptime": 895103, + "wifi_sta": { + "connected": true, + "ip": "192.168.1.80", + "rssi": -41, + "ssid": "Wifi-Network-Name" + } + } +} diff --git a/fixtures/gen2_Shelly BLU Gateway_SNGW-BT01_20231219-133956-1.1.0-g34b5d4f.json b/fixtures/gen2_Shelly BLU Gateway_SNGW-BT01_20231219-133956-1.1.0-g34b5d4f.json new file mode 100644 index 00000000..756ac668 --- /dev/null +++ b/fixtures/gen2_Shelly BLU Gateway_SNGW-BT01_20231219-133956-1.1.0-g34b5d4f.json @@ -0,0 +1,137 @@ +{ + "config": { + "ble": { + "enable": true, + "observer": { + "enable": true + }, + "rpc": { + "enable": true + } + }, + "cloud": { + "enable": true, + "server": "shelly-9-eu.shelly.cloud:6022/jrpc" + }, + "mqtt": { + "client_id": "shellyblugw-aabbccddeeff", + "enable": false, + "enable_control": true, + "enable_rpc": true, + "rpc_ntf": true, + "server": "mqtt.test.server", + "ssl_ca": null, + "status_ntf": false, + "topic_prefix": "shellyblugw-aabbccddeeff", + "use_client_cert": false, + "user": null + }, + "script:1": { + "enable": false, + "id": 1, + "name": "Script Test Name 1" + }, + "sys": { + "cfg_rev": 19, + "debug": { + "file_level": null, + "level": 2, + "mqtt": { + "enable": false + }, + "udp": { + "addr": null + }, + "websocket": { + "enable": false + } + }, + "device": { + "discoverable": true, + "eco_mode": false, + "fw_id": "20231219-133956/1.1.0-g34b5d4f", + "mac": "AABBCCDDEEFF", + "name": "Test Name" + }, + "location": { + "lat": 45.4722, + "lon": 9.1922, + "tz": "Europe/Rome" + }, + "rpc_udp": { + "dst_addr": null, + "listen_port": null + }, + "sntp": { + "server": "sntp.test.server" + }, + "ui_data": {} + }, + "wifi": "Wifi-Network-Name", + "ws": { + "enable": false, + "server": null, + "ssl_ca": "ca.pem" + } + }, + "shelly": { + "app": "BluGw", + "auth_domain": null, + "auth_en": false, + "fw_id": "20231219-133956/1.1.0-g34b5d4f", + "gen": 2, + "id": "shellyblugw-aabbccddeeff", + "mac": "AABBCCDDEEFF", + "model": "SNGW-BT01", + "name": "Test Name", + "slot": 0, + "ver": "1.1.0" + }, + "status": { + "ble": {}, + "cloud": { + "connected": true + }, + "mqtt": { + "connected": false + }, + "script:1": { + "id": 1, + "mem_free": 24626, + "mem_peak": 2548, + "mem_used": 574, + "running": true + }, + "sys": { + "available_updates": { + "beta": { + "version": "1.2.0-beta1" + } + }, + "cfg_rev": 19, + "fs_free": 147456, + "fs_size": 458752, + "kvs_rev": 0, + "mac": "AABBCCDDEEFF", + "ram_free": 117288, + "ram_size": 261904, + "reset_reason": 3, + "restart_required": true, + "schedule_rev": 0, + "time": "14:31", + "unixtime": 1707571873, + "uptime": 913057, + "webhook_rev": 0 + }, + "wifi": { + "ap_client_count": 1, + "rssi": -70, + "ssid": "Wifi-Network-Name", + "sta_ip": "192.168.1.94", + "status": "got ip" + }, + "ws": { + "connected": false + } + } +} diff --git a/fixtures/gen2_Shelly BLU Gateway_SNGW-BT01_20240213-140411-1.2.0-gb1b9aa8.json b/fixtures/gen2_Shelly BLU Gateway_SNGW-BT01_20240213-140411-1.2.0-gb1b9aa8.json new file mode 100644 index 00000000..3700f234 --- /dev/null +++ b/fixtures/gen2_Shelly BLU Gateway_SNGW-BT01_20240213-140411-1.2.0-gb1b9aa8.json @@ -0,0 +1,137 @@ +{ + "config": { + "ble": { + "enable": true, + "observer": { + "enable": true + }, + "rpc": { + "enable": true + } + }, + "cloud": { + "enable": true, + "server": "shelly-9-eu.shelly.cloud:6022/jrpc" + }, + "mqtt": { + "client_id": "shellyblugw-aabbccddeeff", + "enable": false, + "enable_control": true, + "enable_rpc": true, + "rpc_ntf": true, + "server": "mqtt.test.server", + "ssl_ca": null, + "status_ntf": false, + "topic_prefix": "shellyblugw-aabbccddeeff", + "use_client_cert": false, + "user": null + }, + "script:1": { + "enable": false, + "id": 1, + "name": "script 1" + }, + "sys": { + "cfg_rev": 20, + "debug": { + "file_level": null, + "level": 2, + "mqtt": { + "enable": false + }, + "udp": { + "addr": null + }, + "websocket": { + "enable": false + } + }, + "device": { + "discoverable": true, + "eco_mode": false, + "fw_id": "20240213-140411/1.2.0-gb1b9aa8", + "mac": "AABBCCDDEEFF", + "name": "Test Name" + }, + "location": { + "lat": 45.4722, + "lon": 9.1922, + "tz": "Europe/Rome" + }, + "rpc_udp": { + "dst_addr": null, + "listen_port": null + }, + "sntp": { + "server": "sntp.test.server" + }, + "ui_data": {} + }, + "wifi": "Wifi-Network-Name", + "ws": { + "enable": false, + "server": null, + "ssl_ca": "ca.pem" + } + }, + "shelly": { + "app": "BluGw", + "auth_domain": null, + "auth_en": false, + "fw_id": "20240213-140411/1.2.0-gb1b9aa8", + "gen": 2, + "id": "shellyblugw-aabbccddeeff", + "mac": "AABBCCDDEEFF", + "model": "SNGW-BT01", + "name": "Test Name", + "slot": 1, + "ver": "1.2.0" + }, + "status": { + "ble": {}, + "cloud": { + "connected": true + }, + "mqtt": { + "connected": false + }, + "script:1": { + "id": 1, + "mem_free": 24472, + "mem_peak": 2842, + "mem_used": 728, + "running": true + }, + "sys": { + "available_updates": { + "stable": { + "version": "1.1.0" + } + }, + "cfg_rev": 20, + "fs_free": 167936, + "fs_size": 458752, + "kvs_rev": 0, + "mac": "AABBCCDDEEFF", + "ram_free": 115116, + "ram_size": 261524, + "reset_reason": 1, + "restart_required": false, + "schedule_rev": 0, + "time": "10:32", + "unixtime": 1708507962, + "uptime": 247876, + "webhook_rev": 0 + }, + "wifi": { + "ap_client_count": 1, + "rssi": -83, + "ssid": "Wifi-Network-Name", + "sta_ip": "192.168.1.94", + "status": "got ip" + }, + "ws": { + "connected": false + } + } +} diff --git a/fixtures/gen2_Shelly Plus 1PM_SNSW-001P16EU_20231219-133934-1.1.0-g34b5d4f.json b/fixtures/gen2_Shelly Plus 1PM_SNSW-001P16EU_20231219-133934-1.1.0-g34b5d4f.json new file mode 100644 index 00000000..165f39ee --- /dev/null +++ b/fixtures/gen2_Shelly Plus 1PM_SNSW-001P16EU_20231219-133934-1.1.0-g34b5d4f.json @@ -0,0 +1,186 @@ +{ + "config": { + "ble": { + "enable": true, + "observer": { + "enable": false + }, + "rpc": { + "enable": true + } + }, + "cloud": { + "enable": true, + "server": "shelly-9-eu.shelly.cloud:6022/jrpc" + }, + "input:0": { + "enable": true, + "factory_reset": true, + "id": 0, + "invert": false, + "name": "Input Test Name 0", + "type": "switch" + }, + "mqtt": { + "client_id": "shellyplus1pm-aabbccddeeff", + "enable": false, + "enable_control": true, + "enable_rpc": true, + "rpc_ntf": true, + "server": null, + "ssl_ca": null, + "status_ntf": false, + "topic_prefix": null, + "use_client_cert": false, + "user": null + }, + "script:1": { + "enable": false, + "id": 1, + "name": "aioshelly_ble_integration" + }, + "switch:0": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "autorecover_voltage_errors": false, + "current_limit": 16.0, + "id": 0, + "in_mode": "flip", + "initial_state": "off", + "name": "Switch Test Name 0", + "power_limit": 4480, + "voltage_limit": 280 + }, + "sys": { + "cfg_rev": 35, + "debug": { + "file_level": null, + "level": 2, + "mqtt": { + "enable": false + }, + "udp": { + "addr": null + }, + "websocket": { + "enable": true + } + }, + "device": { + "addon_type": null, + "discoverable": true, + "eco_mode": true, + "fw_id": "20231219-133934/1.1.0-g34b5d4f", + "mac": "AABBCCDDEEFF", + "name": "Test Name" + }, + "location": { + "lat": 45.45803, + "lon": 7.87121, + "tz": "Europe/Rome" + }, + "rpc_udp": { + "dst_addr": null, + "listen_port": null + }, + "sntp": { + "server": "192.168.1.10" + }, + "ui_data": { + "consumption_types": [ + "Light" + ] + } + }, + "wifi": "Wifi-Network-Name", + "ws": { + "enable": true, + "server": "ws://192.168.1.10:8123/api/shelly/ws", + "ssl_ca": "ca.pem" + } + }, + "shelly": { + "app": "Plus1PM", + "auth_domain": null, + "auth_en": false, + "fw_id": "20231219-133934/1.1.0-g34b5d4f", + "gen": 2, + "id": "shellyplus1pm-aabbccddeeff", + "mac": "AABBCCDDEEFF", + "model": "SNSW-001P16EU", + "name": "Test Name", + "slot": 0, + "ver": "1.1.0" + }, + "status": { + "ble": {}, + "cloud": { + "connected": true + }, + "input:0": { + "id": 0, + "state": false + }, + "mqtt": { + "connected": false + }, + "script:1": { + "id": 1, + "mem_free": 25200, + "running": false + }, + "switch:0": { + "aenergy": { + "by_minute": [ + 0.0, + 0.0, + 0.0 + ], + "minute_ts": 1707326934, + "total": 110.046 + }, + "apower": 0.0, + "current": 0.0, + "id": 0, + "output": false, + "source": "WS_in", + "temperature": { + "tC": 30.3, + "tF": 86.6 + }, + "voltage": 232.8 + }, + "sys": { + "available_updates": { + "beta": { + "version": "1.2.0-beta1" + } + }, + "cfg_rev": 35, + "fs_free": 135168, + "fs_size": 458752, + "kvs_rev": 4, + "mac": "AABBCCDDEEFF", + "ram_free": 122072, + "ram_size": 260728, + "reset_reason": 3, + "restart_required": false, + "schedule_rev": 0, + "time": "18:28", + "unixtime": 1707326936, + "uptime": 2622735, + "webhook_rev": 0 + }, + "wifi": { + "rssi": -64, + "ssid": "Wifi-Network-Name", + "sta_ip": "192.168.1.52", + "status": "got ip" + }, + "ws": { + "connected": false + } + } +} diff --git a/fixtures/gen2_Shelly Plus Plug IT_SNPL-00110IT_20231219-133948-1.1.0-g34b5d4f.json b/fixtures/gen2_Shelly Plus Plug IT_SNPL-00110IT_20231219-133948-1.1.0-g34b5d4f.json new file mode 100644 index 00000000..fdf77381 --- /dev/null +++ b/fixtures/gen2_Shelly Plus Plug IT_SNPL-00110IT_20231219-133948-1.1.0-g34b5d4f.json @@ -0,0 +1,162 @@ +{ + "config": { + "ble": { + "enable": false, + "observer": { + "enable": false + }, + "rpc": { + "enable": false + } + }, + "cloud": { + "enable": true, + "server": "shelly-9-eu.shelly.cloud:6022/jrpc" + }, + "mqtt": { + "client_id": "shellyplusplugit-aabbccddeeff", + "enable": false, + "enable_control": true, + "enable_rpc": true, + "rpc_ntf": true, + "server": null, + "ssl_ca": null, + "status_ntf": false, + "topic_prefix": "shellyplusplugit-aabbccddeeff", + "use_client_cert": false, + "user": null + }, + "switch:0": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "autorecover_voltage_errors": false, + "current_limit": 10.0, + "id": 0, + "initial_state": "on", + "name": "Switch Test Name 0", + "power_limit": 2300, + "voltage_limit": 280 + }, + "sys": { + "cfg_rev": 27, + "debug": { + "file_level": null, + "level": 2, + "mqtt": { + "enable": false + }, + "udp": { + "addr": null + }, + "websocket": { + "enable": false + } + }, + "device": { + "discoverable": true, + "eco_mode": true, + "fw_id": "20231219-133948/1.1.0-g34b5d4f", + "mac": "AABBCCDDEEFF", + "name": "Test Name" + }, + "location": { + "lat": 45.45803, + "lon": 7.87121, + "tz": "Europe/Rome" + }, + "rpc_udp": { + "dst_addr": null, + "listen_port": null + }, + "sntp": { + "server": "192.168.1.10" + }, + "ui_data": { + "consumption_types": [ + "" + ] + } + }, + "wifi": "Wifi-Network-Name", + "ws": { + "enable": false, + "server": null, + "ssl_ca": "ca.pem" + } + }, + "shelly": { + "app": "PlusPlugIT", + "auth_domain": null, + "auth_en": false, + "fw_id": "20231219-133948/1.1.0-g34b5d4f", + "gen": 2, + "id": "shellyplusplugit-aabbccddeeff", + "mac": "AABBCCDDEEFF", + "model": "SNPL-00110IT", + "name": "Test Name", + "slot": 0, + "ver": "1.1.0" + }, + "status": { + "ble": {}, + "cloud": { + "connected": true + }, + "mqtt": { + "connected": false + }, + "switch:0": { + "aenergy": { + "by_minute": [ + 10.3, + 14.306, + 13.734 + ], + "minute_ts": 1707326925, + "total": 922.282 + }, + "apower": 0.8, + "current": 0.0, + "id": 0, + "output": true, + "source": "WS_in", + "temperature": { + "tC": 26.8, + "tF": 80.3 + }, + "voltage": 222.6 + }, + "sys": { + "available_updates": { + "beta": { + "version": "1.2.0-beta1" + } + }, + "cfg_rev": 27, + "fs_free": 151552, + "fs_size": 458752, + "kvs_rev": 4, + "mac": "AABBCCDDEEFF", + "ram_free": 143224, + "ram_size": 246440, + "reset_reason": 3, + "restart_required": false, + "schedule_rev": 0, + "time": "18:28", + "unixtime": 1707326927, + "uptime": 4346058, + "webhook_rev": 0 + }, + "wifi": { + "rssi": -52, + "ssid": "Wifi-Network-Name", + "sta_ip": "192.168.1.53", + "status": "got ip" + }, + "ws": { + "connected": false + } + } +} diff --git a/fixtures/gen2_Shelly Plus Plug S_SNPL-00112EU_20231219-134003-1.1.0-g34b5d4f.json b/fixtures/gen2_Shelly Plus Plug S_SNPL-00112EU_20231219-134003-1.1.0-g34b5d4f.json new file mode 100644 index 00000000..b79047dc --- /dev/null +++ b/fixtures/gen2_Shelly Plus Plug S_SNPL-00112EU_20231219-134003-1.1.0-g34b5d4f.json @@ -0,0 +1,196 @@ +{ + "config": { + "ble": { + "enable": false, + "observer": { + "enable": false + }, + "rpc": { + "enable": false + } + }, + "cloud": { + "enable": true, + "server": "shelly-9-eu.shelly.cloud:6022/jrpc" + }, + "mqtt": { + "client_id": "shellyplusplugs-aabbccddeeff", + "enable": false, + "enable_control": true, + "enable_rpc": true, + "rpc_ntf": true, + "server": null, + "ssl_ca": null, + "status_ntf": false, + "topic_prefix": "shellyplusplugs-aabbccddeeff", + "use_client_cert": false, + "user": null + }, + "plugs_ui": { + "controls": { + "switch:0": { + "in_mode": "momentary" + } + }, + "leds": { + "colors": { + "power": { + "brightness": 100.0 + }, + "switch:0": { + "off": { + "brightness": 100.0, + "rgb": [ + 100.0, + 0.0, + 0.0 + ] + }, + "on": { + "brightness": 100.0, + "rgb": [ + 0.0, + 100.0, + 0.0 + ] + } + } + }, + "mode": "power", + "night_mode": { + "active_between": [], + "brightness": 100.0, + "enable": false + } + } + }, + "switch:0": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "current_limit": 12.0, + "id": 0, + "initial_state": "on", + "name": "Switch Test Name 0", + "power_limit": 2500, + "voltage_limit": 280 + }, + "sys": { + "cfg_rev": 25, + "debug": { + "file_level": null, + "level": 2, + "mqtt": { + "enable": false + }, + "udp": { + "addr": null + }, + "websocket": { + "enable": false + } + }, + "device": { + "discoverable": true, + "eco_mode": true, + "fw_id": "20231219-134003/1.1.0-g34b5d4f", + "mac": "AABBCCDDEEFF", + "name": "Test Name" + }, + "location": { + "lat": 45.45803, + "lon": 7.87121, + "tz": "Europe/Rome" + }, + "rpc_udp": { + "dst_addr": null, + "listen_port": null + }, + "sntp": { + "server": "time.google.com" + }, + "ui_data": {} + }, + "wifi": "Wifi-Network-Name", + "ws": { + "enable": false, + "server": null, + "ssl_ca": "ca.pem" + } + }, + "shelly": { + "app": "PlusPlugS", + "auth_domain": null, + "auth_en": false, + "fw_id": "20231219-134003/1.1.0-g34b5d4f", + "gen": 2, + "id": "shellyplusplugs-aabbccddeeff", + "mac": "AABBCCDDEEFF", + "model": "SNPL-00112EU", + "name": "Test Name", + "slot": 0, + "ver": "1.1.0" + }, + "status": { + "ble": {}, + "cloud": { + "connected": true + }, + "mqtt": { + "connected": false + }, + "plugs_ui": {}, + "switch:0": { + "aenergy": { + "by_minute": [ + 34.786, + 45.552, + 45.552 + ], + "minute_ts": 1707326925, + "total": 7258.589 + }, + "apower": 2.7, + "current": 0.121, + "id": 0, + "output": true, + "source": "init", + "temperature": { + "tC": 32.1, + "tF": 89.7 + }, + "voltage": 227.9 + }, + "sys": { + "available_updates": { + "beta": { + "version": "1.2.0-beta1" + } + }, + "cfg_rev": 25, + "fs_free": 139264, + "fs_size": 458752, + "kvs_rev": 0, + "mac": "AABBCCDDEEFF", + "ram_free": 141748, + "ram_size": 246084, + "reset_reason": 3, + "restart_required": false, + "schedule_rev": 0, + "time": "18:28", + "unixtime": 1707326927, + "uptime": 4319353, + "webhook_rev": 0 + }, + "wifi": { + "rssi": -53, + "ssid": "Wifi-Network-Name", + "sta_ip": "192.168.1.85", + "status": "got ip" + }, + "ws": { + "connected": false + } + } +} diff --git a/fixtures/gen2_Shelly Pro 3EM_SPEM-003CEBEU_20231219-134001-1.1.0-g34b5d4f.json b/fixtures/gen2_Shelly Pro 3EM_SPEM-003CEBEU_20231219-134001-1.1.0-g34b5d4f.json new file mode 100644 index 00000000..836acb97 --- /dev/null +++ b/fixtures/gen2_Shelly Pro 3EM_SPEM-003CEBEU_20231219-134001-1.1.0-g34b5d4f.json @@ -0,0 +1,199 @@ +{ + "config": { + "ble": { + "enable": false, + "observer": { + "enable": false + }, + "rpc": { + "enable": false + } + }, + "cloud": { + "enable": true, + "server": "shelly-9-eu.shelly.cloud:6022/jrpc" + }, + "em:0": { + "blink_mode_selector": "active_energy", + "id": 0, + "monitor_phase_sequence": false, + "name": "Energy Monitor Test Name 0", + "phase_selector": "all", + "reverse": {} + }, + "emdata:0": {}, + "eth": { + "enable": true, + "gw": null, + "ip": null, + "ipv4mode": "dhcp", + "nameserver": null, + "netmask": null + }, + "modbus": { + "enable": true + }, + "mqtt": { + "client_id": "shellypro3em-aabbccddeeff", + "enable": false, + "enable_control": true, + "enable_rpc": true, + "rpc_ntf": true, + "server": null, + "ssl_ca": null, + "status_ntf": false, + "topic_prefix": "shellypro3em-aabbccddeeff", + "use_client_cert": false, + "user": null + }, + "sys": { + "cfg_rev": 29, + "debug": { + "file_level": null, + "level": 2, + "mqtt": { + "enable": false + }, + "udp": { + "addr": null + }, + "websocket": { + "enable": false + } + }, + "device": { + "addon_type": null, + "discoverable": true, + "eco_mode": true, + "fw_id": "20231219-134001/1.1.0-g34b5d4f", + "mac": "AABBCCDDEEFF", + "name": "Test Name", + "profile": "triphase" + }, + "location": { + "lat": 45.45803, + "lon": 7.87121, + "tz": "Europe/Rome" + }, + "rpc_udp": { + "dst_addr": null, + "listen_port": null + }, + "sntp": { + "server": "192.168.1.10" + }, + "ui_data": {} + }, + "temperature:0": { + "id": 0, + "name": null, + "offset_C": 0.0, + "report_thr_C": 5.0 + }, + "wifi": "Wifi-Network-Name", + "ws": { + "enable": false, + "server": "ws://192.168.1.10:8123/api/shelly/ws", + "ssl_ca": "*" + } + }, + "shelly": { + "app": "Pro3EM", + "auth_domain": null, + "auth_en": false, + "fw_id": "20231219-134001/1.1.0-g34b5d4f", + "gen": 2, + "id": "shellypro3em-aabbccddeeff", + "mac": "AABBCCDDEEFF", + "model": "SPEM-003CEBEU", + "name": "Test Name", + "profile": "triphase", + "slot": 0, + "ver": "1.1.0" + }, + "status": { + "ble": {}, + "cloud": { + "connected": true + }, + "em:0": { + "a_act_power": 375.5, + "a_aprt_power": 547.4, + "a_current": 2.392, + "a_freq": 50.0, + "a_pf": 0.76, + "a_voltage": 229.0, + "b_act_power": 170.8, + "b_aprt_power": 237.2, + "b_current": 1.037, + "b_freq": 50.0, + "b_pf": 0.78, + "b_voltage": 229.0, + "c_act_power": 12.7, + "c_aprt_power": 97.8, + "c_current": 0.428, + "c_freq": 50.0, + "c_pf": 0.53, + "c_voltage": 229.2, + "id": 0, + "n_current": null, + "total_act_power": 558.965, + "total_aprt_power": 882.413, + "total_current": 3.856, + "user_calibrated_phase": [] + }, + "emdata:0": { + "a_total_act_energy": 2034616.71, + "a_total_act_ret_energy": 0.0, + "b_total_act_energy": 185686.89, + "b_total_act_ret_energy": 40.7, + "c_total_act_energy": 369469.8, + "c_total_act_ret_energy": 985.91, + "id": 0, + "total_act": 2589773.39, + "total_act_ret": 1026.61 + }, + "eth": { + "ip": "192.168.1.105" + }, + "modbus": {}, + "mqtt": { + "connected": false + }, + "sys": { + "available_updates": { + "beta": { + "version": "1.2.0-beta1" + } + }, + "cfg_rev": 29, + "fs_free": 184320, + "fs_size": 524288, + "kvs_rev": 0, + "mac": "AABBCCDDEEFF", + "ram_free": 125084, + "ram_size": 241568, + "reset_reason": 1, + "restart_required": false, + "schedule_rev": 0, + "time": "18:28", + "unixtime": 1707326927, + "uptime": 2085615, + "webhook_rev": 0 + }, + "temperature:0": { + "id": 0, + "tC": 46.6, + "tF": 115.9 + }, + "wifi": { + "rssi": 0, + "ssid": null, + "sta_ip": null, + "status": "disconnected" + }, + "ws": { + "connected": false + } + } +} diff --git a/fixtures/gen2_Shelly Pro 3_SPSW-003XE16EU_20231219-133956-1.1.0-g34b5d4f.json b/fixtures/gen2_Shelly Pro 3_SPSW-003XE16EU_20231219-133956-1.1.0-g34b5d4f.json new file mode 100644 index 00000000..f1db4afa --- /dev/null +++ b/fixtures/gen2_Shelly Pro 3_SPSW-003XE16EU_20231219-133956-1.1.0-g34b5d4f.json @@ -0,0 +1,225 @@ +{ + "config": { + "ble": { + "enable": false, + "observer": { + "enable": false + }, + "rpc": { + "enable": true + } + }, + "cloud": { + "enable": true, + "server": "shelly-9-eu.shelly.cloud:6022/jrpc" + }, + "eth": { + "enable": true, + "gw": null, + "ip": null, + "ipv4mode": "dhcp", + "nameserver": null, + "netmask": null + }, + "input:0": { + "enable": true, + "id": 0, + "invert": false, + "name": "Input Test Name 0", + "type": "switch" + }, + "input:1": { + "enable": true, + "id": 1, + "invert": false, + "name": "Input Test Name 1", + "type": "switch" + }, + "input:2": { + "enable": true, + "id": 2, + "invert": false, + "name": "Input Test Name 2", + "type": "switch" + }, + "mqtt": { + "client_id": "shellypro3-aabbccddeeff", + "enable": false, + "enable_control": true, + "enable_rpc": true, + "rpc_ntf": true, + "server": null, + "ssl_ca": null, + "status_ntf": false, + "topic_prefix": "shellypro3-aabbccddeeff", + "use_client_cert": false, + "user": null + }, + "switch:0": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "id": 0, + "in_mode": "follow", + "initial_state": "match_input", + "name": "Switch Test Name 0" + }, + "switch:1": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "id": 1, + "in_mode": "follow", + "initial_state": "match_input", + "name": "Switch Test Name 1" + }, + "switch:2": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "id": 2, + "in_mode": "follow", + "initial_state": "match_input", + "name": "Switch Test Name 2" + }, + "sys": { + "cfg_rev": 23, + "debug": { + "file_level": null, + "level": 2, + "mqtt": { + "enable": false + }, + "udp": { + "addr": null + }, + "websocket": { + "enable": false + } + }, + "device": { + "discoverable": true, + "eco_mode": true, + "fw_id": "20231219-133956/1.1.0-g34b5d4f", + "mac": "AABBCCDDEEFF", + "name": "Test Name" + }, + "location": { + "lat": 45.4722, + "lon": 9.1922, + "tz": "Europe/Rome" + }, + "rpc_udp": { + "dst_addr": null, + "listen_port": null + }, + "sntp": { + "server": "192.168.1.10" + }, + "ui_data": {} + }, + "wifi": "Wifi-Network-Name", + "ws": { + "enable": false, + "server": null, + "ssl_ca": "ca.pem" + } + }, + "shelly": { + "app": "Pro3", + "auth_domain": null, + "auth_en": false, + "fw_id": "20231219-133956/1.1.0-g34b5d4f", + "gen": 2, + "id": "shellypro3-aabbccddeeff", + "mac": "AABBCCDDEEFF", + "model": "SPSW-003XE16EU", + "name": "Test Name", + "slot": 0, + "ver": "1.1.0" + }, + "status": { + "ble": {}, + "cloud": { + "connected": true + }, + "eth": { + "ip": "192.168.1.106" + }, + "input:0": { + "id": 0, + "state": false + }, + "input:1": { + "id": 1, + "state": false + }, + "input:2": { + "id": 2, + "state": false + }, + "mqtt": { + "connected": false + }, + "switch:0": { + "id": 0, + "output": false, + "source": "WS_in", + "temperature": { + "tC": 37.5, + "tF": 99.5 + } + }, + "switch:1": { + "id": 1, + "output": false, + "source": "WS_in", + "temperature": { + "tC": 37.5, + "tF": 99.5 + } + }, + "switch:2": { + "id": 2, + "output": false, + "source": "WS_in", + "temperature": { + "tC": 37.5, + "tF": 99.5 + } + }, + "sys": { + "available_updates": { + "beta": { + "version": "1.2.0-beta1" + } + }, + "cfg_rev": 23, + "fs_free": 212992, + "fs_size": 524288, + "kvs_rev": 0, + "mac": "AABBCCDDEEFF", + "ram_free": 145828, + "ram_size": 244312, + "reset_reason": 3, + "restart_required": false, + "schedule_rev": 0, + "time": "18:28", + "unixtime": 1707326928, + "uptime": 2084007, + "webhook_rev": 0 + }, + "wifi": { + "rssi": 0, + "ssid": null, + "sta_ip": null, + "status": "disconnected" + }, + "ws": { + "connected": false + } + } +} diff --git a/fixtures/gen2_Shelly Pro 4PM_SPSW-004PE16EU_20230912-082358-1.0.3-g6176478.json b/fixtures/gen2_Shelly Pro 4PM_SPSW-004PE16EU_20230912-082358-1.0.3-g6176478.json new file mode 100644 index 00000000..ce93a251 --- /dev/null +++ b/fixtures/gen2_Shelly Pro 4PM_SPSW-004PE16EU_20230912-082358-1.0.3-g6176478.json @@ -0,0 +1,335 @@ +{ + "config": { + "ble": { + "enable": true, + "observer": { + "enable": false + }, + "rpc": { + "enable": true + } + }, + "cloud": { + "enable": true, + "server": "shelly-91-eu.shelly.cloud:6022/jrpc" + }, + "eth": { + "enable": true, + "gw": null, + "ip": null, + "ipv4mode": "dhcp", + "nameserver": null, + "netmask": null + }, + "input:0": { + "id": 0, + "invert": false, + "name": "input 0", + "type": "switch" + }, + "input:1": { + "id": 1, + "invert": false, + "name": "input 1", + "type": "switch" + }, + "input:2": { + "id": 2, + "invert": false, + "name": "input 2", + "type": "switch" + }, + "input:3": { + "id": 3, + "invert": false, + "name": "input 3", + "type": "switch" + }, + "mqtt": { + "client_id": "shellypro4pm-aabbccddeeff", + "enable": false, + "enable_control": true, + "enable_rpc": true, + "rpc_ntf": true, + "server": "mqtt.test.server", + "status_ntf": false, + "topic_prefix": null, + "use_client_cert": false, + "user": null + }, + "script:1": { + "enable": false, + "id": 1, + "name": "script 1" + }, + "switch:0": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "autorecover_voltage_errors": false, + "current_limit": 16.0, + "id": 0, + "in_mode": "follow", + "initial_state": "match_input", + "name": "switch 0", + "power_limit": 4480, + "undervoltage_limit": 0, + "voltage_limit": 280 + }, + "switch:1": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "autorecover_voltage_errors": false, + "current_limit": 16.0, + "id": 1, + "in_mode": "follow", + "initial_state": "match_input", + "name": "switch 1", + "power_limit": 4480, + "undervoltage_limit": 0, + "voltage_limit": 280 + }, + "switch:2": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "autorecover_voltage_errors": false, + "current_limit": 16.0, + "id": 2, + "in_mode": "follow", + "initial_state": "match_input", + "name": "switch 2", + "power_limit": 4480, + "undervoltage_limit": 0, + "voltage_limit": 280 + }, + "switch:3": { + "auto_off": false, + "auto_off_delay": 60.0, + "auto_on": false, + "auto_on_delay": 60.0, + "autorecover_voltage_errors": false, + "current_limit": 16.0, + "id": 3, + "in_mode": "follow", + "initial_state": "match_input", + "name": "switch 3", + "power_limit": 4480, + "undervoltage_limit": 0, + "voltage_limit": 280 + }, + "sys": { + "cfg_rev": 7, + "debug": { + "file_level": null, + "level": 2, + "mqtt": { + "enable": false + }, + "udp": { + "addr": null + }, + "websocket": { + "enable": false + } + }, + "device": { + "discoverable": true, + "eco_mode": false, + "fw_id": "20230912-082358/1.0.3-g6176478", + "mac": "AABBCCDDEEFF", + "name": "Test Name" + }, + "location": { + "lat": 29.76078, + "lon": -95.36952, + "tz": "America/Chicago" + }, + "rpc_udp": { + "dst_addr": null, + "listen_port": null + }, + "sntp": { + "server": "sntp.test.server" + }, + "ui_data": {} + }, + "ui": { + "idle_brightness": 30 + }, + "wifi": "Wifi-Network-Name", + "ws": { + "enable": false, + "server": null, + "ssl_ca": "ca.pem" + } + }, + "shelly": { + "app": "Pro4PM", + "auth_domain": null, + "auth_en": false, + "fw_id": "20230912-082358/1.0.3-g6176478", + "gen": 2, + "id": "shellypro4pm-aabbccddeeff", + "mac": "AABBCCDDEEFF", + "model": "SPSW-004PE16EU", + "name": "Test Name", + "slot": 0, + "ver": "1.0.3" + }, + "status": { + "ble": {}, + "cloud": { + "connected": true + }, + "eth": { + "ip": null + }, + "input:0": { + "id": 0, + "state": false + }, + "input:1": { + "id": 1, + "state": false + }, + "input:2": { + "id": 2, + "state": false + }, + "input:3": { + "id": 3, + "state": false + }, + "mqtt": { + "connected": false + }, + "script:1": { + "id": 1, + "mem_free": 25200, + "running": false + }, + "switch:0": { + "aenergy": { + "by_minute": [ + 0.0, + 0.0, + 0.0 + ], + "minute_ts": 1708381882, + "total": 0.0 + }, + "apower": 0.0, + "current": 0.0, + "freq": 60.0, + "id": 0, + "output": false, + "pf": 0.0, + "source": "init", + "temperature": { + "tC": 25.6, + "tF": 78.0 + }, + "voltage": 121.7 + }, + "switch:1": { + "aenergy": { + "by_minute": [ + 0.0, + 0.0, + 0.0 + ], + "minute_ts": 1708381882, + "total": 0.0 + }, + "apower": 0.0, + "current": 0.0, + "freq": 60.0, + "id": 1, + "output": false, + "pf": 0.0, + "source": "SHC", + "temperature": { + "tC": 25.6, + "tF": 78.0 + }, + "voltage": 121.8 + }, + "switch:2": { + "aenergy": { + "by_minute": [ + 0.0, + 0.0, + 0.0 + ], + "minute_ts": 1708381882, + "total": 0.0 + }, + "apower": 0.0, + "current": 0.0, + "freq": 60.0, + "id": 2, + "output": false, + "pf": 0.0, + "source": "init", + "temperature": { + "tC": 25.6, + "tF": 78.0 + }, + "voltage": 121.8 + }, + "switch:3": { + "aenergy": { + "by_minute": [ + 0.0, + 0.0, + 0.0 + ], + "minute_ts": 1708381882, + "total": 0.0 + }, + "apower": 0.0, + "current": 0.0, + "freq": 60.0, + "id": 3, + "output": false, + "pf": 0.0, + "source": "init", + "temperature": { + "tC": 25.6, + "tF": 78.0 + }, + "voltage": 121.8 + }, + "sys": { + "available_updates": {}, + "cfg_rev": 7, + "fs_free": 204800, + "fs_size": 524288, + "kvs_rev": 0, + "mac": "AABBCCDDEEFF", + "ram_free": 80320, + "ram_size": 256388, + "restart_required": false, + "schedule_rev": 0, + "time": "16:31", + "unixtime": 1708381883, + "uptime": 522703, + "webhook_rev": 0 + }, + "ui": {}, + "wifi": { + "rssi": -71, + "ssid": "Wifi-Network-Name", + "sta_ip": "192.168.212.172", + "status": "got ip" + }, + "ws": { + "connected": false + } + } +} diff --git a/fixtures/gen2_Shelly Wall Display_SAWD-0A1XX10EU1_20240115-105444-1.2.8-59063a9a.json b/fixtures/gen2_Shelly Wall Display_SAWD-0A1XX10EU1_20240115-105444-1.2.8-59063a9a.json new file mode 100644 index 00000000..ddaa1d69 --- /dev/null +++ b/fixtures/gen2_Shelly Wall Display_SAWD-0A1XX10EU1_20240115-105444-1.2.8-59063a9a.json @@ -0,0 +1,248 @@ +{ + "config": { + "awaiting_auth_code": false, + "ble": { + "enable": false, + "observer": { + "enable": false + }, + "rpc": { + "enable": true + } + }, + "cloud": { + "enable": true, + "server": "shelly-9-eu.shelly.cloud:6022/jrpc" + }, + "humidity:0": { + "id": 0, + "name": null, + "offset": 0, + "report_thr": 1 + }, + "illuminance:0": { + "bright_thr": 200, + "dark_thr": 30, + "id": 0, + "name": null + }, + "input:0": { + "factory_reset": true, + "id": 0, + "invert": false, + "name": "input 0", + "type": "switch" + }, + "mqtt": { + "client_id": "ShellyWallDisplay-AABBCCDDEEFF", + "enable": false, + "server": "mqtt.test.server", + "topic_prefix": "ShellyWallDisplay-AABBCCDDEEFF" + }, + "switch:0": { + "auto_off": false, + "auto_on_delay": 0, + "id": 0, + "in_mode": "follow", + "initial_state": "off", + "name": "switch 0" + }, + "sys": { + "cfg_rev": 32, + "debug": { + "logs": { + "Bluetooth": true, + "Cloud": true, + "Generic": true, + "Interface": true, + "Network": true, + "RPC": true, + "Screen": true, + "Thermostat": true, + "UART": true, + "WebSocket": true, + "Webhooks": true + }, + "mqtt": { + "enable": false + }, + "websocket": { + "enable": true + } + }, + "device": { + "discoverable": false, + "eco_mode": true, + "fw_id": "20240115-105444/1.2.8-59063a9a", + "mac": "AABBCCDDEEFF", + "name": "Test Name" + }, + "location": { + "lat": 45.4722, + "lon": 9.1922, + "tz": "Europe/Rome" + }, + "sntp": { + "server": "sntp.test.server" + } + }, + "temperature:0": { + "id": 0, + "name": null, + "offset_C": 0, + "report_thr_C": 1 + }, + "thermostat:0": { + "actuator": "shelly://shellywalldisplay-aabbccddeeff/c/switch:0", + "display_unit": "C", + "enable": true, + "hysteresis": 1, + "id": 0, + "invert_output": false, + "name": null, + "sensor": "shelly://shellywalldisplay-aabbccddeeff/c/temperature:0", + "target_C": 21, + "type": "heating" + }, + "ui": { + "brightness": { + "auto": true, + "auto_off": { + "by_lux": false, + "enable": true + }, + "level": 0 + }, + "disable_gestures_when_locked": false, + "lock_type": "none", + "relay_state_overlay": { + "always_visible": false, + "enable": true + }, + "screen_off_when_idle": true, + "screen_saver": { + "enable": true, + "show_clock": true, + "show_humidity": true, + "show_temperature": true, + "timeout": 10 + }, + "show_favourites": false, + "show_main_sensor_graph": true, + "use_F": false + }, + "wifi": "Wifi-Network-Name", + "ws": { + "enable": false, + "ssl_ca": "ca.pem" + } + }, + "shelly": { + "app": "WallDisplay", + "app_uptime": 104783, + "auth_en": false, + "available_updates": { + "stable": { + "build_id": "20240115-105444/1.2.8-59063a9a", + "version": "1.2.8" + } + }, + "cfg_rev": 32, + "discoverable": false, + "fw_id": "20240115-105444/1.2.8-59063a9a", + "gen": 2, + "id": "ShellyWallDisplay-AABBCCDDEEFF", + "mac": "AABBCCDDEEFF", + "model": "SAWD-0A1XX10EU1", + "name": "Test Name", + "platform": "vXD10000M2", + "relay_in_thermostat": true, + "restart_required": false, + "schedule_rev": 0, + "sensor_in_thermostat": true, + "unixtime": 1708507954, + "uptime": 3119412, + "ver": "1.2.8", + "webhook_rev": 0 + }, + "status": { + "awaiting_auth_code": false, + "ble": {}, + "cloud": { + "connected": true + }, + "humidity:0": { + "id": 0, + "rh": 43.8 + }, + "illuminance:0": { + "id": 0, + "illumination": "twilight", + "lux": 30 + }, + "input:0": { + "id": 0, + "state": false + }, + "mqtt": { + "connected": false + }, + "switch:0": { + "id": 0, + "output": false, + "source": "THERMOSTAT" + }, + "sys": { + "app": "WallDisplay", + "app_uptime": 104783, + "auth_en": false, + "available_updates": { + "stable": { + "build_id": "20240115-105444/1.2.8-59063a9a", + "version": "1.2.8" + } + }, + "cfg_rev": 32, + "discoverable": false, + "fw_id": "20240115-105444/1.2.8-59063a9a", + "gen": 2, + "id": "ShellyWallDisplay-AABBCCDDEEFF", + "mac": "AABBCCDDEEFF", + "model": "SAWD-0A1XX10EU1", + "platform": "vXD10000M2", + "relay_in_thermostat": true, + "restart_required": false, + "schedule_rev": 0, + "sensor_in_thermostat": true, + "unixtime": 1708507954, + "uptime": 3119412, + "ver": "1.2.8", + "webhook_rev": 0 + }, + "temperature:0": { + "id": 0, + "tC": 21.3, + "tF": 70.4 + }, + "thermostat:0": { + "current_C": 21.3, + "enable": true, + "id": 0, + "output": false, + "schedules": { + "enable": false + }, + "target_C": 21 + }, + "wifi": { + "gw": "192.168.1.1", + "mac": "11:22:33:44:55:66", + "nameserver": "192.168.1.10", + "netmask": "255.255.255.0", + "rssi": -59, + "ssid": "Wifi-Network-Name", + "sta_ip": "192.168.1.78", + "status": "got ip" + } + } +} diff --git a/tools/common.py b/tools/common/__init__.py similarity index 89% rename from tools/common.py rename to tools/common/__init__.py index a78dec3c..67698276 100644 --- a/tools/common.py +++ b/tools/common/__init__.py @@ -2,7 +2,10 @@ """Methods for aioshelly cmdline tools.""" from __future__ import annotations +import sys +from collections.abc import Callable from datetime import datetime +from functools import partial from typing import Any, cast import aiohttp @@ -48,18 +51,19 @@ async def connect_and_print_device( """Connect and print device data.""" device = await create_device(aiohttp_session, options, init, gen) print_device(device) - device.subscribe_updates(device_updated) + device.subscribe_updates(partial(device_updated, action=print_device)) def device_updated( cb_device: BlockDevice | RpcDevice, update_type: BlockUpdateType | RpcUpdateType, + action: Callable[[BlockDevice | RpcDevice], None], ) -> None: """Device updated callback.""" print() print(f"{datetime.now().strftime('%H:%M:%S')} Device updated! ({update_type})") try: - print_device(cb_device) + action(cb_device) except InvalidAuthError: print("Invalid or missing authorization (from async init)") @@ -110,6 +114,13 @@ def print_rpc_device(device: RpcDevice) -> None: print(f"Connected: {device.connected}") +def close_connections(_exit_code: int = 0) -> None: + """Close all connections before exiting.""" + coap_context.close() + ws_context.close() + sys.exit(_exit_code) + + async def update_outbound_ws( options: ConnectionOptions, init: bool, ws_url: str ) -> None: diff --git a/tools/example.py b/tools/example.py index 832edd31..34f6b3cf 100644 --- a/tools/example.py +++ b/tools/example.py @@ -7,10 +7,21 @@ import json import logging import signal -import sys import traceback +from functools import partial +from types import FrameType import aiohttp +from common import ( + close_connections, + coap_context, + connect_and_print_device, + create_device, + device_updated, + print_device, + update_outbound_ws, + ws_context, +) from aioshelly.common import ConnectionOptions from aioshelly.const import WS_API_URL @@ -21,15 +32,6 @@ MacAddressMismatchError, WrongShellyGen, ) -from tools.common import ( - coap_context, - connect_and_print_device, - create_device, - device_updated, - print_device, - update_outbound_ws, - ws_context, -) async def test_single(options: ConnectionOptions, init: bool, gen: int | None) -> None: @@ -55,7 +57,7 @@ async def test_single(options: ConnectionOptions, init: bool, gen: int | None) - print_device(device) - device.subscribe_updates(device_updated) + device.subscribe_updates(partial(device_updated, action=print_device)) while True: await asyncio.sleep(0.1) @@ -199,11 +201,9 @@ async def main() -> None: if args.debug: logging.basicConfig(level="DEBUG", force=True) - def handle_sigint(_exit_code: int) -> None: + def handle_sigint(_exit_code: int, _frame: FrameType) -> None: """Handle Keyboard signal interrupt (ctrl-c).""" - coap_context.close() - ws_context.close() - sys.exit(_exit_code) + close_connections(_exit_code) signal.signal(signal.SIGINT, handle_sigint) # type: ignore [func-returns-value] diff --git a/tools/fixture.py b/tools/fixture.py new file mode 100644 index 00000000..9485f320 --- /dev/null +++ b/tools/fixture.py @@ -0,0 +1,360 @@ +# Run with python3 example.py -h for help +"""aioshelly usage example.""" +from __future__ import annotations + +import argparse +import asyncio +import logging +import signal +import sys +from functools import partial +from pathlib import Path +from types import FrameType +from typing import Any + +import aiohttp +import orjson +from common import close_connections, create_device, device_updated + +from aioshelly.block_device import COAP, BlockDevice +from aioshelly.common import ConnectionOptions +from aioshelly.const import BLOCK_GENERATIONS, MODEL_NAMES, WS_API_URL +from aioshelly.exceptions import ( + DeviceConnectionError, + FirmwareUnsupported, + InvalidAuthError, + MacAddressMismatchError, + WrongShellyGen, +) +from aioshelly.rpc_device import RpcDevice, WsServer + +coap_context = COAP() +ws_context = WsServer() + + +async def connect_and_save( + options: ConnectionOptions, init: bool, gen: int | None +) -> None: + """Save fixture single device.""" + async with aiohttp.ClientSession() as aiohttp_session: + try: + device = await create_device(aiohttp_session, options, init, gen) + except FirmwareUnsupported as err: + print(f"Device firmware not supported, error: {repr(err)}") + return + except InvalidAuthError as err: + print(f"Invalid or missing authorization, error: {repr(err)}") + return + except DeviceConnectionError as err: + print(f"Error connecting to {options.ip_address}, error: {repr(err)}") + return + except MacAddressMismatchError as err: + print(f"MAC address mismatch, error: {repr(err)}") + return + except WrongShellyGen: + print(f"Wrong Shelly generation {gen}, device gen: {2 if gen==1 else 1}") + return + + save_endpoints(device) + + device.subscribe_updates(partial(device_updated, action=save_endpoints)) + + while True: + await asyncio.sleep(0.1) + + +def save_endpoints(device: BlockDevice | RpcDevice) -> None: + """Save device endpoints.""" + data_raw = {"shelly": device.shelly.copy(), "status": device.status.copy()} + + if device.gen in BLOCK_GENERATIONS: + data_raw.update({"settings": device.settings.copy()}) + data_normalized = _redact_block_data(data_raw) + else: + data_raw.update({"config": device.config.copy()}) + data_normalized = _redact_rpc_data(data_raw) + + gen = device.gen + model = device.model + name = MODEL_NAMES.get(model, "Unknown") + version = device.firmware_version.replace("/", "-") + current_path = Path(__file__) + fixture_path = ( + current_path.parent.parent.joinpath("fixtures") + / f"gen{gen}_{name}_{model}_{version}.json" + ) + + print(f"Saving fixture to {fixture_path}") + + with open(fixture_path, "wb") as file: + file.write( + orjson.dumps( # pylint: disable=no-member + data_normalized, + option=orjson.OPT_INDENT_2 # pylint: disable=no-member + | orjson.OPT_SORT_KEYS, # pylint: disable=no-member + ) + ) + file.write(b"\n") + + close_connections() + + +REDACTED_VALUES = { + "wifi": "Wifi-Network-Name", + "wifi_mac": "11:22:33:44:55:66", + "device_mac": "AABBCCDDEEFF", + "device_mac_lower": "aabbccddeeff", + "device_short_mac": "DDEEFF", + "device_short_mac_lower": "ddeeff", + "device_name": "Test Name", + "switch_name": "Switch Test Name", + "input_name": "Input Test Name", + "script_name": "Script Test Name", + "em_name": "Energy Monitor Test Name", + "mqtt_server": "mqtt.test.server", + "sntp_server": "sntp.test.server", + "coiot_peer": "home-assistant.server:8123", +} + + +def _redact_block_data(data: dict[str, Any]) -> dict[str, Any]: + """Redact data for BLOCK devices.""" + status: dict[str, Any] = data["status"] + shelly: dict[str, Any] = data["shelly"] + settings: dict[str, dict[str, dict[str, Any] | str]] = data["settings"] + + real_mac: str = status["mac"] + short_mac: str = status["mac"][6:12] + + # Shelly endpoint + shelly["name"] = REDACTED_VALUES["device_name"] + shelly["mac"] = REDACTED_VALUES["device_mac"] + + # Status endpoint + status["mac"] = REDACTED_VALUES["device_mac"] + + if "ssid" in status["wifi_sta"]: + status["wifi_sta"]["ssid"] = REDACTED_VALUES["wifi"] + + # Config endpoint + + if "peer" in settings["coiot"]: + settings["coiot"]["peer"] = REDACTED_VALUES["coiot_peer"] + + # Some devices use short MAC (uppercase/lowercase) + device = settings["device"] + device["hostname"] = ( + device["hostname"] + .replace(real_mac, REDACTED_VALUES["device_mac"]) + .replace(short_mac, REDACTED_VALUES["device_short_mac"]) + ) + device["mac"] = REDACTED_VALUES["device_mac"] + + # Some devices use MAC and short MAC (uppercase/lowercase) + mqtt = settings["mqtt"] + mqtt["id"] = ( + mqtt["id"] + .replace(real_mac, REDACTED_VALUES["device_mac"]) + .replace(real_mac.lower(), REDACTED_VALUES["device_mac_lower"]) + .replace(short_mac, REDACTED_VALUES["device_short_mac"]) + .replace(short_mac.lower(), REDACTED_VALUES["device_short_mac"].lower()) + ) + + settings["name"] = REDACTED_VALUES["device_name"] + # Some devices use MAC and short MAC (uppercase/lowercase) + settings["wifi_ap"]["ssid"] = ( + settings["wifi_ap"]["ssid"] + .replace(real_mac, REDACTED_VALUES["device_mac"]) + .replace(short_mac, REDACTED_VALUES["device_short_mac"]) + ) + settings["wifi_sta"]["ssid"] = REDACTED_VALUES["wifi"] + + return data + + +def _redact_rpc_data(data: dict[str, Any]) -> dict[str, Any]: + """Redact data for RPC devices.""" + config: dict[str, dict[str, Any] | str] = data["config"] + status: dict[str, dict[str, dict[str, Any] | str] | str] = data["status"] + shelly: dict[str, dict[str, Any] | str] = data["shelly"] + + real_mac: str = status["sys"]["mac"] + device = config["sys"]["device"] + + # Config endpoint + device["name"] = REDACTED_VALUES["device_name"] + device["mac"] = REDACTED_VALUES["device_mac"] + + # Some devices use MAC uppercase, others lowercase + mqtt = config["mqtt"] + mqtt["client_id"] = ( + mqtt["client_id"] + .replace(real_mac, REDACTED_VALUES["device_mac"]) + .replace(real_mac.lower(), REDACTED_VALUES["device_mac_lower"]) + ) + mqtt["server"] = REDACTED_VALUES["mqtt_server"] + + if mqtt.get("topic_prefix"): + # Some devices use MAC uppercase, others lowercase + mqtt["topic_prefix"] = ( + mqtt["topic_prefix"] + .replace(real_mac, REDACTED_VALUES["device_mac"]) + .replace(real_mac.lower(), REDACTED_VALUES["device_mac_lower"]) + ) + + if sntp := config["sys"].get("sntp"): + sntp["server"] = REDACTED_VALUES["sntp_server"] + + config_prefixes = ("switch:", "input:", "em:", "script:") + for key in config: + if key.startswith(config_prefixes): + key_name, id_ = key.split(":") + config[key]["name"] = f"{key_name} {id_}" + + for id_ in range(5): + if thermostat := config.get(f"thermostat:{id_}"): + thermostat["sensor"] = thermostat["sensor"].replace( + real_mac.lower(), REDACTED_VALUES["device_mac_lower"] + ) + thermostat["actuator"] = thermostat["actuator"].replace( + real_mac.lower(), REDACTED_VALUES["device_mac_lower"] + ) + + if "wifi" in config: + config["wifi"] = REDACTED_VALUES["wifi"] + + # Shelly endpoint + shelly["name"] = REDACTED_VALUES["device_name"] + # Some devices use MAC uppercase, others lowercase + shelly["id"] = ( + shelly["id"] + .replace(real_mac, REDACTED_VALUES["device_mac"]) + .replace(real_mac.lower(), REDACTED_VALUES["device_mac_lower"]) + ) + shelly["mac"] = REDACTED_VALUES["device_mac"] + + if auth_domain := shelly.get("auth_domain"): + shelly["auth_domain"] = auth_domain.replace( + real_mac, REDACTED_VALUES["device_mac"] + ).replace(real_mac.lower(), REDACTED_VALUES["device_mac_lower"]) + + # Status endpoint + status["sys"]["mac"] = REDACTED_VALUES["device_mac"] + + if status["wifi"].get("ssid"): + status["wifi"]["ssid"] = REDACTED_VALUES["wifi"] + + if status["wifi"].get("mac"): + status["wifi"]["mac"] = REDACTED_VALUES["wifi_mac"] + + if id_ := status["sys"].get("id"): + # Some devices use MAC uppercase, others lowercase + status["sys"]["id"] = id_.replace( + real_mac, REDACTED_VALUES["device_mac"] + ).replace(real_mac.lower(), REDACTED_VALUES["device_mac_lower"]) + + return data + + +def get_arguments() -> tuple[argparse.ArgumentParser, argparse.Namespace]: + """Get parsed passed in arguments.""" + parser = argparse.ArgumentParser(description="aioshelly example") + parser.add_argument( + "--ip_address", "-ip", type=str, help="Test single device by IP address" + ) + parser.add_argument( + "--coap_port", + "-cp", + type=int, + default=5683, + help="Specify CoAP UDP port (default=5683)", + ) + parser.add_argument( + "--ws_port", + "-wp", + type=int, + default=8123, + help="Specify WebSocket TCP port (default=8123)", + ) + parser.add_argument( + "--ws_api_url", + "-au", + type=str, + default=WS_API_URL, + help=f"Specify WebSocket API URL (default={WS_API_URL})", + ) + parser.add_argument( + "--init", "-i", action="store_true", help="Init device(s) at startup" + ) + parser.add_argument("--username", "-u", type=str, help="Set device username") + parser.add_argument("--password", "-p", type=str, help="Set device password") + + parser.add_argument( + "--gen1", "-g1", action="store_true", help="Force Gen1 (CoAP) device" + ) + parser.add_argument( + "--gen2", "-g2", action="store_true", help="Force Gen 2 (RPC) device" + ) + parser.add_argument( + "--gen3", "-g3", action="store_true", help="Force Gen 3 (RPC) device" + ) + parser.add_argument( + "--debug", "-deb", action="store_true", help="Enable debug level for logging" + ) + parser.add_argument( + "--mac", "-m", type=str, help="Optional device MAC to subscribe for updates" + ) + + arguments = parser.parse_args() + + return parser, arguments + + +async def main() -> None: + """Run main.""" + parser, args = get_arguments() + + await coap_context.initialize(args.coap_port) + await ws_context.initialize(args.ws_port, args.ws_api_url) + + if not args.init and not (args.gen1 or args.gen2 or args.gen3): + parser.error("specify gen if no device init at startup") + if args.gen1 and args.gen2: + parser.error("--gen1 and --gen2 can't be used together") + elif args.gen1 and args.gen3: + parser.error("--gen1 and --gen3 can't be used together") + elif args.gen2 and args.gen3: + parser.error("--gen2 and --gen3 can't be used together") + + gen = None + if args.gen1: + gen = 1 + elif args.gen2: + gen = 2 + elif args.gen3: + gen = 3 + + if args.debug: + logging.basicConfig(level="DEBUG", force=True) + + def handle_sigint(_exit_code: int, _frame: FrameType) -> None: + """Handle Keyboard signal interrupt (ctrl-c).""" + coap_context.close() + ws_context.close() + sys.exit() + + signal.signal(signal.SIGINT, handle_sigint) + + if args.ip_address: + if args.username and args.password is None: + parser.error("--username and --password must be used together") + options = ConnectionOptions( + args.ip_address, args.username, args.password, device_mac=args.mac + ) + await connect_and_save(options, args.init, gen) + else: + parser.error("--ip_address or --devices must be specified") + + +if __name__ == "__main__": + asyncio.run(main())