diff --git a/homeassistant/components/homekit_controller/const.py b/homeassistant/components/homekit_controller/const.py index 924d27218a2..6aa5dc93662 100644 --- a/homeassistant/components/homekit_controller/const.py +++ b/homeassistant/components/homekit_controller/const.py @@ -21,6 +21,7 @@ HOMEKIT_ACCESSORY_DISPATCH = { "lock-mechanism": "lock", "contact": "binary_sensor", "motion": "binary_sensor", + "carbon-dioxide": "sensor", "humidity": "sensor", "light": "sensor", "temperature": "sensor", diff --git a/homeassistant/components/homekit_controller/sensor.py b/homeassistant/components/homekit_controller/sensor.py index 16109f08c10..596b697bede 100644 --- a/homeassistant/components/homekit_controller/sensor.py +++ b/homeassistant/components/homekit_controller/sensor.py @@ -1,4 +1,6 @@ """Support for Homekit sensors.""" +from homekit.model.characteristics import CharacteristicsTypes + from homeassistant.const import TEMP_CELSIUS from . import KNOWN_DEVICES, HomeKitEntity @@ -6,39 +8,11 @@ from . import KNOWN_DEVICES, HomeKitEntity HUMIDITY_ICON = "mdi:water-percent" TEMP_C_ICON = "mdi:thermometer" BRIGHTNESS_ICON = "mdi:brightness-6" +CO2_ICON = "mdi:periodic-table-co2" UNIT_PERCENT = "%" UNIT_LUX = "lux" - - -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 covers.""" - hkid = config_entry.data["AccessoryPairingID"] - conn = hass.data[KNOWN_DEVICES][hkid] - - def async_add_service(aid, service): - devtype = service["stype"] - info = {"aid": aid, "iid": service["iid"]} - if devtype == "humidity": - async_add_entities([HomeKitHumiditySensor(conn, info)], True) - return True - - if devtype == "temperature": - async_add_entities([HomeKitTemperatureSensor(conn, info)], True) - return True - - if devtype == "light": - async_add_entities([HomeKitLightSensor(conn, info)], True) - return True - - return False - - conn.add_listener(async_add_service) +UNIT_CO2 = "ppm" class HomeKitHumiditySensor(HomeKitEntity): @@ -51,9 +25,6 @@ class HomeKitHumiditySensor(HomeKitEntity): def get_characteristic_types(self): """Define the homekit characteristics the entity is tracking.""" - # pylint: disable=import-error - from homekit.model.characteristics import CharacteristicsTypes - return [CharacteristicsTypes.RELATIVE_HUMIDITY_CURRENT] @property @@ -90,9 +61,6 @@ class HomeKitTemperatureSensor(HomeKitEntity): def get_characteristic_types(self): """Define the homekit characteristics the entity is tracking.""" - # pylint: disable=import-error - from homekit.model.characteristics import CharacteristicsTypes - return [CharacteristicsTypes.TEMPERATURE_CURRENT] @property @@ -129,9 +97,6 @@ class HomeKitLightSensor(HomeKitEntity): def get_characteristic_types(self): """Define the homekit characteristics the entity is tracking.""" - # pylint: disable=import-error - from homekit.model.characteristics import CharacteristicsTypes - return [CharacteristicsTypes.LIGHT_LEVEL_CURRENT] @property @@ -156,3 +121,68 @@ class HomeKitLightSensor(HomeKitEntity): def state(self): """Return the current light level in lux.""" return self._state + + +class HomeKitCarbonDioxideSensor(HomeKitEntity): + """Representation of a Homekit Carbon Dioxide sensor.""" + + def __init__(self, *args): + """Initialise the entity.""" + super().__init__(*args) + self._state = None + + def get_characteristic_types(self): + """Define the homekit characteristics the entity is tracking.""" + return [CharacteristicsTypes.CARBON_DIOXIDE_LEVEL] + + @property + def name(self): + """Return the name of the device.""" + return "{} {}".format(super().name, "CO2") + + @property + def icon(self): + """Return the sensor icon.""" + return CO2_ICON + + @property + def unit_of_measurement(self): + """Return units for the sensor.""" + return UNIT_CO2 + + def _update_carbon_dioxide_level(self, value): + self._state = value + + @property + def state(self): + """Return the current CO2 level in ppm.""" + return self._state + + +ENTITY_TYPES = { + "humidity": HomeKitHumiditySensor, + "temperature": HomeKitTemperatureSensor, + "light": HomeKitLightSensor, + "carbon-dioxide": HomeKitCarbonDioxideSensor, +} + + +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 sensors.""" + hkid = config_entry.data["AccessoryPairingID"] + conn = hass.data[KNOWN_DEVICES][hkid] + + def async_add_service(aid, service): + entity_class = ENTITY_TYPES.get(service["stype"]) + if not entity_class: + return False + info = {"aid": aid, "iid": service["iid"]} + async_add_entities([entity_class(conn, info)], True) + return True + + conn.add_listener(async_add_service) diff --git a/tests/components/homekit_controller/test_sensor.py b/tests/components/homekit_controller/test_sensor.py index e17ad2a8c73..13d844e0162 100644 --- a/tests/components/homekit_controller/test_sensor.py +++ b/tests/components/homekit_controller/test_sensor.py @@ -4,6 +4,7 @@ from tests.components.homekit_controller.common import FakeService, setup_test_c TEMPERATURE = ("temperature", "temperature.current") HUMIDITY = ("humidity", "relative-humidity.current") LIGHT_LEVEL = ("light", "light-level.current") +CARBON_DIOXIDE_LEVEL = ("carbon-dioxide", "carbon-dioxide.level") def create_temperature_sensor_service(): @@ -36,6 +37,16 @@ def create_light_level_sensor_service(): return service +def create_carbon_dioxide_level_sensor_service(): + """Define carbon dioxide level characteristics.""" + service = FakeService("public.hap.service.sensor.carbon-dioxide") + + cur_state = service.add_characteristic("carbon-dioxide.level") + cur_state.value = 0 + + return service + + async def test_temperature_sensor_read_state(hass, utcnow): """Test reading the state of a HomeKit temperature sensor accessory.""" sensor = create_temperature_sensor_service() @@ -76,3 +87,17 @@ async def test_light_level_sensor_read_state(hass, utcnow): helper.characteristics[LIGHT_LEVEL].value = 20 state = await helper.poll_and_get_state() assert state.state == "20" + + +async def test_carbon_dioxide_level_sensor_read_state(hass, utcnow): + """Test reading the state of a HomeKit carbon dioxide sensor accessory.""" + sensor = create_carbon_dioxide_level_sensor_service() + helper = await setup_test_component(hass, [sensor], suffix="co2") + + helper.characteristics[CARBON_DIOXIDE_LEVEL].value = 10 + state = await helper.poll_and_get_state() + assert state.state == "10" + + helper.characteristics[CARBON_DIOXIDE_LEVEL].value = 20 + state = await helper.poll_and_get_state() + assert state.state == "20"