diff --git a/src/main/java/com/beowulfe/hap/accessories/CarbonMonoxideSensor.java b/src/main/java/com/beowulfe/hap/accessories/CarbonMonoxideSensor.java
new file mode 100644
index 000000000..6133f4ac6
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/accessories/CarbonMonoxideSensor.java
@@ -0,0 +1,46 @@
+package com.beowulfe.hap.accessories;
+
+import com.beowulfe.hap.HomekitAccessory;
+import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
+import com.beowulfe.hap.Service;
+import com.beowulfe.hap.accessories.properties.CarbonMonoxideDetectedState;
+import com.beowulfe.hap.impl.services.CarbonMonoxideSensorService;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ *
A carbon monoxide sensor reports whether carbon monoxide has been detected or not.
+ *
+ * Carbon monoxide sensors that run on batteries will need to implement this interface
+ * and also implement {@link BatteryAccessory}.
+ *
+ * @author Gaston Dombiak
+ */
+public interface CarbonMonoxideSensor extends HomekitAccessory {
+
+ /**
+ * Retrieves the state of the sensor that indicates if carbon monoxide has been detected.
+ *
+ * @return a future that will contain the carbon monoxide sensor's state
+ */
+ CompletableFuture getCarbonMonoxideDetectedState();
+
+ @Override
+ default Collection getServices() {
+ return Collections.singleton(new CarbonMonoxideSensorService(this));
+ }
+
+ /**
+ * Subscribes to changes in the carbon monoxide's state.
+ *
+ * @param callback the function to call when the state changes.
+ */
+ void subscribeCarbonMonoxideDetectedState(HomekitCharacteristicChangeCallback callback);
+
+ /**
+ * Unsubscribes from changes in the carbon monoxide's state.
+ */
+ void unsubscribeCarbonMonoxideDetectedState();
+}
diff --git a/src/main/java/com/beowulfe/hap/accessories/SmokeSensor.java b/src/main/java/com/beowulfe/hap/accessories/SmokeSensor.java
new file mode 100644
index 000000000..ff575dec7
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/accessories/SmokeSensor.java
@@ -0,0 +1,46 @@
+package com.beowulfe.hap.accessories;
+
+import com.beowulfe.hap.HomekitAccessory;
+import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
+import com.beowulfe.hap.Service;
+import com.beowulfe.hap.accessories.properties.SmokeDetectedState;
+import com.beowulfe.hap.impl.services.SmokeSensorService;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * A smoke sensor reports whether smoke has been detected or not.
+ *
+ * Smoke sensors that run on batteries will need to implement this interface
+ * and also implement {@link BatteryAccessory}.
+ *
+ * @author Gaston Dombiak
+ */
+public interface SmokeSensor extends HomekitAccessory {
+
+ /**
+ * Retrieves the state of the smoke sensor. This is whether smoke has been detected or not.
+ *
+ * @return a future that will contain the smoke sensor's state
+ */
+ CompletableFuture getSmokeDetectedState();
+
+ @Override
+ default Collection getServices() {
+ return Collections.singleton(new SmokeSensorService(this));
+ }
+
+ /**
+ * Subscribes to changes in the smoke sensor's state.
+ *
+ * @param callback the function to call when the state changes.
+ */
+ void subscribeSmokeDetectedState(HomekitCharacteristicChangeCallback callback);
+
+ /**
+ * Unsubscribes from changes in the smoke sensor's state.
+ */
+ void unsubscribeSmokeDetectedState();
+}
diff --git a/src/main/java/com/beowulfe/hap/accessories/properties/CarbonMonoxideDetectedState.java b/src/main/java/com/beowulfe/hap/accessories/properties/CarbonMonoxideDetectedState.java
new file mode 100644
index 000000000..95bcf53b1
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/accessories/properties/CarbonMonoxideDetectedState.java
@@ -0,0 +1,30 @@
+package com.beowulfe.hap.accessories.properties;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public enum CarbonMonoxideDetectedState {
+
+ NORMAL(0),
+ ABNORMAL(1);
+
+ private final static Map reverse;
+ static {
+ reverse = Arrays.stream(CarbonMonoxideDetectedState.values()).collect(Collectors.toMap(CarbonMonoxideDetectedState::getCode, t -> t));
+ }
+
+ public static CarbonMonoxideDetectedState fromCode(Integer code) {
+ return reverse.get(code);
+ }
+
+ private final int code;
+
+ CarbonMonoxideDetectedState(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+}
diff --git a/src/main/java/com/beowulfe/hap/accessories/properties/SmokeDetectedState.java b/src/main/java/com/beowulfe/hap/accessories/properties/SmokeDetectedState.java
new file mode 100644
index 000000000..159a767ee
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/accessories/properties/SmokeDetectedState.java
@@ -0,0 +1,30 @@
+package com.beowulfe.hap.accessories.properties;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public enum SmokeDetectedState {
+
+ NOT_DETECTED(0),
+ DETECTED(1);
+
+ private final static Map reverse;
+ static {
+ reverse = Arrays.stream(SmokeDetectedState.values()).collect(Collectors.toMap(SmokeDetectedState::getCode, t -> t));
+ }
+
+ public static SmokeDetectedState fromCode(Integer code) {
+ return reverse.get(code);
+ }
+
+ private final int code;
+
+ SmokeDetectedState(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+}
diff --git a/src/main/java/com/beowulfe/hap/impl/characteristics/carbonmonoxide/Carbon/CarbonMonoxideDetectedCharacteristic.java b/src/main/java/com/beowulfe/hap/impl/characteristics/carbonmonoxide/Carbon/CarbonMonoxideDetectedCharacteristic.java
new file mode 100644
index 000000000..ace90bb9b
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/impl/characteristics/carbonmonoxide/Carbon/CarbonMonoxideDetectedCharacteristic.java
@@ -0,0 +1,38 @@
+package com.beowulfe.hap.impl.characteristics.carbonmonoxide.Carbon;
+
+import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
+import com.beowulfe.hap.accessories.CarbonMonoxideSensor;
+import com.beowulfe.hap.accessories.properties.CarbonMonoxideDetectedState;
+import com.beowulfe.hap.characteristics.EnumCharacteristic;
+import com.beowulfe.hap.characteristics.EventableCharacteristic;
+
+import java.util.concurrent.CompletableFuture;
+
+public class CarbonMonoxideDetectedCharacteristic extends EnumCharacteristic implements EventableCharacteristic {
+
+ private final CarbonMonoxideSensor carbonMonoxideSensor;
+
+ public CarbonMonoxideDetectedCharacteristic(CarbonMonoxideSensor carbonMonoxideSensor) {
+ super("00000069-0000-1000-8000-0026BB765291", false, true, "Carbon Monoxide Detected", 1);
+ this.carbonMonoxideSensor = carbonMonoxideSensor;
+ }
+
+ @Override
+ protected CompletableFuture getValue() {
+ return carbonMonoxideSensor.getCarbonMonoxideDetectedState().thenApply(CarbonMonoxideDetectedState::getCode);
+ }
+
+ @Override
+ protected void setValue(Integer value) throws Exception {
+ //Read Only
+ }
+
+ @Override
+ public void subscribe(HomekitCharacteristicChangeCallback callback) {
+ carbonMonoxideSensor.subscribeCarbonMonoxideDetectedState(callback);
+ }
+
+ @Override
+ public void unsubscribe() {
+ carbonMonoxideSensor.unsubscribeCarbonMonoxideDetectedState();
+ }}
diff --git a/src/main/java/com/beowulfe/hap/impl/characteristics/smokesensor/SmokeDetectedCharacteristic.java b/src/main/java/com/beowulfe/hap/impl/characteristics/smokesensor/SmokeDetectedCharacteristic.java
new file mode 100644
index 000000000..c351697d8
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/impl/characteristics/smokesensor/SmokeDetectedCharacteristic.java
@@ -0,0 +1,39 @@
+package com.beowulfe.hap.impl.characteristics.smokesensor;
+
+import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
+import com.beowulfe.hap.accessories.SmokeSensor;
+import com.beowulfe.hap.accessories.properties.SmokeDetectedState;
+import com.beowulfe.hap.characteristics.EnumCharacteristic;
+import com.beowulfe.hap.characteristics.EventableCharacteristic;
+
+import java.util.concurrent.CompletableFuture;
+
+public class SmokeDetectedCharacteristic extends EnumCharacteristic implements EventableCharacteristic {
+
+ private final SmokeSensor smokeSensor;
+
+ public SmokeDetectedCharacteristic(SmokeSensor smokeSensor) {
+ super("00000076-0000-1000-8000-0026BB765291", false, true, "Smoke Detected", 1);
+ this.smokeSensor = smokeSensor;
+ }
+
+ @Override
+ protected CompletableFuture getValue() {
+ return smokeSensor.getSmokeDetectedState().thenApply(SmokeDetectedState::getCode);
+ }
+
+ @Override
+ protected void setValue(Integer value) throws Exception {
+ //Read Only
+ }
+
+ @Override
+ public void subscribe(HomekitCharacteristicChangeCallback callback) {
+ smokeSensor.subscribeSmokeDetectedState(callback);
+ }
+
+ @Override
+ public void unsubscribe() {
+ smokeSensor.unsubscribeSmokeDetectedState();
+ }
+}
diff --git a/src/main/java/com/beowulfe/hap/impl/services/CarbonMonoxideSensorService.java b/src/main/java/com/beowulfe/hap/impl/services/CarbonMonoxideSensorService.java
new file mode 100644
index 000000000..d1b65fe99
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/impl/services/CarbonMonoxideSensorService.java
@@ -0,0 +1,12 @@
+package com.beowulfe.hap.impl.services;
+
+import com.beowulfe.hap.accessories.CarbonMonoxideSensor;
+import com.beowulfe.hap.impl.characteristics.carbonmonoxide.Carbon.CarbonMonoxideDetectedCharacteristic;
+
+public class CarbonMonoxideSensorService extends AbstractServiceImpl {
+
+ public CarbonMonoxideSensorService(CarbonMonoxideSensor carbonMonoxideSensor) {
+ super("0000007F-0000-1000-8000-0026BB765291", carbonMonoxideSensor);
+ addCharacteristic(new CarbonMonoxideDetectedCharacteristic(carbonMonoxideSensor));
+ }
+}
diff --git a/src/main/java/com/beowulfe/hap/impl/services/SmokeSensorService.java b/src/main/java/com/beowulfe/hap/impl/services/SmokeSensorService.java
new file mode 100644
index 000000000..16026a2b2
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/impl/services/SmokeSensorService.java
@@ -0,0 +1,12 @@
+package com.beowulfe.hap.impl.services;
+
+import com.beowulfe.hap.accessories.SmokeSensor;
+import com.beowulfe.hap.impl.characteristics.smokesensor.SmokeDetectedCharacteristic;
+
+public class SmokeSensorService extends AbstractServiceImpl {
+
+ public SmokeSensorService(SmokeSensor smokeSensor) {
+ super("00000087-0000-1000-8000-0026BB765291", smokeSensor);
+ addCharacteristic(new SmokeDetectedCharacteristic(smokeSensor));
+ }
+}