From 462db36fefaa463bfa84094f48d556dc46d2e48a Mon Sep 17 00:00:00 2001 From: cdnninja Date: Tue, 4 Nov 2025 22:40:35 -0700 Subject: [PATCH] add update platform to vesync (#154915) --- homeassistant/components/vesync/__init__.py | 1 + homeassistant/components/vesync/update.py | 68 + tests/components/vesync/common.py | 11 + tests/components/vesync/conftest.py | 20 +- .../vesync/fixtures/vesync-firmware.json | 301 ++++ .../vesync/snapshots/test_binary_sensor.ambr | 24 +- .../vesync/snapshots/test_diagnostics.ambr | 31 +- .../components/vesync/snapshots/test_fan.ambr | 24 +- .../vesync/snapshots/test_humidifier.ambr | 24 +- .../vesync/snapshots/test_light.ambr | 24 +- .../vesync/snapshots/test_sensor.ambr | 24 +- .../vesync/snapshots/test_switch.ambr | 24 +- .../vesync/snapshots/test_update.ambr | 1239 +++++++++++++++++ tests/components/vesync/test_diagnostics.py | 3 + tests/components/vesync/test_init.py | 2 + tests/components/vesync/test_update.py | 51 + 16 files changed, 1781 insertions(+), 90 deletions(-) create mode 100644 homeassistant/components/vesync/update.py create mode 100644 tests/components/vesync/fixtures/vesync-firmware.json create mode 100644 tests/components/vesync/snapshots/test_update.ambr create mode 100644 tests/components/vesync/test_update.py diff --git a/homeassistant/components/vesync/__init__.py b/homeassistant/components/vesync/__init__.py index 003d93ed6039..5bddf08393f3 100644 --- a/homeassistant/components/vesync/__init__.py +++ b/homeassistant/components/vesync/__init__.py @@ -25,6 +25,7 @@ PLATFORMS = [ Platform.SELECT, Platform.SENSOR, Platform.SWITCH, + Platform.UPDATE, ] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/vesync/update.py b/homeassistant/components/vesync/update.py new file mode 100644 index 000000000000..433da715d5fd --- /dev/null +++ b/homeassistant/components/vesync/update.py @@ -0,0 +1,68 @@ +"""Update entity for VeSync..""" + +from pyvesync.base_devices.vesyncbasedevice import VeSyncBaseDevice + +from homeassistant.components.update import UpdateDeviceClass, UpdateEntity +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback + +from .const import DOMAIN, VS_COORDINATOR, VS_DEVICES, VS_DISCOVERY, VS_MANAGER +from .coordinator import VeSyncDataCoordinator +from .entity import VeSyncBaseEntity + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddConfigEntryEntitiesCallback, +) -> None: + """Set up update entity.""" + coordinator = hass.data[DOMAIN][VS_COORDINATOR] + + @callback + def discover(devices): + """Add new devices to platform.""" + _setup_entities(devices, async_add_entities, coordinator) + + config_entry.async_on_unload( + async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_DEVICES), discover) + ) + + _setup_entities( + hass.data[DOMAIN][VS_MANAGER].devices, async_add_entities, coordinator + ) + + +@callback +def _setup_entities( + devices: list[VeSyncBaseDevice], + async_add_entities: AddConfigEntryEntitiesCallback, + coordinator: VeSyncDataCoordinator, +) -> None: + """Check if device is a light and add entity.""" + + async_add_entities( + VeSyncDeviceUpdate( + device=device, + coordinator=coordinator, + ) + for device in devices + ) + + +class VeSyncDeviceUpdate(VeSyncBaseEntity, UpdateEntity): + """Representation of a VeSync device update entity.""" + + _attr_device_class = UpdateDeviceClass.FIRMWARE + + @property + def installed_version(self) -> str | None: + """Return installed_version.""" + return self.device.current_firm_version + + @property + def latest_version(self) -> str | None: + """Return latest_version.""" + return self.device.latest_firm_version diff --git a/tests/components/vesync/common.py b/tests/components/vesync/common.py index a33edcc48ab8..6b33cf7828cc 100644 --- a/tests/components/vesync/common.py +++ b/tests/components/vesync/common.py @@ -112,6 +112,7 @@ def mock_devices_response( f"https://smartapi.vesync.com{fixture[1]}", json=load_json_object_fixture(fixture[2], DOMAIN), ) + mock_firmware(aioclient_mock) def mock_multiple_device_responses( @@ -148,6 +149,7 @@ def mock_multiple_device_responses( f"https://smartapi.vesync.com{fixture[1]}", json=load_json_object_fixture(fixture[2], DOMAIN), ) + mock_firmware(aioclient_mock) def mock_device_response( @@ -176,6 +178,7 @@ def mock_device_response( f"https://smartapi.vesync.com{item[1]}", json=load_and_merge(item[2]), ) + mock_firmware(aioclient_mock) def mock_outlet_energy_response( @@ -200,3 +203,11 @@ def mock_outlet_energy_response( f"https://smartapi.vesync.com{fixture[1]}", json=load_and_merge(fixture[2]), ) + + +def mock_firmware(aioclient_mock: AiohttpClientMocker): + """Always mock the firmware update info endpoint with the same fixture.""" + aioclient_mock.post( + "https://smartapi.vesync.com/cloud/v2/deviceManaged/getFirmwareUpdateInfoList", + json=load_json_object_fixture("vesync-firmware.json", DOMAIN), + ) diff --git a/tests/components/vesync/conftest.py b/tests/components/vesync/conftest.py index 8b15e7c76d3c..3ff5275ce4aa 100644 --- a/tests/components/vesync/conftest.py +++ b/tests/components/vesync/conftest.py @@ -31,15 +31,6 @@ from tests.common import MockConfigEntry from tests.test_util.aiohttp import AiohttpClientMocker -@pytest.fixture(autouse=True) -def patch_vesync_firmware(): - """Patch VeSync to disable firmware checks.""" - with patch( - "pyvesync.vesync.VeSync.check_firmware", new=AsyncMock(return_value=True) - ): - yield - - @pytest.fixture(autouse=True) def patch_vesync_login(): """Patch VeSync login method.""" @@ -54,13 +45,7 @@ def patch_vesync(): "enabled": True, } - with ( - patch.multiple( - "pyvesync.vesync.VeSync", - check_firmware=AsyncMock(return_value=True), - ), - ExitStack() as stack, - ): + with ExitStack() as stack: for name, value in props.items(): mock = stack.enter_context( patch.object(VeSync, name, new_callable=PropertyMock) @@ -163,6 +148,7 @@ def fan_fixture(): modes=[], connection_status="online", current_firm_version="1.0.0", + latest_firm_version="1.0.1", ) @@ -236,6 +222,7 @@ def humidifier_fixture(): ), connection_status="online", current_firm_version="1.0.0", + latest_firm_version="1.0.1", ) @@ -271,6 +258,7 @@ def humidifier_300s_fixture(): ), config_module="configModule", current_firm_version="1.0.0", + latest_firm_version="1.0.1", ) diff --git a/tests/components/vesync/fixtures/vesync-firmware.json b/tests/components/vesync/fixtures/vesync-firmware.json new file mode 100644 index 000000000000..d27d0e301777 --- /dev/null +++ b/tests/components/vesync/fixtures/vesync-firmware.json @@ -0,0 +1,301 @@ +{ + "traceId": "1234", + "code": 0, + "msg": "request success", + "module": null, + "stacktrace": null, + "result": { + "cidFwInfoList": [ + { + "deviceCid": "200s-humidifier", + "deviceName": "Humidifier 200s", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 100, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "600s-humidifier", + "deviceName": "Humidifier 600S", + "deviceImg": "https://image.vesync.com/defaultImages/LV_600S_Series/icon_lv600s_humidifier_160.png", + "defaultImg": "https://image.vesync.com/defaultImages/LV_600S_Series/icon_lv600s_humidifier_160.png", + "uuid": "00000000-1111-2222-3333-555555555555", + "configModule": "WFON_AHM_LUH-A602S-WUS_US", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 101, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "air-purifier", + "deviceName": "Air Purifier 131s", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 102, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "asd_sdfKIHG7IJHGwJGJ7GJ_ag5h3G55", + "deviceName": "Air Purifier 200s", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 103, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "400s-purifier", + "deviceName": "Air Purifier 400s", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 104, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "600s-purifier", + "deviceName": "Air Purifier 600s", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 105, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "dimmable-bulb", + "deviceName": "Dimmable Light", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 106, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "tunable-bulb", + "deviceName": "Temperature Light", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 107, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "outlet", + "deviceName": "Outlet", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 108, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "switch", + "deviceName": "Wall Switch", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 109, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "dimmable-switch", + "deviceName": "Dimmer Switch", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 110, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + }, + { + "deviceCid": "smarttowerfan", + "deviceName": "SmartTowerFan", + "deviceImg": "", + "defaultImg": "", + "uuid": "00000000-1111-2222-3333-444444444444", + "configModule": "configModule", + "connectionType": "wifi", + "deviceRegion": "US", + "code": 0, + "msg": null, + "firmUpdateInfos": [ + { + "currentVersion": "1.0.0", + "latestVersion": "1.0.1", + "latestFirmId": 111, + "releaseNotes": "Various bug fixes and performance improvements", + "pluginName": "mainFw", + "priority": 0, + "upgradeTimeoutInSec": 180, + "isMainFw": false + } + ] + } + ], + "macIDFwInfoList": null, + "configModelFwInfoList": null + } +} diff --git a/tests/components/vesync/snapshots/test_binary_sensor.ambr b/tests/components/vesync/snapshots/test_binary_sensor.ambr index 6ee31aacdce2..1ab8b44879b9 100644 --- a/tests/components/vesync/snapshots/test_binary_sensor.ambr +++ b/tests/components/vesync/snapshots/test_binary_sensor.ambr @@ -27,7 +27,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -64,7 +64,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -101,7 +101,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -138,7 +138,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -175,7 +175,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -212,7 +212,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -277,7 +277,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -539,7 +539,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -642,7 +642,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -679,7 +679,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -716,7 +716,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -753,7 +753,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) diff --git a/tests/components/vesync/snapshots/test_diagnostics.ambr b/tests/components/vesync/snapshots/test_diagnostics.ambr index 44c30f5ce857..7ced964e3be2 100644 --- a/tests/components/vesync/snapshots/test_diagnostics.ambr +++ b/tests/components/vesync/snapshots/test_diagnostics.ambr @@ -63,7 +63,7 @@ 'get_timer': 'Method', 'is_on': 'Method', 'last_response': 'Method', - 'latest_firm_version': 'Method', + 'latest_firm_version': '1.0.1', 'mac_id': 'Method', 'manager': 'Method', 'method_calls': list([ @@ -385,13 +385,40 @@ }), 'unit_of_measurement': None, }), + dict({ + 'device_class': None, + 'disabled': False, + 'disabled_by': None, + 'domain': 'update', + 'entity_category': 'diagnostic', + 'entity_id': 'update.test_fan_firmware', + 'icon': None, + 'name': None, + 'original_device_class': 'firmware', + 'original_icon': None, + 'original_name': 'Firmware', + 'state': dict({ + 'attributes': dict({ + 'device_class': 'firmware', + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Test Fan Firmware', + 'supported_features': 0, + }), + 'entity_id': 'update.test_fan_firmware', + 'last_changed': str, + 'last_reported': str, + 'last_updated': str, + 'state': 'unavailable', + }), + 'unit_of_measurement': None, + }), ]), 'name': 'Test Fan', 'name_by_user': None, }), 'is_on': 'Method', 'last_response': 'Method', - 'latest_firm_version': 'Method', + 'latest_firm_version': '1.0.1', 'mac_id': 'Method', 'manager': 'Method', 'manual_mode': 'Method', diff --git a/tests/components/vesync/snapshots/test_fan.ambr b/tests/components/vesync/snapshots/test_fan.ambr index 7b33ef94fa4f..3098d7e2a050 100644 --- a/tests/components/vesync/snapshots/test_fan.ambr +++ b/tests/components/vesync/snapshots/test_fan.ambr @@ -27,7 +27,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -127,7 +127,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -226,7 +226,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -327,7 +327,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -428,7 +428,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -465,7 +465,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -502,7 +502,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -576,7 +576,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -613,7 +613,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -650,7 +650,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -754,7 +754,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -791,7 +791,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) diff --git a/tests/components/vesync/snapshots/test_humidifier.ambr b/tests/components/vesync/snapshots/test_humidifier.ambr index 5e5e77cca3fb..9b2b831f132c 100644 --- a/tests/components/vesync/snapshots/test_humidifier.ambr +++ b/tests/components/vesync/snapshots/test_humidifier.ambr @@ -27,7 +27,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -64,7 +64,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -101,7 +101,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -138,7 +138,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -175,7 +175,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -212,7 +212,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -249,7 +249,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -453,7 +453,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -555,7 +555,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -592,7 +592,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -629,7 +629,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -666,7 +666,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) diff --git a/tests/components/vesync/snapshots/test_light.ambr b/tests/components/vesync/snapshots/test_light.ambr index 9560292b1741..6ea053ef3daf 100644 --- a/tests/components/vesync/snapshots/test_light.ambr +++ b/tests/components/vesync/snapshots/test_light.ambr @@ -27,7 +27,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -64,7 +64,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -101,7 +101,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -138,7 +138,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -175,7 +175,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -266,7 +266,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -359,7 +359,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -433,7 +433,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -470,7 +470,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -507,7 +507,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -544,7 +544,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -660,7 +660,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) diff --git a/tests/components/vesync/snapshots/test_sensor.ambr b/tests/components/vesync/snapshots/test_sensor.ambr index 5e3a6958eb02..2a1a51fd51b3 100644 --- a/tests/components/vesync/snapshots/test_sensor.ambr +++ b/tests/components/vesync/snapshots/test_sensor.ambr @@ -27,7 +27,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -160,7 +160,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -247,7 +247,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -431,7 +431,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -615,7 +615,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -652,7 +652,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -689,7 +689,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -865,7 +865,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -953,7 +953,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -1314,7 +1314,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -1351,7 +1351,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -1388,7 +1388,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) diff --git a/tests/components/vesync/snapshots/test_switch.ambr b/tests/components/vesync/snapshots/test_switch.ambr index 89de6fd7720f..8b511e8216cb 100644 --- a/tests/components/vesync/snapshots/test_switch.ambr +++ b/tests/components/vesync/snapshots/test_switch.ambr @@ -27,7 +27,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -156,7 +156,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -285,7 +285,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -414,7 +414,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -543,7 +543,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -580,7 +580,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -617,7 +617,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -783,7 +783,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -866,7 +866,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -950,7 +950,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -1033,7 +1033,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) @@ -1070,7 +1070,7 @@ 'name_by_user': None, 'primary_config_entry': , 'serial_number': None, - 'sw_version': None, + 'sw_version': '1.0.0', 'via_device_id': None, }), ]) diff --git a/tests/components/vesync/snapshots/test_update.ambr b/tests/components/vesync/snapshots/test_update.ambr new file mode 100644 index 000000000000..f532b9ca2f6c --- /dev/null +++ b/tests/components/vesync/snapshots/test_update.ambr @@ -0,0 +1,1239 @@ +# serializer version: 1 +# name: test_update_state[Air Purifier 131s][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + 'air-purifier', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'LV-PUR131S', + 'model_id': None, + 'name': 'Air Purifier 131s', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Air Purifier 131s][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.air_purifier_131s_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'air-purifier', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Air Purifier 131s][update.air_purifier_131s_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Air Purifier 131s Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.air_purifier_131s_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[Air Purifier 200s][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + 'asd_sdfKIHG7IJHGwJGJ7GJ_ag5h3G55', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'Core200S', + 'model_id': None, + 'name': 'Air Purifier 200s', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Air Purifier 200s][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.air_purifier_200s_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'asd_sdfKIHG7IJHGwJGJ7GJ_ag5h3G55', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Air Purifier 200s][update.air_purifier_200s_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Air Purifier 200s Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.air_purifier_200s_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[Air Purifier 400s][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + '400s-purifier', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'LAP-C401S-WJP', + 'model_id': None, + 'name': 'Air Purifier 400s', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Air Purifier 400s][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.air_purifier_400s_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '400s-purifier', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Air Purifier 400s][update.air_purifier_400s_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Air Purifier 400s Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.air_purifier_400s_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[Air Purifier 600s][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + '600s-purifier', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'LAP-C601S-WUS', + 'model_id': None, + 'name': 'Air Purifier 600s', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Air Purifier 600s][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.air_purifier_600s_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '600s-purifier', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Air Purifier 600s][update.air_purifier_600s_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Air Purifier 600s Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.air_purifier_600s_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[Dimmable Light][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + 'dimmable-bulb', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'ESL100', + 'model_id': None, + 'name': 'Dimmable Light', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Dimmable Light][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.dimmable_light_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'dimmable-bulb', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Dimmable Light][update.dimmable_light_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'firmware', + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Dimmable Light Firmware', + 'supported_features': , + }), + 'context': , + 'entity_id': 'update.dimmable_light_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_update_state[Dimmer Switch][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + 'dimmable-switch', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'ESWD16', + 'model_id': None, + 'name': 'Dimmer Switch', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Dimmer Switch][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.dimmer_switch_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'dimmable-switch', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Dimmer Switch][update.dimmer_switch_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Dimmer Switch Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.dimmer_switch_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[Humidifier 200s][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + '200s-humidifier4321', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'Classic200S', + 'model_id': None, + 'name': 'Humidifier 200s', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Humidifier 200s][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.humidifier_200s_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '200s-humidifier4321', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Humidifier 200s][update.humidifier_200s_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Humidifier 200s Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.humidifier_200s_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[Humidifier 6000s][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + '6000s', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'LEH-S601S-WUS', + 'model_id': None, + 'name': 'Humidifier 6000s', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': None, + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Humidifier 6000s][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.humidifier_6000s_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '6000s', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Humidifier 6000s][update.humidifier_6000s_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Humidifier 6000s Firmware', + 'in_progress': False, + 'installed_version': None, + 'latest_version': None, + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.humidifier_6000s_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_update_state[Humidifier 600S][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + '600s-humidifier', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'LUH-A602S-WUS', + 'model_id': None, + 'name': 'Humidifier 600S', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Humidifier 600S][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.humidifier_600s_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '600s-humidifier', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Humidifier 600S][update.humidifier_600s_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Humidifier 600S Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.humidifier_600s_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[Outlet][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + 'outlet', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'wifi-switch-1.3', + 'model_id': None, + 'name': 'Outlet', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Outlet][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.outlet_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'outlet', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Outlet][update.outlet_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Outlet Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.outlet_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[SmartTowerFan][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + 'smarttowerfan', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'LTF-F422S-KEU', + 'model_id': None, + 'name': 'SmartTowerFan', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[SmartTowerFan][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.smarttowerfan_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'smarttowerfan', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[SmartTowerFan][update.smarttowerfan_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'SmartTowerFan Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.smarttowerfan_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[Temperature Light][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + 'tunable-bulb', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'ESL100CW', + 'model_id': None, + 'name': 'Temperature Light', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Temperature Light][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.temperature_light_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'tunable-bulb', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Temperature Light][update.temperature_light_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Temperature Light Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.temperature_light_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_update_state[Wall Switch][devices] + list([ + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'vesync', + 'switch', + ), + }), + 'labels': set({ + }), + 'manufacturer': 'VeSync', + 'model': 'ESWL01', + 'model_id': None, + 'name': 'Wall Switch', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': '1.0.0', + 'via_device_id': None, + }), + ]) +# --- +# name: test_update_state[Wall Switch][entities] + list([ + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'update', + 'entity_category': , + 'entity_id': 'update.wall_switch_firmware', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Firmware', + 'platform': 'vesync', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'switch', + 'unit_of_measurement': None, + }), + ]) +# --- +# name: test_update_state[Wall Switch][update.wall_switch_firmware] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'auto_update': False, + 'device_class': 'firmware', + 'display_precision': 0, + 'entity_picture': 'https://brands.home-assistant.io/_/vesync/icon.png', + 'friendly_name': 'Wall Switch Firmware', + 'in_progress': False, + 'installed_version': '1.0.0', + 'latest_version': '1.0.1', + 'release_summary': None, + 'release_url': None, + 'skipped_version': None, + 'supported_features': , + 'title': None, + 'update_percentage': None, + }), + 'context': , + 'entity_id': 'update.wall_switch_firmware', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- diff --git a/tests/components/vesync/test_diagnostics.py b/tests/components/vesync/test_diagnostics.py index 7929d838fbeb..4cbf733022ab 100644 --- a/tests/components/vesync/test_diagnostics.py +++ b/tests/components/vesync/test_diagnostics.py @@ -110,6 +110,9 @@ async def test_async_get_device_diagnostics__single_fan( "home_assistant.entities.7.state.last_changed": (str,), "home_assistant.entities.7.state.last_reported": (str,), "home_assistant.entities.7.state.last_updated": (str,), + "home_assistant.entities.8.state.last_updated": (str,), + "home_assistant.entities.8.state.last_changed": (str,), + "home_assistant.entities.8.state.last_reported": (str,), } ) ) diff --git a/tests/components/vesync/test_init.py b/tests/components/vesync/test_init.py index de6aa358e76b..ae0c96f382ea 100644 --- a/tests/components/vesync/test_init.py +++ b/tests/components/vesync/test_init.py @@ -51,6 +51,7 @@ async def test_async_setup_entry__no_devices( Platform.SELECT, Platform.SENSOR, Platform.SWITCH, + Platform.UPDATE, ] assert manager.login.call_count == 1 @@ -79,6 +80,7 @@ async def test_async_setup_entry__loads_fans( Platform.SELECT, Platform.SENSOR, Platform.SWITCH, + Platform.UPDATE, ] assert manager.login.call_count == 1 assert hass.data[DOMAIN][VS_MANAGER] == manager diff --git a/tests/components/vesync/test_update.py b/tests/components/vesync/test_update.py new file mode 100644 index 000000000000..700659c0da42 --- /dev/null +++ b/tests/components/vesync/test_update.py @@ -0,0 +1,51 @@ +"""Tests for the update module.""" + +import pytest +from syrupy.assertion import SnapshotAssertion + +from homeassistant.components.update import DOMAIN as UPDATE_DOMAIN +from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr, entity_registry as er + +from .common import ALL_DEVICE_NAMES, mock_devices_response + +from tests.common import MockConfigEntry +from tests.test_util.aiohttp import AiohttpClientMocker + + +@pytest.mark.parametrize("device_name", ALL_DEVICE_NAMES) +async def test_update_state( + hass: HomeAssistant, + snapshot: SnapshotAssertion, + config_entry: MockConfigEntry, + device_registry: dr.DeviceRegistry, + entity_registry: er.EntityRegistry, + aioclient_mock: AiohttpClientMocker, + device_name: str, +) -> None: + """Test the resulting setup state is as expected for the platform.""" + + # Configure the API devices call for device_name + mock_devices_response(aioclient_mock, device_name) + + # setup platform - only including the named device + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + # Check device registry + devices = dr.async_entries_for_config_entry(device_registry, config_entry.entry_id) + assert devices == snapshot(name="devices") + + # Check entity registry + entities = [ + entity + for entity in er.async_entries_for_config_entry( + entity_registry, config_entry.entry_id + ) + if entity.domain == UPDATE_DOMAIN + ] + assert entities == snapshot(name="entities") + + # Check states + for entity in entities: + assert hass.states.get(entity.entity_id) == snapshot(name=entity.entity_id)