Skip to content

Commit

Permalink
Deprecate homekit_controller's air quality entity in favor of separat…
Browse files Browse the repository at this point in the history
…e sensor entities (#54673)
  • Loading branch information
Jc2k authored Aug 17, 2021
1 parent f39dc74 commit ea80614
Show file tree
Hide file tree
Showing 5 changed files with 647 additions and 2 deletions.
18 changes: 18 additions & 0 deletions homeassistant/components/homekit_controller/air_quality.py
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -7,6 +9,8 @@

from . import KNOWN_DEVICES, HomeKitEntity

_LOGGER = logging.getLogger(__name__)

AIR_QUALITY_TEXT = {
0: "unknown",
1: "excellent",
Expand All @@ -20,6 +24,20 @@
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 [
Expand Down
55 changes: 53 additions & 2 deletions homeassistant/components/homekit_controller/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@

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,
Expand Down Expand Up @@ -52,7 +59,7 @@
"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,
Expand All @@ -62,7 +69,7 @@
"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,
Expand All @@ -72,8 +79,52 @@
"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."""
Expand Down
Original file line number Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions tests/components/homekit_controller/test_air_quality.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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"

Expand Down
Loading

0 comments on commit ea80614

Please sign in to comment.