diff --git a/homeassistant/components/homekit_controller/const.py b/homeassistant/components/homekit_controller/const.py index eee244c8cf1..2de7156482e 100644 --- a/homeassistant/components/homekit_controller/const.py +++ b/homeassistant/components/homekit_controller/const.py @@ -47,6 +47,7 @@ HOMEKIT_ACCESSORY_DISPATCH = { } CHARACTERISTIC_PLATFORMS = { + CharacteristicsTypes.Vendor.AQARA_GATEWAY_VOLUME: "number", CharacteristicsTypes.Vendor.EVE_ENERGY_WATT: "sensor", CharacteristicsTypes.Vendor.EVE_DEGREE_AIR_PRESSURE: "sensor", CharacteristicsTypes.Vendor.EVE_DEGREE_ELEVATION: "number", diff --git a/homeassistant/components/homekit_controller/manifest.json b/homeassistant/components/homekit_controller/manifest.json index d9645d22a2d..4b4b971b3b6 100644 --- a/homeassistant/components/homekit_controller/manifest.json +++ b/homeassistant/components/homekit_controller/manifest.json @@ -3,7 +3,7 @@ "name": "HomeKit Controller", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/homekit_controller", - "requirements": ["aiohomekit==0.6.4"], + "requirements": ["aiohomekit==0.6.10"], "zeroconf": ["_hap._tcp.local."], "after_dependencies": ["zeroconf"], "codeowners": ["@Jc2k", "@bdraco"], diff --git a/homeassistant/components/homekit_controller/number.py b/homeassistant/components/homekit_controller/number.py index beb0ffa7fa5..f646072425b 100644 --- a/homeassistant/components/homekit_controller/number.py +++ b/homeassistant/components/homekit_controller/number.py @@ -10,6 +10,7 @@ from aiohomekit.model.characteristics import Characteristic, CharacteristicsType from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.core import callback +from homeassistant.helpers.entity import EntityCategory from . import KNOWN_DEVICES, CharacteristicEntity @@ -18,11 +19,25 @@ NUMBER_ENTITIES: dict[str, NumberEntityDescription] = { key=CharacteristicsTypes.Vendor.VOCOLINC_HUMIDIFIER_SPRAY_LEVEL, name="Spray Quantity", icon="mdi:water", + entity_category=EntityCategory.CONFIG, ), CharacteristicsTypes.Vendor.EVE_DEGREE_ELEVATION: NumberEntityDescription( key=CharacteristicsTypes.Vendor.EVE_DEGREE_ELEVATION, name="Elevation", icon="mdi:elevation-rise", + entity_category=EntityCategory.CONFIG, + ), + CharacteristicsTypes.Vendor.AQARA_GATEWAY_VOLUME: NumberEntityDescription( + key=CharacteristicsTypes.Vendor.AQARA_GATEWAY_VOLUME, + name="Volume", + icon="mdi:volume-high", + entity_category=EntityCategory.CONFIG, + ), + CharacteristicsTypes.Vendor.AQARA_E1_GATEWAY_VOLUME: NumberEntityDescription( + key=CharacteristicsTypes.Vendor.AQARA_E1_GATEWAY_VOLUME, + name="Volume", + icon="mdi:volume-high", + entity_category=EntityCategory.CONFIG, ), } @@ -57,6 +72,14 @@ class HomeKitNumber(CharacteristicEntity, NumberEntity): self.entity_description = description super().__init__(conn, info, char) + @property + def name(self) -> str: + """Return the name of the device if any.""" + prefix = "" + if name := super().name: + prefix = f"{name} -" + return f"{prefix} {self.entity_description.name}" + def get_characteristic_types(self): """Define the homekit characteristics the entity is tracking.""" return [self._char.type] diff --git a/requirements_all.txt b/requirements_all.txt index ed35c50a1e7..7e7fd6f7b95 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -186,7 +186,7 @@ aioguardian==2021.11.0 aioharmony==0.2.8 # homeassistant.components.homekit_controller -aiohomekit==0.6.4 +aiohomekit==0.6.10 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 8cc174d9127..1eb99cfec45 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -130,7 +130,7 @@ aioguardian==2021.11.0 aioharmony==0.2.8 # homeassistant.components.homekit_controller -aiohomekit==0.6.4 +aiohomekit==0.6.10 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/tests/components/homekit_controller/specific_devices/test_aqara_gateway.py b/tests/components/homekit_controller/specific_devices/test_aqara_gateway.py index b4437a7a9b5..08c9e7b3976 100644 --- a/tests/components/homekit_controller/specific_devices/test_aqara_gateway.py +++ b/tests/components/homekit_controller/specific_devices/test_aqara_gateway.py @@ -3,9 +3,14 @@ Regression tests for Aqara Gateway V3. https://github.com/home-assistant/core/issues/20957 """ - +from homeassistant.components.alarm_control_panel import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.components.light import SUPPORT_BRIGHTNESS, SUPPORT_COLOR from homeassistant.helpers import device_registry as dr, entity_registry as er +from homeassistant.helpers.entity import EntityCategory from tests.components.homekit_controller.common import ( Helper, @@ -20,44 +25,58 @@ async def test_aqara_gateway_setup(hass): config_entry, pairing = await setup_test_accessories(hass, accessories) entity_registry = er.async_get(hass) - - # Check that the light is correctly found and set up - alarm_id = "alarm_control_panel.aqara_hub_1563" - alarm = entity_registry.async_get(alarm_id) - assert alarm.unique_id == "homekit-0000000123456789-66304" - - alarm_helper = Helper( - hass, - "alarm_control_panel.aqara_hub_1563", - pairing, - accessories[0], - config_entry, - ) - alarm_state = await alarm_helper.poll_and_get_state() - assert alarm_state.attributes["friendly_name"] == "Aqara Hub-1563" - - # Check that the light is correctly found and set up - light = entity_registry.async_get("light.aqara_hub_1563") - assert light.unique_id == "homekit-0000000123456789-65792" - - light_helper = Helper( - hass, "light.aqara_hub_1563", pairing, accessories[0], config_entry - ) - light_state = await light_helper.poll_and_get_state() - assert light_state.attributes["friendly_name"] == "Aqara Hub-1563" - assert light_state.attributes["supported_features"] == ( - SUPPORT_BRIGHTNESS | SUPPORT_COLOR - ) - device_registry = dr.async_get(hass) - # All the entities are services of the same accessory - # So it looks at the protocol like a single physical device - assert alarm.device_id == light.device_id + sensors = [ + ( + "alarm_control_panel.aqara_hub_1563", + "homekit-0000000123456789-66304", + "Aqara Hub-1563", + SUPPORT_ALARM_ARM_NIGHT | SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY, + None, + ), + ( + "light.aqara_hub_1563", + "homekit-0000000123456789-65792", + "Aqara Hub-1563", + SUPPORT_BRIGHTNESS | SUPPORT_COLOR, + None, + ), + ( + "number.aqara_hub_1563_volume", + "homekit-0000000123456789-aid:1-sid:65536-cid:65541", + "Aqara Hub-1563 - Volume", + None, + EntityCategory.CONFIG, + ), + ] - device = device_registry.async_get(light.device_id) - assert device.manufacturer == "Aqara" - assert device.name == "Aqara Hub-1563" - assert device.model == "ZHWA11LM" - assert device.sw_version == "1.4.7" - assert device.via_device_id is None + device_ids = set() + + for (entity_id, unique_id, friendly_name, supported_features, category) in sensors: + entry = entity_registry.async_get(entity_id) + assert entry.unique_id == unique_id + assert entry.entity_category == category + + helper = Helper( + hass, + entity_id, + pairing, + accessories[0], + config_entry, + ) + state = await helper.poll_and_get_state() + assert state.attributes["friendly_name"] == friendly_name + assert state.attributes.get("supported_features") == supported_features + + device = device_registry.async_get(entry.device_id) + assert device.manufacturer == "Aqara" + assert device.name == "Aqara Hub-1563" + assert device.model == "ZHWA11LM" + assert device.sw_version == "1.4.7" + assert device.via_device_id is None + + device_ids.add(entry.device_id) + + # All entities should be part of same device + assert len(device_ids) == 1 diff --git a/tests/components/homekit_controller/specific_devices/test_eve_degree.py b/tests/components/homekit_controller/specific_devices/test_eve_degree.py index e419b140e94..043920fadec 100644 --- a/tests/components/homekit_controller/specific_devices/test_eve_degree.py +++ b/tests/components/homekit_controller/specific_devices/test_eve_degree.py @@ -39,9 +39,9 @@ async def test_eve_degree_setup(hass): "Eve Degree AA11 Battery", ), ( - "number.eve_degree_aa11", + "number.eve_degree_aa11_elevation", "homekit-AA00A0A00000-aid:1-sid:30-cid:33", - "Eve Degree AA11", + "Eve Degree AA11 - Elevation", ), ] diff --git a/tests/components/homekit_controller/specific_devices/test_vocolinc_flowerbud.py b/tests/components/homekit_controller/specific_devices/test_vocolinc_flowerbud.py index 391ac1c8f39..fe570ff0b73 100644 --- a/tests/components/homekit_controller/specific_devices/test_vocolinc_flowerbud.py +++ b/tests/components/homekit_controller/specific_devices/test_vocolinc_flowerbud.py @@ -19,14 +19,21 @@ async def test_vocolinc_flowerbud_setup(hass): # Check that the switch entity is handled correctly - entry = entity_registry.async_get("number.vocolinc_flowerbud_0d324b") + entry = entity_registry.async_get("number.vocolinc_flowerbud_0d324b_spray_quantity") assert entry.unique_id == "homekit-AM01121849000327-aid:1-sid:30-cid:38" helper = Helper( - hass, "number.vocolinc_flowerbud_0d324b", pairing, accessories[0], config_entry + hass, + "number.vocolinc_flowerbud_0d324b_spray_quantity", + pairing, + accessories[0], + config_entry, ) state = await helper.poll_and_get_state() - assert state.attributes["friendly_name"] == "VOCOlinc-Flowerbud-0d324b" + assert ( + state.attributes["friendly_name"] + == "VOCOlinc-Flowerbud-0d324b - Spray Quantity" + ) device = device_registry.async_get(entry.device_id) assert device.manufacturer == "VOCOlinc" diff --git a/tests/components/homekit_controller/test_number.py b/tests/components/homekit_controller/test_number.py index 490b69b1a80..8eebcbda8f5 100644 --- a/tests/components/homekit_controller/test_number.py +++ b/tests/components/homekit_controller/test_number.py @@ -33,7 +33,7 @@ async def test_read_number(hass, utcnow): # Helper will be for the primary entity, which is the outlet. Make a helper for the sensor. energy_helper = Helper( hass, - "number.testdevice", + "number.testdevice_spray_quantity", helper.pairing, helper.accessory, helper.config_entry, @@ -61,7 +61,7 @@ async def test_write_number(hass, utcnow): # Helper will be for the primary entity, which is the outlet. Make a helper for the sensor. energy_helper = Helper( hass, - "number.testdevice", + "number.testdevice_spray_quantity", helper.pairing, helper.accessory, helper.config_entry, @@ -73,7 +73,7 @@ async def test_write_number(hass, utcnow): await hass.services.async_call( "number", "set_value", - {"entity_id": "number.testdevice", "value": 5}, + {"entity_id": "number.testdevice_spray_quantity", "value": 5}, blocking=True, ) assert spray_level.value == 5 @@ -81,7 +81,7 @@ async def test_write_number(hass, utcnow): await hass.services.async_call( "number", "set_value", - {"entity_id": "number.testdevice", "value": 3}, + {"entity_id": "number.testdevice_spray_quantity", "value": 3}, blocking=True, ) assert spray_level.value == 3