]> git.basschouten.com Git - openhab-addons.git/commitdiff
[nikohomecontrol] Add console commands (#17352)
authorMark Herwege <mherwege@users.noreply.github.com>
Thu, 12 Sep 2024 13:14:22 +0000 (15:14 +0200)
committerGitHub <noreply@github.com>
Thu, 12 Sep 2024 13:14:22 +0000 (15:14 +0200)
* dump devices from console

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
bundles/org.openhab.binding.nikohomecontrol/README.md
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlBindingConstants.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/NikoHomeControlHandlerFactory.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/console/NikoHomeControlCommandExtension.java [new file with mode: 0644]
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/discovery/NikoHomeControlBridgeDiscoveryService.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler1.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeHandler2.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NikoHomeControlDiscover.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc2/NikoHomeControlCommunication2.java

index 4688ac3ac0ab02d8815e46a6b26397f730016a0f..21f83ac76242716c9be4a562fa5197b63719ed31 100644 (file)
@@ -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 <controller ID>`: Info about the system
+- `nikohomecontrol devicelist <controller ID>`: JSON list of devices with their characteristics in a Niko Home Control II system
+- `nikohomecontrol devicelist  <controller ID> 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.
index bf5df0cc4b038395c1bb1f319d25a20a052b1a66..5dba879791ec5c177bad05c760c9a2420fe80d7f 100644 (file)
@@ -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";
index 05a209c5f915412c754016e3cf4a7399249469cc..31ab59d34c548f8e9b00c6df799146c6de8ef8ae 100644 (file)
@@ -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 (file)
index 0000000..2d7312e
--- /dev/null
@@ -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<NikoHomeControlBridgeHandler> 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<String, String> bridgeNhcVersion = bridgeHandlers.stream().collect(Collectors
+                .toMap(b -> b.getControllerId(), b -> b instanceof NikoHomeControlBridgeHandler2 ? "II" : "I"));
+
+        NikoHomeControlBridgeHandler bridgeHandler = null;
+        if (args.length > 1) {
+            Optional<NikoHomeControlBridgeHandler> 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<String, String> bridgeIds = bridgeHandlers.stream().collect(Collectors
+                            .toMap(b -> b.getThing().getUID().toString(), b -> b.getControllerId().toLowerCase()));
+                    List<String> controllerIds = List.of();
+                    Map<String, String> 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<String, String> 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<String, String> 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<String> getUsages() {
+        return Arrays.asList(new String[] { buildCommandUsage(CONTROLLERS, "list all Niko Home Control Controllers"),
+                buildCommandUsage(SYSTEMINFO + " <controller ID>",
+                        "show system info for Controller with controller ID"),
+                buildCommandUsage(DEVICELIST + " <controller ID>",
+                        "create device list of installation on Controller with controller ID"),
+                buildCommandUsage(DEVICELIST + " <controller ID> " + 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<String> 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;
+    }
+}
index 182772668bbc0dd2eae33ac98ec2475a886ee318..96d33c5e3b5b91d3ea6a6cda8b8e86299502dd53 100644 (file)
@@ -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);
     }
 
index a31ac029ebc6a422a00a9b37a963d750ba0b42e9..620d1cf736e414305f665b736d97c0d97597b0ac 100644 (file)
@@ -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<Class<? extends ThingHandlerService>> 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;
+    }
 }
index 71cf17bf00374db1ce588ce75f7134d696f9229f..74e8359a7396a6bf1db4a2f723b805690166d4cd 100644 (file)
@@ -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<String, String> properties = new HashMap<>();
+        Map<String, String> properties = new HashMap<>(thing.getProperties());
 
         NikoHomeControlCommunication1 comm = (NikoHomeControlCommunication1) nhcComm;
         if (comm != null) {
index eea88ea8d2fa5487639607354978a7116cbc760d..8a1aaae213f0454afbe630a71e7ea46aefdcc524 100644 (file)
@@ -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<String, String> properties = new HashMap<>();
+        Map<String, String> properties = new HashMap<>(thing.getProperties());
 
         NikoHomeControlCommunication2 comm = (NikoHomeControlCommunication2) nhcComm;
         if (comm != null) {
index 0237ab088963fd3af940d1f35d8b5bcafcd3cc29..ff7435e3e87f44322ff586907337350299acaa48 100644 (file)
@@ -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<String> nhcBridgeIds = new ArrayList<>();
-    private Map<String, InetAddress> inetAdresses = new HashMap<>();
+    private Map<String, InetAddress> inetAddresses = new HashMap<>();
     private Map<String, Boolean> 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;
     }
 
index d307b859db2899e55831e6e24807ddd7fe1c4288..353ed0ad6a5c6d453cb5e81e7046758e2365ee97 100644 (file)
@@ -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<NhcMessage2>() {
         }.getType();
         List<NhcDevice2> 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