From a815d684dd92699aae48fa6c434d817fdf6f0faf Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Thu, 12 Sep 2024 15:14:22 +0200 Subject: [PATCH] [nikohomecontrol] Add console commands (#17352) * dump devices from console Signed-off-by: Mark Herwege Signed-off-by: Ciprian Pascu --- .../README.md | 9 + .../NikoHomeControlBindingConstants.java | 1 + .../NikoHomeControlHandlerFactory.java | 2 +- .../NikoHomeControlCommandExtension.java | 280 ++++++++++++++++++ ...NikoHomeControlBridgeDiscoveryService.java | 8 +- .../handler/NikoHomeControlBridgeHandler.java | 36 ++- .../NikoHomeControlBridgeHandler1.java | 10 +- .../NikoHomeControlBridgeHandler2.java | 9 +- .../protocol/NikoHomeControlDiscover.java | 16 +- .../nhc2/NikoHomeControlCommunication2.java | 7 + 10 files changed, 361 insertions(+), 17 deletions(-) create mode 100644 bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/console/NikoHomeControlCommandExtension.java diff --git a/bundles/org.openhab.binding.nikohomecontrol/README.md b/bundles/org.openhab.binding.nikohomecontrol/README.md index 4688ac3ac0a..21f83ac7624 100644 --- a/bundles/org.openhab.binding.nikohomecontrol/README.md +++ b/bundles/org.openhab.binding.nikohomecontrol/README.md @@ -220,6 +220,15 @@ Thing nikohomecontrol:alarm:mybridge:myalarm [ alarmId="abcdef01-dcba-1234-ab98- | notice | | | | bridge | trigger channel with notice event message, can be used in rules | +## Console Commands + +To help with further development, a number of console commands allow you to collect information about your current system: + +- `nikohomecontrol controllers`: Lists all controllers in the network and return the controller ID +- `nikohomecontrol systeminfo `: Info about the system +- `nikohomecontrol devicelist `: JSON list of devices with their characteristics in a Niko Home Control II system +- `nikohomecontrol devicelist dump`: Dump system info and device characteristics in a file + ## Limitations The binding has been tested with a Niko Home Control I IP-interface (550-00508) and the Niko Home Control Connected Controller (550-00003) for Niko Home Control I and II, and the Niko Home Control Wireless Smart Hub for Niko Home Control II. diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlBindingConstants.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlBindingConstants.java index bf5df0cc4b0..5dba879791e 100644 --- a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlBindingConstants.java +++ b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlBindingConstants.java @@ -107,6 +107,7 @@ public class NikoHomeControlBindingConstants { public static final String CHANNEL_NOTICE = "notice"; // Bridge config properties + public static final String CONFIG_CONTROLLER_ID = "controllerId"; public static final String CONFIG_HOST_NAME = "addr"; public static final String CONFIG_PORT = "port"; public static final String CONFIG_REFRESH = "refresh"; diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlHandlerFactory.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlHandlerFactory.java index 05a209c5f91..31ab59d34c5 100644 --- a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlHandlerFactory.java +++ b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlHandlerFactory.java @@ -68,7 +68,7 @@ public class NikoHomeControlHandlerFactory extends BaseThingHandlerFactory { if (BRIDGEII_THING_TYPE.equals(thing.getThingTypeUID())) { return new NikoHomeControlBridgeHandler2((Bridge) thing, networkAddressService, timeZoneProvider); } else { - return new NikoHomeControlBridgeHandler1((Bridge) thing, timeZoneProvider); + return new NikoHomeControlBridgeHandler1((Bridge) thing, networkAddressService, timeZoneProvider); } } else if (ACTION_THING_TYPES_UIDS.contains(thing.getThingTypeUID())) { return new NikoHomeControlActionHandler(thing); diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/console/NikoHomeControlCommandExtension.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/console/NikoHomeControlCommandExtension.java new file mode 100644 index 00000000000..2d7312eb7a3 --- /dev/null +++ b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/console/NikoHomeControlCommandExtension.java @@ -0,0 +1,280 @@ +/** + * Copyright (c) 2010-2024 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.nikohomecontrol.internal.console; + +import static org.openhab.binding.nikohomecontrol.internal.NikoHomeControlBindingConstants.BINDING_ID; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.nikohomecontrol.internal.handler.NikoHomeControlBridgeHandler; +import org.openhab.binding.nikohomecontrol.internal.handler.NikoHomeControlBridgeHandler2; +import org.openhab.binding.nikohomecontrol.internal.protocol.NikoHomeControlDiscover; +import org.openhab.binding.nikohomecontrol.internal.protocol.nhc2.NikoHomeControlCommunication2; +import org.openhab.core.io.console.Console; +import org.openhab.core.io.console.ConsoleCommandCompleter; +import org.openhab.core.io.console.StringsCompleter; +import org.openhab.core.io.console.extensions.AbstractConsoleCommandExtension; +import org.openhab.core.io.console.extensions.ConsoleCommandExtension; +import org.openhab.core.net.NetworkAddressService; +import org.openhab.core.thing.ThingRegistry; +import org.openhab.core.thing.ThingStatus; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; + +/** + * The {@link NikoHomeControlCommandExtension} is responsible for handling console commands + * + * @author Mark Herwege - Initial contribution + */ + +@NonNullByDefault +@Component(service = ConsoleCommandExtension.class) +public class NikoHomeControlCommandExtension extends AbstractConsoleCommandExtension + implements ConsoleCommandCompleter { + + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + private static final String CONTROLLERS = "controllers"; + private static final String SYSTEMINFO = "systeminfo"; + private static final String DEVICELIST = "devicelist"; + private static final String DUMP = "dump"; + + private static final String ROOT_PATH = System.getProperty("user.home") + File.separator + BINDING_ID + + File.separator + DEVICELIST; + + private static final StringsCompleter CMD_COMPLETER = new StringsCompleter( + List.of(CONTROLLERS, SYSTEMINFO, DEVICELIST), false); + private static final StringsCompleter DUMP_COMPLETER = new StringsCompleter(List.of(DUMP), false); + + private final ThingRegistry thingRegistry; + private final NetworkAddressService networkAddressService; + + private List bridgeHandlers = List.of(); + + @Activate + public NikoHomeControlCommandExtension(final @Reference ThingRegistry thingRegistry, + final @Reference NetworkAddressService networkAddressService) { + super("nikohomecontrol", "Interact with the Niko Home Control binding"); + this.thingRegistry = thingRegistry; + this.networkAddressService = networkAddressService; + } + + @Override + public void execute(String[] args, Console console) { + if ((args.length < 1) || (args.length > 3)) { + console.println("Invalid number of arguments"); + printUsage(console); + return; + } + + bridgeHandlers = thingRegistry.getAll().stream() + .filter(t -> t.getHandler() instanceof NikoHomeControlBridgeHandler) + .map(b -> ((NikoHomeControlBridgeHandler) b.getHandler())).toList(); + Map bridgeNhcVersion = bridgeHandlers.stream().collect(Collectors + .toMap(b -> b.getControllerId(), b -> b instanceof NikoHomeControlBridgeHandler2 ? "II" : "I")); + + NikoHomeControlBridgeHandler bridgeHandler = null; + if (args.length > 1) { + Optional bridgeOptional = bridgeHandlers.stream() + .filter(b -> b.getControllerId().toLowerCase().equals(args[1].toLowerCase())).findAny(); + if (bridgeOptional.isEmpty()) { + console.println("'" + args[1] + "' is not a valid controller ID"); + printUsage(console); + return; + } + bridgeHandler = bridgeOptional.get(); + } + + switch (args[0].toLowerCase()) { + case CONTROLLERS: + if (args.length > 1) { + console.println("No extra argument allowed after 'controllers'"); + printUsage(console); + return; + } else { + Map bridgeIds = bridgeHandlers.stream().collect(Collectors + .toMap(b -> b.getThing().getUID().toString(), b -> b.getControllerId().toLowerCase())); + List controllerIds = List.of(); + Map controllerNhcVersion = Map.of(); + try { + String broadcastAddr = networkAddressService.getConfiguredBroadcastAddress(); + if (broadcastAddr == null) { + console.println( + "Controller discovery not possible, no broadcast address found, result only contains bridges"); + } else { + NikoHomeControlDiscover nhcDiscover; + nhcDiscover = new NikoHomeControlDiscover(broadcastAddr); + controllerIds = nhcDiscover.getNhcBridgeIds().stream().map(String::toLowerCase) + .filter(id -> !bridgeIds.containsValue(id)).toList(); + controllerNhcVersion = controllerIds.stream().collect( + Collectors.toMap(Function.identity(), id -> nhcDiscover.isNhcII(id) ? "II" : "I")); + } + } catch (IOException e) { + console.println( + "Controller discovery not possible, network error, result only contains bridges"); + } + Map nhcVersion = Map.copyOf(controllerNhcVersion); + console.printf("%-14s %-12s %s%n", "Controller-ID", "NHC-Version", "Bridge-ID"); + console.printf("%-14s %-12s %s%n", "-------------", "-----------", "---------"); + bridgeIds.forEach( + (bridge, id) -> console.printf("%-14s %-12s %s%n", id, bridgeNhcVersion.get(id), bridge)); + controllerIds.forEach(id -> console.printf("%-14s %-12s %s%n", id, nhcVersion.get(id), " ")); + } + break; + case SYSTEMINFO: + if (args.length < 2) { + console.println("No controller ID provided"); + printUsage(console); + return; + } + if (bridgeHandler != null) { + if (!ThingStatus.ONLINE.equals(bridgeHandler.getThing().getStatus())) { + console.println("Niko Home Control bridge not online, system info may be out of date"); + } + console.println("Property Value"); + console.println("-------- -----"); + Map properties = bridgeHandler.getThing().getProperties(); + for (String key : properties.keySet()) { + console.printf("%-28.28s %s%n", key, properties.get(key)); + } + } + break; + case DEVICELIST: + if (args.length < 2) { + console.println("No controller ID provided"); + printUsage(console); + return; + } + if (!"II".equals(bridgeNhcVersion.get(args[1]))) { + console.println("'" + args[1] + "' is not a Niko Home Control II bridge"); + printUsage(console); + return; + } + if (bridgeHandler != null) { + if (!ThingStatus.ONLINE.equals(bridgeHandler.getThing().getStatus())) { + console.println("Niko Home Control bridge not online, device list may be out of date"); + } + NikoHomeControlCommunication2 nhcComm = (NikoHomeControlCommunication2) bridgeHandler + .getCommunication(); + if (nhcComm != null) { + String devices = prettyJson(nhcComm.getRawDevicesListResponse()); + if (args.length == 2) { + console.println(devices); + } else if (DUMP.equals(args[2])) { + String filename = ROOT_PATH + LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE) + + ".json"; + String systeminfo = GSON.toJson(bridgeHandler.getThing().getProperties()); + writeJsonToFile(filename, systeminfo, console); + writeJsonToFile(filename, devices, console); + console.printf("System info and device list dumped to file '%s'%n", filename); + } else { + console.println("Command argument '" + args[2] + "' not recognized"); + printUsage(console); + return; + } + } + } + break; + default: + console.println("Command argument '" + args[0] + "' not recognized"); + printUsage(console); + } + } + + private String prettyJson(String json) { + try { + return GSON.toJson(JsonParser.parseString(json)); + } catch (JsonSyntaxException e) { + // Keep the unformatted json if there is a syntax exception + return json; + } + } + + private void writeJsonToFile(String filename, String json, Console console) { + try { + JsonElement element = JsonParser.parseString(json); + if (element.isJsonNull() || (element.isJsonArray() && ((JsonArray) element).size() == 0)) { + console.println("Empty device list, nothing to dump"); + return; + } + } catch (JsonSyntaxException e) { + // Just continue and write the file with non-valid json anyway + } + + // ensure full path exists + File file = new File(filename); + File parentFile = file.getParentFile(); + if (parentFile != null) { + parentFile.mkdirs(); + } + + final byte[] contents = (json + "\n").getBytes(StandardCharsets.UTF_8); + try { + Files.write(file.toPath(), contents, StandardOpenOption.CREATE, StandardOpenOption.APPEND); + } catch (IOException e) { + console.println("I/O error writing device list to file"); + } + } + + @Override + public List getUsages() { + return Arrays.asList(new String[] { buildCommandUsage(CONTROLLERS, "list all Niko Home Control Controllers"), + buildCommandUsage(SYSTEMINFO + " ", + "show system info for Controller with controller ID"), + buildCommandUsage(DEVICELIST + " ", + "create device list of installation on Controller with controller ID"), + buildCommandUsage(DEVICELIST + " " + DUMP, + "dump device list of installation with controller ID to file") }); + } + + @Override + public @Nullable ConsoleCommandCompleter getCompleter() { + return this; + } + + @Override + public boolean complete(String[] args, int cursorArgumentIndex, int cursorPosition, List candidates) { + if (cursorArgumentIndex <= 0) { + return CMD_COMPLETER.complete(args, cursorArgumentIndex, cursorPosition, candidates); + } else if (cursorArgumentIndex == 1) { + return new StringsCompleter(bridgeHandlers.stream().filter(b -> b instanceof NikoHomeControlBridgeHandler2) + .map(b -> b.getControllerId()).toList(), false) + .complete(args, cursorArgumentIndex, cursorPosition, candidates); + } else if (cursorArgumentIndex == 2) { + return DUMP_COMPLETER.complete(args, cursorArgumentIndex, cursorPosition, candidates); + } + return false; + } +} diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/discovery/NikoHomeControlBridgeDiscoveryService.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/discovery/NikoHomeControlBridgeDiscoveryService.java index 182772668bb..96d33c5e3b5 100644 --- a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/discovery/NikoHomeControlBridgeDiscoveryService.java +++ b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/discovery/NikoHomeControlBridgeDiscoveryService.java @@ -92,8 +92,8 @@ public class NikoHomeControlBridgeDiscoveryService extends AbstractDiscoveryServ ThingUID uid = new ThingUID(BINDING_ID, "bridge", bridgeId); DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(uid).withLabel(bridgeName) - .withProperty(CONFIG_HOST_NAME, addr.getHostAddress()).withRepresentationProperty(CONFIG_HOST_NAME) - .build(); + .withProperty(CONFIG_HOST_NAME, addr.getHostAddress()).withProperty(CONFIG_CONTROLLER_ID, bridgeId) + .withRepresentationProperty(CONFIG_CONTROLLER_ID).build(); thingDiscovered(discoveryResult); } @@ -104,8 +104,8 @@ public class NikoHomeControlBridgeDiscoveryService extends AbstractDiscoveryServ ThingUID uid = new ThingUID(BINDING_ID, "bridge2", bridgeId); DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(uid).withLabel(bridgeName) - .withProperty(CONFIG_HOST_NAME, addr.getHostAddress()).withRepresentationProperty(CONFIG_HOST_NAME) - .build(); + .withProperty(CONFIG_HOST_NAME, addr.getHostAddress()).withProperty(CONFIG_CONTROLLER_ID, bridgeId) + .withRepresentationProperty(CONFIG_CONTROLLER_ID).build(); thingDiscovered(discoveryResult); } diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler.java index a31ac029ebc..620d1cf736e 100644 --- a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler.java +++ b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler.java @@ -14,6 +14,7 @@ package org.openhab.binding.nikohomecontrol.internal.handler; import static org.openhab.binding.nikohomecontrol.internal.NikoHomeControlBindingConstants.*; +import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.time.ZoneId; @@ -29,8 +30,10 @@ import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.nikohomecontrol.internal.discovery.NikoHomeControlDiscoveryService; import org.openhab.binding.nikohomecontrol.internal.protocol.NhcControllerEvent; import org.openhab.binding.nikohomecontrol.internal.protocol.NikoHomeControlCommunication; +import org.openhab.binding.nikohomecontrol.internal.protocol.NikoHomeControlDiscover; import org.openhab.core.config.core.Configuration; import org.openhab.core.i18n.TimeZoneProvider; +import org.openhab.core.net.NetworkAddressService; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ThingStatus; @@ -57,10 +60,14 @@ public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler imp private volatile @Nullable ScheduledFuture refreshTimer; + protected final NetworkAddressService networkAddressService; + protected final TimeZoneProvider timeZoneProvider; - public NikoHomeControlBridgeHandler(Bridge nikoHomeControlBridge, TimeZoneProvider timeZoneProvider) { + public NikoHomeControlBridgeHandler(Bridge nikoHomeControlBridge, NetworkAddressService networkAddressService, + TimeZoneProvider timeZoneProvider) { super(nikoHomeControlBridge); + this.networkAddressService = networkAddressService; this.timeZoneProvider = timeZoneProvider; } @@ -268,4 +275,31 @@ public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler imp public Collection> getServices() { return Set.of(NikoHomeControlDiscoveryService.class); } + + public String getControllerId() { + String id = thing.getProperties().get(CONFIG_CONTROLLER_ID); + if (id != null) { + return id; + } + try { + id = ""; + String broadcastAddr = networkAddressService.getConfiguredBroadcastAddress(); + if (broadcastAddr != null) { + NikoHomeControlDiscover nhcDiscover = new NikoHomeControlDiscover(broadcastAddr); + InetAddress address = getAddr(); + if (address != null) { + id = nhcDiscover.getBridgeId(address); + id = id != null ? id : ""; + } + } + } catch (IOException e) { + id = ""; + } + if (!id.isEmpty()) { + thing.setProperty(CONFIG_CONTROLLER_ID, id); + } else { + logger.warn("failure setting controller ID property"); + } + return id; + } } diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler1.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler1.java index 71cf17bf003..74e8359a739 100644 --- a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler1.java +++ b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler1.java @@ -21,6 +21,7 @@ import java.util.Map; import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.nikohomecontrol.internal.protocol.nhc1.NikoHomeControlCommunication1; import org.openhab.core.i18n.TimeZoneProvider; +import org.openhab.core.net.NetworkAddressService; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingStatusDetail; @@ -38,14 +39,17 @@ public class NikoHomeControlBridgeHandler1 extends NikoHomeControlBridgeHandler private final Logger logger = LoggerFactory.getLogger(NikoHomeControlBridgeHandler1.class); - public NikoHomeControlBridgeHandler1(Bridge nikoHomeControlBridge, TimeZoneProvider timeZoneProvider) { - super(nikoHomeControlBridge, timeZoneProvider); + public NikoHomeControlBridgeHandler1(Bridge nikoHomeControlBridge, NetworkAddressService networkAddressService, + TimeZoneProvider timeZoneProvider) { + super(nikoHomeControlBridge, networkAddressService, timeZoneProvider); } @Override public void initialize() { logger.debug("initializing bridge handler"); + scheduler.submit(() -> getControllerId()); + InetAddress addr = getAddr(); int port = getPort(); @@ -63,7 +67,7 @@ public class NikoHomeControlBridgeHandler1 extends NikoHomeControlBridgeHandler @Override protected void updateProperties() { - Map properties = new HashMap<>(); + Map properties = new HashMap<>(thing.getProperties()); NikoHomeControlCommunication1 comm = (NikoHomeControlCommunication1) nhcComm; if (comm != null) { diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler2.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler2.java index eea88ea8d2f..8a1aaae213f 100644 --- a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler2.java +++ b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler2.java @@ -49,18 +49,17 @@ public class NikoHomeControlBridgeHandler2 extends NikoHomeControlBridgeHandler private final Gson gson = new GsonBuilder().create(); - NetworkAddressService networkAddressService; - public NikoHomeControlBridgeHandler2(Bridge nikoHomeControlBridge, NetworkAddressService networkAddressService, TimeZoneProvider timeZoneProvider) { - super(nikoHomeControlBridge, timeZoneProvider); - this.networkAddressService = networkAddressService; + super(nikoHomeControlBridge, networkAddressService, timeZoneProvider); } @Override public void initialize() { logger.debug("initializing NHC II bridge handler"); + scheduler.submit(() -> getControllerId()); + Date expiryDate = getTokenExpiryDate(); if (expiryDate == null) { if (getToken().isEmpty()) { @@ -98,7 +97,7 @@ public class NikoHomeControlBridgeHandler2 extends NikoHomeControlBridgeHandler @Override protected void updateProperties() { - Map properties = new HashMap<>(); + Map properties = new HashMap<>(thing.getProperties()); NikoHomeControlCommunication2 comm = (NikoHomeControlCommunication2) nhcComm; if (comm != null) { diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NikoHomeControlDiscover.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NikoHomeControlDiscover.java index 0237ab08896..ff7435e3e87 100644 --- a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NikoHomeControlDiscover.java +++ b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NikoHomeControlDiscover.java @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -50,7 +51,7 @@ public final class NikoHomeControlDiscover { private final Logger logger = LoggerFactory.getLogger(NikoHomeControlDiscover.class); private List nhcBridgeIds = new ArrayList<>(); - private Map inetAdresses = new HashMap<>(); + private Map inetAddresses = new HashMap<>(); private Map isNhcII = new HashMap<>(); /** @@ -104,7 +105,16 @@ public final class NikoHomeControlDiscover { * @return the addr, null if not in the list of discovered bridgeId's */ public @Nullable InetAddress getAddr(String bridgeId) { - return inetAdresses.get(bridgeId); + return inetAddresses.get(bridgeId); + } + + /** + * @param inetAddress inetAddress of the controller + * @return the bridgeId, null if not found + */ + public @Nullable String getBridgeId(InetAddress inetAddress) { + return inetAddresses.entrySet().stream().filter(entry -> inetAddress.equals(entry.getValue())) + .map(Entry::getKey).findAny().get(); } /** @@ -168,7 +178,7 @@ public final class NikoHomeControlDiscover { */ private InetAddress setAddr(String bridgeId, DatagramPacket packet) { InetAddress address = packet.getAddress(); - inetAdresses.put(bridgeId, address); + inetAddresses.put(bridgeId, address); return address; } diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc2/NikoHomeControlCommunication2.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc2/NikoHomeControlCommunication2.java index d307b859db2..353ed0ad6a5 100644 --- a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc2/NikoHomeControlCommunication2.java +++ b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc2/NikoHomeControlCommunication2.java @@ -85,6 +85,8 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication private volatile String profile = ""; + private String rawDevicesListResponse = ""; + private volatile @Nullable NhcSystemInfo2 nhcSystemInfo; private volatile @Nullable NhcTimeInfo2 nhcTimeInfo; @@ -270,6 +272,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication } private void devicesListRsp(String response) { + rawDevicesListResponse = response; Type messageType = new TypeToken() { }.getType(); List deviceList = null; @@ -1278,6 +1281,10 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication return services.stream().map(NhcService2::name).collect(Collectors.joining(", ")); } + public String getRawDevicesListResponse() { + return rawDevicesListResponse; + } + @Override public void connectionStateChanged(MqttConnectionState state, @Nullable Throwable error) { // do in separate thread as this method needs to return early