Deprecate homekit_controller's air quality entity in favor of separate sensor entities (#54673)

pull/54769/head
Jc2k 2021-08-17 15:29:52 +01:00 committed by GitHub
parent f39dc749bb
commit ea8061469c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 647 additions and 2 deletions

View File

@ -1,4 +1,6 @@
"""Support for HomeKit Controller air quality sensors.""" """Support for HomeKit Controller air quality sensors."""
import logging
from aiohomekit.model.characteristics import CharacteristicsTypes from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes from aiohomekit.model.services import ServicesTypes
@ -7,6 +9,8 @@ from homeassistant.core import callback
from . import KNOWN_DEVICES, HomeKitEntity from . import KNOWN_DEVICES, HomeKitEntity
_LOGGER = logging.getLogger(__name__)
AIR_QUALITY_TEXT = { AIR_QUALITY_TEXT = {
0: "unknown", 0: "unknown",
1: "excellent", 1: "excellent",
@ -20,6 +24,20 @@ AIR_QUALITY_TEXT = {
class HomeAirQualitySensor(HomeKitEntity, AirQualityEntity): class HomeAirQualitySensor(HomeKitEntity, AirQualityEntity):
"""Representation of a HomeKit Controller Air Quality sensor.""" """Representation of a HomeKit Controller Air Quality sensor."""
async def async_added_to_hass(self):
"""Call when entity is added to hass."""
_LOGGER.warning(
"The homekit_controller air_quality entity has been "
"deprecated and will be removed in 2021.12.0"
)
await super().async_added_to_hass()
@property
def entity_registry_enabled_default(self) -> bool:
"""Whether or not to enable this entity by default."""
# This entity is deprecated, so don't enable by default
return False
def get_characteristic_types(self): def get_characteristic_types(self):
"""Define the homekit characteristics the entity cares about.""" """Define the homekit characteristics the entity cares about."""
return [ return [

View File

@ -4,12 +4,19 @@ from aiohomekit.model.services import ServicesTypes
from homeassistant.components.sensor import STATE_CLASS_MEASUREMENT, SensorEntity from homeassistant.components.sensor import STATE_CLASS_MEASUREMENT, SensorEntity
from homeassistant.const import ( from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_MILLION, CONCENTRATION_PARTS_PER_MILLION,
DEVICE_CLASS_AQI,
DEVICE_CLASS_BATTERY, DEVICE_CLASS_BATTERY,
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_NITROGEN_DIOXIDE,
DEVICE_CLASS_OZONE,
DEVICE_CLASS_PM10,
DEVICE_CLASS_PM25,
DEVICE_CLASS_POWER, DEVICE_CLASS_POWER,
DEVICE_CLASS_PRESSURE, DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_SULPHUR_DIOXIDE,
DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_TEMPERATURE,
LIGHT_LUX, LIGHT_LUX,
PERCENTAGE, PERCENTAGE,
@ -52,7 +59,7 @@ SIMPLE_SENSOR = {
"state_class": STATE_CLASS_MEASUREMENT, "state_class": STATE_CLASS_MEASUREMENT,
"unit": PRESSURE_HPA, "unit": PRESSURE_HPA,
}, },
CharacteristicsTypes.get_uuid(CharacteristicsTypes.TEMPERATURE_CURRENT): { CharacteristicsTypes.TEMPERATURE_CURRENT: {
"name": "Current Temperature", "name": "Current Temperature",
"device_class": DEVICE_CLASS_TEMPERATURE, "device_class": DEVICE_CLASS_TEMPERATURE,
"state_class": STATE_CLASS_MEASUREMENT, "state_class": STATE_CLASS_MEASUREMENT,
@ -62,7 +69,7 @@ SIMPLE_SENSOR = {
"probe": lambda char: char.service.type "probe": lambda char: char.service.type
!= ServicesTypes.get_uuid(ServicesTypes.TEMPERATURE_SENSOR), != ServicesTypes.get_uuid(ServicesTypes.TEMPERATURE_SENSOR),
}, },
CharacteristicsTypes.get_uuid(CharacteristicsTypes.RELATIVE_HUMIDITY_CURRENT): { CharacteristicsTypes.RELATIVE_HUMIDITY_CURRENT: {
"name": "Current Humidity", "name": "Current Humidity",
"device_class": DEVICE_CLASS_HUMIDITY, "device_class": DEVICE_CLASS_HUMIDITY,
"state_class": STATE_CLASS_MEASUREMENT, "state_class": STATE_CLASS_MEASUREMENT,
@ -72,8 +79,52 @@ SIMPLE_SENSOR = {
"probe": lambda char: char.service.type "probe": lambda char: char.service.type
!= ServicesTypes.get_uuid(ServicesTypes.HUMIDITY_SENSOR), != ServicesTypes.get_uuid(ServicesTypes.HUMIDITY_SENSOR),
}, },
CharacteristicsTypes.AIR_QUALITY: {
"name": "Air Quality",
"device_class": DEVICE_CLASS_AQI,
"state_class": STATE_CLASS_MEASUREMENT,
},
CharacteristicsTypes.DENSITY_PM25: {
"name": "PM2.5 Density",
"device_class": DEVICE_CLASS_PM25,
"state_class": STATE_CLASS_MEASUREMENT,
"unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
},
CharacteristicsTypes.DENSITY_PM10: {
"name": "PM10 Density",
"device_class": DEVICE_CLASS_PM10,
"state_class": STATE_CLASS_MEASUREMENT,
"unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
},
CharacteristicsTypes.DENSITY_OZONE: {
"name": "Ozone Density",
"device_class": DEVICE_CLASS_OZONE,
"state_class": STATE_CLASS_MEASUREMENT,
"unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
},
CharacteristicsTypes.DENSITY_NO2: {
"name": "Nitrogen Dioxide Density",
"device_class": DEVICE_CLASS_NITROGEN_DIOXIDE,
"state_class": STATE_CLASS_MEASUREMENT,
"unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
},
CharacteristicsTypes.DENSITY_SO2: {
"name": "Sulphur Dioxide Density",
"device_class": DEVICE_CLASS_SULPHUR_DIOXIDE,
"state_class": STATE_CLASS_MEASUREMENT,
"unit": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
},
} }
# For legacy reasons, "built-in" characteristic types are in their short form
# And vendor types don't have a short form
# This means long and short forms get mixed up in this dict, and comparisons
# don't work!
# We call get_uuid on *every* type to normalise them to the long form
# Eventually aiohomekit will use the long form exclusively amd this can be removed.
for k, v in list(SIMPLE_SENSOR.items()):
SIMPLE_SENSOR[CharacteristicsTypes.get_uuid(k)] = SIMPLE_SENSOR.pop(k)
class HomeKitHumiditySensor(HomeKitEntity, SensorEntity): class HomeKitHumiditySensor(HomeKitEntity, SensorEntity):
"""Representation of a Homekit humidity sensor.""" """Representation of a Homekit humidity sensor."""

View File

@ -0,0 +1,84 @@
"""Make sure that an Arlo Baby can be setup."""
from homeassistant.helpers import device_registry as dr, entity_registry as er
from tests.components.homekit_controller.common import (
Helper,
setup_accessories_from_file,
setup_test_accessories,
)
async def test_arlo_baby_setup(hass):
"""Test that an Arlo Baby can be correctly setup in HA."""
accessories = await setup_accessories_from_file(hass, "arlo_baby.json")
config_entry, pairing = await setup_test_accessories(hass, accessories)
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
sensors = [
(
"camera.arlobabya0",
"homekit-00A0000000000-aid:1",
"ArloBabyA0",
),
(
"binary_sensor.arlobabya0",
"homekit-00A0000000000-500",
"ArloBabyA0",
),
(
"sensor.arlobabya0_battery",
"homekit-00A0000000000-700",
"ArloBabyA0 Battery",
),
(
"sensor.arlobabya0_humidity",
"homekit-00A0000000000-900",
"ArloBabyA0 Humidity",
),
(
"sensor.arlobabya0_temperature",
"homekit-00A0000000000-1000",
"ArloBabyA0 Temperature",
),
(
"sensor.arlobabya0_air_quality",
"homekit-00A0000000000-aid:1-sid:800-cid:802",
"ArloBabyA0 - Air Quality",
),
(
"light.arlobabya0",
"homekit-00A0000000000-1100",
"ArloBabyA0",
),
]
device_ids = set()
for (entity_id, unique_id, friendly_name) in sensors:
entry = entity_registry.async_get(entity_id)
assert entry.unique_id == unique_id
helper = Helper(
hass,
entity_id,
pairing,
accessories[0],
config_entry,
)
state = await helper.poll_and_get_state()
assert state.attributes["friendly_name"] == friendly_name
device = device_registry.async_get(entry.device_id)
assert device.manufacturer == "Netgear, Inc"
assert device.name == "ArloBabyA0"
assert device.model == "ABC1000"
assert device.sw_version == "1.10.931"
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

View File

@ -2,6 +2,8 @@
from aiohomekit.model.characteristics import CharacteristicsTypes from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes from aiohomekit.model.services import ServicesTypes
from homeassistant.helpers import entity_registry as er
from tests.components.homekit_controller.common import setup_test_component from tests.components.homekit_controller.common import setup_test_component
@ -35,6 +37,12 @@ async def test_air_quality_sensor_read_state(hass, utcnow):
"""Test reading the state of a HomeKit temperature sensor accessory.""" """Test reading the state of a HomeKit temperature sensor accessory."""
helper = await setup_test_component(hass, create_air_quality_sensor_service) helper = await setup_test_component(hass, create_air_quality_sensor_service)
entity_registry = er.async_get(hass)
entity_registry.async_update_entity(
entity_id="air_quality.testdevice", disabled_by=None
)
await hass.async_block_till_done()
state = await helper.poll_and_get_state() state = await helper.poll_and_get_state()
assert state.state == "4444" assert state.state == "4444"

View File

@ -0,0 +1,484 @@
[
{
"aid": 1,
"services": [
{
"type": "0000003E-0000-1000-8000-0026BB765291",
"iid": 1,
"characteristics": [
{
"type": "00000023-0000-1000-8000-0026BB765291",
"iid": 2,
"value": "ArloBabyA0",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000020-0000-1000-8000-0026BB765291",
"iid": 3,
"value": "Netgear, Inc",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000030-0000-1000-8000-0026BB765291",
"iid": 4,
"value": "00A0000000000",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000021-0000-1000-8000-0026BB765291",
"iid": 5,
"value": "ABC1000",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000052-0000-1000-8000-0026BB765291",
"iid": 7,
"value": "1.10.931",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000014-0000-1000-8000-0026BB765291",
"iid": 6,
"perms": [
"pw"
],
"format": "bool"
}
]
},
{
"type": "000000A2-0000-1000-8000-0026BB765291",
"iid": 20,
"characteristics": [
{
"type": "00000037-0000-1000-8000-0026BB765291",
"iid": 21,
"value": "1.1.0",
"perms": [
"pr"
],
"format": "string"
}
]
},
{
"type": "00000110-0000-1000-8000-0026BB765291",
"iid": 100,
"characteristics": [
{
"type": "00000120-0000-1000-8000-0026BB765291",
"iid": 106,
"value": "AQEB",
"perms": [
"pr",
"ev"
],
"format": "tlv8"
},
{
"type": "00000114-0000-1000-8000-0026BB765291",
"iid": 101,
"value": "AY8BAQACFQEBAAEBAQEBAQIBAAMBAAQBAAUBAQMLAQKABwICOAQDAR4DCwECAAUCAsADAwEeAwsBAgAEAgIAAwMBHgMLAQIABQIC0AIDAR4DCwECgAICAmgBAwEeAwsBAuABAgIOAQMBHgMLAQKAAgIC4AEDAR4DCwEC4AECAmgBAwEeAwsBAkABAgLwAAMBHg==",
"perms": [
"pr"
],
"format": "tlv8"
},
{
"type": "00000115-0000-1000-8000-0026BB765291",
"iid": 102,
"value": "AQ4BAQMCCQEBAQIBAAMBAQIBAA==",
"perms": [
"pr"
],
"format": "tlv8"
},
{
"type": "00000116-0000-1000-8000-0026BB765291",
"iid": 103,
"value": "AgEAAgEBAgEC",
"perms": [
"pr"
],
"format": "tlv8"
},
{
"type": "00000117-0000-1000-8000-0026BB765291",
"iid": 104,
"value": "",
"perms": [
"pr",
"pw"
],
"format": "tlv8"
},
{
"type": "00000118-0000-1000-8000-0026BB765291",
"iid": 108,
"value": "",
"perms": [
"pr",
"pw"
],
"format": "tlv8"
}
]
},
{
"type": "00000110-0000-1000-8000-0026BB765291",
"iid": 110,
"characteristics": [
{
"type": "00000120-0000-1000-8000-0026BB765291",
"iid": 116,
"value": "AQEA",
"perms": [
"pr",
"ev"
],
"format": "tlv8"
},
{
"type": "00000114-0000-1000-8000-0026BB765291",
"iid": 111,
"value": "AWgBAQACFQEBAAEBAQEBAQIBAAMBAAQBAAUBAQMLAQIABQIC0AIDAR4DCwECgAICAmgBAwEeAwsBAuABAgIOAQMBHgMLAQKAAgIC4AEDAR4DCwEC4AECAmgBAwEeAwsBAkABAgLwAAMBHg==",
"perms": [
"pr"
],
"format": "tlv8"
},
{
"type": "00000115-0000-1000-8000-0026BB765291",
"iid": 112,
"value": "AQ4BAQMCCQEBAQIBAAMBAQIBAA==",
"perms": [
"pr"
],
"format": "tlv8"
},
{
"type": "00000116-0000-1000-8000-0026BB765291",
"iid": 113,
"value": "AgEAAgEBAgEC",
"perms": [
"pr"
],
"format": "tlv8"
},
{
"type": "00000117-0000-1000-8000-0026BB765291",
"iid": 114,
"value": "",
"perms": [
"pr",
"pw"
],
"format": "tlv8"
},
{
"type": "00000118-0000-1000-8000-0026BB765291",
"iid": 118,
"value": "",
"perms": [
"pr",
"pw"
],
"format": "tlv8"
}
]
},
{
"type": "00000112-0000-1000-8000-0026BB765291",
"iid": 300,
"characteristics": [
{
"type": "0000011A-0000-1000-8000-0026BB765291",
"iid": 302,
"value": false,
"perms": [
"pr",
"pw",
"ev"
],
"format": "bool"
}
]
},
{
"type": "00000113-0000-1000-8000-0026BB765291",
"iid": 400,
"characteristics": [
{
"type": "0000011A-0000-1000-8000-0026BB765291",
"iid": 402,
"value": false,
"perms": [
"pr",
"pw",
"ev"
],
"format": "bool"
},
{
"type": "00000119-0000-1000-8000-0026BB765291",
"iid": 403,
"value": 50,
"perms": [
"pr",
"pw",
"ev"
],
"format": "uint8",
"minValue": 0,
"maxValue": 100,
"minStep": 1,
"unit": "percentage"
}
]
},
{
"type": "00000085-0000-1000-8000-0026BB765291",
"iid": 500,
"characteristics": [
{
"type": "00000023-0000-1000-8000-0026BB765291",
"iid": 501,
"value": "Motion",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000022-0000-1000-8000-0026BB765291",
"iid": 502,
"value": false,
"perms": [
"pr",
"ev"
],
"format": "bool"
}
]
},
{
"type": "00000096-0000-1000-8000-0026BB765291",
"iid": 700,
"characteristics": [
{
"type": "00000068-0000-1000-8000-0026BB765291",
"iid": 701,
"value": 82,
"perms": [
"pr",
"ev"
],
"format": "uint8",
"minValue": 0,
"maxValue": 100,
"minStep": 1,
"unit": "percentage"
},
{
"type": "0000008F-0000-1000-8000-0026BB765291",
"iid": 702,
"value": 0,
"perms": [
"pr",
"ev"
],
"format": "uint8",
"minValue": 0,
"maxValue": 2,
"minStep": 1
},
{
"type": "00000079-0000-1000-8000-0026BB765291",
"iid": 703,
"value": 0,
"perms": [
"pr",
"ev"
],
"format": "uint8",
"minValue": 0,
"maxValue": 2,
"minStep": 1
}
]
},
{
"type": "0000008D-0000-1000-8000-0026BB765291",
"iid": 800,
"characteristics": [
{
"type": "00000023-0000-1000-8000-0026BB765291",
"iid": 801,
"value": "Air Quality",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000095-0000-1000-8000-0026BB765291",
"iid": 802,
"value": 1,
"perms": [
"pr",
"ev"
],
"format": "uint8",
"minValue": 0,
"maxValue": 5,
"minStep": 1
}
]
},
{
"type": "00000082-0000-1000-8000-0026BB765291",
"iid": 900,
"characteristics": [
{
"type": "00000023-0000-1000-8000-0026BB765291",
"iid": 901,
"value": "Humidity",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000010-0000-1000-8000-0026BB765291",
"iid": 902,
"value": 60.099998,
"perms": [
"pr",
"ev"
],
"format": "float",
"minValue": 0.0,
"maxValue": 100.0,
"minStep": 1.0,
"unit": "percentage"
}
]
},
{
"type": "0000008A-0000-1000-8000-0026BB765291",
"iid": 1000,
"characteristics": [
{
"type": "00000023-0000-1000-8000-0026BB765291",
"iid": 1001,
"value": "Temperature",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000011-0000-1000-8000-0026BB765291",
"iid": 1002,
"value": 24.0,
"perms": [
"pr",
"ev"
],
"format": "float",
"minValue": 0.0,
"maxValue": 100.0,
"minStep": 0.1,
"unit": "celsius"
}
]
},
{
"type": "00000043-0000-1000-8000-0026BB765291",
"iid": 1100,
"characteristics": [
{
"type": "00000023-0000-1000-8000-0026BB765291",
"iid": 1101,
"value": "Nightlight",
"perms": [
"pr"
],
"format": "string"
},
{
"type": "00000025-0000-1000-8000-0026BB765291",
"iid": 1102,
"value": false,
"perms": [
"pr",
"pw",
"ev"
],
"format": "bool"
},
{
"type": "00000008-0000-1000-8000-0026BB765291",
"iid": 1103,
"value": 100,
"perms": [
"pr",
"pw",
"ev"
],
"format": "int",
"minValue": 0,
"maxValue": 100,
"minStep": 1,
"unit": "percentage"
},
{
"type": "00000013-0000-1000-8000-0026BB765291",
"iid": 1104,
"value": 0.0,
"perms": [
"pr",
"pw",
"ev"
],
"format": "float",
"minValue": 0.0,
"maxValue": 360.0,
"minStep": 1.0,
"unit": "arcdegrees"
},
{
"type": "0000002F-0000-1000-8000-0026BB765291",
"iid": 1105,
"value": 0.0,
"perms": [
"pr",
"pw",
"ev"
],
"format": "float",
"minValue": 0.0,
"maxValue": 100.0,
"minStep": 1.0,
"unit": "percentage"
}
]
}
]
}
]