-
-
Notifications
You must be signed in to change notification settings - Fork 28.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for homekit air quality sensors (#30510)
* Add air quality sensor * Fix comment from review * Fix comment from review * Lint fix
- Loading branch information
1 parent
1fffa21
commit a58c796
Showing
4 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
homeassistant/components/homekit_controller/air_quality.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,4 +29,5 @@ | |
"smoke": "binary_sensor", | ||
"fan": "fan", | ||
"fanv2": "fan", | ||
"air-quality": "air_quality", | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |