diff --git a/src/main/java/com/beowulfe/hap/accessories/OccupancySensor.java b/src/main/java/com/beowulfe/hap/accessories/OccupancySensor.java
new file mode 100644
index 000000000..3b177e89a
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/accessories/OccupancySensor.java
@@ -0,0 +1,41 @@
+package com.beowulfe.hap.accessories;
+
+import com.beowulfe.hap.HomekitAccessory;
+import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
+import com.beowulfe.hap.Service;
+import com.beowulfe.hap.impl.services.OccupancySensorService;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * An occupancy sensor that reports whether occupancy has been detected.
+ *
+ *
Occupancy sensors that run on batteries will need to implement this interface and also
+ * implement {@link BatteryStatusAccessory}.
+ *
+ * @author Tim Harper
+ */
+public interface OccupancySensor extends HomekitAccessory {
+ /**
+ * Retrieves the state of the occupancy sensor. If true then occupancy has been detected.
+ *
+ * @return a future that will contain the occupancy sensor's state
+ */
+ CompletableFuture getOccupancyDetected();
+
+ @Override
+ default Collection getServices() {
+ return Collections.singleton(new OccupancySensorService(this));
+ }
+
+ /**
+ * Subscribes to changes in the occupancy sensor.
+ *
+ * @param callback the function to call when the state changes.
+ */
+ void subscribeOccupancyDetected(HomekitCharacteristicChangeCallback callback);
+
+ /** Unsubscribes from changes in the occupancy sensor. */
+ void unsubscribeOccupancyDetected();
+}
diff --git a/src/main/java/com/beowulfe/hap/impl/characteristics/occupancysensor/OccupancyDetectedStateCharacteristic.java b/src/main/java/com/beowulfe/hap/impl/characteristics/occupancysensor/OccupancyDetectedStateCharacteristic.java
new file mode 100644
index 000000000..15ff8cfe0
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/impl/characteristics/occupancysensor/OccupancyDetectedStateCharacteristic.java
@@ -0,0 +1,38 @@
+package com.beowulfe.hap.impl.characteristics.occupancysensor;
+
+import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
+import com.beowulfe.hap.accessories.OccupancySensor;
+import com.beowulfe.hap.characteristics.BooleanCharacteristic;
+import com.beowulfe.hap.characteristics.EventableCharacteristic;
+import java.util.concurrent.CompletableFuture;
+
+public class OccupancyDetectedStateCharacteristic extends BooleanCharacteristic
+ implements EventableCharacteristic {
+
+ private final OccupancySensor occupancySensor;
+
+ public OccupancyDetectedStateCharacteristic(OccupancySensor occupancySensor) {
+ super("00000071-0000-1000-8000-0026BB765291", false, true, "Occupancy Detected");
+ this.occupancySensor = occupancySensor;
+ }
+
+ @Override
+ protected CompletableFuture getValue() {
+ return occupancySensor.getOccupancyDetected();
+ }
+
+ @Override
+ protected void setValue(Boolean value) throws Exception {
+ // Read Only
+ }
+
+ @Override
+ public void subscribe(HomekitCharacteristicChangeCallback callback) {
+ occupancySensor.subscribeOccupancyDetected(callback);
+ }
+
+ @Override
+ public void unsubscribe() {
+ occupancySensor.unsubscribeOccupancyDetected();
+ }
+}
diff --git a/src/main/java/com/beowulfe/hap/impl/services/OccupancySensorService.java b/src/main/java/com/beowulfe/hap/impl/services/OccupancySensorService.java
new file mode 100644
index 000000000..73704f6d9
--- /dev/null
+++ b/src/main/java/com/beowulfe/hap/impl/services/OccupancySensorService.java
@@ -0,0 +1,16 @@
+package com.beowulfe.hap.impl.services;
+
+import com.beowulfe.hap.accessories.OccupancySensor;
+import com.beowulfe.hap.impl.characteristics.occupancysensor.OccupancyDetectedStateCharacteristic;
+
+public class OccupancySensorService extends AbstractServiceImpl {
+
+ public OccupancySensorService(OccupancySensor occupancySensor) {
+ this(occupancySensor, occupancySensor.getLabel());
+ }
+
+ public OccupancySensorService(OccupancySensor occupancySensor, String serviceName) {
+ super("00000086-0000-1000-8000-0026BB765291", occupancySensor, serviceName);
+ addCharacteristic(new OccupancyDetectedStateCharacteristic(occupancySensor));
+ }
+}