Skip to content

Commit 3ec7264

Browse files
authored
Merge pull request #52 from timcharper/tharper/leak-sensor
Add support for LeakSensor and Valve devices
2 parents 683a362 + f3a5f2b commit 3ec7264

File tree

12 files changed

+550
-0
lines changed

12 files changed

+550
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.beowulfe.hap.accessories;
2+
3+
import java.util.Collection;
4+
import java.util.Collections;
5+
import java.util.concurrent.CompletableFuture;
6+
7+
import com.beowulfe.hap.HomekitAccessory;
8+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
9+
import com.beowulfe.hap.Service;
10+
import com.beowulfe.hap.impl.services.LeakSensorService;
11+
12+
/**
13+
* <p>
14+
* A leak sensor that reports whether a leak has been detected.
15+
* </p>
16+
*
17+
* <p>
18+
* Leak sensors that run on batteries will need to implement this interface
19+
* and also implement {@link BatteryStatusAccessory}.
20+
* </p>
21+
*
22+
* @author Tim Harper
23+
*/
24+
public interface LeakSensor extends HomekitAccessory {
25+
26+
/**
27+
* Retrieves the state of the leak sensor. If true then leak has been detected.
28+
*
29+
* @return a future that will contain the leak sensor's state
30+
*/
31+
CompletableFuture<Boolean> getLeakDetected();
32+
33+
@Override
34+
default Collection<Service> getServices() {
35+
return Collections.singleton(new LeakSensorService(this));
36+
}
37+
38+
/**
39+
* Subscribes to changes in the leak sensor.
40+
*
41+
* @param callback the function to call when the state changes.
42+
*/
43+
void subscribeLeakDetected(HomekitCharacteristicChangeCallback callback);
44+
45+
/**
46+
* Unsubscribes from changes in the leak sensor.
47+
*/
48+
void unsubscribeLeakDetected();
49+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.beowulfe.hap.accessories;
2+
3+
import java.util.Collection;
4+
import java.util.Collections;
5+
import java.util.concurrent.CompletableFuture;
6+
7+
import com.beowulfe.hap.HomekitAccessory;
8+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
9+
import com.beowulfe.hap.Service;
10+
import com.beowulfe.hap.accessories.properties.ValveType;
11+
import com.beowulfe.hap.impl.services.ValveService;
12+
13+
/**
14+
* A Valve (sprinkler head, faucet, etc.)
15+
*
16+
* @author Tim Harper
17+
*/
18+
public interface Valve extends HomekitAccessory {
19+
20+
@Override
21+
default Collection<Service> getServices() {
22+
return Collections.singleton(new ValveService(this));
23+
}
24+
25+
/**
26+
* Retrieves the current active state of the valve; Active could mean the valve is open (but not necessarily
27+
* running),
28+
* or that the valve is associated with an active watering program (like a watering program) but is not currently
29+
* running.
30+
*
31+
* To communicate water is flowing through a valve, inUse should be used.
32+
*
33+
* @return a future that will contain the binary state
34+
*/
35+
CompletableFuture<Boolean> getValveActive();
36+
37+
/**
38+
* Sets the valve active state
39+
*
40+
* @param active the binary state to set
41+
* @return a future that completes when the change is made
42+
* @throws Exception when the change cannot be made
43+
*/
44+
CompletableFuture<Void> setValveActive(boolean active) throws Exception;
45+
46+
/**
47+
* Subscribes to changes in the active state of the valve.
48+
*
49+
* @param callback the function to call when the state changes.
50+
*/
51+
void subscribeValveActive(HomekitCharacteristicChangeCallback callback);
52+
53+
/**
54+
* Unsubscribes from changes in the valve active state.
55+
*/
56+
void unsubscribeValveActive();
57+
58+
/**
59+
* Retrieves the current inUse state of the valve; InUse usually means water is flowing through the valve.
60+
*
61+
* To communicate water is flowing through a valve, inUse should be used.
62+
*
63+
* @return a future that will contain the binary state
64+
*/
65+
CompletableFuture<Boolean> getValveInUse();
66+
67+
/**
68+
* Subscribes to changes in the inUse state of the valve.
69+
*
70+
* @param callback the function to call when the state changes.
71+
*/
72+
void subscribeValveInUse(HomekitCharacteristicChangeCallback callback);
73+
74+
/**
75+
* Unsubscribes from changes in the valve inUse state.
76+
*/
77+
void unsubscribeValveInUse();
78+
79+
/**
80+
* Retrieves the valve type.
81+
*
82+
* To communicate water is flowing through a valve, inUse should be used.
83+
*
84+
* @return a future that will contain the binary state
85+
*/
86+
CompletableFuture<ValveType> getValveType();
87+
88+
/**
89+
* Subscribes to changes in the valveType state of the valve.
90+
*
91+
* @param callback the function to call when the state changes.
92+
*/
93+
void subscribeValveType(HomekitCharacteristicChangeCallback callback);
94+
95+
/**
96+
* Unsubscribes from changes in the valveType state light.
97+
*/
98+
void unsubscribeValveType();
99+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.beowulfe.hap.accessories;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
5+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
6+
7+
/**
8+
* Extends {@link Valve} with timer values.
9+
*
10+
* @author Tim Harper
11+
*/
12+
public interface ValveWithTimer extends Valve {
13+
14+
/**
15+
* Retrieves the current duration for which the valve will run
16+
*
17+
* @return a future with the value
18+
*/
19+
CompletableFuture<Integer> getRemainingDuration();
20+
21+
/**
22+
* Subscribes to changes in the duration; note it is not necessary to emit a
23+
* change every second, homekit infers the countdown progress clientside.
24+
*
25+
* @param callback the function when the existing duration has been replaced with a new one.
26+
*/
27+
void subscribeRemainingDuration(HomekitCharacteristicChangeCallback callback);
28+
29+
/**
30+
* Unsubscribes from changes
31+
*/
32+
void unsubscribeRemainingDuration();
33+
34+
/**
35+
* Retrieves the current set duration for which the valve will be scheduled
36+
* to run; this is usually used as the duration to use when the valve is set
37+
* to active.
38+
*
39+
* @return a future with the value
40+
*/
41+
CompletableFuture<Integer> getSetDuration();
42+
43+
/**
44+
* Sets the duration for which the valve will be scheduled to run; this is
45+
* usually used as the duration to use when the valve is set to active.
46+
*
47+
* If the valve is currently running, then Homekit assumes that changing
48+
* this value affects the current remaining duration.
49+
*
50+
* @return a future with the value
51+
*/
52+
CompletableFuture<Void> setSetDuration(int value);
53+
54+
/**
55+
* Subscribes to changes in the set duration
56+
*
57+
* @param callback the function when the value has changed
58+
*/
59+
void subscribeSetDuration(HomekitCharacteristicChangeCallback callback);
60+
61+
/**
62+
* Unsubscribes from changes
63+
*/
64+
void unsubscribeSetDuration();
65+
66+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
import com.beowulfe.hap.accessories.Valve;
8+
9+
/**
10+
* The mode used by a {@link Valve}
11+
*
12+
* @author Tim Harper
13+
*/
14+
public enum ValveType {
15+
16+
GENERIC(0),
17+
IRRIGATION(1),
18+
SHOWER(2),
19+
WATER_FAUCET(3);
20+
21+
private final static Map<Integer, ValveType> reverse;
22+
static {
23+
reverse = Arrays.stream(ValveType.values()).collect(Collectors.toMap(t -> t.getCode(), t -> t));
24+
}
25+
26+
public static ValveType fromCode(Integer code) {
27+
return reverse.get(code);
28+
}
29+
30+
private final int code;
31+
32+
private ValveType(int code) {
33+
this.code = code;
34+
}
35+
36+
public int getCode() {
37+
return code;
38+
}
39+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.beowulfe.hap.impl.characteristics.common;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
import java.util.function.Consumer;
5+
import java.util.function.Supplier;
6+
7+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
8+
import com.beowulfe.hap.characteristics.BooleanCharacteristic;
9+
import com.beowulfe.hap.characteristics.EventableCharacteristic;
10+
import com.beowulfe.hap.impl.ExceptionalConsumer;
11+
12+
public class ActiveCharacteristic extends BooleanCharacteristic implements EventableCharacteristic {
13+
14+
private final Supplier<CompletableFuture<Boolean>> getter;
15+
private final ExceptionalConsumer<Boolean> setter;
16+
private final Consumer<HomekitCharacteristicChangeCallback> subscriber;
17+
private final Runnable unsubscriber;
18+
19+
public ActiveCharacteristic(Supplier<CompletableFuture<Boolean>> getter, ExceptionalConsumer<Boolean> setter,
20+
Consumer<HomekitCharacteristicChangeCallback> subscriber, Runnable unsubscriber) {
21+
super("000000B0-0000-1000-8000-0026BB765291", true, true, "Active");
22+
this.getter = getter;
23+
this.setter = setter;
24+
this.subscriber = subscriber;
25+
this.unsubscriber = unsubscriber;
26+
}
27+
28+
@Override
29+
protected CompletableFuture<Boolean> getValue() {
30+
return getter.get();
31+
}
32+
33+
@Override
34+
protected void setValue(Boolean value) throws Exception {
35+
setter.accept(value);
36+
}
37+
38+
@Override
39+
public void subscribe(HomekitCharacteristicChangeCallback callback) {
40+
subscriber.accept(callback);
41+
}
42+
43+
@Override
44+
public void unsubscribe() {
45+
unsubscriber.run();
46+
}
47+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.beowulfe.hap.impl.characteristics.common;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
import java.util.function.Consumer;
5+
import java.util.function.Supplier;
6+
7+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
8+
import com.beowulfe.hap.characteristics.BooleanCharacteristic;
9+
import com.beowulfe.hap.characteristics.EventableCharacteristic;
10+
11+
public class InUseCharacteristic extends BooleanCharacteristic implements EventableCharacteristic {
12+
13+
private final Supplier<CompletableFuture<Boolean>> getter;
14+
private final Consumer<HomekitCharacteristicChangeCallback> subscriber;
15+
private final Runnable unsubscriber;
16+
17+
public InUseCharacteristic(Supplier<CompletableFuture<Boolean>> getter,
18+
Consumer<HomekitCharacteristicChangeCallback> subscriber, Runnable unsubscriber) {
19+
super("000000D2-0000-1000-8000-0026BB765291", false, true, "InUse");
20+
this.getter = getter;
21+
this.subscriber = subscriber;
22+
this.unsubscriber = unsubscriber;
23+
}
24+
25+
@Override
26+
protected CompletableFuture<Boolean> getValue() {
27+
return getter.get();
28+
}
29+
30+
@Override
31+
protected void setValue(Boolean value) throws Exception {
32+
// Read Only
33+
}
34+
35+
@Override
36+
public void subscribe(HomekitCharacteristicChangeCallback callback) {
37+
subscriber.accept(callback);
38+
}
39+
40+
@Override
41+
public void unsubscribe() {
42+
unsubscriber.run();
43+
}
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.beowulfe.hap.impl.characteristics.common;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
import java.util.function.Consumer;
5+
import java.util.function.Supplier;
6+
7+
import com.beowulfe.hap.HomekitCharacteristicChangeCallback;
8+
import com.beowulfe.hap.characteristics.EventableCharacteristic;
9+
import com.beowulfe.hap.characteristics.IntegerCharacteristic;
10+
11+
public class RemainingDurationCharacteristic extends IntegerCharacteristic implements EventableCharacteristic {
12+
13+
private final Supplier<CompletableFuture<Integer>> getter;
14+
private final Consumer<HomekitCharacteristicChangeCallback> subscriber;
15+
private final Runnable unsubscriber;
16+
17+
public RemainingDurationCharacteristic(Supplier<CompletableFuture<Integer>> getter,
18+
Consumer<HomekitCharacteristicChangeCallback> subscriber, Runnable unsubscriber) {
19+
super("000000D4-0000-1000-8000-0026BB765291", false, true, "Remaining Duration", 0, 3600, "seconds");
20+
this.getter = getter;
21+
this.subscriber = subscriber;
22+
this.unsubscriber = unsubscriber;
23+
}
24+
25+
@Override
26+
protected CompletableFuture<Integer> getValue() {
27+
return getter.get();
28+
}
29+
30+
@Override
31+
protected void setValue(Integer value) throws Exception {
32+
// Read Only
33+
}
34+
35+
@Override
36+
public void subscribe(HomekitCharacteristicChangeCallback callback) {
37+
subscriber.accept(callback);
38+
}
39+
40+
@Override
41+
public void unsubscribe() {
42+
unsubscriber.run();
43+
}
44+
}

0 commit comments

Comments
 (0)