[hueemulation] Changes to fix pairing and device discovery with Alexa (#9164)

Signed-off-by: Mike Major <mike_j_major@hotmail.com>
This commit is contained in:
Mike Major
2020-11-29 03:46:35 +00:00
committed by GitHub
parent be61a70030
commit ab7ac79fab
7 changed files with 33 additions and 11 deletions

View File

@@ -17,8 +17,8 @@ import java.net.UnknownHostException;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -147,7 +147,7 @@ public class ConfigStore {
determineHighestAssignedHueID();
if (config.uuid.isEmpty()) {
config.uuid = UUID.randomUUID().toString();
config.uuid = getHueUUID();
writeUUIDFuture = scheduler.schedule(() -> {
logger.info("No unique ID assigned yet. Assigning {} and restarting...", config.uuid);
WriteConfig.setUUID(configAdmin, config.uuid);
@@ -158,6 +158,19 @@ public class ConfigStore {
}
}
private static String getHueUUID() {
// Hue API example is AA:BB:CC:DD:EE:FF:00:11-XX
// XX is generated from the item.
final Random r = new Random();
int n = r.nextInt(255);
final StringBuilder uuid = new StringBuilder(String.format("%02X", n));
for (int i = 0; i < 7; i++) {
n = r.nextInt(255);
uuid.append(String.format(":%02X", n));
}
return uuid.toString();
}
private @Nullable InetAddress byName(@Nullable String address) {
if (address == null) {
return null;
@@ -311,7 +324,7 @@ public class ConfigStore {
metadataRegistry.add(new Metadata(key, String.valueOf(hueId), null));
}
return String.valueOf(hueId);
return String.format("%02X", hueId);
}
public boolean isReady() {

View File

@@ -126,7 +126,7 @@ public class HueEmulationService implements EventHandler {
@Override
public Set<Object> getSingletons() {
return Set.of(userManagement, configurationAccess, lightItems, sensors, scenes, schedules, rules,
statusResource, accessInterceptor);
statusResource, accessInterceptor, requestCleaner);
}
Dictionary<String, String> serviceProperties() {

View File

@@ -95,8 +95,7 @@ class HueEmulationConfigWithRuntime extends Thread implements Runnable {
}
}
public synchronized CompletableFuture<@Nullable HueEmulationConfigWithRuntime> startNow(
@Nullable HueEmulationConfigWithRuntime ignored) {
public synchronized CompletableFuture<@Nullable HueEmulationConfigWithRuntime> startNow() {
if (hasAlreadyBeenStarted) {
logger.debug("Cannot restart thread");
return future;

View File

@@ -349,8 +349,9 @@ public class UpnpServer extends HttpServlet implements Consumer<HueEmulationConf
}
configChangeFuture = root.thenApply(this::createConfiguration)
.thenApplyAsync(this::performAddressTest, executor).thenApply(this::applyConfiguration)
.thenCompose(config::startNow)
.whenComplete((HueEmulationConfigWithRuntime config, @Nullable Throwable e) -> {
.thenCompose(c -> {
return c.startNow();
}).whenComplete((HueEmulationConfigWithRuntime config, @Nullable Throwable e) -> {
if (e != null) {
logger.warn("Upnp server: Address test failed", e);
}

View File

@@ -88,7 +88,7 @@ public class ItemUIDtoHueIDMappingTests {
itemRegistry.add(item);
String hueID = cs.mapItemUIDtoHueID(item);
assertThat(hueID, CoreMatchers.is("2"));
assertThat(hueID, CoreMatchers.is("02"));
HueLightEntry device = cs.ds.lights.get(hueID);
assertThat(device.item, is(item));
@@ -108,7 +108,7 @@ public class ItemUIDtoHueIDMappingTests {
itemRegistry.add(item);
String hueID = cs.mapItemUIDtoHueID(item);
assertThat(hueID, CoreMatchers.is("10"));
assertThat(hueID, CoreMatchers.is("0A"));
HueLightEntry device = cs.ds.lights.get(hueID);
assertThat(device.item, is(item));

View File

@@ -123,7 +123,7 @@ public class UpnpTests {
}
// UDP thread started?
r.startNow(r).get(5, TimeUnit.SECONDS);
r.startNow().get(5, TimeUnit.SECONDS);
assertThat(subject.upnpAnnouncementThreadRunning(), is(true));
// Send M-SEARCH UPNP "packet" and check if the result contains our bridge ID