From fccb13b76257cc894fcbd219cdba0885f64579d3 Mon Sep 17 00:00:00 2001
From: Jc2k <john.carr@unrouted.co.uk>
Date: Mon, 30 Dec 2019 08:05:49 +0000
Subject: [PATCH] Add homekit_controller service.sensor.smoke (#30269)

---
 .../homekit_controller/binary_sensor.py       | 37 ++++++++++++++++++-
 .../components/homekit_controller/const.py    |  1 +
 .../homekit_controller/test_binary_sensor.py  | 27 ++++++++++++++
 3 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/homeassistant/components/homekit_controller/binary_sensor.py b/homeassistant/components/homekit_controller/binary_sensor.py
index 1e1c8ef5d44..2998ce18641 100644
--- a/homeassistant/components/homekit_controller/binary_sensor.py
+++ b/homeassistant/components/homekit_controller/binary_sensor.py
@@ -3,7 +3,10 @@ import logging
 
 from homekit.model.characteristics import CharacteristicsTypes
 
-from homeassistant.components.binary_sensor import BinarySensorDevice
+from homeassistant.components.binary_sensor import (
+    DEVICE_CLASS_SMOKE,
+    BinarySensorDevice,
+)
 
 from . import KNOWN_DEVICES, HomeKitEntity
 
@@ -57,7 +60,37 @@ class HomeKitContactSensor(HomeKitEntity, BinarySensorDevice):
         return self._state == 1
 
 
-ENTITY_TYPES = {"motion": HomeKitMotionSensor, "contact": HomeKitContactSensor}
+class HomeKitSmokeSensor(HomeKitEntity, BinarySensorDevice):
+    """Representation of a Homekit smoke sensor."""
+
+    def __init__(self, *args):
+        """Initialise the entity."""
+        super().__init__(*args)
+        self._state = None
+
+    @property
+    def device_class(self) -> str:
+        """Return the class of this sensor."""
+        return DEVICE_CLASS_SMOKE
+
+    def get_characteristic_types(self):
+        """Define the homekit characteristics the entity is tracking."""
+        return [CharacteristicsTypes.SMOKE_DETECTED]
+
+    def _update_smoke_detected(self, value):
+        self._state = value
+
+    @property
+    def is_on(self):
+        """Return true if smoke is currently detected."""
+        return self._state == 1
+
+
+ENTITY_TYPES = {
+    "motion": HomeKitMotionSensor,
+    "contact": HomeKitContactSensor,
+    "smoke": HomeKitSmokeSensor,
+}
 
 
 async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
diff --git a/homeassistant/components/homekit_controller/const.py b/homeassistant/components/homekit_controller/const.py
index 09a7df2a2bf..204f0e07d3e 100644
--- a/homeassistant/components/homekit_controller/const.py
+++ b/homeassistant/components/homekit_controller/const.py
@@ -26,4 +26,5 @@ HOMEKIT_ACCESSORY_DISPATCH = {
     "light": "sensor",
     "temperature": "sensor",
     "battery": "sensor",
+    "smoke": "binary_sensor",
 }
diff --git a/tests/components/homekit_controller/test_binary_sensor.py b/tests/components/homekit_controller/test_binary_sensor.py
index 1b73021e44c..f472ac38d1d 100644
--- a/tests/components/homekit_controller/test_binary_sensor.py
+++ b/tests/components/homekit_controller/test_binary_sensor.py
@@ -3,6 +3,7 @@ from tests.components.homekit_controller.common import FakeService, setup_test_c
 
 MOTION_DETECTED = ("motion", "motion-detected")
 CONTACT_STATE = ("contact", "contact-state")
+SMOKE_DETECTED = ("smoke", "smoke-detected")
 
 
 def create_motion_sensor_service():
@@ -51,3 +52,29 @@ async def test_contact_sensor_read_state(hass, utcnow):
     helper.characteristics[CONTACT_STATE].value = 1
     state = await helper.poll_and_get_state()
     assert state.state == "on"
+
+
+def create_smoke_sensor_service():
+    """Define smoke sensor characteristics."""
+    service = FakeService("public.hap.service.sensor.smoke")
+
+    cur_state = service.add_characteristic("smoke-detected")
+    cur_state.value = 0
+
+    return service
+
+
+async def test_smoke_sensor_read_state(hass, utcnow):
+    """Test that we can read the state of a HomeKit contact accessory."""
+    sensor = create_smoke_sensor_service()
+    helper = await setup_test_component(hass, [sensor])
+
+    helper.characteristics[SMOKE_DETECTED].value = 0
+    state = await helper.poll_and_get_state()
+    assert state.state == "off"
+
+    helper.characteristics[SMOKE_DETECTED].value = 1
+    state = await helper.poll_and_get_state()
+    assert state.state == "on"
+
+    assert state.attributes["device_class"] == "smoke"
-- 
GitLab