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."""
import logging
from aiohomekit.model.characteristics import CharacteristicsTypes
from aiohomekit.model.services import ServicesTypes
@ -7,6 +9,8 @@ from homeassistant.core import callback
from . import KNOWN_DEVICES, HomeKitEntity
_LOGGER = logging.getLogger(__name__)
AIR_QUALITY_TEXT = {
0: "unknown",
1: "excellent",
@ -20,6 +24,20 @@ AIR_QUALITY_TEXT = {
class HomeAirQualitySensor(HomeKitEntity, AirQualityEntity):
"""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):
"""Define the homekit characteristics the entity cares about."""
return [

View File

@ -4,12 +4,19 @@ from aiohomekit.model.services import ServicesTypes
from homeassistant.components.sensor import STATE_CLASS_MEASUREMENT, SensorEntity
from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_MILLION,
DEVICE_CLASS_AQI,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_NITROGEN_DIOXIDE,
DEVICE_CLASS_OZONE,
DEVICE_CLASS_PM10,
DEVICE_CLASS_PM25,
DEVICE_CLASS_POWER,
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_SULPHUR_DIOXIDE,
DEVICE_CLASS_TEMPERATURE,
LIGHT_LUX,
PERCENTAGE,
@ -52,7 +59,7 @@ SIMPLE_SENSOR = {
"state_class": STATE_CLASS_MEASUREMENT,
"unit": PRESSURE_HPA,
},
CharacteristicsTypes.get_uuid(CharacteristicsTypes.TEMPERATURE_CURRENT): {
CharacteristicsTypes.TEMPERATURE_CURRENT: {
"name": "Current Temperature",
"device_class": DEVICE_CLASS_TEMPERATURE,
"state_class": STATE_CLASS_MEASUREMENT,
@ -62,7 +69,7 @@ SIMPLE_SENSOR = {
"probe": lambda char: char.service.type
!= ServicesTypes.get_uuid(ServicesTypes.TEMPERATURE_SENSOR),
},
CharacteristicsTypes.get_uuid(CharacteristicsTypes.RELATIVE_HUMIDITY_CURRENT): {
CharacteristicsTypes.RELATIVE_HUMIDITY_CURRENT: {
"name": "Current Humidity",
"device_class": DEVICE_CLASS_HUMIDITY,
"state_class": STATE_CLASS_MEASUREMENT,
@ -72,8 +79,52 @@ SIMPLE_SENSOR = {
"probe": lambda char: char.service.type
!= 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):
"""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.services import ServicesTypes
from homeassistant.helpers import entity_registry as er
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."""
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()
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"
}
]
}
]
}
]