diff --git a/homeassistant/auth/auth_store.py b/homeassistant/auth/auth_store.py index 1c2e8b0dfab81..429aad09edb79 100644 --- a/homeassistant/auth/auth_store.py +++ b/homeassistant/auth/auth_store.py @@ -120,6 +120,9 @@ async def async_create_user( new_user = models.User(**kwargs) + while new_user.id in self._users: + new_user = models.User(**kwargs) + self._users[new_user.id] = new_user if credentials is None: diff --git a/homeassistant/components/caldav/manifest.json b/homeassistant/components/caldav/manifest.json index d0e0bd0b1d04e..3b201c79e0cbb 100644 --- a/homeassistant/components/caldav/manifest.json +++ b/homeassistant/components/caldav/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/caldav", "iot_class": "cloud_polling", "loggers": ["caldav", "vobject"], - "requirements": ["caldav==1.6.0", "icalendar==6.1.0"] + "requirements": ["caldav==1.6.0", "icalendar==6.3.1"] } diff --git a/homeassistant/components/ecovacs/manifest.json b/homeassistant/components/ecovacs/manifest.json index ceb7a1da9de91..ddd464bdc6a57 100644 --- a/homeassistant/components/ecovacs/manifest.json +++ b/homeassistant/components/ecovacs/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/ecovacs", "iot_class": "cloud_push", "loggers": ["sleekxmppfs", "sucks", "deebot_client"], - "requirements": ["py-sucks==0.9.11", "deebot-client==13.5.0"] + "requirements": ["py-sucks==0.9.11", "deebot-client==13.6.0"] } diff --git a/homeassistant/components/husqvarna_automower/manifest.json b/homeassistant/components/husqvarna_automower/manifest.json index a0f25b1df4cac..49eb364858fa9 100644 --- a/homeassistant/components/husqvarna_automower/manifest.json +++ b/homeassistant/components/husqvarna_automower/manifest.json @@ -8,5 +8,5 @@ "iot_class": "cloud_push", "loggers": ["aioautomower"], "quality_scale": "silver", - "requirements": ["aioautomower==2.1.1"] + "requirements": ["aioautomower==2.1.2"] } diff --git a/homeassistant/components/knx/manifest.json b/homeassistant/components/knx/manifest.json index 6a4565dde0ea1..f40fa028e88ec 100644 --- a/homeassistant/components/knx/manifest.json +++ b/homeassistant/components/knx/manifest.json @@ -13,7 +13,7 @@ "requirements": [ "xknx==3.8.0", "xknxproject==3.8.2", - "knx-frontend==2025.7.23.50952" + "knx-frontend==2025.8.4.154919" ], "single_config_entry": true } diff --git a/homeassistant/components/matter/number.py b/homeassistant/components/matter/number.py index 4456496d52ec9..d2184891dc1be 100644 --- a/homeassistant/components/matter/number.py +++ b/homeassistant/components/matter/number.py @@ -285,7 +285,9 @@ def _update_from_device(self) -> None: native_min_value=0.5, native_step=0.5, device_to_ha=( - lambda x: None if x is None else x / 2 # Matter range (1-200) + lambda x: None + if x is None + else min(x, 200) / 2 # Matter range (1-200, capped at 200) ), ha_to_device=lambda x: round(x * 2), # HA range 0.5–100.0% mode=NumberMode.SLIDER, diff --git a/homeassistant/components/tuya/fan.py b/homeassistant/components/tuya/fan.py index 90f4132cef075..056107d313f6a 100644 --- a/homeassistant/components/tuya/fan.py +++ b/homeassistant/components/tuya/fan.py @@ -45,6 +45,8 @@ "ks", } +_SWITCH_DP_CODES = (DPCode.SWITCH_FAN, DPCode.FAN_SWITCH, DPCode.SWITCH) + async def async_setup_entry( hass: HomeAssistant, @@ -60,7 +62,9 @@ def async_discover_device(device_ids: list[str]) -> None: entities: list[TuyaFanEntity] = [] for device_id in device_ids: device = hass_data.manager.device_map[device_id] - if device and device.category in TUYA_SUPPORT_TYPE: + if device.category in TUYA_SUPPORT_TYPE and any( + code in device.status for code in _SWITCH_DP_CODES + ): entities.append(TuyaFanEntity(device, hass_data.manager)) async_add_entities(entities) @@ -90,9 +94,7 @@ def __init__( """Init Tuya Fan Device.""" super().__init__(device, device_manager) - self._switch = self.find_dpcode( - (DPCode.SWITCH_FAN, DPCode.FAN_SWITCH, DPCode.SWITCH), prefer_function=True - ) + self._switch = self.find_dpcode(_SWITCH_DP_CODES, prefer_function=True) self._attr_preset_modes = [] if enum_type := self.find_dpcode( diff --git a/homeassistant/components/zwave_js/__init__.py b/homeassistant/components/zwave_js/__init__.py index 923cd776f9241..af42f024e6ac0 100644 --- a/homeassistant/components/zwave_js/__init__.py +++ b/homeassistant/components/zwave_js/__init__.py @@ -509,7 +509,7 @@ async def async_on_node_added(self, node: ZwaveNode) -> None: ) ) - await self.async_check_preprovisioned_device(node) + await self.async_check_pre_provisioned_device(node) if node.is_controller_node: # Create a controller status sensor for each device @@ -637,8 +637,8 @@ def async_on_identify(self, event: dict) -> None: f"{DOMAIN}.identify_controller.{dev_id[1]}", ) - async def async_check_preprovisioned_device(self, node: ZwaveNode) -> None: - """Check if the node was preprovisioned and update the device registry.""" + async def async_check_pre_provisioned_device(self, node: ZwaveNode) -> None: + """Check if the node was pre-provisioned and update the device registry.""" provisioning_entry = ( await self.driver_events.driver.controller.async_get_provisioning_entry( node.node_id @@ -648,29 +648,37 @@ async def async_check_preprovisioned_device(self, node: ZwaveNode) -> None: provisioning_entry and provisioning_entry.additional_properties and "device_id" in provisioning_entry.additional_properties - ): - preprovisioned_device = self.dev_reg.async_get( - provisioning_entry.additional_properties["device_id"] + and ( + pre_provisioned_device := self.dev_reg.async_get( + provisioning_entry.additional_properties["device_id"] + ) ) - - if preprovisioned_device: - dsk = provisioning_entry.dsk - dsk_identifier = (DOMAIN, f"provision_{dsk}") - - # If the pre-provisioned device has the DSK identifier, remove it - if dsk_identifier in preprovisioned_device.identifiers: - driver = self.driver_events.driver - device_id = get_device_id(driver, node) - device_id_ext = get_device_id_ext(driver, node) - new_identifiers = preprovisioned_device.identifiers.copy() - new_identifiers.remove(dsk_identifier) - new_identifiers.add(device_id) - if device_id_ext: - new_identifiers.add(device_id_ext) - self.dev_reg.async_update_device( - preprovisioned_device.id, - new_identifiers=new_identifiers, - ) + and (dsk_identifier := (DOMAIN, f"provision_{provisioning_entry.dsk}")) + in pre_provisioned_device.identifiers + ): + driver = self.driver_events.driver + device_id = get_device_id(driver, node) + device_id_ext = get_device_id_ext(driver, node) + new_identifiers = pre_provisioned_device.identifiers.copy() + new_identifiers.remove(dsk_identifier) + new_identifiers.add(device_id) + if device_id_ext: + new_identifiers.add(device_id_ext) + + if self.dev_reg.async_get_device(identifiers=new_identifiers): + # If a device entry is registered with the node ID based identifiers, + # just remove the device entry with the DSK identifier. + self.dev_reg.async_update_device( + pre_provisioned_device.id, + remove_config_entry_id=self.config_entry.entry_id, + ) + else: + # Add the node ID based identifiers to the device entry + # with the DSK identifier and remove the DSK identifier. + self.dev_reg.async_update_device( + pre_provisioned_device.id, + new_identifiers=new_identifiers, + ) async def async_register_node_in_dev_reg(self, node: ZwaveNode) -> dr.DeviceEntry: """Register node in dev reg.""" diff --git a/requirements_all.txt b/requirements_all.txt index 2b07456128b81..6c3b27b3fe539 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -204,7 +204,7 @@ aioaseko==1.0.0 aioasuswrt==1.4.0 # homeassistant.components.husqvarna_automower -aioautomower==2.1.1 +aioautomower==2.1.2 # homeassistant.components.azure_devops aioazuredevops==2.2.1 @@ -777,7 +777,7 @@ decora-wifi==1.4 # decora==0.6 # homeassistant.components.ecovacs -deebot-client==13.5.0 +deebot-client==13.6.0 # homeassistant.components.ihc # homeassistant.components.namecheapdns @@ -1216,7 +1216,7 @@ ibmiotf==0.3.4 ical==11.0.0 # homeassistant.components.caldav -icalendar==6.1.0 +icalendar==6.3.1 # homeassistant.components.ping icmplib==3.0 @@ -1307,7 +1307,7 @@ kiwiki-client==0.1.1 knocki==0.4.2 # homeassistant.components.knx -knx-frontend==2025.7.23.50952 +knx-frontend==2025.8.4.154919 # homeassistant.components.konnected konnected==1.2.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 750be1cb2bee7..5443891fc18bb 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -192,7 +192,7 @@ aioaseko==1.0.0 aioasuswrt==1.4.0 # homeassistant.components.husqvarna_automower -aioautomower==2.1.1 +aioautomower==2.1.2 # homeassistant.components.azure_devops aioazuredevops==2.2.1 @@ -677,7 +677,7 @@ debugpy==1.8.14 # decora==0.6 # homeassistant.components.ecovacs -deebot-client==13.5.0 +deebot-client==13.6.0 # homeassistant.components.ihc # homeassistant.components.namecheapdns @@ -1056,7 +1056,7 @@ ibeacon-ble==1.2.0 ical==11.0.0 # homeassistant.components.caldav -icalendar==6.1.0 +icalendar==6.3.1 # homeassistant.components.ping icmplib==3.0 @@ -1129,7 +1129,7 @@ kegtron-ble==0.4.0 knocki==0.4.2 # homeassistant.components.knx -knx-frontend==2025.7.23.50952 +knx-frontend==2025.8.4.154919 # homeassistant.components.konnected konnected==1.2.0 diff --git a/tests/auth/test_auth_store.py b/tests/auth/test_auth_store.py index 65bc35a5ff81e..e5d3cf04a37c3 100644 --- a/tests/auth/test_auth_store.py +++ b/tests/auth/test_auth_store.py @@ -2,7 +2,7 @@ import asyncio from typing import Any -from unittest.mock import patch +from unittest.mock import PropertyMock, patch from freezegun.api import FrozenDateTimeFactory import pytest @@ -300,6 +300,20 @@ async def test_loading_does_not_write_right_away( assert hass_storage[auth_store.STORAGE_KEY] != {} +async def test_duplicate_uuid( + hass: HomeAssistant, hass_storage: dict[str, Any] +) -> None: + """Test we don't override user if we have a duplicate user ID.""" + hass_storage[auth_store.STORAGE_KEY] = MOCK_STORAGE_DATA + store = auth_store.AuthStore(hass) + await store.async_load() + with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex_mock: + hex_mock.side_effect = ["user-id", "new-id"] + user = await store.async_create_user("Test User") + assert len(hex_mock.mock_calls) == 2 + assert user.id == "new-id" + + async def test_add_remove_user_affects_tokens( hass: HomeAssistant, hass_storage: dict[str, Any] ) -> None: diff --git a/tests/components/matter/fixtures/nodes/pump.json b/tests/components/matter/fixtures/nodes/pump.json index e4afc0b4f33d8..6d74b3d1b89c1 100644 --- a/tests/components/matter/fixtures/nodes/pump.json +++ b/tests/components/matter/fixtures/nodes/pump.json @@ -203,7 +203,7 @@ "1/6/65528": [], "1/6/65529": [0, 1, 2], "1/6/65531": [0, 65532, 65533, 65528, 65529, 65531], - "1/8/0": 254, + "1/8/0": 200, "1/8/15": 0, "1/8/17": 0, "1/8/65532": 0, diff --git a/tests/components/matter/snapshots/test_number.ambr b/tests/components/matter/snapshots/test_number.ambr index f7f467b4ed0a3..24a92799082fb 100644 --- a/tests/components/matter/snapshots/test_number.ambr +++ b/tests/components/matter/snapshots/test_number.ambr @@ -2189,7 +2189,7 @@ 'last_changed': , 'last_reported': , 'last_updated': , - 'state': '127.0', + 'state': '100.0', }) # --- # name: test_numbers[silabs_laundrywasher][number.laundrywasher_temperature_setpoint-entry] diff --git a/tests/components/matter/test_number.py b/tests/components/matter/test_number.py index b59e6848f6317..d35a889a436db 100644 --- a/tests/components/matter/test_number.py +++ b/tests/components/matter/test_number.py @@ -172,7 +172,7 @@ async def test_pump_level( # CurrentLevel on LevelControl cluster state = hass.states.get("number.mock_pump_setpoint") assert state - assert state.state == "127.0" + assert state.state == "100.0" set_node_attribute(matter_node, 1, 8, 0, 100) await trigger_subscription_callback(hass, matter_client) diff --git a/tests/components/tuya/__init__.py b/tests/components/tuya/__init__.py index a66bd3141853a..04fe034bb61c2 100644 --- a/tests/components/tuya/__init__.py +++ b/tests/components/tuya/__init__.py @@ -43,7 +43,7 @@ ], "cs_vmxuxszzjwp5smli": [ # https://github.com/home-assistant/core/issues/119865 - Platform.FAN, + # Platform.FAN, missing DPCodes in device status Platform.HUMIDIFIER, ], "cs_zibqa9dutqyaxym2": [ @@ -214,6 +214,10 @@ # https://github.com/home-assistant/core/issues/143499 Platform.SENSOR, ], + "fs_ibytpo6fpnugft1c": [ + # https://github.com/home-assistant/core/issues/135541 + # Platform.FAN, missing DPCodes in device status + ], "gyd_lgekqfxdabipm3tn": [ # https://github.com/home-assistant/core/issues/133173 Platform.LIGHT, @@ -294,6 +298,15 @@ Platform.BINARY_SENSOR, Platform.SENSOR, ], + "sd_lr33znaodtyarrrz": [ + # https://github.com/home-assistant/core/issues/141278 + Platform.BUTTON, + Platform.NUMBER, + Platform.SELECT, + Platform.SENSOR, + Platform.SWITCH, + Platform.VACUUM, + ], "sfkzq_o6dagifntoafakst": [ # https://github.com/home-assistant/core/issues/148116 Platform.SWITCH, diff --git a/tests/components/tuya/fixtures/clkg_nhyj64w2.json b/tests/components/tuya/fixtures/clkg_nhyj64w2.json index 28e3248f8b5e6..0f64bae778f5e 100644 --- a/tests/components/tuya/fixtures/clkg_nhyj64w2.json +++ b/tests/components/tuya/fixtures/clkg_nhyj64w2.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1729466466688hgsTp2", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/co2bj_yrr3eiyiacm31ski.json b/tests/components/tuya/fixtures/co2bj_yrr3eiyiacm31ski.json index 8d7e744fb5217..fb544fb7d5ec1 100644 --- a/tests/components/tuya/fixtures/co2bj_yrr3eiyiacm31ski.json +++ b/tests/components/tuya/fixtures/co2bj_yrr3eiyiacm31ski.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaus.com", - "terminal_id": "1732306182276g6jQLp", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/cs_ka2wfrdoogpvgzfi.json b/tests/components/tuya/fixtures/cs_ka2wfrdoogpvgzfi.json index 8a2fd881262e7..755b46fa397f7 100644 --- a/tests/components/tuya/fixtures/cs_ka2wfrdoogpvgzfi.json +++ b/tests/components/tuya/fixtures/cs_ka2wfrdoogpvgzfi.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "mock_terminal_id", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/cs_vmxuxszzjwp5smli.json b/tests/components/tuya/fixtures/cs_vmxuxszzjwp5smli.json index ff922f506c5cd..27d4e825ab16b 100644 --- a/tests/components/tuya/fixtures/cs_vmxuxszzjwp5smli.json +++ b/tests/components/tuya/fixtures/cs_vmxuxszzjwp5smli.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "mock_terminal_id", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/cwjwq_agwu93lr.json b/tests/components/tuya/fixtures/cwjwq_agwu93lr.json index a4a9fc6aaffc3..84f769083384d 100644 --- a/tests/components/tuya/fixtures/cwjwq_agwu93lr.json +++ b/tests/components/tuya/fixtures/cwjwq_agwu93lr.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1750837476328i3TNXQ", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/cwwsq_wfkzyy0evslzsmoi.json b/tests/components/tuya/fixtures/cwwsq_wfkzyy0evslzsmoi.json index ec6f3ce512277..4bdd6f3167d12 100644 --- a/tests/components/tuya/fixtures/cwwsq_wfkzyy0evslzsmoi.json +++ b/tests/components/tuya/fixtures/cwwsq_wfkzyy0evslzsmoi.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1747045731408d0tb5M", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/cwysj_z3rpyvznfcch99aa.json b/tests/components/tuya/fixtures/cwysj_z3rpyvznfcch99aa.json index 0f5e5e5f2419a..695da229041f5 100644 --- a/tests/components/tuya/fixtures/cwysj_z3rpyvznfcch99aa.json +++ b/tests/components/tuya/fixtures/cwysj_z3rpyvznfcch99aa.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1751729689584Vh0VoL", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/cz_2jxesipczks0kdct.json b/tests/components/tuya/fixtures/cz_2jxesipczks0kdct.json index 9cd3c4ffd6f8e..27c3ae0c37f4b 100644 --- a/tests/components/tuya/fixtures/cz_2jxesipczks0kdct.json +++ b/tests/components/tuya/fixtures/cz_2jxesipczks0kdct.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaus.com", - "terminal_id": "1742695000703Ozq34h", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/dlq_kxdr6su0c55p7bbo.json b/tests/components/tuya/fixtures/dlq_kxdr6su0c55p7bbo.json index 8e9a06cc9a9d4..2652399bdcb20 100644 --- a/tests/components/tuya/fixtures/dlq_kxdr6su0c55p7bbo.json +++ b/tests/components/tuya/fixtures/dlq_kxdr6su0c55p7bbo.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1733006572651YokbqV", + "terminal_id": "REDACTED", "mqtt_connected": null, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/fs_ibytpo6fpnugft1c.json b/tests/components/tuya/fixtures/fs_ibytpo6fpnugft1c.json new file mode 100644 index 0000000000000..02b3808f84d15 --- /dev/null +++ b/tests/components/tuya/fixtures/fs_ibytpo6fpnugft1c.json @@ -0,0 +1,23 @@ +{ + "endpoint": "https://apigw.tuyaeu.com", + "terminal_id": "REDACTED", + "mqtt_connected": true, + "disabled_by": null, + "disabled_polling": false, + "id": "10706550a4e57c88b93a", + "name": "Ventilador Cama", + "category": "fs", + "product_id": "ibytpo6fpnugft1c", + "product_name": "Tower bladeless fan ", + "online": true, + "sub": false, + "time_zone": "+01:00", + "active_time": "2025-01-10T18:47:46+00:00", + "create_time": "2025-01-10T18:47:46+00:00", + "update_time": "2025-01-10T18:47:46+00:00", + "function": {}, + "status_range": {}, + "status": {}, + "set_up": true, + "support_local": true +} diff --git a/tests/components/tuya/fixtures/gyd_lgekqfxdabipm3tn.json b/tests/components/tuya/fixtures/gyd_lgekqfxdabipm3tn.json index 28f2b8e8f464e..ddfbce3ae1199 100644 --- a/tests/components/tuya/fixtures/gyd_lgekqfxdabipm3tn.json +++ b/tests/components/tuya/fixtures/gyd_lgekqfxdabipm3tn.json @@ -1,10 +1,9 @@ { "endpoint": "https://apigw.tuyaus.com", - "terminal_id": "1732306182276g6jQLp", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, - "id": "eb3e988f33c233290cfs3l", "name": "Colorful PIR Night Light", "category": "gyd", diff --git a/tests/components/tuya/fixtures/kg_gbm9ata1zrzaez4a.json b/tests/components/tuya/fixtures/kg_gbm9ata1zrzaez4a.json index 63d9148afbf6a..a190161953b7f 100644 --- a/tests/components/tuya/fixtures/kg_gbm9ata1zrzaez4a.json +++ b/tests/components/tuya/fixtures/kg_gbm9ata1zrzaez4a.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaus.com", - "terminal_id": "1750526976566fMhqJs", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": true, diff --git a/tests/components/tuya/fixtures/kj_yrzylxax1qspdgpp.json b/tests/components/tuya/fixtures/kj_yrzylxax1qspdgpp.json index 909022793ba9f..642ef9686082a 100644 --- a/tests/components/tuya/fixtures/kj_yrzylxax1qspdgpp.json +++ b/tests/components/tuya/fixtures/kj_yrzylxax1qspdgpp.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "CENSORED", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/ks_j9fa8ahzac8uvlfl.json b/tests/components/tuya/fixtures/ks_j9fa8ahzac8uvlfl.json index 071596e8e6ce7..cb158a967b4cb 100644 --- a/tests/components/tuya/fixtures/ks_j9fa8ahzac8uvlfl.json +++ b/tests/components/tuya/fixtures/ks_j9fa8ahzac8uvlfl.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "mock_terminal_id", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/kt_5wnlzekkstwcdsvm.json b/tests/components/tuya/fixtures/kt_5wnlzekkstwcdsvm.json index 8fa2d7b0512e1..5b29fd0a1913c 100644 --- a/tests/components/tuya/fixtures/kt_5wnlzekkstwcdsvm.json +++ b/tests/components/tuya/fixtures/kt_5wnlzekkstwcdsvm.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "mock_terminal_id", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/qccdz_7bvgooyjhiua1yyq.json b/tests/components/tuya/fixtures/qccdz_7bvgooyjhiua1yyq.json index 1ae5e966de7c0..6cae732aedf0e 100644 --- a/tests/components/tuya/fixtures/qccdz_7bvgooyjhiua1yyq.json +++ b/tests/components/tuya/fixtures/qccdz_7bvgooyjhiua1yyq.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1737479380414pasuj4", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/qxj_fsea1lat3vuktbt6.json b/tests/components/tuya/fixtures/qxj_fsea1lat3vuktbt6.json index c52086213fd69..c538630c542b1 100644 --- a/tests/components/tuya/fixtures/qxj_fsea1lat3vuktbt6.json +++ b/tests/components/tuya/fixtures/qxj_fsea1lat3vuktbt6.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1751921699759JsVujI", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/qxj_is2indt9nlth6esa.json b/tests/components/tuya/fixtures/qxj_is2indt9nlth6esa.json index caccb0b923481..efffe12a2f946 100644 --- a/tests/components/tuya/fixtures/qxj_is2indt9nlth6esa.json +++ b/tests/components/tuya/fixtures/qxj_is2indt9nlth6esa.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1708196692712PHOeqy", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/rqbj_4iqe2hsfyd86kwwc.json b/tests/components/tuya/fixtures/rqbj_4iqe2hsfyd86kwwc.json index 58cbaedb0f198..24b4dbda5949c 100644 --- a/tests/components/tuya/fixtures/rqbj_4iqe2hsfyd86kwwc.json +++ b/tests/components/tuya/fixtures/rqbj_4iqe2hsfyd86kwwc.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaus.com", - "terminal_id": "17421891051898r7yM6", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/sd_lr33znaodtyarrrz.json b/tests/components/tuya/fixtures/sd_lr33znaodtyarrrz.json new file mode 100644 index 0000000000000..77d94cb951b12 --- /dev/null +++ b/tests/components/tuya/fixtures/sd_lr33znaodtyarrrz.json @@ -0,0 +1,476 @@ +{ + "endpoint": "https://apigw.tuyaeu.com", + "terminal_id": "REDACTED", + "mqtt_connected": true, + "disabled_by": null, + "disabled_polling": false, + "id": "bfa951ca98fcf64fddqlmt", + "name": "V20", + "category": "sd", + "product_id": "lr33znaodtyarrrz", + "product_name": "V20", + "online": true, + "sub": false, + "time_zone": "+01:00", + "active_time": "2025-03-23T16:37:02+00:00", + "create_time": "2025-03-23T16:37:02+00:00", + "update_time": "2025-03-23T16:37:02+00:00", + "function": { + "power_go": { + "type": "Boolean", + "value": {} + }, + "pause": { + "type": "Boolean", + "value": {} + }, + "switch_charge": { + "type": "Boolean", + "value": {} + }, + "mode": { + "type": "Enum", + "value": { + "range": ["smart", "zone", "pose", "part"] + } + }, + "suction": { + "type": "Enum", + "value": { + "range": ["gentle", "normal", "strong"] + } + }, + "cistern": { + "type": "Enum", + "value": { + "range": ["low", "middle", "high"] + } + }, + "seek": { + "type": "Boolean", + "value": {} + }, + "direction_control": { + "type": "Enum", + "value": { + "range": ["forward", "turn_left", "turn_right", "stop"] + } + }, + "reset_map": { + "type": "Boolean", + "value": {} + }, + "path_data": { + "type": "Raw", + "value": {} + }, + "command_trans": { + "type": "Raw", + "value": {} + }, + "request": { + "type": "Enum", + "value": { + "range": ["get_map", "get_path", "get_both"] + } + }, + "reset_edge_brush": { + "type": "Boolean", + "value": {} + }, + "reset_roll_brush": { + "type": "Boolean", + "value": {} + }, + "reset_filter": { + "type": "Boolean", + "value": {} + }, + "reset_duster_cloth": { + "type": "Boolean", + "value": {} + }, + "switch_disturb": { + "type": "Boolean", + "value": {} + }, + "volume_set": { + "type": "Integer", + "value": { + "unit": "%", + "min": 0, + "max": 100, + "scale": 0, + "step": 1 + } + }, + "break_clean": { + "type": "Boolean", + "value": {} + }, + "device_timer": { + "type": "Raw", + "value": {} + }, + "disturb_time_set": { + "type": "Raw", + "value": {} + }, + "voice_data": { + "type": "Raw", + "value": {} + }, + "language": { + "type": "Enum", + "value": { + "range": [ + "chinese_simplified", + "chinese_traditional", + "english", + "german", + "french", + "russian", + "spanish", + "korean", + "latin", + "portuguese", + "japanese", + "italian" + ] + } + }, + "customize_mode_switch": { + "type": "Boolean", + "value": {} + } + }, + "status_range": { + "power_go": { + "type": "Boolean", + "value": {} + }, + "pause": { + "type": "Boolean", + "value": {} + }, + "switch_charge": { + "type": "Boolean", + "value": {} + }, + "mode": { + "type": "Enum", + "value": { + "range": ["smart", "zone", "pose", "part"] + } + }, + "status": { + "type": "Enum", + "value": { + "range": [ + "standby", + "zone_clean", + "part_clean", + "cleaning", + "paused", + "goto_pos", + "pos_arrived", + "pos_unarrive", + "goto_charge", + "charging", + "charge_done", + "sleep" + ] + } + }, + "clean_time": { + "type": "Integer", + "value": { + "unit": "min", + "min": 0, + "max": 9999, + "scale": 0, + "step": 1 + } + }, + "clean_area": { + "type": "Integer", + "value": { + "unit": "㎡", + "min": 0, + "max": 9999, + "scale": 0, + "step": 1 + } + }, + "electricity_left": { + "type": "Integer", + "value": { + "unit": "%", + "min": 0, + "max": 100, + "scale": 0, + "step": 1 + } + }, + "suction": { + "type": "Enum", + "value": { + "range": ["closed", "gentle", "normal", "strong"] + } + }, + "cistern": { + "type": "Enum", + "value": { + "range": ["closed", "low", "middle", "high"] + } + }, + "seek": { + "type": "Boolean", + "value": {} + }, + "direction_control": { + "type": "Enum", + "value": { + "range": ["forward", "turn_left", "turn_right", "stop"] + } + }, + "reset_map": { + "type": "Boolean", + "value": {} + }, + "path_data": { + "type": "Raw", + "value": {} + }, + "command_trans": { + "type": "Raw", + "value": {} + }, + "request": { + "type": "Enum", + "value": { + "range": ["get_map", "get_path", "get_both"] + } + }, + "edge_brush": { + "type": "Integer", + "value": { + "unit": "min", + "min": 0, + "max": 9000, + "scale": 0, + "step": 1 + } + }, + "reset_edge_brush": { + "type": "Boolean", + "value": {} + }, + "roll_brush": { + "type": "Integer", + "value": { + "unit": "min", + "min": 0, + "max": 18000, + "scale": 0, + "step": 1 + } + }, + "reset_roll_brush": { + "type": "Boolean", + "value": {} + }, + "filter": { + "type": "Integer", + "value": { + "unit": "min", + "min": 0, + "max": 9000, + "scale": 0, + "step": 1 + } + }, + "reset_filter": { + "type": "Boolean", + "value": {} + }, + "duster_cloth": { + "type": "Integer", + "value": { + "unit": "min", + "min": 0, + "max": 9000, + "scale": 0, + "step": 1 + } + }, + "reset_duster_cloth": { + "type": "Boolean", + "value": {} + }, + "switch_disturb": { + "type": "Boolean", + "value": {} + }, + "volume_set": { + "type": "Integer", + "value": { + "unit": "%", + "min": 0, + "max": 100, + "scale": 0, + "step": 1 + } + }, + "break_clean": { + "type": "Boolean", + "value": {} + }, + "fault": { + "type": "Bitmap", + "value": { + "label": [ + "low_power", + "poweroff", + "wheel_trap", + "cannot_upgrade", + "collision_stuck", + "dust_station_full", + "tile_error", + "lidar_speed_err", + "lidar_cover", + "lidar_point_err", + "front_wall_dirty", + "psd_dirty", + "middle_sweep", + "side_sweep", + "fan_speed", + "dustbox_out", + "dustbox_full", + "no_dust_box", + "dustbox_fullout", + "trapped", + "pick_up", + "no_dust_water_box", + "water_box_empty", + "forbid_area", + "land_check", + "findcharge_fail", + "battery_err", + "kit_wheel", + "kit_lidar", + "kit_water_pump" + ] + } + }, + "total_clean_area": { + "type": "Integer", + "value": { + "unit": "㎡", + "min": 0, + "max": 99999, + "scale": 0, + "step": 1 + } + }, + "total_clean_count": { + "type": "Integer", + "value": { + "min": 0, + "max": 99999, + "scale": 0, + "step": 1 + } + }, + "total_clean_time": { + "type": "Integer", + "value": { + "unit": "min", + "min": 0, + "max": 99999, + "scale": 0, + "step": 1 + } + }, + "device_timer": { + "type": "Raw", + "value": {} + }, + "disturb_time_set": { + "type": "Raw", + "value": {} + }, + "device_info": { + "type": "Raw", + "value": {} + }, + "voice_data": { + "type": "Raw", + "value": {} + }, + "language": { + "type": "Enum", + "value": { + "range": [ + "chinese_simplified", + "chinese_traditional", + "english", + "german", + "french", + "russian", + "spanish", + "korean", + "latin", + "portuguese", + "japanese", + "italian" + ] + } + }, + "customize_mode_switch": { + "type": "Boolean", + "value": {} + } + }, + "status": { + "power_go": false, + "pause": false, + "switch_charge": false, + "mode": "goto_charge", + "status": "charge_done", + "clean_time": 0, + "clean_area": 0, + "electricity_left": 100, + "suction": "strong", + "cistern": "middle", + "seek": false, + "direction_control": "forward", + "reset_map": false, + "path_data": "", + "command_trans": "qgABFxc=", + "request": "get_map", + "edge_brush": 8944, + "reset_edge_brush": false, + "roll_brush": 17948, + "reset_roll_brush": false, + "filter": 8956, + "reset_filter": false, + "duster_cloth": 9000, + "reset_duster_cloth": false, + "switch_disturb": false, + "volume_set": 95, + "break_clean": true, + "fault": 0, + "total_clean_area": 24, + "total_clean_count": 1, + "total_clean_time": 42, + "device_timer": "qgADMQEAMg==", + "disturb_time_set": "qgAIMwEWAAAIAABS", + "device_info": "eyJEZXZpY2VfU04iOiJJRlYyMDI1MDExNTAyMDIwMiIsIkZpcm13YXJlX1ZlcnNpb24iOiIxLjQuMyIsIklQIjoiMTkyLjE2OC4wLjIwMyIsIk1DVV9WZXJzaW9uIjoiMC4zMTQxLjEwNyIsIk1hYyI6IjM0OjE3OjM2OkU1OjAyOjc4IiwiTW9kdWxlX1VVSUQiOiJ6ZjExYjJmNzQ4Mzg5ZTY5ZDk4NiIsIlJTU0kiOiItNTAiLCJXaUZpX05hbWUiOiJGcnl0a2lfemFfZGFybW8ifQ==", + "voice_data": "qwAAAAAHNQAAAAADZJw=", + "language": "chinese_simplified", + "customize_mode_switch": false + }, + "set_up": true, + "support_local": true +} diff --git a/tests/components/tuya/fixtures/sfkzq_o6dagifntoafakst.json b/tests/components/tuya/fixtures/sfkzq_o6dagifntoafakst.json index dd95050e2bfbd..e57e927469028 100644 --- a/tests/components/tuya/fixtures/sfkzq_o6dagifntoafakst.json +++ b/tests/components/tuya/fixtures/sfkzq_o6dagifntoafakst.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1739471569144tcmeiO", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/tdq_cq1p0nt0a4rixnex.json b/tests/components/tuya/fixtures/tdq_cq1p0nt0a4rixnex.json index c139e79d19b7d..e7c79f3fb41b2 100644 --- a/tests/components/tuya/fixtures/tdq_cq1p0nt0a4rixnex.json +++ b/tests/components/tuya/fixtures/tdq_cq1p0nt0a4rixnex.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1748383912663Y2lvlm", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/tyndj_pyakuuoc.json b/tests/components/tuya/fixtures/tyndj_pyakuuoc.json index 973cecabc0b02..656c626c4fe02 100644 --- a/tests/components/tuya/fixtures/tyndj_pyakuuoc.json +++ b/tests/components/tuya/fixtures/tyndj_pyakuuoc.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1753247726209KOaaPc", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/wk_aqoouq7x.json b/tests/components/tuya/fixtures/wk_aqoouq7x.json index 2c162a1a51426..900ae356f3817 100644 --- a/tests/components/tuya/fixtures/wk_aqoouq7x.json +++ b/tests/components/tuya/fixtures/wk_aqoouq7x.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1749538552551GHfV17", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/wk_fi6dne5tu4t1nm6j.json b/tests/components/tuya/fixtures/wk_fi6dne5tu4t1nm6j.json index e96389ca215fe..002b060946410 100644 --- a/tests/components/tuya/fixtures/wk_fi6dne5tu4t1nm6j.json +++ b/tests/components/tuya/fixtures/wk_fi6dne5tu4t1nm6j.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "xxxxxxxxxxxxxxxxxxx", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/wsdcg_g2y6z3p3ja2qhyav.json b/tests/components/tuya/fixtures/wsdcg_g2y6z3p3ja2qhyav.json index 06d07a4c506ce..2929872f4c158 100644 --- a/tests/components/tuya/fixtures/wsdcg_g2y6z3p3ja2qhyav.json +++ b/tests/components/tuya/fixtures/wsdcg_g2y6z3p3ja2qhyav.json @@ -1,10 +1,9 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "17150293164666xhFUk", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, - "id": "bf316b8707b061f044th18", "name": "NP DownStairs North", "category": "wsdcg", diff --git a/tests/components/tuya/fixtures/ydkt_jevroj5aguwdbs2e.json b/tests/components/tuya/fixtures/ydkt_jevroj5aguwdbs2e.json index f50aab00a2666..a7ab15a451182 100644 --- a/tests/components/tuya/fixtures/ydkt_jevroj5aguwdbs2e.json +++ b/tests/components/tuya/fixtures/ydkt_jevroj5aguwdbs2e.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "mock_terminal_id", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/fixtures/zndb_ze8faryrxr0glqnn.json b/tests/components/tuya/fixtures/zndb_ze8faryrxr0glqnn.json index 139cf81434781..797ddba3587a7 100644 --- a/tests/components/tuya/fixtures/zndb_ze8faryrxr0glqnn.json +++ b/tests/components/tuya/fixtures/zndb_ze8faryrxr0glqnn.json @@ -1,6 +1,6 @@ { "endpoint": "https://apigw.tuyaeu.com", - "terminal_id": "1739198173271wpFacM", + "terminal_id": "REDACTED", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, diff --git a/tests/components/tuya/snapshots/test_button.ambr b/tests/components/tuya/snapshots/test_button.ambr new file mode 100644 index 0000000000000..61b62e124e58f --- /dev/null +++ b/tests/components/tuya/snapshots/test_button.ambr @@ -0,0 +1,241 @@ +# serializer version: 1 +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_duster_cloth-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.v20_reset_duster_cloth', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Reset duster cloth', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'reset_duster_cloth', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtreset_duster_cloth', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_duster_cloth-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Reset duster cloth', + }), + 'context': , + 'entity_id': 'button.v20_reset_duster_cloth', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_edge_brush-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.v20_reset_edge_brush', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Reset edge brush', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'reset_edge_brush', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtreset_edge_brush', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_edge_brush-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Reset edge brush', + }), + 'context': , + 'entity_id': 'button.v20_reset_edge_brush', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_filter-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.v20_reset_filter', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Reset filter', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'reset_filter', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtreset_filter', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_filter-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Reset filter', + }), + 'context': , + 'entity_id': 'button.v20_reset_filter', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_map-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.v20_reset_map', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Reset map', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'reset_map', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtreset_map', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_map-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Reset map', + }), + 'context': , + 'entity_id': 'button.v20_reset_map', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_roll_brush-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.v20_reset_roll_brush', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Reset roll brush', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'reset_roll_brush', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtreset_roll_brush', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][button.v20_reset_roll_brush-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Reset roll brush', + }), + 'context': , + 'entity_id': 'button.v20_reset_roll_brush', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- diff --git a/tests/components/tuya/snapshots/test_fan.ambr b/tests/components/tuya/snapshots/test_fan.ambr index 69eb1b467e9ae..52c4594f37b9f 100644 --- a/tests/components/tuya/snapshots/test_fan.ambr +++ b/tests/components/tuya/snapshots/test_fan.ambr @@ -53,56 +53,6 @@ 'state': 'unavailable', }) # --- -# name: test_platform_setup_and_discovery[cs_vmxuxszzjwp5smli][fan.dehumidifier-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'fan', - 'entity_category': None, - 'entity_id': 'fan.dehumidifier', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': None, - 'original_icon': None, - 'original_name': None, - 'platform': 'tuya', - 'previous_unique_id': None, - 'suggested_object_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'tuya.mock_device_id', - 'unit_of_measurement': None, - }) -# --- -# name: test_platform_setup_and_discovery[cs_vmxuxszzjwp5smli][fan.dehumidifier-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'Dehumidifier ', - 'supported_features': , - }), - 'context': , - 'entity_id': 'fan.dehumidifier', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- # name: test_platform_setup_and_discovery[cs_zibqa9dutqyaxym2][fan.dehumidifier-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/tuya/snapshots/test_number.ambr b/tests/components/tuya/snapshots/test_number.ambr index fa9d735831427..b05b45cdd487f 100644 --- a/tests/components/tuya/snapshots/test_number.ambr +++ b/tests/components/tuya/snapshots/test_number.ambr @@ -469,6 +469,64 @@ 'state': '3.0', }) # --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][number.v20_volume-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'max': 100.0, + 'min': 0.0, + 'mode': , + 'step': 1.0, + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'number', + 'entity_category': , + 'entity_id': 'number.v20_volume', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Volume', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'volume', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtvolume_set', + 'unit_of_measurement': '%', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][number.v20_volume-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Volume', + 'max': 100.0, + 'min': 0.0, + 'mode': , + 'step': 1.0, + 'unit_of_measurement': '%', + }), + 'context': , + 'entity_id': 'number.v20_volume', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '95.0', + }) +# --- # name: test_platform_setup_and_discovery[sgbj_ulv4nnue7gqp0rjk][number.siren_veranda_time-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/tuya/snapshots/test_select.ambr b/tests/components/tuya/snapshots/test_select.ambr index 84af76355d5c2..d2b3b3900e92f 100644 --- a/tests/components/tuya/snapshots/test_select.ambr +++ b/tests/components/tuya/snapshots/test_select.ambr @@ -479,6 +479,126 @@ 'state': 'cancel', }) # --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][select.v20_mode-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'smart', + 'zone', + 'pose', + 'part', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': , + 'entity_id': 'select.v20_mode', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Mode', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'vacuum_mode', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtmode', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][select.v20_mode-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Mode', + 'options': list([ + 'smart', + 'zone', + 'pose', + 'part', + ]), + }), + 'context': , + 'entity_id': 'select.v20_mode', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][select.v20_water_tank_adjustment-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'low', + 'middle', + 'high', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': , + 'entity_id': 'select.v20_water_tank_adjustment', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Water tank adjustment', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'vacuum_cistern', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtcistern', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][select.v20_water_tank_adjustment-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Water tank adjustment', + 'options': list([ + 'low', + 'middle', + 'high', + ]), + }), + 'context': , + 'entity_id': 'select.v20_water_tank_adjustment', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'middle', + }) +# --- # name: test_platform_setup_and_discovery[sgbj_ulv4nnue7gqp0rjk][select.siren_veranda_volume-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/tuya/snapshots/test_sensor.ambr b/tests/components/tuya/snapshots/test_sensor.ambr index d2cd0eb0676f0..061c6c5867708 100644 --- a/tests/components/tuya/snapshots/test_sensor.ambr +++ b/tests/components/tuya/snapshots/test_sensor.ambr @@ -2556,6 +2556,473 @@ 'state': '0.0', }) # --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_cleaning_area-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.v20_cleaning_area', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Cleaning area', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cleaning_area', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtclean_area', + 'unit_of_measurement': '㎡', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_cleaning_area-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Cleaning area', + 'state_class': , + 'unit_of_measurement': '㎡', + }), + 'context': , + 'entity_id': 'sensor.v20_cleaning_area', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '0.0', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_cleaning_time-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.v20_cleaning_time', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Cleaning time', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'cleaning_time', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtclean_time', + 'unit_of_measurement': 'min', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_cleaning_time-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Cleaning time', + 'state_class': , + 'unit_of_measurement': 'min', + }), + 'context': , + 'entity_id': 'sensor.v20_cleaning_time', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '0.0', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_duster_cloth_lifetime-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.v20_duster_cloth_lifetime', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Duster cloth lifetime', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'duster_cloth_life', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtduster_cloth', + 'unit_of_measurement': 'min', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_duster_cloth_lifetime-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Duster cloth lifetime', + 'state_class': , + 'unit_of_measurement': 'min', + }), + 'context': , + 'entity_id': 'sensor.v20_duster_cloth_lifetime', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '9000.0', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_filter_lifetime-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.v20_filter_lifetime', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Filter lifetime', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'filter_life', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtfilter', + 'unit_of_measurement': 'min', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_filter_lifetime-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Filter lifetime', + 'state_class': , + 'unit_of_measurement': 'min', + }), + 'context': , + 'entity_id': 'sensor.v20_filter_lifetime', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '8956.0', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_rolling_brush_lifetime-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.v20_rolling_brush_lifetime', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Rolling brush lifetime', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'rolling_brush_life', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtroll_brush', + 'unit_of_measurement': 'min', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_rolling_brush_lifetime-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Rolling brush lifetime', + 'state_class': , + 'unit_of_measurement': 'min', + }), + 'context': , + 'entity_id': 'sensor.v20_rolling_brush_lifetime', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '17948.0', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_side_brush_lifetime-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.v20_side_brush_lifetime', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Side brush lifetime', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'side_brush_life', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtedge_brush', + 'unit_of_measurement': 'min', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_side_brush_lifetime-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Side brush lifetime', + 'state_class': , + 'unit_of_measurement': 'min', + }), + 'context': , + 'entity_id': 'sensor.v20_side_brush_lifetime', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '8944.0', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_total_cleaning_area-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.v20_total_cleaning_area', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Total cleaning area', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'total_cleaning_area', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmttotal_clean_area', + 'unit_of_measurement': '㎡', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_total_cleaning_area-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Total cleaning area', + 'state_class': , + 'unit_of_measurement': '㎡', + }), + 'context': , + 'entity_id': 'sensor.v20_total_cleaning_area', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '24.0', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_total_cleaning_time-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.v20_total_cleaning_time', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Total cleaning time', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'total_cleaning_time', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmttotal_clean_time', + 'unit_of_measurement': 'min', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_total_cleaning_time-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Total cleaning time', + 'state_class': , + 'unit_of_measurement': 'min', + }), + 'context': , + 'entity_id': 'sensor.v20_total_cleaning_time', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '42.0', + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_total_cleaning_times-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'state_class': , + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': None, + 'entity_id': 'sensor.v20_total_cleaning_times', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Total cleaning times', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'total_cleaning_times', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmttotal_clean_count', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][sensor.v20_total_cleaning_times-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Total cleaning times', + 'state_class': , + }), + 'context': , + 'entity_id': 'sensor.v20_total_cleaning_times', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '1.0', + }) +# --- # name: test_platform_setup_and_discovery[sp_sdd5f5f2dl5wydjf][sensor.c9_battery-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/tuya/snapshots/test_switch.ambr b/tests/components/tuya/snapshots/test_switch.ambr index aa80ac08ee5ad..e5b41853703b5 100644 --- a/tests/components/tuya/snapshots/test_switch.ambr +++ b/tests/components/tuya/snapshots/test_switch.ambr @@ -1406,6 +1406,54 @@ 'state': 'off', }) # --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][switch.v20_do_not_disturb-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.v20_do_not_disturb', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Do not disturb', + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'do_not_disturb', + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmtswitch_disturb', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][switch.v20_do_not_disturb-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'V20 Do not disturb', + }), + 'context': , + 'entity_id': 'switch.v20_do_not_disturb', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'off', + }) +# --- # name: test_platform_setup_and_discovery[sfkzq_o6dagifntoafakst][switch.sprinkler_cesare_switch-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/tuya/snapshots/test_vacuum.ambr b/tests/components/tuya/snapshots/test_vacuum.ambr new file mode 100644 index 0000000000000..0425cc4506061 --- /dev/null +++ b/tests/components/tuya/snapshots/test_vacuum.ambr @@ -0,0 +1,64 @@ +# serializer version: 1 +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][vacuum.v20-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'fan_speed_list': list([ + 'gentle', + 'normal', + 'strong', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'vacuum', + 'entity_category': None, + 'entity_id': 'vacuum.v20', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': None, + 'platform': 'tuya', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': , + 'translation_key': None, + 'unique_id': 'tuya.bfa951ca98fcf64fddqlmt', + 'unit_of_measurement': None, + }) +# --- +# name: test_platform_setup_and_discovery[sd_lr33znaodtyarrrz][vacuum.v20-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'battery_icon': 'mdi:battery-charging-100', + 'battery_level': 100, + 'fan_speed': 'strong', + 'fan_speed_list': list([ + 'gentle', + 'normal', + 'strong', + ]), + 'friendly_name': 'V20', + 'supported_features': , + }), + 'context': , + 'entity_id': 'vacuum.v20', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'docked', + }) +# --- diff --git a/tests/components/tuya/test_button.py b/tests/components/tuya/test_button.py new file mode 100644 index 0000000000000..b8c6dda4afa48 --- /dev/null +++ b/tests/components/tuya/test_button.py @@ -0,0 +1,57 @@ +"""Test Tuya button platform.""" + +from __future__ import annotations + +from unittest.mock import patch + +import pytest +from syrupy.assertion import SnapshotAssertion +from tuya_sharing import CustomerDevice + +from homeassistant.components.tuya import ManagerCompat +from homeassistant.const import Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from . import DEVICE_MOCKS, initialize_entry + +from tests.common import MockConfigEntry, snapshot_platform + + +@pytest.mark.parametrize( + "mock_device_code", + [k for k, v in DEVICE_MOCKS.items() if Platform.BUTTON in v], +) +@patch("homeassistant.components.tuya.PLATFORMS", [Platform.BUTTON]) +async def test_platform_setup_and_discovery( + hass: HomeAssistant, + mock_manager: ManagerCompat, + mock_config_entry: MockConfigEntry, + mock_device: CustomerDevice, + entity_registry: er.EntityRegistry, + snapshot: SnapshotAssertion, +) -> None: + """Test platform setup and discovery.""" + await initialize_entry(hass, mock_manager, mock_config_entry, mock_device) + + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) + + +@pytest.mark.parametrize( + "mock_device_code", + [k for k, v in DEVICE_MOCKS.items() if Platform.BUTTON not in v], +) +@patch("homeassistant.components.tuya.PLATFORMS", [Platform.BUTTON]) +async def test_platform_setup_no_discovery( + hass: HomeAssistant, + mock_manager: ManagerCompat, + mock_config_entry: MockConfigEntry, + mock_device: CustomerDevice, + entity_registry: er.EntityRegistry, +) -> None: + """Test platform setup without discovery.""" + await initialize_entry(hass, mock_manager, mock_config_entry, mock_device) + + assert not er.async_entries_for_config_entry( + entity_registry, mock_config_entry.entry_id + ) diff --git a/tests/components/tuya/test_vacuum.py b/tests/components/tuya/test_vacuum.py new file mode 100644 index 0000000000000..1caf298f3c4d6 --- /dev/null +++ b/tests/components/tuya/test_vacuum.py @@ -0,0 +1,91 @@ +"""Test Tuya vacuum platform.""" + +from __future__ import annotations + +from unittest.mock import patch + +import pytest +from syrupy.assertion import SnapshotAssertion +from tuya_sharing import CustomerDevice + +from homeassistant.components.tuya import ManagerCompat +from homeassistant.components.vacuum import ( + DOMAIN as VACUUM_DOMAIN, + SERVICE_RETURN_TO_BASE, +) +from homeassistant.const import Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from . import DEVICE_MOCKS, initialize_entry + +from tests.common import MockConfigEntry, snapshot_platform + + +@pytest.mark.parametrize( + "mock_device_code", + [k for k, v in DEVICE_MOCKS.items() if Platform.VACUUM in v], +) +@patch("homeassistant.components.tuya.PLATFORMS", [Platform.VACUUM]) +async def test_platform_setup_and_discovery( + hass: HomeAssistant, + mock_manager: ManagerCompat, + mock_config_entry: MockConfigEntry, + mock_device: CustomerDevice, + entity_registry: er.EntityRegistry, + snapshot: SnapshotAssertion, +) -> None: + """Test platform setup and discovery.""" + await initialize_entry(hass, mock_manager, mock_config_entry, mock_device) + + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) + + +@pytest.mark.parametrize( + "mock_device_code", + [k for k, v in DEVICE_MOCKS.items() if Platform.VACUUM not in v], +) +@patch("homeassistant.components.tuya.PLATFORMS", [Platform.VACUUM]) +async def test_platform_setup_no_discovery( + hass: HomeAssistant, + mock_manager: ManagerCompat, + mock_config_entry: MockConfigEntry, + mock_device: CustomerDevice, + entity_registry: er.EntityRegistry, +) -> None: + """Test platform setup without discovery.""" + await initialize_entry(hass, mock_manager, mock_config_entry, mock_device) + + assert not er.async_entries_for_config_entry( + entity_registry, mock_config_entry.entry_id + ) + + +@pytest.mark.parametrize( + "mock_device_code", + ["sd_lr33znaodtyarrrz"], +) +async def test_return_home( + hass: HomeAssistant, + mock_manager: ManagerCompat, + mock_config_entry: MockConfigEntry, + mock_device: CustomerDevice, +) -> None: + """Test return home service.""" + # Based on #141278 + entity_id = "vacuum.v20" + await initialize_entry(hass, mock_manager, mock_config_entry, mock_device) + + state = hass.states.get(entity_id) + assert state is not None, f"{entity_id} does not exist" + await hass.services.async_call( + VACUUM_DOMAIN, + SERVICE_RETURN_TO_BASE, + { + "entity_id": entity_id, + }, + blocking=True, + ) + mock_manager.send_commands.assert_called_once_with( + mock_device.id, [{"code": "switch_charge", "value": True}] + ) diff --git a/tests/components/zimi/conftest.py b/tests/components/zimi/conftest.py index 44d898deffb98..b26c2f89784dc 100644 --- a/tests/components/zimi/conftest.py +++ b/tests/components/zimi/conftest.py @@ -1,6 +1,6 @@ """Test fixtures for Zimi component.""" -from unittest.mock import patch +from unittest.mock import MagicMock, patch import pytest @@ -19,6 +19,8 @@ def mock_api(): """Mock the API with defaults.""" with patch("homeassistant.components.zimi.async_connect_to_controller") as mock: mock_api = mock.return_value + mock_api.describe = MagicMock() + mock_api.disconnect = MagicMock() mock_api.connect.return_value = True mock_api.mac = INPUT_MAC mock_api.brand = API_INFO["brand"] diff --git a/tests/components/zwave_js/test_init.py b/tests/components/zwave_js/test_init.py index 3c39868ff9314..1aaa9013d8731 100644 --- a/tests/components/zwave_js/test_init.py +++ b/tests/components/zwave_js/test_init.py @@ -497,17 +497,17 @@ async def test_on_node_added_ready( ) -async def test_on_node_added_preprovisioned( +async def test_check_pre_provisioned_device_update_device( hass: HomeAssistant, device_registry: dr.DeviceRegistry, - multisensor_6_state, - client, - integration, + multisensor_6_state: NodeDataType, + client: MagicMock, + integration: MockConfigEntry, ) -> None: - """Test node added event with a preprovisioned device.""" + """Test check pre-provisioned device that should update the device.""" dsk = "test" node = Node(client, deepcopy(multisensor_6_state)) - device = device_registry.async_get_or_create( + pre_provisioned_device = device_registry.async_get_or_create( config_entry_id=integration.entry_id, identifiers={(DOMAIN, f"provision_{dsk}")}, ) @@ -515,7 +515,7 @@ async def test_on_node_added_preprovisioned( { "dsk": dsk, "securityClasses": [SecurityClass.S2_UNAUTHENTICATED], - "device_id": device.id, + "device_id": pre_provisioned_device.id, } ) with patch( @@ -526,14 +526,60 @@ async def test_on_node_added_preprovisioned( client.driver.controller.emit("node added", event) await hass.async_block_till_done() - device = device_registry.async_get(device.id) + device = device_registry.async_get(pre_provisioned_device.id) assert device assert device.identifiers == { get_device_id(client.driver, node), get_device_id_ext(client.driver, node), } assert device.sw_version == node.firmware_version - # There should only be the controller and the preprovisioned device + # There should only be the controller and the pre-provisioned device + assert len(device_registry.devices) == 2 + + +async def test_check_pre_provisioned_device_remove_device( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + multisensor_6_state: NodeDataType, + client: MagicMock, + integration: MockConfigEntry, +) -> None: + """Test check pre-provisioned device that should remove the device.""" + dsk = "test" + driver = client.driver + node = Node(client, deepcopy(multisensor_6_state)) + pre_provisioned_device = device_registry.async_get_or_create( + config_entry_id=integration.entry_id, + identifiers={(DOMAIN, f"provision_{dsk}")}, + ) + extended_identifier = get_device_id_ext(driver, node) + assert extended_identifier + existing_device = device_registry.async_get_or_create( + config_entry_id=integration.entry_id, + identifiers={ + get_device_id(driver, node), + extended_identifier, + }, + ) + provisioning_entry = ProvisioningEntry.from_dict( + { + "dsk": dsk, + "securityClasses": [SecurityClass.S2_UNAUTHENTICATED], + "device_id": pre_provisioned_device.id, + } + ) + with patch( + f"{CONTROLLER_PATCH_PREFIX}.async_get_provisioning_entry", + side_effect=lambda id: provisioning_entry if id == node.node_id else None, + ): + event = {"node": node} + client.driver.controller.emit("node added", event) + await hass.async_block_till_done() + + assert not device_registry.async_get(pre_provisioned_device.id) + assert device_registry.async_get(existing_device.id) + + # There should only be the controller and the existing device assert len(device_registry.devices) == 2