Skip to content

Commit e49fcc0

Browse files
committed
Added support for motion sensors and contact sensors
1 parent c64e5b0 commit e49fcc0

File tree

7 files changed

+219
-0
lines changed

7 files changed

+219
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.beowulfe.hap.accessories;
2+
3+
import com.beowulfe.hap.HomekitAccessory;
4+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
5+
import com.beowulfe.hap.Service;
6+
import com.beowulfe.hap.accessories.properties.ContactState;
7+
import com.beowulfe.hap.impl.services.ContactSensorService;
8+
9+
import java.util.Collection;
10+
import java.util.Collections;
11+
import java.util.concurrent.CompletableFuture;
12+
13+
/**
14+
* A contact sensor that reports whether contact is detected or not. Typical
15+
* contact sensors are window/door sensors. When contact is detected it means
16+
* that the door/window is closed.
17+
*/
18+
public interface ContactSensor extends HomekitAccessory {
19+
20+
/**
21+
* Retrieves the state of the contact. This is whether the contact is detected or not.
22+
* Detected contact means door/window is closed.
23+
*
24+
* @return a future that will contain the contact's state
25+
*/
26+
CompletableFuture<ContactState> getCurrentState();
27+
28+
@Override
29+
default Collection<Service> getServices() {
30+
return Collections.singleton(new ContactSensorService(this));
31+
}
32+
33+
/**
34+
* Subscribes to changes in the contact state.
35+
*
36+
* @param callback the function to call when the state changes.
37+
*/
38+
void subscribeContactState(HomekitCharacteristicChangeCallback callback);
39+
40+
/**
41+
* Unsubscribes from changes in the contact state.
42+
*/
43+
void unsubscribeContactState();
44+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.beowulfe.hap.accessories;
2+
3+
import com.beowulfe.hap.HomekitAccessory;
4+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
5+
import com.beowulfe.hap.Service;
6+
import com.beowulfe.hap.impl.services.MotionSensorService;
7+
8+
import java.util.Collection;
9+
import java.util.Collections;
10+
import java.util.concurrent.CompletableFuture;
11+
12+
/**
13+
* A motion sensor that reports whether motion has been detected.
14+
*/
15+
public interface MotionSensor extends HomekitAccessory {
16+
17+
/**
18+
* Retrieves the state of the motion sensor. If true then motion has been detected.
19+
*
20+
* @return a future that will contain the motion sensor's state
21+
*/
22+
CompletableFuture<Boolean> getMotionDetected();
23+
24+
@Override
25+
default Collection<Service> getServices() {
26+
return Collections.singleton(new MotionSensorService(this));
27+
}
28+
29+
/**
30+
* Subscribes to changes in the motion sensor.
31+
*
32+
* @param callback the function to call when the state changes.
33+
*/
34+
void subscribeMotionDetected(HomekitCharacteristicChangeCallback callback);
35+
36+
/**
37+
* Unsubscribes from changes in the motion sensor.
38+
*/
39+
void unsubscribeMotionDetected();
40+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.beowulfe.hap.accessories.properties;
2+
3+
import java.util.Arrays;
4+
import java.util.Map;
5+
import java.util.stream.Collectors;
6+
7+
public enum ContactState {
8+
9+
DETECTED(0),
10+
NOT_DETECTED(1);
11+
12+
private final static Map<Integer, ContactState> reverse;
13+
static {
14+
reverse = Arrays.stream(ContactState.values()).collect(Collectors.toMap(ContactState::getCode, t -> t));
15+
}
16+
17+
public static ContactState fromCode(Integer code) {
18+
return reverse.get(code);
19+
}
20+
21+
private final int code;
22+
23+
ContactState(int code) {
24+
this.code = code;
25+
}
26+
27+
public int getCode() {
28+
return code;
29+
}
30+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.beowulfe.hap.impl.characteristics.contactsensor;
2+
3+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
4+
import com.beowulfe.hap.accessories.ContactSensor;
5+
import com.beowulfe.hap.accessories.properties.ContactState;
6+
import com.beowulfe.hap.characteristics.EnumCharacteristic;
7+
import com.beowulfe.hap.characteristics.EventableCharacteristic;
8+
9+
import java.util.concurrent.CompletableFuture;
10+
11+
public class ContactSensorStateCharacteristic extends EnumCharacteristic implements EventableCharacteristic {
12+
13+
private final ContactSensor contactSensor;
14+
15+
public ContactSensorStateCharacteristic(ContactSensor contactSensor) {
16+
super("0000006A-0000-1000-8000-0026BB765291", false, true, "Contact State", 1);
17+
this.contactSensor = contactSensor;
18+
}
19+
20+
@Override
21+
protected CompletableFuture<Integer> getValue() {
22+
return contactSensor.getCurrentState().thenApply(ContactState::getCode);
23+
}
24+
25+
@Override
26+
protected void setValue(Integer value) throws Exception {
27+
//Read Only
28+
}
29+
30+
@Override
31+
public void subscribe(HomekitCharacteristicChangeCallback callback) {
32+
contactSensor.subscribeContactState(callback);
33+
}
34+
35+
@Override
36+
public void unsubscribe() {
37+
contactSensor.unsubscribeContactState();
38+
}
39+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.beowulfe.hap.impl.characteristics.motionsensor;
2+
3+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
4+
import com.beowulfe.hap.accessories.MotionSensor;
5+
import com.beowulfe.hap.characteristics.BooleanCharacteristic;
6+
import com.beowulfe.hap.characteristics.EventableCharacteristic;
7+
8+
import java.util.concurrent.CompletableFuture;
9+
10+
public class MotionDetectedStateCharacteristic extends BooleanCharacteristic implements EventableCharacteristic {
11+
12+
private final MotionSensor motionSensor;
13+
14+
public MotionDetectedStateCharacteristic(MotionSensor motionSensor) {
15+
super("00000022-0000-1000-8000-0026BB765291", false, true, "Motion Detected");
16+
this.motionSensor = motionSensor;
17+
}
18+
19+
@Override
20+
protected CompletableFuture<Boolean> getValue() {
21+
return motionSensor.getMotionDetected();
22+
}
23+
24+
@Override
25+
protected void setValue(Boolean value) throws Exception {
26+
//Read Only
27+
}
28+
29+
@Override
30+
public void subscribe(HomekitCharacteristicChangeCallback callback) {
31+
motionSensor.subscribeMotionDetected(callback);
32+
}
33+
34+
@Override
35+
public void unsubscribe() {
36+
motionSensor.unsubscribeMotionDetected();
37+
}
38+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.beowulfe.hap.impl.services;
2+
3+
import com.beowulfe.hap.accessories.ContactSensor;
4+
import com.beowulfe.hap.impl.characteristics.common.Name;
5+
import com.beowulfe.hap.impl.characteristics.contactsensor.ContactSensorStateCharacteristic;
6+
7+
public class ContactSensorService extends AbstractServiceImpl {
8+
9+
public ContactSensorService(ContactSensor contactSensor) {
10+
super("00000080-0000-1000-8000-0026BB765291");
11+
addCharacteristic(new Name(contactSensor));
12+
addCharacteristic(new ContactSensorStateCharacteristic(contactSensor));
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.beowulfe.hap.impl.services;
2+
3+
import com.beowulfe.hap.accessories.MotionSensor;
4+
import com.beowulfe.hap.impl.characteristics.common.Name;
5+
import com.beowulfe.hap.impl.characteristics.motionsensor.MotionDetectedStateCharacteristic;
6+
7+
public class MotionSensorService extends AbstractServiceImpl {
8+
9+
public MotionSensorService(MotionSensor motionSensor) {
10+
super("00000085-0000-1000-8000-0026BB765291");
11+
addCharacteristic(new Name(motionSensor));
12+
addCharacteristic(new MotionDetectedStateCharacteristic(motionSensor));
13+
}
14+
}

0 commit comments

Comments
 (0)