From 2b6842aee07c950bf8d6b115aa6a61d4184cc7fa Mon Sep 17 00:00:00 2001 From: Jc2k Date: Thu, 17 Dec 2020 16:12:06 +0000 Subject: [PATCH] Fix velux homekit covers not enumerated correctly (#44318) --- .../components/homekit_controller/cover.py | 1 + .../specific_devices/test_velux_gateway.py | 79 ++++ .../homekit_controller/velux_gateway.json | 380 ++++++++++++++++++ 3 files changed, 460 insertions(+) create mode 100644 tests/components/homekit_controller/specific_devices/test_velux_gateway.py create mode 100644 tests/fixtures/homekit_controller/velux_gateway.json diff --git a/homeassistant/components/homekit_controller/cover.py b/homeassistant/components/homekit_controller/cover.py index fdf48ebba5d..6c945c81115 100644 --- a/homeassistant/components/homekit_controller/cover.py +++ b/homeassistant/components/homekit_controller/cover.py @@ -248,4 +248,5 @@ class HomeKitWindowCover(HomeKitEntity, CoverEntity): ENTITY_TYPES = { ServicesTypes.GARAGE_DOOR_OPENER: HomeKitGarageDoorCover, ServicesTypes.WINDOW_COVERING: HomeKitWindowCover, + ServicesTypes.WINDOW: HomeKitWindowCover, } diff --git a/tests/components/homekit_controller/specific_devices/test_velux_gateway.py b/tests/components/homekit_controller/specific_devices/test_velux_gateway.py new file mode 100644 index 00000000000..033b4aa7b4d --- /dev/null +++ b/tests/components/homekit_controller/specific_devices/test_velux_gateway.py @@ -0,0 +1,79 @@ +""" +Test against characteristics captured from a Velux Gateway. + +https://github.com/home-assistant/core/issues/44314 +""" + +from homeassistant.components.cover import ( + SUPPORT_CLOSE, + SUPPORT_OPEN, + SUPPORT_SET_POSITION, +) + +from tests.components.homekit_controller.common import ( + Helper, + setup_accessories_from_file, + setup_test_accessories, +) + + +async def test_simpleconnect_cover_setup(hass): + """Test that a velux gateway can be correctly setup in HA.""" + accessories = await setup_accessories_from_file(hass, "velux_gateway.json") + config_entry, pairing = await setup_test_accessories(hass, accessories) + + entity_registry = await hass.helpers.entity_registry.async_get_registry() + + # Check that the cover is correctly found and set up + cover_id = "cover.velux_window" + cover = entity_registry.async_get(cover_id) + assert cover.unique_id == "homekit-1111111a114a111a-8" + + cover_helper = Helper( + hass, + cover_id, + pairing, + accessories[0], + config_entry, + ) + + cover_state = await cover_helper.poll_and_get_state() + assert cover_state.attributes["friendly_name"] == "VELUX Window" + assert cover_state.state == "closed" + assert cover_state.attributes["supported_features"] == ( + SUPPORT_CLOSE | SUPPORT_SET_POSITION | SUPPORT_OPEN + ) + + # Check that one of the sensors is correctly found and set up + sensor_id = "sensor.velux_sensor_temperature" + sensor = entity_registry.async_get(sensor_id) + assert sensor.unique_id == "homekit-a11b111-8" + + sensor_helper = Helper( + hass, + sensor_id, + pairing, + accessories[0], + config_entry, + ) + + sensor_state = await sensor_helper.poll_and_get_state() + assert sensor_state.attributes["friendly_name"] == "VELUX Sensor Temperature" + assert sensor_state.state == "18.9" + + # The cover and sensor are different devices (accessories) attached to the same bridge + assert cover.device_id != sensor.device_id + + device_registry = await hass.helpers.device_registry.async_get_registry() + + device = device_registry.async_get(cover.device_id) + assert device.manufacturer == "VELUX" + assert device.name == "VELUX Window" + assert device.model == "VELUX Window" + assert device.sw_version == "48" + + bridge = device_registry.async_get(device.via_device_id) + assert bridge.manufacturer == "VELUX" + assert bridge.name == "VELUX Gateway" + assert bridge.model == "VELUX Gateway" + assert bridge.sw_version == "70" diff --git a/tests/fixtures/homekit_controller/velux_gateway.json b/tests/fixtures/homekit_controller/velux_gateway.json new file mode 100644 index 00000000000..1a6f60537b3 --- /dev/null +++ b/tests/fixtures/homekit_controller/velux_gateway.json @@ -0,0 +1,380 @@ +[ + { + "aid": 1, + "services": [ + { + "type": "0000003E-0000-1000-8000-0026BB765291", + "iid": 1, + "characteristics": [ + { + "type": "00000023-0000-1000-8000-0026BB765291", + "iid": 2, + "perms": [ + "pr" + ], + "format": "string", + "value": "VELUX Gateway" + }, + { + "type": "00000020-0000-1000-8000-0026BB765291", + "iid": 3, + "perms": [ + "pr" + ], + "format": "string", + "value": "VELUX" + }, + { + "type": "00000021-0000-1000-8000-0026BB765291", + "iid": 4, + "perms": [ + "pr" + ], + "format": "string", + "value": "VELUX Gateway" + }, + { + "type": "00000030-0000-1000-8000-0026BB765291", + "iid": 5, + "perms": [ + "pr" + ], + "format": "string", + "value": "a1a11a1" + }, + { + "type": "00000014-0000-1000-8000-0026BB765291", + "iid": 6, + "perms": [ + "pw" + ], + "format": "bool" + }, + { + "type": "00000052-0000-1000-8000-0026BB765291", + "iid": 7, + "perms": [ + "pr" + ], + "format": "string", + "value": "70" + } + ], + "hidden": false, + "primary": false + }, + { + "type": "000000A2-0000-1000-8000-0026BB765291", + "iid": 8, + "characteristics": [ + { + "type": "00000037-0000-1000-8000-0026BB765291", + "iid": 9, + "perms": [ + "pr" + ], + "format": "string", + "value": "1.1.0" + } + ], + "hidden": false, + "primary": false + } + ] + }, + { + "aid": 2, + "services": [ + { + "type": "0000003E-0000-1000-8000-0026BB765291", + "iid": 1, + "characteristics": [ + { + "type": "00000023-0000-1000-8000-0026BB765291", + "iid": 2, + "perms": [ + "pr" + ], + "format": "string", + "value": "VELUX Sensor" + }, + { + "type": "00000020-0000-1000-8000-0026BB765291", + "iid": 3, + "perms": [ + "pr" + ], + "format": "string", + "value": "VELUX" + }, + { + "type": "00000021-0000-1000-8000-0026BB765291", + "iid": 4, + "perms": [ + "pr" + ], + "format": "string", + "value": "VELUX Sensor" + }, + { + "type": "00000030-0000-1000-8000-0026BB765291", + "iid": 5, + "perms": [ + "pr" + ], + "format": "string", + "value": "a11b111" + }, + { + "type": "00000014-0000-1000-8000-0026BB765291", + "iid": 7, + "perms": [ + "pw" + ], + "format": "bool" + }, + { + "type": "00000052-0000-1000-8000-0026BB765291", + "iid": 6, + "perms": [ + "pr" + ], + "format": "string", + "value": "16" + } + ], + "hidden": false, + "primary": false + }, + { + "type": "0000008A-0000-1000-8000-0026BB765291", + "iid": 8, + "characteristics": [ + { + "type": "00000023-0000-1000-8000-0026BB765291", + "iid": 9, + "perms": [ + "pr" + ], + "format": "string", + "value": "Temperature sensor" + }, + { + "type": "00000011-0000-1000-8000-0026BB765291", + "iid": 10, + "perms": [ + "pr", + "ev" + ], + "format": "float", + "value": 18.9, + "minValue": 0, + "maxValue": 50, + "minStep": 0.1, + "unit": "celsius" + } + ], + "hidden": false, + "primary": true + }, + { + "type": "00000082-0000-1000-8000-0026BB765291", + "iid": 11, + "characteristics": [ + { + "type": "00000023-0000-1000-8000-0026BB765291", + "iid": 12, + "perms": [ + "pr" + ], + "format": "string", + "value": "Humidity sensor" + }, + { + "type": "00000010-0000-1000-8000-0026BB765291", + "iid": 13, + "perms": [ + "pr", + "ev" + ], + "format": "float", + "value": 58, + "minValue": 0, + "maxValue": 100, + "minStep": 1, + "unit": "percentage" + } + ], + "hidden": false, + "primary": false + }, + { + "type": "00000097-0000-1000-8000-0026BB765291", + "iid": 14, + "characteristics": [ + { + "type": "00000023-0000-1000-8000-0026BB765291", + "iid": 15, + "perms": [ + "pr" + ], + "format": "string", + "value": "Carbon Dioxide sensor" + }, + { + "type": "00000092-0000-1000-8000-0026BB765291", + "iid": 16, + "perms": [ + "pr", + "ev" + ], + "format": "uint8", + "value": 0, + "maxValue": 1, + "minValue": 0, + "minStep": 1 + }, + { + "type": "00000093-0000-1000-8000-0026BB765291", + "iid": 17, + "perms": [ + "pr", + "ev" + ], + "format": "float", + "value": 400, + "minValue": 0, + "maxValue": 5000 + } + ], + "hidden": false, + "primary": false + } + ] + }, + { + "aid": 3, + "services": [ + { + "type": "0000003E-0000-1000-8000-0026BB765291", + "iid": 1, + "characteristics": [ + { + "type": "00000023-0000-1000-8000-0026BB765291", + "iid": 2, + "perms": [ + "pr" + ], + "format": "string", + "value": "VELUX Window" + }, + { + "type": "00000020-0000-1000-8000-0026BB765291", + "iid": 3, + "perms": [ + "pr" + ], + "format": "string", + "value": "VELUX" + }, + { + "type": "00000021-0000-1000-8000-0026BB765291", + "iid": 4, + "perms": [ + "pr" + ], + "format": "string", + "value": "VELUX Window" + }, + { + "type": "00000030-0000-1000-8000-0026BB765291", + "iid": 5, + "perms": [ + "pr" + ], + "format": "string", + "value": "1111111a114a111a" + }, + { + "type": "00000014-0000-1000-8000-0026BB765291", + "iid": 7, + "perms": [ + "pw" + ], + "format": "bool" + }, + { + "type": "00000052-0000-1000-8000-0026BB765291", + "iid": 6, + "perms": [ + "pr" + ], + "format": "string", + "value": "48" + } + ], + "hidden": false, + "primary": false + }, + { + "type": "0000008B-0000-1000-8000-0026BB765291", + "iid": 8, + "characteristics": [ + { + "type": "00000023-0000-1000-8000-0026BB765291", + "iid": 9, + "perms": [ + "pr" + ], + "format": "string", + "value": "Roof Window" + }, + { + "type": "0000007C-0000-1000-8000-0026BB765291", + "iid": 11, + "perms": [ + "pr", + "pw", + "ev" + ], + "format": "uint8", + "value": 0, + "maxValue": 100, + "minValue": 0, + "unit": "percentage", + "minStep": 1 + }, + { + "type": "0000006D-0000-1000-8000-0026BB765291", + "iid": 10, + "perms": [ + "pr", + "ev" + ], + "format": "uint8", + "value": 0, + "maxValue": 100, + "minValue": 0, + "unit": "percentage", + "minStep": 1 + }, + { + "type": "00000072-0000-1000-8000-0026BB765291", + "iid": 12, + "perms": [ + "pr", + "ev" + ], + "format": "uint8", + "value": 2, + "maxValue": 2, + "minValue": 0, + "minStep": 1 + } + ], + "hidden": false, + "primary": true + } + ] + } +] \ No newline at end of file