Add support for homekit air quality sensors (#30510)
* Add air quality sensor * Fix comment from review * Fix comment from review * Lint fix
This commit is contained in:
parent
1fffa210e1
commit
a58c796641
4 changed files with 156 additions and 0 deletions
|
@ -109,6 +109,16 @@ class HomeKitEntity(Entity):
|
|||
return
|
||||
setup_fn(char)
|
||||
|
||||
def get_hk_char_value(self, characteristic_type):
|
||||
"""Return the value for a given characteristic type enum."""
|
||||
state = self._accessory.current_state.get(self._aid)
|
||||
if not state:
|
||||
return None
|
||||
char = self._chars.get(CharacteristicsTypes.get_short(characteristic_type))
|
||||
if not char:
|
||||
return None
|
||||
return state.get(char, {}).get("value")
|
||||
|
||||
@callback
|
||||
def async_state_changed(self):
|
||||
"""Collect new data from bridge and update the entity state in hass."""
|
||||
|
|
98
homeassistant/components/homekit_controller/air_quality.py
Normal file
98
homeassistant/components/homekit_controller/air_quality.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
"""Support for HomeKit Controller air quality sensors."""
|
||||
from homekit.model.characteristics import CharacteristicsTypes
|
||||
|
||||
from homeassistant.components.air_quality import AirQualityEntity
|
||||
|
||||
from . import KNOWN_DEVICES, HomeKitEntity
|
||||
|
||||
AIR_QUALITY_TEXT = {
|
||||
0: "unknown",
|
||||
1: "excellent",
|
||||
2: "good",
|
||||
3: "fair",
|
||||
4: "inferior",
|
||||
5: "poor",
|
||||
}
|
||||
|
||||
|
||||
class HomeAirQualitySensor(HomeKitEntity, AirQualityEntity):
|
||||
"""Representation of a HomeKit Controller Air Quality sensor."""
|
||||
|
||||
def get_characteristic_types(self):
|
||||
"""Define the homekit characteristics the entity cares about."""
|
||||
return [
|
||||
CharacteristicsTypes.AIR_QUALITY,
|
||||
CharacteristicsTypes.DENSITY_PM25,
|
||||
CharacteristicsTypes.DENSITY_PM10,
|
||||
CharacteristicsTypes.DENSITY_OZONE,
|
||||
CharacteristicsTypes.DENSITY_NO2,
|
||||
CharacteristicsTypes.DENSITY_SO2,
|
||||
CharacteristicsTypes.DENSITY_VOC,
|
||||
]
|
||||
|
||||
@property
|
||||
def particulate_matter_2_5(self):
|
||||
"""Return the particulate matter 2.5 level."""
|
||||
return self.get_hk_char_value(CharacteristicsTypes.DENSITY_PM25)
|
||||
|
||||
@property
|
||||
def particulate_matter_10(self):
|
||||
"""Return the particulate matter 10 level."""
|
||||
return self.get_hk_char_value(CharacteristicsTypes.DENSITY_PM10)
|
||||
|
||||
@property
|
||||
def ozone(self):
|
||||
"""Return the O3 (ozone) level."""
|
||||
return self.get_hk_char_value(CharacteristicsTypes.DENSITY_OZONE)
|
||||
|
||||
@property
|
||||
def sulphur_dioxide(self):
|
||||
"""Return the SO2 (sulphur dioxide) level."""
|
||||
return self.get_hk_char_value(CharacteristicsTypes.DENSITY_SO2)
|
||||
|
||||
@property
|
||||
def nitrogen_dioxide(self):
|
||||
"""Return the NO2 (nitrogen dioxide) level."""
|
||||
return self.get_hk_char_value(CharacteristicsTypes.DENSITY_NO2)
|
||||
|
||||
@property
|
||||
def air_quality_text(self):
|
||||
"""Return the Air Quality Index (AQI)."""
|
||||
air_quality = self.get_hk_char_value(CharacteristicsTypes.AIR_QUALITY)
|
||||
return AIR_QUALITY_TEXT.get(air_quality, "unknown")
|
||||
|
||||
@property
|
||||
def volatile_organic_compounds(self):
|
||||
"""Return the volatile organic compounds (VOC) level."""
|
||||
return self.get_hk_char_value(CharacteristicsTypes.DENSITY_VOC)
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the device state attributes."""
|
||||
data = {"air_quality_text": self.air_quality_text}
|
||||
|
||||
voc = self.volatile_organic_compounds
|
||||
if voc:
|
||||
data["volatile_organic_compounds"] = voc
|
||||
|
||||
return data
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
"""Legacy set up platform."""
|
||||
pass
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Homekit air quality sensor."""
|
||||
hkid = config_entry.data["AccessoryPairingID"]
|
||||
conn = hass.data[KNOWN_DEVICES][hkid]
|
||||
|
||||
def async_add_service(aid, service):
|
||||
if service["stype"] != "air-quality":
|
||||
return False
|
||||
info = {"aid": aid, "iid": service["iid"]}
|
||||
async_add_entities([HomeAirQualitySensor(conn, info)], True)
|
||||
return True
|
||||
|
||||
conn.add_listener(async_add_service)
|
|
@ -29,4 +29,5 @@ HOMEKIT_ACCESSORY_DISPATCH = {
|
|||
"smoke": "binary_sensor",
|
||||
"fan": "fan",
|
||||
"fanv2": "fan",
|
||||
"air-quality": "air_quality",
|
||||
}
|
||||
|
|
47
tests/components/homekit_controller/test_air_quality.py
Normal file
47
tests/components/homekit_controller/test_air_quality.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
"""Basic checks for HomeKit air quality sensor."""
|
||||
from tests.components.homekit_controller.common import FakeService, setup_test_component
|
||||
|
||||
|
||||
def create_air_quality_sensor_service():
|
||||
"""Define temperature characteristics."""
|
||||
service = FakeService("public.hap.service.sensor.air-quality")
|
||||
|
||||
cur_state = service.add_characteristic("air-quality")
|
||||
cur_state.value = 5
|
||||
|
||||
cur_state = service.add_characteristic("density.ozone")
|
||||
cur_state.value = 1111
|
||||
|
||||
cur_state = service.add_characteristic("density.no2")
|
||||
cur_state.value = 2222
|
||||
|
||||
cur_state = service.add_characteristic("density.so2")
|
||||
cur_state.value = 3333
|
||||
|
||||
cur_state = service.add_characteristic("density.pm25")
|
||||
cur_state.value = 4444
|
||||
|
||||
cur_state = service.add_characteristic("density.pm10")
|
||||
cur_state.value = 5555
|
||||
|
||||
cur_state = service.add_characteristic("density.voc")
|
||||
cur_state.value = 6666
|
||||
|
||||
return service
|
||||
|
||||
|
||||
async def test_air_quality_sensor_read_state(hass, utcnow):
|
||||
"""Test reading the state of a HomeKit temperature sensor accessory."""
|
||||
sensor = create_air_quality_sensor_service()
|
||||
helper = await setup_test_component(hass, [sensor])
|
||||
|
||||
state = await helper.poll_and_get_state()
|
||||
assert state.state == "4444"
|
||||
|
||||
assert state.attributes["air_quality_text"] == "poor"
|
||||
assert state.attributes["ozone"] == 1111
|
||||
assert state.attributes["nitrogen_dioxide"] == 2222
|
||||
assert state.attributes["sulphur_dioxide"] == 3333
|
||||
assert state.attributes["particulate_matter_2_5"] == 4444
|
||||
assert state.attributes["particulate_matter_10"] == 5555
|
||||
assert state.attributes["volatile_organic_compounds"] == 6666
|
Loading…
Add table
Reference in a new issue