Skip to content

merge to upstream #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.github.hapjava.accessories;

import io.github.hapjava.HomekitAccessory;
import io.github.hapjava.HomekitCharacteristicChangeCallback;
import io.github.hapjava.Service;
import io.github.hapjava.accessories.properties.CarbonDioxideDetectedState;
import io.github.hapjava.impl.services.CarbonDioxideSensorService;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.CompletableFuture;

/**
* A carbon dioxide sensor reports whether carbon dioxide has been detected or not.
*
* <p>Carbon dioxide sensors that run on batteries will need to implement this interface and also
* implement {@link BatteryStatusAccessory}.
*
* @author Eugen Freiter
*/
public interface CarbonDioxideSensor extends HomekitAccessory {

/**
* Retrieves the state of the sensor that indicates if carbon dioxide has been detected.
*
* @return a future that will contain the carbon dioxide sensor's state
*/
CompletableFuture<CarbonDioxideDetectedState> getCarbonDioxideDetectedState();

@Override
default Collection<Service> getServices() {
return Collections.singleton(new CarbonDioxideSensorService(this));
}

/**
* Subscribes to changes in the carbon dioxide's state.
*
* @param callback the function to call when the state changes.
*/
void subscribeCarbonDioxideDetectedState(HomekitCharacteristicChangeCallback callback);

/**
* Retrieves the carbon dioxide level
*
* @return a future that will contain the carbon dioxide level as a value between 0 and 100000
*/
CompletableFuture<Double> getCarbonDioxideLevel();

/** Unsubscribes from changes in the carbon dioxide's state. */
void unsubscribeCarbonDioxideDetectedState();

/**
* Subscribes to changes in the carbon dioxide level.
*
* @param callback the function to call when the state changes.
*/
void subscribeCarbonDioxideLevel(HomekitCharacteristicChangeCallback callback);

/** Unsubscribes from changes in the carbon dioxide level. */
void unsubscribeCarbonDioxideLevel();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.github.hapjava.accessories.properties;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

public enum CarbonDioxideDetectedState {
NORMAL(0),
ABNORMAL(1);

private static final Map<Integer, CarbonDioxideDetectedState> reverse;

static {
reverse =
Arrays.stream(CarbonDioxideDetectedState.values())
.collect(Collectors.toMap(CarbonDioxideDetectedState::getCode, t -> t));
}

public static CarbonDioxideDetectedState fromCode(Integer code) {
return reverse.get(code);
}

private final int code;

CarbonDioxideDetectedState(int code) {
this.code = code;
}

public int getCode() {
return code;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.github.hapjava.impl.characteristics.carbondioxide;

import io.github.hapjava.HomekitCharacteristicChangeCallback;
import io.github.hapjava.accessories.CarbonDioxideSensor;
import io.github.hapjava.accessories.properties.CarbonDioxideDetectedState;
import io.github.hapjava.characteristics.EnumCharacteristic;
import io.github.hapjava.characteristics.EventableCharacteristic;
import java.util.concurrent.CompletableFuture;

public class CarbonDioxideDetectedCharacteristic extends EnumCharacteristic
implements EventableCharacteristic {

private final CarbonDioxideSensor carbonDioxideSensor;

public CarbonDioxideDetectedCharacteristic(CarbonDioxideSensor carbonDioxideSensor) {
super("00000092-0000-1000-8000-0026BB765291", false, true, "Carbon Dioxide Detected", 1);
this.carbonDioxideSensor = carbonDioxideSensor;
}

@Override
protected CompletableFuture<Integer> getValue() {
return carbonDioxideSensor
.getCarbonDioxideDetectedState()
.thenApply(CarbonDioxideDetectedState::getCode);
}

@Override
protected void setValue(Integer value) throws Exception {
// Read Only
}

@Override
public void subscribe(HomekitCharacteristicChangeCallback callback) {
carbonDioxideSensor.subscribeCarbonDioxideDetectedState(callback);
}

@Override
public void unsubscribe() {
carbonDioxideSensor.unsubscribeCarbonDioxideDetectedState();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.github.hapjava.impl.characteristics.carbondioxide;

import io.github.hapjava.HomekitCharacteristicChangeCallback;
import io.github.hapjava.accessories.CarbonDioxideSensor;
import io.github.hapjava.characteristics.EventableCharacteristic;
import io.github.hapjava.characteristics.FloatCharacteristic;
import java.util.concurrent.CompletableFuture;

public class CarbonDioxideLevelCharacteristic extends FloatCharacteristic
implements EventableCharacteristic {

private final CarbonDioxideSensor sensor;

public CarbonDioxideLevelCharacteristic(CarbonDioxideSensor sensor) {
super(
"00000093-0000-1000-8000-0026BB765291",
false,
true,
"Carbon Dioxide level",
0,
100000,
0.1,
"%");
this.sensor = sensor;
}

@Override
public void subscribe(HomekitCharacteristicChangeCallback callback) {
sensor.subscribeCarbonDioxideLevel(callback);
}

@Override
public void unsubscribe() {
sensor.unsubscribeCarbonDioxideLevel();
}

@Override
protected void setValue(Double value) throws Exception {
// Read Only
}

@Override
protected CompletableFuture<Double> getDoubleValue() {
return sensor.getCarbonDioxideLevel();
}

@Override
public String toString() {
return "CarbonDioxideLevelCharacteristic{"
+ "sensor level ="
+ sensor.getCarbonDioxideLevel()
+ '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public HttpResponse handleRequest(HttpRequest request) throws IOException {
}

public HttpResponse handleAuthenticatedRequest(HttpRequest request) throws IOException {
advertiser.setDiscoverable(
false); // brigde is already bound and should not be discoverable anymore
try {
switch (request.getUri()) {
case "/accessories":
Expand Down Expand Up @@ -101,7 +103,7 @@ private HttpResponse handlePairSetup(HttpRequest request) {
if (pairingManager == null) {
synchronized (HttpSession.class) {
if (pairingManager == null) {
pairingManager = new PairingManager(authInfo, registry, advertiser);
pairingManager = new PairingManager(authInfo, registry);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ private CompletableFuture<JsonObject> toJson(Service service, int interfaceId) t
.thenApply(
v -> {
JsonArrayBuilder jsonCharacteristics = Json.createArrayBuilder();
characteristicFutures
.stream()
characteristicFutures.stream()
.map(future -> future.join())
.forEach(c -> jsonCharacteristics.add(c));
builder.add("characteristics", jsonCharacteristics);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import io.github.hapjava.HomekitAuthInfo;
import io.github.hapjava.impl.crypto.*;
import io.github.hapjava.impl.http.HttpResponse;
import io.github.hapjava.impl.jmdns.JmdnsHomekitAdvertiser;
import io.github.hapjava.impl.pairing.PairSetupRequest.Stage3Request;
import io.github.hapjava.impl.pairing.TypeLengthValueUtils.DecodeResult;
import io.github.hapjava.impl.pairing.TypeLengthValueUtils.Encoder;
Expand All @@ -16,14 +15,12 @@ class FinalPairHandler {

private final byte[] k;
private final HomekitAuthInfo authInfo;
private final JmdnsHomekitAdvertiser advertiser;

private byte[] hkdf_enc_key;

public FinalPairHandler(byte[] k, HomekitAuthInfo authInfo, JmdnsHomekitAdvertiser advertiser) {
public FinalPairHandler(byte[] k, HomekitAuthInfo authInfo) {
this.k = k;
this.authInfo = authInfo;
this.advertiser = advertiser;
}

public HttpResponse handle(PairSetupRequest req) throws Exception {
Expand Down Expand Up @@ -66,7 +63,6 @@ private HttpResponse createUser(byte[] username, byte[] ltpk, byte[] proof) thro
throw new Exception("Invalid signature");
}
authInfo.createUser(authInfo.getMac() + new String(username, StandardCharsets.UTF_8), ltpk);
advertiser.setDiscoverable(false);
return createResponse();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import io.github.hapjava.impl.HomekitRegistry;
import io.github.hapjava.impl.http.HttpRequest;
import io.github.hapjava.impl.http.HttpResponse;
import io.github.hapjava.impl.jmdns.JmdnsHomekitAdvertiser;
import io.github.hapjava.impl.responses.NotFoundResponse;
import io.github.hapjava.impl.responses.UnauthorizedResponse;
import org.slf4j.Logger;
Expand All @@ -16,15 +15,12 @@ public class PairingManager {

private final HomekitAuthInfo authInfo;
private final HomekitRegistry registry;
private final JmdnsHomekitAdvertiser advertiser;

private SrpHandler srpHandler;

public PairingManager(
HomekitAuthInfo authInfo, HomekitRegistry registry, JmdnsHomekitAdvertiser advertiser) {
public PairingManager(HomekitAuthInfo authInfo, HomekitRegistry registry) {
this.authInfo = authInfo;
this.registry = registry;
this.advertiser = advertiser;
}

public HttpResponse handle(HttpRequest httpRequest) throws Exception {
Expand Down Expand Up @@ -54,7 +50,7 @@ public HttpResponse handle(HttpRequest httpRequest) throws Exception {
logger.warn("Received unexpected stage 3 request for " + registry.getLabel());
return new UnauthorizedResponse();
} else {
FinalPairHandler handler = new FinalPairHandler(srpHandler.getK(), authInfo, advertiser);
FinalPairHandler handler = new FinalPairHandler(srpHandler.getK(), authInfo);
try {
return handler.handle(req);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.github.hapjava.impl.services;

import io.github.hapjava.accessories.CarbonDioxideSensor;
import io.github.hapjava.impl.characteristics.carbondioxide.CarbonDioxideDetectedCharacteristic;
import io.github.hapjava.impl.characteristics.carbondioxide.CarbonDioxideLevelCharacteristic;

public class CarbonDioxideSensorService extends AbstractServiceImpl {

public CarbonDioxideSensorService(CarbonDioxideSensor carbonDioxideSensor) {
this(carbonDioxideSensor, carbonDioxideSensor.getLabel());
}

public CarbonDioxideSensorService(CarbonDioxideSensor carbonDioxideSensor, String serviceName) {
super("00000097-0000-1000-8000-0026BB765291", carbonDioxideSensor, serviceName);
addCharacteristic(new CarbonDioxideDetectedCharacteristic(carbonDioxideSensor));
addCharacteristic(new CarbonDioxideLevelCharacteristic(carbonDioxideSensor));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import io.github.hapjava.impl.HomekitWebHandler;
import io.github.hapjava.impl.http.HomekitClientConnectionFactory;
import io.github.hapjava.impl.jmdns.JmdnsHomekitAdvertiser;
import java.util.concurrent.CompletableFuture;
import org.junit.*;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class HomekitRootTest {

Expand Down Expand Up @@ -64,7 +69,7 @@ public void testWebHandlerStops() throws Exception {

@Test
public void testAdvertiserStarts() throws Exception {
String mac = "00:00:00:00:00:00";
final String mac = "00:00:00:00:00:00";
when(authInfo.getMac()).thenReturn(mac);
root.start();
verify(advertiser).advertise(eq(LABEL), eq(mac), eq(PORT), eq(1));
Expand Down