]> git.basschouten.com Git - openhab-addons.git/commitdiff
[nikohomecontrol] Add shutter invert and fix connection with NHC does not recover...
authorMark Herwege <mherwege@users.noreply.github.com>
Sat, 13 Mar 2021 19:44:36 +0000 (20:44 +0100)
committerGitHub <noreply@github.com>
Sat, 13 Mar 2021 19:44:36 +0000 (20:44 +0100)
* Ignore devices.changed event.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
* Null warnings cleanup.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
* Remove @NonNullByDefault({})

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
* Shorten logger messages.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
* Introduce rollershutter invert flag.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
* Add null annotations.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
* Connection resilience improvements and log level cleanup.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
* Update bundles/org.openhab.binding.nikohomecontrol/src/main/resources/OH-INF/thing/thing-types.xml

Signed-off-by: Fabian Wolter <github@fabian-wolter.de>
Co-authored-by: Fabian Wolter <github@fabian-wolter.de>
38 files changed:
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/discovery/NikoHomeControlDiscoveryService.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NhcJwtToken2.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlActionBlindConfig.java [new file with mode: 0644]
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlActionConfig.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlActionDimmerConfig.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlActionHandler.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeConfig.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlBridgeConfig2.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/handler/NikoHomeControlEnergyMeterConfig.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlEnergyMeterHandler.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlThermostatConfig.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlThermostatHandler.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NhcAction.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NhcActionEvent.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NhcControllerEvent.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NhcEnergyMeter.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NhcEnergyMeterEvent.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NhcThermostat.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NhcThermostatEvent.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/NikoHomeControlCommunication.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/nhc1/NhcAction1.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc1/NhcMessageBase1.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc1/NhcMessageCmd1.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc1/NhcMessageListMap1.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc1/NhcMessageMap1.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc1/NhcThermostat1.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc1/NikoHomeControlCommunication1.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc1/NikoHomeControlMessageDeserializer1.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc2/NhcAction2.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc2/NhcMqttConnection2.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc2/NhcThermostat2.java
bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/protocol/nhc2/NikoHomeControlCommunication2.java
bundles/org.openhab.binding.nikohomecontrol/src/main/resources/OH-INF/thing/thing-types.xml

index 50b0e1b73fedc63514af3cd1a7f26202f6f2f3bd..ffe67643dbbaefe967d3fef5b83f609c51969f02 100644 (file)
@@ -55,7 +55,7 @@ public class NikoHomeControlBridgeDiscoveryService extends AbstractDiscoveryServ
 
     public NikoHomeControlBridgeDiscoveryService() {
         super(NikoHomeControlBindingConstants.BRIDGE_THING_TYPES_UIDS, TIMEOUT);
-        logger.debug("Niko Home Control: bridge discovery service started");
+        logger.debug("bridge discovery service started");
     }
 
     /**
@@ -65,10 +65,10 @@ public class NikoHomeControlBridgeDiscoveryService extends AbstractDiscoveryServ
         try {
             String broadcastAddr = networkAddressService.getConfiguredBroadcastAddress();
             if (broadcastAddr == null) {
-                logger.warn("Niko Home Control: discovery not possible, no broadcast address found");
+                logger.warn("discovery not possible, no broadcast address found");
                 return;
             }
-            logger.debug("Niko Home Control: discovery broadcast on {}", broadcastAddr);
+            logger.debug("discovery broadcast on {}", broadcastAddr);
             NikoHomeControlDiscover nhcDiscover = new NikoHomeControlDiscover(broadcastAddr);
             if (nhcDiscover.isNhcII()) {
                 addNhcIIBridge(nhcDiscover.getAddr(), nhcDiscover.getNhcBridgeId());
@@ -76,12 +76,12 @@ public class NikoHomeControlBridgeDiscoveryService extends AbstractDiscoveryServ
                 addNhcIBridge(nhcDiscover.getAddr(), nhcDiscover.getNhcBridgeId());
             }
         } catch (IOException e) {
-            logger.debug("Niko Home Control: no bridge found.");
+            logger.debug("no bridge found.");
         }
     }
 
     private void addNhcIBridge(InetAddress addr, String bridgeId) {
-        logger.debug("Niko Home Control: NHC I bridge found at {}", addr);
+        logger.debug("NHC I bridge found at {}", addr);
 
         String bridgeName = "Niko Home Control Bridge";
         ThingUID uid = new ThingUID(BINDING_ID, "bridge", bridgeId);
@@ -92,7 +92,7 @@ public class NikoHomeControlBridgeDiscoveryService extends AbstractDiscoveryServ
     }
 
     private void addNhcIIBridge(InetAddress addr, String bridgeId) {
-        logger.debug("Niko Home Control: NHC II bridge found at {}", addr);
+        logger.debug("NHC II bridge found at {}", addr);
 
         String bridgeName = "Niko Home Control II Bridge";
         ThingUID uid = new ThingUID(BINDING_ID, "bridge2", bridgeId);
@@ -115,7 +115,7 @@ public class NikoHomeControlBridgeDiscoveryService extends AbstractDiscoveryServ
 
     @Override
     protected void startBackgroundDiscovery() {
-        logger.debug("Niko Home Control: Start background bridge discovery");
+        logger.debug("Start background bridge discovery");
         ScheduledFuture<?> job = nhcDiscoveryJob;
         if (job == null || job.isCancelled()) {
             nhcDiscoveryJob = scheduler.scheduleWithFixedDelay(this::discoverBridge, 0, REFRESH_INTERVAL,
@@ -125,7 +125,7 @@ public class NikoHomeControlBridgeDiscoveryService extends AbstractDiscoveryServ
 
     @Override
     protected void stopBackgroundDiscovery() {
-        logger.debug("Niko Home Control: Stop bridge background discovery");
+        logger.debug("Stop bridge background discovery");
         ScheduledFuture<?> job = nhcDiscoveryJob;
         if (job != null && !job.isCancelled()) {
             job.cancel(true);
index 838b49f2d492048489cbfbd8cb2b9411041b4c63..63e847068dc5da17deba2355ab154a4dd1f91dbd 100644 (file)
@@ -48,7 +48,7 @@ public class NikoHomeControlDiscoveryService extends AbstractDiscoveryService {
 
     public NikoHomeControlDiscoveryService(NikoHomeControlBridgeHandler handler) {
         super(SUPPORTED_THING_TYPES_UIDS, TIMEOUT, false);
-        logger.debug("Niko Home Control: discovery service {}", handler);
+        logger.debug("discovery service {}", handler);
         bridgeUID = handler.getThing().getUID();
         this.handler = handler;
     }
@@ -70,10 +70,10 @@ public class NikoHomeControlDiscoveryService extends AbstractDiscoveryService {
         NikoHomeControlCommunication nhcComm = handler.getCommunication();
 
         if ((nhcComm == null) || !nhcComm.communicationActive()) {
-            logger.warn("Niko Home Control: not connected.");
+            logger.warn("not connected");
             return;
         }
-        logger.debug("Niko Home Control: getting devices on {}", handler.getThing().getUID().getId());
+        logger.debug("getting devices on {}", handler.getThing().getUID().getId());
 
         Map<String, NhcAction> actions = nhcComm.getActions();
 
@@ -99,8 +99,7 @@ public class NikoHomeControlDiscoveryService extends AbstractDiscoveryService {
                             thingName, thingLocation);
                     break;
                 default:
-                    logger.debug("Niko Home Control: unrecognized action type {} for {} {}", nhcAction.getType(),
-                            actionId, thingName);
+                    logger.debug("unrecognized action type {} for {} {}", nhcAction.getType(), actionId, thingName);
             }
         });
 
index abab7e20367309dbddb9c6796739abf372ec9720..38ebff218e41097f3ca1287ba8c6c059e9bcb1f4 100644 (file)
@@ -14,17 +14,20 @@ package org.openhab.binding.nikohomecontrol.internal.handler;
 
 import java.util.List;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * {@link NhcJwtToken2} represents the Niko Home Control II hobby API token payload.
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 class NhcJwtToken2 {
-    String sub;
-    String iat;
-    String exp;
-    String aud;
-    String iss;
-    String jti;
-    List<String> role;
+    String sub = "";
+    String iat = "";
+    String exp = "";
+    String aud = "";
+    String iss = "";
+    String jti = "";
+    List<String> role = List.of();
 }
diff --git a/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlActionBlindConfig.java b/bundles/org.openhab.binding.nikohomecontrol/src/main/java/org/openhab/binding/nikohomecontrol/internal/handler/NikoHomeControlActionBlindConfig.java
new file mode 100644 (file)
index 0000000..6423c31
--- /dev/null
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2010-2021 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.handler;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * {@link NikoHomeControlActionBlindConfig} is the config class for Niko Home Control Blind Actions.
+ *
+ * @author Mark Herwege - Initial Contribution
+ */
+@NonNullByDefault
+public class NikoHomeControlActionBlindConfig extends NikoHomeControlActionConfig {
+    public boolean invert;
+}
index 2cd963c169055fdfb15dc2064018fe523b4f07d0..39c0a3a74d344623277f1bc6c1408f5cc3c95f11 100644 (file)
  */
 package org.openhab.binding.nikohomecontrol.internal.handler;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * {@link NikoHomeControlActionConfig} is the general config class for Niko Home Control Actions.
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 public class NikoHomeControlActionConfig {
-    public String actionId;
+    public String actionId = "";
 }
index 2a5d52f32633c38a713bee3733c80bbcabfe8146..712c09b42c30cf8505320fb5928be9d98010380b 100644 (file)
  */
 package org.openhab.binding.nikohomecontrol.internal.handler;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * {@link NikoHomeControlActionDimmerConfig} is the config class for Niko Home Control Dimmer Actions.
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 public class NikoHomeControlActionDimmerConfig extends NikoHomeControlActionConfig {
-    public int step;
+    public int step = 10;
 }
index 4b39852d2ba5d37cd00f13e360c7bc5c6a76c631..3cd76e9da2d168d79f069fe77b40ae81388269e1 100644 (file)
@@ -52,10 +52,11 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
 
     private final Logger logger = LoggerFactory.getLogger(NikoHomeControlActionHandler.class);
 
-    private volatile @NonNullByDefault({}) NhcAction nhcAction;
+    private volatile @Nullable NhcAction nhcAction;
 
     private String actionId = "";
     private int stepValue;
+    private boolean invert;
 
     public NikoHomeControlActionHandler(Thing thing) {
         super(thing);
@@ -66,8 +67,7 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
         NikoHomeControlCommunication nhcComm = getCommunication();
         if (nhcComm == null) {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                    "Niko Home Control: bridge communication not initialized when trying to execute action command "
-                            + actionId);
+                    "Bridge communication not initialized when trying to execute action command " + actionId);
             return;
         }
 
@@ -84,7 +84,13 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
     }
 
     private void handleCommandSelection(ChannelUID channelUID, Command command) {
-        logger.debug("Niko Home Control: handle command {} for {}", command, channelUID);
+        NhcAction nhcAction = this.nhcAction;
+        if (nhcAction == null) {
+            logger.debug("action with ID {} not initialized", actionId);
+            return;
+        }
+
+        logger.debug("handle command {} for {}", command, channelUID);
 
         if (command == REFRESH) {
             actionEvent(nhcAction.getState());
@@ -109,11 +115,17 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
 
             default:
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                        "Niko Home Control: channel unknown " + channelUID.getId());
+                        "Channel unknown " + channelUID.getId());
         }
     }
 
     private void handleSwitchCommand(Command command) {
+        NhcAction nhcAction = this.nhcAction;
+        if (nhcAction == null) {
+            logger.debug("action with ID {} not initialized", actionId);
+            return;
+        }
+
         if (command instanceof OnOffType) {
             OnOffType s = (OnOffType) command;
             if (OnOffType.OFF.equals(s)) {
@@ -125,6 +137,12 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
     }
 
     private void handleBrightnessCommand(Command command) {
+        NhcAction nhcAction = this.nhcAction;
+        if (nhcAction == null) {
+            logger.debug("action with ID {} not initialized", actionId);
+            return;
+        }
+
         if (command instanceof OnOffType) {
             OnOffType s = (OnOffType) command;
             if (OnOffType.OFF.equals(s)) {
@@ -162,18 +180,24 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
     }
 
     private void handleRollershutterCommand(Command command) {
+        NhcAction nhcAction = this.nhcAction;
+        if (nhcAction == null) {
+            logger.debug("action with ID {} not initialized", actionId);
+            return;
+        }
+
         if (command instanceof UpDownType) {
             UpDownType s = (UpDownType) command;
             if (UpDownType.UP.equals(s)) {
-                nhcAction.execute(NHCUP);
+                nhcAction.execute(!invert ? NHCUP : NHCDOWN);
             } else {
-                nhcAction.execute(NHCDOWN);
+                nhcAction.execute(!invert ? NHCDOWN : NHCUP);
             }
         } else if (command instanceof StopMoveType) {
             nhcAction.execute(NHCSTOP);
         } else if (command instanceof PercentType) {
             PercentType p = (PercentType) command;
-            nhcAction.execute(Integer.toString(100 - p.intValue()));
+            nhcAction.execute(!invert ? Integer.toString(100 - p.intValue()) : Integer.toString(p.intValue()));
         }
     }
 
@@ -183,6 +207,9 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
         if (thing.getThingTypeUID().equals(THING_TYPE_DIMMABLE_LIGHT)) {
             config = getConfig().as(NikoHomeControlActionDimmerConfig.class);
             stepValue = ((NikoHomeControlActionDimmerConfig) config).step;
+        } else if (thing.getThingTypeUID().equals(THING_TYPE_BLIND)) {
+            config = getConfig().as(NikoHomeControlActionBlindConfig.class);
+            invert = ((NikoHomeControlActionBlindConfig) config).invert;
         } else {
             config = getConfig().as(NikoHomeControlActionConfig.class);
         }
@@ -190,6 +217,8 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
 
         NikoHomeControlCommunication nhcComm = getCommunication();
         if (nhcComm == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+                    "Connection with controller not started yet, could not initialize action " + actionId);
             return;
         }
 
@@ -197,15 +226,14 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
         scheduler.submit(() -> {
             if (!nhcComm.communicationActive()) {
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                        "Niko Home Control: no connection with Niko Home Control, could not initialize action "
-                                + actionId);
+                        "No connection with controller, could not initialize action " + actionId);
                 return;
             }
 
-            nhcAction = nhcComm.getActions().get(actionId);
+            NhcAction nhcAction = nhcComm.getActions().get(actionId);
             if (nhcAction == null) {
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                        "Niko Home Control: actionId does not match an action in the controller " + actionId);
+                        "Action " + actionId + " does not match an action in the controller");
                 return;
             }
 
@@ -220,7 +248,9 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
 
             actionEvent(nhcAction.getState());
 
-            logger.debug("Niko Home Control: action initialized {}", actionId);
+            this.nhcAction = nhcAction;
+
+            logger.debug("action initialized {}", actionId);
 
             Bridge bridge = getBridge();
             if ((bridge != null) && (bridge.getStatus() == ThingStatus.ONLINE)) {
@@ -232,6 +262,12 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
     }
 
     private void updateProperties() {
+        NhcAction nhcAction = this.nhcAction;
+        if (nhcAction == null) {
+            logger.debug("action with ID {} not initialized", actionId);
+            return;
+        }
+
         Map<String, String> properties = new HashMap<>();
         properties.put("type", String.valueOf(nhcAction.getType()));
         if (getThing().getThingTypeUID() == THING_TYPE_BLIND) {
@@ -250,6 +286,12 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
 
     @Override
     public void actionEvent(int actionState) {
+        NhcAction nhcAction = this.nhcAction;
+        if (nhcAction == null) {
+            logger.debug("action with ID {} not initialized", actionId);
+            return;
+        }
+
         ActionType actionType = nhcAction.getType();
 
         switch (actionType) {
@@ -265,19 +307,28 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
                 updateStatus(ThingStatus.ONLINE);
                 break;
             case ROLLERSHUTTER:
-                updateState(CHANNEL_ROLLERSHUTTER, new PercentType(actionState));
+                updateState(CHANNEL_ROLLERSHUTTER,
+                        !invert ? new PercentType(100 - actionState) : new PercentType(actionState));
                 updateStatus(ThingStatus.ONLINE);
                 break;
             default:
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                        "Niko Home Control: unknown action type " + actionType);
+                        "Unknown action type " + actionType);
+        }
+    }
+
+    @Override
+    public void actionInitialized() {
+        Bridge bridge = getBridge();
+        if ((bridge != null) && (bridge.getStatus() == ThingStatus.ONLINE)) {
+            updateStatus(ThingStatus.ONLINE);
         }
     }
 
     @Override
     public void actionRemoved() {
         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                "Niko Home Control: action has been removed from the controller " + actionId);
+                "Action " + actionId + " has been removed from the controller");
     }
 
     private void restartCommunication(NikoHomeControlCommunication nhcComm) {
@@ -286,8 +337,7 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
         nhcComm.restartCommunication();
         // If still not active, take thing offline and return.
         if (!nhcComm.communicationActive()) {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                    "Niko Home Control: communication socket error");
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Communication error");
             return;
         }
         // Also put the bridge back online
@@ -301,7 +351,7 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
         NikoHomeControlBridgeHandler nhcBridgeHandler = getBridgeHandler();
         if (nhcBridgeHandler == null) {
             updateStatus(ThingStatus.UNINITIALIZED, ThingStatusDetail.BRIDGE_UNINITIALIZED,
-                    "Niko Home Control: no bridge initialized for action " + actionId);
+                    "No bridge initialized for action " + actionId);
             return null;
         }
         NikoHomeControlCommunication nhcComm = nhcBridgeHandler.getCommunication();
@@ -312,7 +362,7 @@ public class NikoHomeControlActionHandler extends BaseThingHandler implements Nh
         Bridge nhcBridge = getBridge();
         if (nhcBridge == null) {
             updateStatus(ThingStatus.UNINITIALIZED, ThingStatusDetail.BRIDGE_UNINITIALIZED,
-                    "Niko Home Control: no bridge initialized for action " + actionId);
+                    "No bridge initialized for action " + actionId);
             return null;
         }
         NikoHomeControlBridgeHandler nhcBridgeHandler = (NikoHomeControlBridgeHandler) nhcBridge.getHandler();
index 614cd0ac4ec41d1a5c2279a440456d48538e13cf..979ad3d8d421d1f8c81fdc02dcd04d416978ebbd 100644 (file)
  */
 package org.openhab.binding.nikohomecontrol.internal.handler;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * {@link NikoHomeControlBridgeConfig} is the general config class for Niko Home Control Bridges.
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 public class NikoHomeControlBridgeConfig {
-    public String addr;
+    public String addr = "";
     public int port;
     public int refresh;
 }
index 5d1d3eb17c1930a866eb884f78319cb2a893d591..384d869ef418111a65cbb5c9d7ecff41e8124839 100644 (file)
  */
 package org.openhab.binding.nikohomecontrol.internal.handler;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * {@link NikoHomeControlBridgeConfig2} is the extended config class for Niko Home Control II Bridges.
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 public class NikoHomeControlBridgeConfig2 extends NikoHomeControlBridgeConfig {
-    public String profile;
-    public String password;
+    public String profile = "";
+    public String password = "";
 }
index f120e93d7eb6fde07e27e81133df7ae2d34915c0..b7e4472ff5071da2fdc685c0d3edf8b95448465c 100644 (file)
@@ -95,7 +95,7 @@ public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler imp
             if (discovery != null) {
                 discovery.discoverDevices();
             } else {
-                logger.debug("Niko Home Control: cannot discover devices, discovery service not started");
+                logger.debug("cannot discover devices, discovery service not started");
             }
         });
     }
@@ -117,9 +117,9 @@ public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler imp
         }
 
         // This timer will restart the bridge connection periodically
-        logger.debug("Niko Home Control: restart bridge connection every {} min", refreshInterval);
+        logger.debug("restart bridge connection every {} min", refreshInterval);
         refreshTimer = scheduler.scheduleWithFixedDelay(() -> {
-            logger.debug("Niko Home Control: restart communication at scheduled time");
+            logger.debug("restart communication at scheduled time");
 
             NikoHomeControlCommunication comm = nhcComm;
             if (comm != null) {
@@ -141,7 +141,7 @@ public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler imp
      */
     protected void bridgeOffline() {
         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
-                "Niko Home Control: error starting bridge connection");
+                "Error with bridge connection");
     }
 
     /**
@@ -153,8 +153,8 @@ public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler imp
     }
 
     @Override
-    public void controllerOffline() {
-        bridgeOffline();
+    public void controllerOffline(String message) {
+        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, message);
     }
 
     @Override
@@ -231,14 +231,14 @@ public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler imp
 
     @Override
     public void alarmEvent(String alarmText) {
-        logger.debug("Niko Home Control: triggering alarm channel with {}", alarmText);
+        logger.debug("triggering alarm channel with {}", alarmText);
         triggerChannel(CHANNEL_ALARM, alarmText);
         updateStatus(ThingStatus.ONLINE);
     }
 
     @Override
     public void noticeEvent(String alarmText) {
-        logger.debug("Niko Home Control: triggering notice channel with {}", alarmText);
+        logger.debug("triggering notice channel with {}", alarmText);
         triggerChannel(CHANNEL_NOTICE, alarmText);
         updateStatus(ThingStatus.ONLINE);
     }
@@ -263,7 +263,7 @@ public abstract class NikoHomeControlBridgeHandler extends BaseBridgeHandler imp
         try {
             addr = InetAddress.getByName(config.addr);
         } catch (UnknownHostException e) {
-            logger.debug("Niko Home Control: Cannot resolve hostname {} to IP adress", config.addr);
+            logger.debug("Cannot resolve hostname {} to IP adress", config.addr);
         }
         return addr;
     }
index 5f6408db7f317e5843dab6d4a4a81fde8b690cb8..e0938e1a2cdb140142801d648d991f94a86ccbeb 100644 (file)
@@ -41,20 +41,20 @@ public class NikoHomeControlBridgeHandler1 extends NikoHomeControlBridgeHandler
 
     @Override
     public void initialize() {
-        logger.debug("Niko Home Control: initializing bridge handler");
+        logger.debug("initializing bridge handler");
 
         setConfig();
         InetAddress addr = getAddr();
         int port = getPort();
 
-        logger.debug("Niko Home Control: bridge handler host {}, port {}", addr, port);
+        logger.debug("bridge handler host {}, port {}", addr, port);
 
         if (addr != null) {
             nhcComm = new NikoHomeControlCommunication1(this, scheduler);
             startCommunication();
         } else {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
-                    "Niko Home Control: cannot resolve bridge IP with hostname " + config.addr);
+                    "Cannot resolve bridge IP with hostname " + config.addr);
         }
     }
 
index 668d7f33a789d6b9301f61164ea50f15ccaa8d63..e6687926e96a2c632d2ce04b785bdb954fccc830 100644 (file)
@@ -57,7 +57,7 @@ public class NikoHomeControlBridgeHandler2 extends NikoHomeControlBridgeHandler
 
     @Override
     public void initialize() {
-        logger.debug("Niko Home Control: initializing NHC II bridge handler");
+        logger.debug("initializing NHC II bridge handler");
 
         setConfig();
 
@@ -69,15 +69,14 @@ public class NikoHomeControlBridgeHandler2 extends NikoHomeControlBridgeHandler
                 // advanced configuration, skipping token validation.
                 // This behavior would allow the same logic to be used (with profile UUID) as before token validation
                 // was introduced.
-                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
-                        "Niko Home Control: token is empty");
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, "Token is empty");
                 return;
             }
         } else {
             Date now = new Date();
             if (expiryDate.before(now)) {
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
-                        "Niko Home Control: hobby api token has expired");
+                        "Hobby api token has expired");
                 return;
             }
         }
@@ -91,7 +90,7 @@ public class NikoHomeControlBridgeHandler2 extends NikoHomeControlBridgeHandler
         } catch (CertificateException e) {
             // this should not happen unless there is a programming error
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
-                    "Niko Home Control: not able to set SSL context");
+                    "Not able to set SSL context");
             return;
         }
     }
@@ -167,9 +166,8 @@ public class NikoHomeControlBridgeHandler2 extends NikoHomeControlBridgeHandler
     @Override
     public String getToken() {
         String token = ((NikoHomeControlBridgeConfig2) config).password;
-        if ((token == null) || token.isEmpty()) {
-            logger.debug("Niko Home Control: no JWT token set.");
-            return "";
+        if (token.isEmpty()) {
+            logger.debug("no JWT token set.");
         }
         return token;
     }
@@ -192,10 +190,10 @@ public class NikoHomeControlBridgeHandler2 extends NikoHomeControlBridgeHandler
             try {
                 jwtToken = gson.fromJson(tokenPayload, NhcJwtToken2.class);
             } catch (JsonSyntaxException e) {
-                logger.debug("Niko Home Control: unexpected token payload {}", tokenPayload);
+                logger.debug("unexpected token payload {}", tokenPayload);
             } catch (NoSuchElementException ignore) {
                 // Ignore if exp not present in response, this should not happen in token payload response
-                logger.trace("Niko Home Control: no expiry date found in payload {}", tokenPayload);
+                logger.trace("no expiry date found in payload {}", tokenPayload);
             }
         }
 
@@ -206,20 +204,20 @@ public class NikoHomeControlBridgeHandler2 extends NikoHomeControlBridgeHandler
                 long epoch = Long.parseLong(expiryEpoch) * 1000; // convert to milliseconds
                 expiryDate = new Date(epoch);
             } catch (NumberFormatException e) {
-                logger.debug("Niko Home Control: token expiry not valid {}", jwtToken.exp);
+                logger.debug("token expiry not valid {}", jwtToken.exp);
                 return null;
             }
 
             Date now = new Date();
             if (expiryDate.before(now)) {
-                logger.warn("Niko Home Control: hobby API token expired, was valid until {}",
+                logger.warn("hobby API token expired, was valid until {}",
                         DateFormat.getDateInstance().format(expiryDate));
             } else {
                 Calendar c = Calendar.getInstance();
                 c.setTime(expiryDate);
                 c.add(Calendar.DATE, -14);
                 if (c.getTime().before(now)) {
-                    logger.info("Niko Home Control: hobby API token will expire in less than 14 days, valid until {}",
+                    logger.info("hobby API token will expire in less than 14 days, valid until {}",
                             DateFormat.getDateInstance().format(expiryDate));
                 }
             }
index dd61f042787719830e3c930355b5a236c331ab35..2af74b26ca2a90068e1b700f50958e7b4ca29379 100644 (file)
  */
 package org.openhab.binding.nikohomecontrol.internal.handler;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * {@link NikoHomeControlEnergyMeterConfig} is the config class for Niko Home Control Thermostats.
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 public class NikoHomeControlEnergyMeterConfig {
-    public String energyMeterId;
+    public String energyMeterId = "";
 }
index 7f22acc7907fa2a0d41a3bb027e4b2f9b6736d9d..637f065f5af01d5bb5fd27cce4820573cada575c 100644 (file)
@@ -48,7 +48,7 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
 
     private final Logger logger = LoggerFactory.getLogger(NikoHomeControlEnergyMeterHandler.class);
 
-    private volatile @NonNullByDefault({}) NhcEnergyMeter nhcEnergyMeter;
+    private volatile @Nullable NhcEnergyMeter nhcEnergyMeter;
 
     private String energyMeterId = "";
 
@@ -58,6 +58,12 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
 
     @Override
     public void handleCommand(ChannelUID channelUID, Command command) {
+        NhcEnergyMeter nhcEnergyMeter = this.nhcEnergyMeter;
+        if (nhcEnergyMeter == null) {
+            logger.debug("energy meter with ID {} not initialized", energyMeterId);
+            return;
+        }
+
         if (command == REFRESH) {
             energyMeterEvent(nhcEnergyMeter.getPower());
         }
@@ -71,6 +77,8 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
 
         NikoHomeControlCommunication nhcComm = getCommunication();
         if (nhcComm == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+                    "Connection with controller not started yet, could not initialize energy meter " + energyMeterId);
             return;
         }
 
@@ -79,16 +87,14 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
         scheduler.submit(() -> {
             if (!nhcComm.communicationActive()) {
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                        "Niko Home Control: no connection with Niko Home Control, could not initialize energy meter "
-                                + energyMeterId);
+                        "No connection with controller, could not initialize energy meter " + energyMeterId);
                 return;
             }
 
-            nhcEnergyMeter = nhcComm.getEnergyMeters().get(energyMeterId);
+            NhcEnergyMeter nhcEnergyMeter = nhcComm.getEnergyMeters().get(energyMeterId);
             if (nhcEnergyMeter == null) {
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                        "Niko Home Control: energyMeterId does not match a energy meter in the controller "
-                                + energyMeterId);
+                        "Energy meter " + energyMeterId + " does not match a energy meter in the controller");
                 return;
             }
 
@@ -102,7 +108,9 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
                 nhcComm.startEnergyMeter(energyMeterId);
             }
 
-            logger.debug("Niko Home Control: energy meter intialized {}", energyMeterId);
+            this.nhcEnergyMeter = nhcEnergyMeter;
+
+            logger.debug("energy meter intialized {}", energyMeterId);
 
             Bridge bridge = getBridge();
             if ((bridge != null) && (bridge.getStatus() == ThingStatus.ONLINE)) {
@@ -144,10 +152,18 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
         updateStatus(ThingStatus.ONLINE);
     }
 
+    @Override
+    public void energyMeterInitialized() {
+        Bridge bridge = getBridge();
+        if ((bridge != null) && (bridge.getStatus() == ThingStatus.ONLINE)) {
+            updateStatus(ThingStatus.ONLINE);
+        }
+    }
+
     @Override
     public void energyMeterRemoved() {
         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                "Niko Home Control: energy meter has been removed from the controller " + energyMeterId);
+                "Energy meter " + energyMeterId + " has been removed from the controller");
     }
 
     @Override
@@ -157,8 +173,7 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
         NikoHomeControlCommunication nhcComm = getCommunication();
         if (nhcComm == null) {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                    "Niko Home Control: bridge communication not initialized when trying to start energy meter "
-                            + energyMeterId);
+                    "Bridge communication not initialized when trying to start energy meter " + energyMeterId);
             return;
         }
 
@@ -180,8 +195,7 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
         NikoHomeControlCommunication nhcComm = getCommunication();
         if (nhcComm == null) {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                    "Niko Home Control: bridge communication not initialized when trying to stop energy meter "
-                            + energyMeterId);
+                    "Bridge communication not initialized when trying to stop energy meter " + energyMeterId);
             return;
         }
 
@@ -206,8 +220,7 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
         nhcComm.restartCommunication();
         // If still not active, take thing offline and return.
         if (!nhcComm.communicationActive()) {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                    "Niko Home Control: communication socket error");
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Communication error");
             return;
         }
         // Also put the bridge back online
@@ -221,7 +234,7 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
         NikoHomeControlBridgeHandler nhcBridgeHandler = getBridgeHandler();
         if (nhcBridgeHandler == null) {
             updateStatus(ThingStatus.UNINITIALIZED, ThingStatusDetail.BRIDGE_UNINITIALIZED,
-                    "Niko Home Control: no bridge initialized for energy meter " + energyMeterId);
+                    "No bridge initialized for energy meter " + energyMeterId);
             return null;
         }
         NikoHomeControlCommunication nhcComm = nhcBridgeHandler.getCommunication();
@@ -232,7 +245,7 @@ public class NikoHomeControlEnergyMeterHandler extends BaseThingHandler implemen
         Bridge nhcBridge = getBridge();
         if (nhcBridge == null) {
             updateStatus(ThingStatus.UNINITIALIZED, ThingStatusDetail.BRIDGE_UNINITIALIZED,
-                    "Niko Home Control: no bridge initialized for energy meter " + energyMeterId);
+                    "No bridge initialized for energy meter " + energyMeterId);
             return null;
         }
         NikoHomeControlBridgeHandler nhcBridgeHandler = (NikoHomeControlBridgeHandler) nhcBridge.getHandler();
index d6cf3a453b92fc58a3808715f79091d954f294a4..725a8e0ed91366d7a5ac9db45f5527ae576335bd 100644 (file)
  */
 package org.openhab.binding.nikohomecontrol.internal.handler;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * {@link NikoHomeControlThermostatConfig} is the config class for Niko Home Control Thermostats.
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 public class NikoHomeControlThermostatConfig {
-    public String thermostatId;
-    public int overruleTime;
+    public String thermostatId = "";
+    public int overruleTime = 60;
 }
index 12da67d0e763be529d0a65d3fed09c1a23f2d666..d852f07ade143e8ae54fef9f15b6265c8697851e 100644 (file)
@@ -52,7 +52,7 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
 
     private final Logger logger = LoggerFactory.getLogger(NikoHomeControlThermostatHandler.class);
 
-    private volatile @NonNullByDefault({}) NhcThermostat nhcThermostat;
+    private volatile @Nullable NhcThermostat nhcThermostat;
 
     private String thermostatId = "";
     private int overruleTime;
@@ -69,7 +69,7 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
         NikoHomeControlCommunication nhcComm = getCommunication();
         if (nhcComm == null) {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                    "Niko Home Control: bridge communication not initialized when trying to execute thermostat command "
+                    "Bridge communication not initialized when trying to execute thermostat command on "
                             + thermostatId);
             return;
         }
@@ -87,7 +87,13 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
     }
 
     private void handleCommandSelection(ChannelUID channelUID, Command command) {
-        logger.debug("Niko Home Control: handle command {} for {}", command, channelUID);
+        NhcThermostat nhcThermostat = this.nhcThermostat;
+        if (nhcThermostat == null) {
+            logger.debug("thermostat with ID {} not initialized", thermostatId);
+            return;
+        }
+
+        logger.debug("handle command {} for {}", command, channelUID);
 
         if (REFRESH.equals(command)) {
             thermostatEvent(nhcThermostat.getMeasured(), nhcThermostat.getSetpoint(), nhcThermostat.getMode(),
@@ -140,7 +146,7 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
 
             default:
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                        "Niko Home Control: channel unknown " + channelUID.getId());
+                        "Channel unknown " + channelUID.getId());
         }
     }
 
@@ -153,6 +159,8 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
 
         NikoHomeControlCommunication nhcComm = getCommunication();
         if (nhcComm == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+                    "Connection with controller not started yet, could not initialize thermostat " + thermostatId);
             return;
         }
 
@@ -161,16 +169,14 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
         scheduler.submit(() -> {
             if (!nhcComm.communicationActive()) {
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                        "Niko Home Control: no connection with Niko Home Control, could not initialize thermostat "
-                                + thermostatId);
+                        "No connection with controller, could not initialize thermostat " + thermostatId);
                 return;
             }
 
-            nhcThermostat = nhcComm.getThermostats().get(thermostatId);
+            NhcThermostat nhcThermostat = nhcComm.getThermostats().get(thermostatId);
             if (nhcThermostat == null) {
                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                        "Niko Home Control: thermostatId does not match a thermostat in the controller "
-                                + thermostatId);
+                        "Thermostat " + thermostatId + " does not match a thermostat in the controller");
                 return;
             }
 
@@ -186,7 +192,9 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
             thermostatEvent(nhcThermostat.getMeasured(), nhcThermostat.getSetpoint(), nhcThermostat.getMode(),
                     nhcThermostat.getOverrule(), nhcThermostat.getDemand());
 
-            logger.debug("Niko Home Control: thermostat intialized {}", thermostatId);
+            this.nhcThermostat = nhcThermostat;
+
+            logger.debug("thermostat intialized {}", thermostatId);
 
             Bridge bridge = getBridge();
             if ((bridge != null) && (bridge.getStatus() == ThingStatus.ONLINE)) {
@@ -211,6 +219,12 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
 
     @Override
     public void thermostatEvent(int measured, int setpoint, int mode, int overrule, int demand) {
+        NhcThermostat nhcThermostat = this.nhcThermostat;
+        if (nhcThermostat == null) {
+            logger.debug("thermostat with ID {} not initialized", thermostatId);
+            return;
+        }
+
         updateState(CHANNEL_MEASURED, new QuantityType<>(nhcThermostat.getMeasured() / 10.0, CELSIUS));
 
         int overruletime = nhcThermostat.getRemainingOverruletime();
@@ -263,10 +277,18 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
         refreshTimer = null;
     }
 
+    @Override
+    public void thermostatInitialized() {
+        Bridge bridge = getBridge();
+        if ((bridge != null) && (bridge.getStatus() == ThingStatus.ONLINE)) {
+            updateStatus(ThingStatus.ONLINE);
+        }
+    }
+
     @Override
     public void thermostatRemoved() {
         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                "Niko Home Control: thermostat has been removed from the controller " + thermostatId);
+                "Thermostat " + thermostatId + " has been removed from the controller");
     }
 
     private void restartCommunication(NikoHomeControlCommunication nhcComm) {
@@ -275,8 +297,7 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
         nhcComm.restartCommunication();
         // If still not active, take thing offline and return.
         if (!nhcComm.communicationActive()) {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                    "Niko Home Control: communication socket error");
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Communication error");
             return;
         }
         // Also put the bridge back online
@@ -290,7 +311,7 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
         NikoHomeControlBridgeHandler nhcBridgeHandler = getBridgeHandler();
         if (nhcBridgeHandler == null) {
             updateStatus(ThingStatus.UNINITIALIZED, ThingStatusDetail.BRIDGE_UNINITIALIZED,
-                    "Niko Home Control: no bridge initialized for thermostat " + thermostatId);
+                    "No bridge initialized for thermostat " + thermostatId);
             return null;
         }
         NikoHomeControlCommunication nhcComm = nhcBridgeHandler.getCommunication();
@@ -301,7 +322,7 @@ public class NikoHomeControlThermostatHandler extends BaseThingHandler implement
         Bridge nhcBridge = getBridge();
         if (nhcBridge == null) {
             updateStatus(ThingStatus.UNINITIALIZED, ThingStatusDetail.BRIDGE_UNINITIALIZED,
-                    "Niko Home Control: no bridge initialized for thermostat " + thermostatId);
+                    "No bridge initialized for thermostat " + thermostatId);
             return null;
         }
         NikoHomeControlBridgeHandler nhcBridgeHandler = (NikoHomeControlBridgeHandler) nhcBridge.getHandler();
index 8425d7588fe49a501e6857ed1988376d2617203f..dbe5d5a3471f8a2e84750453c632826055880b99 100644 (file)
@@ -158,7 +158,7 @@ public abstract class NhcAction {
     protected void updateState(int state) {
         NhcActionEvent eventHandler = this.eventHandler;
         if (eventHandler != null) {
-            logger.debug("Niko Home Control: update channel state for {} with {}", id, state);
+            logger.debug("update channel state for {} with {}", id, state);
             eventHandler.actionEvent(state);
         }
     }
@@ -167,7 +167,7 @@ public abstract class NhcAction {
      * Method called when action is removed from the Niko Home Control Controller.
      */
     public void actionRemoved() {
-        logger.warn("Niko Home Control: action removed {}, {}", id, name);
+        logger.debug("action removed {}, {}", id, name);
         NhcActionEvent eventHandler = this.eventHandler;
         if (eventHandler != null) {
             eventHandler.actionRemoved();
index 4f8495c8e3234bab6cc5dfb12999748070522fe2..a58b1f422e16a55dd4afe5d9e5550951e2a622cd 100644 (file)
@@ -32,6 +32,12 @@ public interface NhcActionEvent {
      */
     public void actionEvent(int state);
 
+    /**
+     * Called to indicate the action has been initialized.
+     *
+     */
+    public void actionInitialized();
+
     /**
      * Called to indicate the action has been removed from the Niko Home Control controller.
      *
index a3eea885a1c0d460d4389c2ea51405464210244f..ead01aeddaf45acd32645b2542cf3c68cdf5f674 100644 (file)
@@ -67,8 +67,9 @@ public interface NhcControllerEvent {
     /**
      * Called to indicate the connection with the Niko Home Control Controller is offline.
      *
+     * @param message
      */
-    public void controllerOffline();
+    public void controllerOffline(String message);
 
     /**
      * Called to indicate the connection with the Niko Home Control Controller is online.
index c37daa87416361335fb24f64f3fd140d35936198..c6dad086b0896149c4c1eb7282b5303582ab56d1 100644 (file)
@@ -56,7 +56,7 @@ public abstract class NhcEnergyMeter {
     public void updateState(int power) {
         NhcEnergyMeterEvent handler = eventHandler;
         if (handler != null) {
-            logger.debug("Niko Home Control: update channel for {}", id);
+            logger.debug("update channel for {}", id);
             handler.energyMeterEvent(power);
         }
     }
@@ -65,7 +65,7 @@ public abstract class NhcEnergyMeter {
      * Method called when energyMeters meter is removed from the Niko Home Control Controller.
      */
     public void energyMeterRemoved() {
-        logger.warn("Niko Home Control: action removed {}, {}", id, name);
+        logger.debug("action removed {}, {}", id, name);
         NhcEnergyMeterEvent eventHandler = this.eventHandler;
         if (eventHandler != null) {
             eventHandler.energyMeterRemoved();
@@ -117,7 +117,7 @@ public abstract class NhcEnergyMeter {
         this.power = power;
         NhcEnergyMeterEvent handler = eventHandler;
         if (handler != null) {
-            logger.debug("Niko Home Control: update power channel for {} with {}", id, power);
+            logger.debug("update power channel for {} with {}", id, power);
             handler.energyMeterEvent(power);
         }
     }
index 8beae434f1a9c82a847e9a83e128dc7dd969a027..f7dee8b8072735ab9de8b07b6ccf56966b3d741f 100644 (file)
@@ -28,14 +28,20 @@ import org.eclipse.jdt.annotation.Nullable;
 public interface NhcEnergyMeterEvent {
 
     /**
-     * This method is called when an energyMeters meter event is received from the Niko Home Control controller.
+     * This method is called when an energyMeter event is received from the Niko Home Control controller.
      *
      * @param power current power consumption/production in W (positive for consumption), null for an empty reading
      */
     public void energyMeterEvent(@Nullable Integer power);
 
     /**
-     * Called to indicate the energyMeters meter has been removed from the Niko Home Control controller.
+     * Called to indicate the energyMeter has been initialized.
+     *
+     */
+    public void energyMeterInitialized();
+
+    /**
+     * Called to indicate the energyMeter has been removed from the Niko Home Control controller.
      *
      */
     public void energyMeterRemoved();
index c25124f8895ea93f47af87dd5d2db856bf4f94ef..0d4d5a866f6ac6d5c88ec27a95ea71e2f1f766c9 100644 (file)
@@ -115,7 +115,7 @@ public abstract class NhcThermostat {
      * Method called when thermostat is removed from the Niko Home Control Controller.
      */
     public void thermostatRemoved() {
-        logger.warn("Niko Home Control: action removed {}, {}", id, name);
+        logger.debug("action removed {}, {}", id, name);
         NhcThermostatEvent eventHandler = this.eventHandler;
         if (eventHandler != null) {
             eventHandler.thermostatRemoved();
@@ -125,7 +125,7 @@ public abstract class NhcThermostat {
     private void updateChannels() {
         NhcThermostatEvent handler = eventHandler;
         if (handler != null) {
-            logger.debug("Niko Home Control: update channels for {}", id);
+            logger.debug("update channels for {}", id);
             handler.thermostatEvent(measured, setpoint, mode, overrule, demand);
         }
     }
index 6eb1fa5e69460fa0b540093c413233d25aa40c2a..7bdf1c803d1cc0b6308ca0f3679dc904da9e2c6d 100644 (file)
@@ -37,6 +37,12 @@ public interface NhcThermostatEvent {
      */
     public void thermostatEvent(int measured, int setpoint, int mode, int overrule, int demand);
 
+    /**
+     * Called to indicate the thermostat has been initialized.
+     *
+     */
+    public void thermostatInitialized();
+
     /**
      * Called to indicate the thermostat has been removed from the Niko Home Control controller.
      *
index e2a4f5a221f351597a0afb5d613c4593424bc837..853e9c9cb4f17c3adc9b149b64a34a86da17533c 100644 (file)
@@ -65,7 +65,7 @@ public abstract class NikoHomeControlCommunication {
     public synchronized void restartCommunication() {
         stopCommunication();
 
-        logger.debug("Niko Home Control: restart communication from thread {}", Thread.currentThread().getId());
+        logger.debug("restart communication from thread {}", Thread.currentThread().getId());
 
         startCommunication();
     }
index 29de7bae862a4314da070a3009fedd739ec6c0e3..708e399929f5495af8289c0ab0270a7a326b7622 100644 (file)
@@ -70,7 +70,7 @@ public final class NikoHomeControlDiscover {
             datagramSocket.send(discoveryPacket);
             while (true) {
                 datagramSocket.receive(packet);
-                logger.trace("Niko Home Control: bridge discovery response {}",
+                logger.trace("bridge discovery response {}",
                         HexUtils.bytesToHex(Arrays.copyOf(packet.getData(), packet.getLength())));
                 if (isNhc(packet)) {
                     break;
@@ -79,7 +79,7 @@ public final class NikoHomeControlDiscover {
             addr = packet.getAddress();
             setNhcBridgeId(packet);
             setIsNhcII(packet);
-            logger.debug("Niko Home Control: IP address is {}, unique ID is {}", addr, nhcBridgeId);
+            logger.debug("IP address is {}, unique ID is {}", addr, nhcBridgeId);
         }
     }
 
index a88c23c47f1b82c84261b7c91b4ffe20225a2789..784f5d79fc654fdf01e9b07fce2cb48910a2db74 100644 (file)
@@ -74,7 +74,7 @@ public class NhcAction1 extends NhcAction {
         if (getType() == ActionType.ROLLERSHUTTER) {
             if (filterEvent) {
                 filterEvent = false;
-                logger.debug("Niko Home Control: filtered event {} for {}", newState, id);
+                logger.debug("filtered event {} for {}", newState, id);
                 return;
             }
 
@@ -88,7 +88,7 @@ public class NhcAction1 extends NhcAction {
             }
         }
         if (waitForEvent) {
-            logger.debug("Niko Home Control: received requested rollershutter {} position event {}", id, newState);
+            logger.debug("received requested rollershutter {} position event {}", id, newState);
             executeRollershutterTask();
         } else {
             state = newState;
@@ -103,7 +103,7 @@ public class NhcAction1 extends NhcAction {
      */
     @Override
     public void execute(String command) {
-        logger.debug("Niko Home Control: execute action {} of type {} for {}", command, type, id);
+        logger.debug("execute action {} of type {} for {}", command, type, id);
 
         String value = "";
         switch (getType()) {
@@ -162,7 +162,7 @@ public class NhcAction1 extends NhcAction {
             } else if (command.equals(NHCSTOP)) {
                 executeRollershutterStop();
             } else {
-                int newValue = 100 - Integer.parseInt(command);
+                int newValue = Integer.parseInt(command);
                 if (logger.isTraceEnabled()) {
                     logger.trace("handleRollerShutterCommand: rollershutter {} percent command, current {}, new {}", id,
                             currentValue, newValue);
@@ -174,9 +174,9 @@ public class NhcAction1 extends NhcAction {
                     scheduleRollershutterStop(currentValue, newValue);
                 }
                 if (newValue < currentValue) {
-                    executeRollershutterDown();
-                } else if (newValue > currentValue) {
                     executeRollershutterUp();
+                } else if (newValue > currentValue) {
+                    executeRollershutterDown();
                 }
             }
         };
index a80ae058a060ac17b468cd6cb86c27101bc0238c..8ae35740f30e7b5e7c5c1def16f662065a46220e 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.nikohomecontrol.internal.protocol.nhc1;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Class {@link NhcMessageBase1} used as base class for output from gson for cmd or event feedback from Niko Home
  * Control. This class only contains the common base fields required for the deserializer
@@ -21,10 +23,11 @@ package org.openhab.binding.nikohomecontrol.internal.protocol.nhc1;
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 abstract class NhcMessageBase1 {
 
-    private String cmd;
-    private String event;
+    private String cmd = "";
+    private String event = "";
 
     String getCmd() {
         return cmd;
index d9700913bd9c44f949f51c83efb6140787bd2059..c0bac1dff6d7f952a864026a565b2efbbf7182ae 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.nikohomecontrol.internal.protocol.nhc1;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Class {@link NhcMessageCmd1} used as input to gson to send commands to Niko Home Control. Extends
  * {@link NhcMessageBase1}.
@@ -21,6 +23,7 @@ package org.openhab.binding.nikohomecontrol.internal.protocol.nhc1;
  * @author Mark Herwege - Initial Contribution
  */
 @SuppressWarnings("unused")
+@NonNullByDefault
 class NhcMessageCmd1 extends NhcMessageBase1 {
 
     private int id;
@@ -29,7 +32,7 @@ class NhcMessageCmd1 extends NhcMessageBase1 {
     private int value3;
     private int mode;
     private int overrule;
-    private String overruletime;
+    private String overruletime = "";
 
     NhcMessageCmd1(String cmd) {
         super.setCmd(cmd);
index 016405dcc314243d0e1738491addb1d998daa9d6..a8f9418c15472ad158f20e89aae7084225a1ccb4 100644 (file)
@@ -16,6 +16,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Class {@link NhcMessageListMap1} used as output from gson for cmd or event feedback from Niko Home Control where the
  * data part is enclosed by [] and contains a list of json strings. Extends {@link NhcMessageBase1}.
@@ -25,6 +27,7 @@ import java.util.Map;
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 class NhcMessageListMap1 extends NhcMessageBase1 {
 
     private List<Map<String, String>> data = new ArrayList<>();
index 12cfb12d5f4c91a9a03a1aaa7af082b846d2ef62..a2ed5497f5ff46f9b792c3d4345753292eb7c454 100644 (file)
@@ -15,6 +15,8 @@ package org.openhab.binding.nikohomecontrol.internal.protocol.nhc1;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Class {@link NhcMessageMap1} used as output from gson for cmd or event feedback from Niko Home Control where the
  * data part is a simple json string. Extends {@link NhcMessageBase1}.
@@ -23,6 +25,7 @@ import java.util.Map;
  *
  * @author Mark Herwege - Initial Contribution
  */
+@NonNullByDefault
 class NhcMessageMap1 extends NhcMessageBase1 {
 
     private Map<String, String> data = new HashMap<>();
index c9c85339a5f234dba27c06a49239d76bcff582ff..697ad9c34b79ba5bf11ebffa915d21c59af4b6eb 100644 (file)
@@ -42,7 +42,7 @@ public class NhcThermostat1 extends NhcThermostat {
      */
     @Override
     public void executeMode(int mode) {
-        logger.debug("Niko Home Control: execute thermostat mode {} for {}", mode, id);
+        logger.debug("execute thermostat mode {} for {}", mode, id);
 
         nhcComm.executeThermostat(id, Integer.toString(mode));
     }
@@ -55,8 +55,7 @@ public class NhcThermostat1 extends NhcThermostat {
      */
     @Override
     public void executeOverrule(int overrule, int overruletime) {
-        logger.debug("Niko Home Control: execute thermostat overrule {} during {} min for {}", overrule, overruletime,
-                id);
+        logger.debug("execute thermostat overrule {} during {} min for {}", overrule, overruletime, id);
 
         nhcComm.executeThermostat(id, overrule, overruletime);
     }
index 0eb1adb653aa071eb81d06116ecb0ef44883a30e..a2c8b7bd409083da1575556b0b8b7d565040cf20 100644 (file)
@@ -20,6 +20,7 @@ import java.net.InetAddress;
 import java.net.Socket;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.function.Consumer;
@@ -94,7 +95,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
                 Thread.sleep(1000);
             }
             if (nhcEventsRunning) {
-                logger.debug("Niko Home Control: starting but previous connection still active after 5000ms");
+                logger.debug("starting but previous connection still active after 5000ms");
                 throw new IOException();
             }
 
@@ -105,7 +106,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
             nhcSocket = socket;
             nhcOut = new PrintWriter(socket.getOutputStream(), true);
             nhcIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-            logger.debug("Niko Home Control: connected via local port {}", socket.getLocalPort());
+            logger.debug("connected via local port {}", socket.getLocalPort());
 
             // initialize all info in local fields
             initialize();
@@ -115,9 +116,8 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
             (new Thread(this::runNhcEvents)).start();
 
         } catch (IOException | InterruptedException e) {
-            logger.warn("Niko Home Control: error initializing communication");
             stopCommunication();
-            handler.controllerOffline();
+            handler.controllerOffline("Error initializing communication");
         }
     }
 
@@ -139,7 +139,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
         }
         nhcSocket = null;
 
-        logger.debug("Niko Home Control: communication stopped");
+        logger.debug("communication stopped");
     }
 
     @Override
@@ -158,7 +158,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
     private void runNhcEvents() {
         String nhcMessage;
 
-        logger.debug("Niko Home Control: listening for events");
+        logger.debug("listening for events");
         listenerStopped = false;
         nhcEventsRunning = true;
 
@@ -170,7 +170,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
             if (!listenerStopped) {
                 nhcEventsRunning = false;
                 // this is a socket error, not a communication stop triggered from outside this runnable
-                logger.warn("Niko Home Control: IO error in listener");
+                logger.debug("IO error in listener");
                 // the IO has stopped working, so we need to close cleanly and try to restart
                 restartCommunication();
                 return;
@@ -181,7 +181,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
 
         nhcEventsRunning = false;
         // this is a stop from outside the runnable, so just log it and stop
-        logger.debug("Niko Home Control: event listener thread stopped");
+        logger.debug("event listener thread stopped");
     }
 
     /**
@@ -218,17 +218,16 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
     @SuppressWarnings("null")
     private synchronized void sendMessage(Object nhcMessage) {
         String json = gsonOut.toJson(nhcMessage);
-        logger.debug("Niko Home Control: send json {}", json);
+        logger.debug("send json {}", json);
         nhcOut.println(json);
         if (nhcOut.checkError()) {
-            logger.warn("Niko Home Control: error sending message, trying to restart communication");
+            logger.debug("error sending message, trying to restart communication");
             restartCommunication();
             // retry sending after restart
-            logger.debug("Niko Home Control: resend json {}", json);
+            logger.debug("resend json {}", json);
             nhcOut.println(json);
             if (nhcOut.checkError()) {
-                logger.warn("Niko Home Control: error resending message");
-                handler.controllerOffline();
+                handler.controllerOffline("Error resending message");
             }
         }
     }
@@ -239,11 +238,14 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
      * @param nhcMessage message read from Niko Home Control.
      */
     private void readMessage(@Nullable String nhcMessage) {
-        logger.debug("Niko Home Control: received json {}", nhcMessage);
+        logger.debug("received json {}", nhcMessage);
 
         try {
             NhcMessageBase1 nhcMessageGson = gsonIn.fromJson(nhcMessage, NhcMessageBase1.class);
 
+            if (nhcMessageGson == null) {
+                return;
+            }
             String cmd = nhcMessageGson.getCmd();
             String event = nhcMessageGson.getEvent();
 
@@ -268,10 +270,10 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
             } else if ("getalarms".equals(event)) {
                 eventGetAlarms(((NhcMessageMap1) nhcMessageGson).getData());
             } else {
-                logger.debug("Niko Home Control: not acted on json {}", nhcMessage);
+                logger.debug("not acted on json {}", nhcMessage);
             }
         } catch (JsonParseException e) {
-            logger.debug("Niko Home Control: not acted on unsupported json {}", nhcMessage);
+            logger.debug("not acted on unsupported json {}", nhcMessage);
         }
     }
 
@@ -283,7 +285,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
     }
 
     private synchronized void cmdSystemInfo(Map<String, String> data) {
-        logger.debug("Niko Home Control: systeminfo");
+        logger.debug("systeminfo");
 
         setIfPresent(data, "swversion", systemInfo::setSwVersion);
         setIfPresent(data, "api", systemInfo::setApi);
@@ -311,17 +313,17 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
         if (errorCodeString != null) {
             int errorCode = Integer.parseInt(errorCodeString);
             if (errorCode == 0) {
-                logger.debug("Niko Home Control: start events success");
+                logger.debug("start events success");
             } else {
-                logger.warn("Niko Home Control: error code {} returned on start events", errorCode);
+                logger.debug("error code {} returned on start events", errorCode);
             }
         } else {
-            logger.warn("Niko Home Control: could not determine error code returned on start events");
+            logger.debug("could not determine error code returned on start events");
         }
     }
 
     private void cmdListLocations(List<Map<String, String>> data) {
-        logger.debug("Niko Home Control: list locations");
+        logger.debug("list locations");
 
         locations.clear();
 
@@ -338,7 +340,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
     }
 
     private void cmdListActions(List<Map<String, String>> data) {
-        logger.debug("Niko Home Control: list actions");
+        logger.debug("list actions");
 
         for (Map<String, String> action : data) {
             String id = action.get("id");
@@ -360,7 +362,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
                     logger.debug("name not found in action {}", action);
                     continue;
                 }
-                String type = action.get("type");
+                String type = Optional.ofNullable(action.get("type")).orElse("");
                 ActionType actionType = ActionType.GENERIC;
                 switch (type) {
                     case "0":
@@ -377,7 +379,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
                         actionType = ActionType.ROLLERSHUTTER;
                         break;
                     default:
-                        logger.debug("Niko Home Control: unknown action type {} for action {}", type, id);
+                        logger.debug("unknown action type {} for action {}", type, id);
                         continue;
                 }
                 String locationId = action.get("location");
@@ -395,14 +397,18 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
                 // Action object already exists, so only update state.
                 // If we would re-instantiate action, we would lose pointer back from action to thing handler that was
                 // set in thing handler initialize().
-                actions.get(id).setState(state);
+                NhcAction nhcAction = actions.get(id);
+                if (nhcAction != null) {
+                    nhcAction.setState(state);
+                }
             }
         }
     }
 
     private int parseIntOrThrow(@Nullable String str) throws IllegalArgumentException {
-        if (str == null)
+        if (str == null) {
             throw new IllegalArgumentException("String is null");
+        }
         try {
             return Integer.parseInt(str);
         } catch (NumberFormatException e) {
@@ -411,7 +417,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
     }
 
     private void cmdListThermostat(List<Map<String, String>> data) {
-        logger.debug("Niko Home Control: list thermostats");
+        logger.debug("list thermostats");
 
         for (Map<String, String> thermostat : data) {
             try {
@@ -442,8 +448,11 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
                     String name = thermostat.get("name");
                     String locationId = thermostat.get("location");
                     String location = "";
-                    if (!locationId.isEmpty()) {
-                        location = locations.get(locationId).getName();
+                    if (!((locationId == null) || locationId.isEmpty())) {
+                        NhcLocation1 nhcLocation = locations.get(locationId);
+                        if (nhcLocation != null) {
+                            location = nhcLocation.getName();
+                        }
                     }
                     if (name != null) {
                         return new NhcThermostat1(i, name, location, this);
@@ -463,12 +472,12 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
         try {
             int errorCode = parseIntOrThrow(data.get("error"));
             if (errorCode == 0) {
-                logger.debug("Niko Home Control: execute action success");
+                logger.debug("execute action success");
             } else {
-                logger.warn("Niko Home Control: error code {} returned on command execution", errorCode);
+                logger.debug("error code {} returned on command execution", errorCode);
             }
         } catch (IllegalArgumentException e) {
-            logger.warn("Niko Home Control: no error code returned on command execution");
+            logger.debug("no error code returned on command execution");
         }
     }
 
@@ -476,12 +485,12 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
         try {
             int errorCode = parseIntOrThrow(data.get("error"));
             if (errorCode == 0) {
-                logger.debug("Niko Home Control: execute thermostats success");
+                logger.debug("execute thermostats success");
             } else {
-                logger.warn("Niko Home Control: error code {} returned on command execution", errorCode);
+                logger.debug("error code {} returned on command execution", errorCode);
             }
         } catch (IllegalArgumentException e) {
-            logger.warn("Niko Home Control: no error code returned on command execution");
+            logger.debug("no error code returned on command execution");
         }
     }
 
@@ -489,13 +498,13 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
         for (Map<String, String> action : data) {
             String id = action.get("id");
             if (id == null || !actions.containsKey(id)) {
-                logger.warn("Niko Home Control: action in controller not known {}", id);
+                logger.warn("action in controller not known {}", id);
                 return;
             }
             String stateString = action.get("value1");
             if (stateString != null) {
                 int state = Integer.parseInt(stateString);
-                logger.debug("Niko Home Control: event execute action {} with state {}", id, state);
+                logger.debug("event execute action {} with state {}", id, state);
                 NhcAction action1 = actions.get(id);
                 if (action1 != null) {
                     action1.setState(state);
@@ -509,7 +518,7 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
             try {
                 String id = thermostat.get("id");
                 if (!thermostats.containsKey(id)) {
-                    logger.warn("Niko Home Control: thermostat in controller not known {}", id);
+                    logger.warn("thermostat in controller not known {}", id);
                     return;
                 }
 
@@ -549,15 +558,15 @@ public class NikoHomeControlCommunication1 extends NikoHomeControlCommunication
         }
         switch (data.getOrDefault("type", "")) {
             case "0":
-                logger.debug("Niko Home Control: alarm - {}", alarmText);
+                logger.debug("alarm - {}", alarmText);
                 handler.alarmEvent(alarmText);
                 break;
             case "1":
-                logger.debug("Niko Home Control: notice - {}", alarmText);
+                logger.debug("notice - {}", alarmText);
                 handler.noticeEvent(alarmText);
                 break;
             default:
-                logger.debug("Niko Home Control: unexpected message type {}", data.get("type"));
+                logger.debug("unexpected message type {}", data.get("type"));
         }
     }
 
index 3429512631bc06ef454ab2d320aede85b13b982a..df5b4fd9816b26e1e7a8689cd9c7b380d0c9d1b3 100644 (file)
@@ -19,6 +19,9 @@ 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;
+
 import com.google.gson.JsonArray;
 import com.google.gson.JsonDeserializationContext;
 import com.google.gson.JsonDeserializer;
@@ -33,16 +36,17 @@ import com.google.gson.JsonParseException;
  * @author Mark Herwege - Initial Contribution
  *
  */
+@NonNullByDefault
 class NikoHomeControlMessageDeserializer1 implements JsonDeserializer<NhcMessageBase1> {
 
     @Override
-    public NhcMessageBase1 deserialize(final JsonElement json, final Type typeOfT,
+    public @Nullable NhcMessageBase1 deserialize(final JsonElement json, final Type typeOfT,
             final JsonDeserializationContext context) throws JsonParseException {
         final JsonObject jsonObject = json.getAsJsonObject();
 
         try {
-            String cmd = null;
-            String event = null;
+            String cmd = "";
+            String event = "";
             if (jsonObject.has("cmd")) {
                 cmd = jsonObject.get("cmd").getAsString();
             }
index 3b66d90f45b2792cd3ef82343d6ee05bff6de572..1155ac5b6f843253a6af44526c49f9f3acef55f6 100644 (file)
@@ -115,7 +115,7 @@ public class NhcAction2 extends NhcAction {
      */
     @Override
     public void execute(String command) {
-        logger.debug("Niko Home Control: execute action {} of type {} for {}", command, type, id);
+        logger.debug("execute action {} of type {} for {}", command, type, id);
 
         nhcComm.executeAction(id, command);
     }
index 86ff112c0adf7901d214942d377dd7c230d5b93f..6ad1a686db3c133f2eb2b867a4b3115762db6d8e 100644 (file)
@@ -100,7 +100,7 @@ public class NhcMqttConnection2 implements MqttActionCallback {
             tmFactory.init(keyStore);
             return tmFactory.getTrustManagers();
         } catch (CertificateException | KeyStoreException | NoSuchAlgorithmException | IOException e) {
-            logger.warn("Niko Home Control: error with SSL context creation: {} ", e.getMessage());
+            logger.debug("error with SSL context creation: {} ", e.getMessage());
             throw new CertificateException("SSL context creation exception", e);
         } finally {
             ResourceBundle.clearCache();
@@ -121,14 +121,14 @@ public class NhcMqttConnection2 implements MqttActionCallback {
         if (future != null) {
             try {
                 future.get(5000, TimeUnit.MILLISECONDS);
-                logger.debug("Niko Home Control: finished stopping connection");
+                logger.debug("finished stopping connection");
             } catch (InterruptedException | ExecutionException | TimeoutException ignore) {
-                logger.debug("Niko Home Control: error stopping connection");
+                logger.debug("error stopping connection");
             }
             stoppedFuture = null;
         }
 
-        logger.debug("Niko Home Control: starting connection...");
+        logger.debug("starting connection...");
         this.cocoAddress = cocoAddress;
         this.port = port;
         this.profile = profile;
@@ -142,17 +142,17 @@ public class NhcMqttConnection2 implements MqttActionCallback {
                     subscribedFuture = connection.subscribe("#", messageSubscriber);
                 }
             } else {
-                logger.debug("Niko Home Control: error connecting");
+                logger.debug("error connecting");
                 throw new MqttException("Connection execution exception");
             }
         } catch (InterruptedException e) {
-            logger.debug("Niko Home Control: connection interrupted exception");
+            logger.debug("connection interrupted exception");
             throw new MqttException("Connection interrupted exception");
         } catch (ExecutionException e) {
-            logger.debug("Niko Home Control: connection execution exception", e.getCause());
+            logger.debug("connection execution exception", e.getCause());
             throw new MqttException("Connection execution exception");
         } catch (TimeoutException e) {
-            logger.debug("Niko Home Control: connection timeout exception");
+            logger.debug("connection timeout exception");
             throw new MqttException("Connection timeout exception");
         }
     }
@@ -169,7 +169,7 @@ public class NhcMqttConnection2 implements MqttActionCallback {
      * Stop the MQTT connection.
      */
     void stopConnection() {
-        logger.debug("Niko Home Control: stopping connection...");
+        logger.debug("stopping connection...");
         MqttBrokerConnection connection = mqttConnection;
         if (connection != null) {
             connection.removeConnectionObserver(connectionObserver);
@@ -203,7 +203,7 @@ public class NhcMqttConnection2 implements MqttActionCallback {
             try {
                 if ((future != null) && future.get(5000, TimeUnit.MILLISECONDS)) {
                     MqttConnectionState state = connection.connectionState();
-                    logger.debug("Niko Home Control: connection state {} for {}", state, connection.getClientId());
+                    logger.debug("connection state {} for {}", state, connection.getClientId());
                     return state == MqttConnectionState.CONNECTED;
                 }
             } catch (InterruptedException | ExecutionException | TimeoutException e) {
@@ -223,25 +223,25 @@ public class NhcMqttConnection2 implements MqttActionCallback {
     void connectionPublish(String topic, String payload) throws MqttException {
         MqttBrokerConnection connection = mqttConnection;
         if (connection == null) {
-            logger.debug("Niko Home Control: cannot publish, no connection");
+            logger.debug("cannot publish, no connection");
             throw new MqttException("No connection exception");
         }
 
         if (isConnected()) {
-            logger.debug("Niko Home Control: publish {}, {}", topic, payload);
+            logger.debug("publish {}, {}", topic, payload);
             connection.publish(topic, payload.getBytes(), connection.getQos(), false);
         } else {
-            logger.debug("Niko Home Control: cannot publish, not subscribed to connection messages");
+            logger.debug("cannot publish, not subscribed to connection messages");
         }
     }
 
     @Override
     public void onSuccess(String topic) {
-        logger.debug("Niko Home Control: publish succeeded {}", topic);
+        logger.debug("publish succeeded {}", topic);
     }
 
     @Override
     public void onFailure(String topic, Throwable error) {
-        logger.debug("Niko Home Control: publish failed {}, {}", topic, error.getMessage(), error);
+        logger.debug("publish failed {}, {}", topic, error.getMessage(), error);
     }
 }
index 4f05e4421359dc9df1c6c12158a928fad4902bf2..06b0936727759431d3d8acd06812e275efdd3794 100644 (file)
@@ -45,7 +45,7 @@ public class NhcThermostat2 extends NhcThermostat {
 
     @Override
     public void executeMode(int mode) {
-        logger.debug("Niko Home Control: execute thermostat mode {} for {}", mode, id);
+        logger.debug("execute thermostat mode {} for {}", mode, id);
 
         String program = THERMOSTATMODES[mode];
         nhcComm.executeThermostat(id, program);
@@ -53,8 +53,7 @@ public class NhcThermostat2 extends NhcThermostat {
 
     @Override
     public void executeOverrule(int overrule, int overruletime) {
-        logger.debug("Niko Home Control: execute thermostat overrule {} during {} min for {}", overrule, overruletime,
-                id);
+        logger.debug("execute thermostat overrule {} during {} min for {}", overrule, overruletime, id);
 
         nhcComm.executeThermostat(id, overrule, overruletime);
     }
index 916ae9c20ecaa154e1528cf237e863a5e8d28d89..866e18283ddb2abf2589f2633d12811edbf0914c 100644 (file)
@@ -33,7 +33,11 @@ import java.util.stream.IntStream;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.nikohomecontrol.internal.protocol.*;
+import org.openhab.binding.nikohomecontrol.internal.protocol.NhcAction;
+import org.openhab.binding.nikohomecontrol.internal.protocol.NhcControllerEvent;
+import org.openhab.binding.nikohomecontrol.internal.protocol.NhcEnergyMeter;
+import org.openhab.binding.nikohomecontrol.internal.protocol.NhcThermostat;
+import org.openhab.binding.nikohomecontrol.internal.protocol.NikoHomeControlCommunication;
 import org.openhab.binding.nikohomecontrol.internal.protocol.NikoHomeControlConstants.ActionType;
 import org.openhab.binding.nikohomecontrol.internal.protocol.nhc2.NhcDevice2.NhcProperty;
 import org.openhab.binding.nikohomecontrol.internal.protocol.nhc2.NhcMessage2.NhcMessageParam;
@@ -104,19 +108,19 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
 
         InetAddress addr = handler.getAddr();
         if (addr == null) {
-            logger.warn("Niko Home Control: IP address cannot be empty");
+            logger.warn("IP address cannot be empty");
             stopCommunication();
             return;
         }
         String addrString = addr.getHostAddress();
         int port = handler.getPort();
-        logger.debug("Niko Home Control: initializing for mqtt connection to CoCo on {}:{}", addrString, port);
+        logger.debug("initializing for mqtt connection to CoCo on {}:{}", addrString, port);
 
         profile = handler.getProfile();
 
         String token = handler.getToken();
         if (token.isEmpty()) {
-            logger.warn("Niko Home Control: JWT token cannot be empty");
+            logger.warn("JWT token cannot be empty");
             stopCommunication();
             return;
         }
@@ -125,7 +129,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
             mqttConnection.startConnection(addrString, port, profile, token);
             initialize();
         } catch (MqttException e) {
-            logger.warn("Niko Home Control: error in mqtt communication");
+            logger.debug("error in mqtt communication");
             stopCommunication();
         }
     }
@@ -150,7 +154,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
             // Wait until we received all devices info to confirm we are active.
             return started.get(5000, TimeUnit.MILLISECONDS);
         } catch (InterruptedException | ExecutionException | TimeoutException e) {
-            logger.debug("Niko Home Control: exception waiting for connection start");
+            logger.debug("exception waiting for connection start");
             return false;
         }
     }
@@ -176,10 +180,10 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         mqttConnection.connectionPublish(profile + "/notification/cmd", gson.toJson(message));
     }
 
-    private void connectionLost() {
-        logger.debug("Niko Home Control: connection lost");
+    private void connectionLost(String message) {
+        logger.debug("connection lost");
         stopCommunication();
-        handler.controllerOffline();
+        handler.controllerOffline(message);
     }
 
     private void systemEvt(String response) {
@@ -189,13 +193,13 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         List<NhcSystemInfo2> systemInfo = null;
         try {
             NhcMessage2 message = gson.fromJson(response, messageType);
-            List<NhcMessageParam> messageParams = message.params;
+            List<NhcMessageParam> messageParams = (message != null) ? message.params : null;
             if (messageParams != null) {
                 timeInfo = messageParams.stream().filter(p -> (p.timeInfo != null)).findFirst().get().timeInfo;
                 systemInfo = messageParams.stream().filter(p -> (p.systemInfo != null)).findFirst().get().systemInfo;
             }
         } catch (JsonSyntaxException e) {
-            logger.debug("Niko Home Control: unexpected json {}", response);
+            logger.debug("unexpected json {}", response);
         } catch (NoSuchElementException ignore) {
             // Ignore if timeInfo not present in response, this should not happen in a timeInfo response
         }
@@ -214,12 +218,12 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         List<NhcSystemInfo2> systemInfo = null;
         try {
             NhcMessage2 message = gson.fromJson(response, messageType);
-            List<NhcMessageParam> messageParams = message.params;
+            List<NhcMessageParam> messageParams = (message != null) ? message.params : null;
             if (messageParams != null) {
                 systemInfo = messageParams.stream().filter(p -> (p.systemInfo != null)).findFirst().get().systemInfo;
             }
         } catch (JsonSyntaxException e) {
-            logger.debug("Niko Home Control: unexpected json {}", response);
+            logger.debug("unexpected json {}", response);
         } catch (NoSuchElementException ignore) {
             // Ignore if systemInfo not present in response, this should not happen in a systemInfo response
         }
@@ -234,12 +238,12 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         List<NhcService2> serviceList = null;
         try {
             NhcMessage2 message = gson.fromJson(response, messageType);
-            List<NhcMessageParam> messageParams = message.params;
+            List<NhcMessageParam> messageParams = (message != null) ? message.params : null;
             if (messageParams != null) {
                 serviceList = messageParams.stream().filter(p -> (p.services != null)).findFirst().get().services;
             }
         } catch (JsonSyntaxException e) {
-            logger.debug("Niko Home Control: unexpected json {}", response);
+            logger.debug("unexpected json {}", response);
         } catch (NoSuchElementException ignore) {
             // Ignore if services not present in response, this should not happen in a services response
         }
@@ -255,12 +259,12 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         List<NhcDevice2> deviceList = null;
         try {
             NhcMessage2 message = gson.fromJson(response, messageType);
-            List<NhcMessageParam> messageParams = message.params;
+            List<NhcMessageParam> messageParams = (message != null) ? message.params : null;
             if (messageParams != null) {
                 deviceList = messageParams.stream().filter(p -> (p.devices != null)).findFirst().get().devices;
             }
         } catch (JsonSyntaxException e) {
-            logger.debug("Niko Home Control: unexpected json {}", response);
+            logger.debug("unexpected json {}", response);
         } catch (NoSuchElementException ignore) {
             // Ignore if devices not present in response, this should not happen in a devices response
         }
@@ -274,7 +278,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         }
 
         // Once a devices list response is received, we know the communication is fully started.
-        logger.debug("Niko Home Control: Communication start complete.");
+        logger.debug("Communication start complete.");
         handler.controllerOnline();
         CompletableFuture<Boolean> future = communicationStarted;
         if (future != null) {
@@ -289,13 +293,13 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         String method = null;
         try {
             NhcMessage2 message = gson.fromJson(response, messageType);
-            method = message.method;
-            List<NhcMessageParam> messageParams = message.params;
+            method = (message != null) ? message.method : null;
+            List<NhcMessageParam> messageParams = (message != null) ? message.params : null;
             if (messageParams != null) {
                 deviceList = messageParams.stream().filter(p -> (p.devices != null)).findFirst().get().devices;
             }
         } catch (JsonSyntaxException e) {
-            logger.debug("Niko Home Control: unexpected json {}", response);
+            logger.debug("unexpected json {}", response);
         } catch (NoSuchElementException ignore) {
             // Ignore if devices not present in response, this should not happen in a devices event
         }
@@ -308,9 +312,6 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
             return;
         } else if ("devices.added".equals(method)) {
             deviceList.forEach(this::addDevice);
-        } else if ("devices.changed".equals(method)) {
-            deviceList.forEach(this::removeDevice);
-            deviceList.forEach(this::addDevice);
         }
 
         deviceList.forEach(this::updateState);
@@ -322,17 +323,17 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         List<NhcNotification2> notificationList = null;
         try {
             NhcMessage2 message = gson.fromJson(response, messageType);
-            List<NhcMessageParam> messageParams = message.params;
+            List<NhcMessageParam> messageParams = (message != null) ? message.params : null;
             if (messageParams != null) {
                 notificationList = messageParams.stream().filter(p -> (p.notifications != null)).findFirst()
                         .get().notifications;
             }
         } catch (JsonSyntaxException e) {
-            logger.debug("Niko Home Control: unexpected json {}", response);
+            logger.debug("unexpected json {}", response);
         } catch (NoSuchElementException ignore) {
             // Ignore if notifications not present in response, this should not happen in a notifications event
         }
-        logger.debug("Niko Home Control: notifications {}", notificationList);
+        logger.debug("notifications {}", notificationList);
         if (notificationList == null) {
             return;
         }
@@ -348,7 +349,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
                         handler.noticeEvent(alarmText);
                         break;
                     default:
-                        logger.debug("Niko Home Control: unexpected message type {}", notification.type);
+                        logger.debug("unexpected message type {}", notification.type);
                 }
             }
         }
@@ -363,7 +364,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
 
         if ("action".equals(device.type)) {
             if (!actions.containsKey(device.uuid)) {
-                logger.debug("Niko Home Control: adding action device {}, {}", device.uuid, device.name);
+                logger.debug("adding action device {}, {}", device.uuid, device.name);
 
                 ActionType actionType;
                 switch (device.model) {
@@ -394,8 +395,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
                         break;
                     default:
                         actionType = ActionType.GENERIC;
-                        logger.debug("Niko Home Control: device type {} not recognised, default to GENERIC action",
-                                device.type);
+                        logger.debug("device type {} not recognised, default to GENERIC action", device.type);
                 }
 
                 NhcAction2 nhcAction = new NhcAction2(device.uuid, device.name, device.model, device.technology,
@@ -404,7 +404,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
             }
         } else if ("thermostat".equals(device.type)) {
             if (!thermostats.containsKey(device.uuid)) {
-                logger.debug("Niko Home Control: adding thermostat device {}, {}", device.uuid, device.name);
+                logger.debug("adding thermostat device {}, {}", device.uuid, device.name);
 
                 NhcThermostat2 nhcThermostat = new NhcThermostat2(device.uuid, device.name, device.model,
                         device.technology, location, this);
@@ -412,26 +412,28 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
             }
         } else if ("centralmeter".equals(device.type)) {
             if (!energyMeters.containsKey(device.uuid)) {
-                logger.debug("Niko Home Control: adding centralmeter device {}, {}", device.uuid, device.name);
+                logger.debug("adding centralmeter device {}, {}", device.uuid, device.name);
                 NhcEnergyMeter2 nhcEnergyMeter = new NhcEnergyMeter2(device.uuid, device.name, device.model,
                         device.technology, this, scheduler);
                 energyMeters.put(device.uuid, nhcEnergyMeter);
             }
         } else {
-            logger.debug("Niko Home Control: device type {} not supported for {}, {}", device.type, device.uuid,
-                    device.name);
+            logger.debug("device type {} not supported for {}, {}", device.type, device.uuid, device.name);
         }
     }
 
     private void removeDevice(NhcDevice2 device) {
-        if (actions.containsKey(device.uuid)) {
-            actions.get(device.uuid).actionRemoved();
+        NhcAction action = actions.get(device.uuid);
+        NhcThermostat thermostat = thermostats.get(device.uuid);
+        NhcEnergyMeter energyMeter = energyMeters.get(device.uuid);
+        if (action != null) {
+            action.actionRemoved();
             actions.remove(device.uuid);
-        } else if (thermostats.containsKey(device.uuid)) {
-            thermostats.get(device.uuid).thermostatRemoved();
+        } else if (thermostat != null) {
+            thermostat.thermostatRemoved();
             thermostats.remove(device.uuid);
-        } else if (energyMeters.containsKey(device.uuid)) {
-            energyMeters.get(device.uuid).energyMeterRemoved();
+        } else if (energyMeter != null) {
+            energyMeter.energyMeterRemoved();
             energyMeters.remove(device.uuid);
         }
     }
@@ -481,10 +483,10 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         if (booleanState != null) {
             if (NHCON.equals(booleanState)) {
                 action.setBooleanState(true);
-                logger.debug("Niko Home Control: setting action {} internally to ON", action.getId());
+                logger.debug("setting action {} internally to ON", action.getId());
             } else if (NHCOFF.equals(booleanState)) {
                 action.setBooleanState(false);
-                logger.debug("Niko Home Control: setting action {} internally to OFF", action.getId());
+                logger.debug("setting action {} internally to OFF", action.getId());
             }
         }
 
@@ -492,8 +494,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
             String brightness = dimmerProperty.get().brightness;
             if (brightness != null) {
                 action.setState(Integer.parseInt(brightness));
-                logger.debug("Niko Home Control: setting action {} internally to {}", action.getId(),
-                        dimmerProperty.get().brightness);
+                logger.debug("setting action {} internally to {}", action.getId(), dimmerProperty.get().brightness);
             }
         }
     }
@@ -502,9 +503,9 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         deviceProperties.stream().map(p -> p.position).filter(Objects::nonNull).findFirst().ifPresent(position -> {
             try {
                 action.setState(Integer.parseInt(position));
-                logger.debug("Niko Home Control: setting action {} internally to {}", action.getId(), position);
+                logger.debug("setting action {} internally to {}", action.getId(), position);
             } catch (NumberFormatException e) {
-                logger.trace("Niko Home Control: received empty rollershutter {} position info", action.getId());
+                logger.trace("received empty rollershutter {} position info", action.getId());
             }
         });
     }
@@ -577,12 +578,10 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
                 .ifPresent(electricalPower -> {
                     try {
                         energyMeter.setPower(Integer.parseInt(electricalPower));
-                        logger.trace("Niko Home Control: setting energy meter {} power to {}", energyMeter.getId(),
-                                electricalPower);
+                        logger.trace("setting energy meter {} power to {}", energyMeter.getId(), electricalPower);
                     } catch (NumberFormatException e) {
                         energyMeter.setPower(null);
-                        logger.trace("Niko Home Control: received empty energy meter {} power reading",
-                                energyMeter.getId());
+                        logger.trace("received empty energy meter {} power reading", energyMeter.getId());
                     }
                 });
     }
@@ -607,6 +606,9 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         device.properties = deviceProperties;
 
         NhcAction2 action = (NhcAction2) actions.get(actionId);
+        if (action == null) {
+            return;
+        }
 
         switch (action.getType()) {
             case GENERIC:
@@ -639,7 +641,7 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
                 } else if (NHCDOWN.equals(value)) {
                     property.position = "0";
                 } else {
-                    int position = 100 - Integer.parseInt(value);
+                    int position = Integer.parseInt(value);
                     property.position = String.valueOf(position);
                 }
                 break;
@@ -745,12 +747,18 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         String topic = profile + "/control/devices/cmd";
         String gsonMessage = gson.toJson(message);
 
-        ((NhcEnergyMeter2) energyMeters.get(energyMeterId)).startEnergyMeter(topic, gsonMessage);
+        NhcEnergyMeter2 energyMeter = (NhcEnergyMeter2) energyMeters.get(energyMeterId);
+        if (energyMeter != null) {
+            energyMeter.startEnergyMeter(topic, gsonMessage);
+        }
     }
 
     @Override
     public void stopEnergyMeter(String energyMeterId) {
-        ((NhcEnergyMeter2) energyMeters.get(energyMeterId)).stopEnergyMeter();
+        NhcEnergyMeter2 energyMeter = (NhcEnergyMeter2) energyMeters.get(energyMeterId);
+        if (energyMeter != null) {
+            energyMeter.stopEnergyMeter();
+        }
     }
 
     /**
@@ -768,19 +776,26 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
             mqttConnection.connectionPublish(topic, gsonMessage);
 
         } catch (MqttException e) {
-            logger.warn("Niko Home Control: sending command failed, trying to restart communication");
+            String message = e.getMessage();
+            message = (message != null) ? message : "Communication error";
+
+            logger.debug("sending command failed, trying to restart communication");
             restartCommunication();
             // retry sending after restart
             try {
                 if (communicationActive()) {
                     mqttConnection.connectionPublish(topic, gsonMessage);
                 } else {
-                    logger.warn("Niko Home Control: failed to restart communication");
-                    connectionLost();
+                    logger.debug("failed to restart communication");
                 }
             } catch (MqttException e1) {
-                logger.warn("Niko Home Control: error resending device command");
-                connectionLost();
+                message = e1.getMessage();
+                message = (message != null) ? message : "Communication error";
+
+                logger.debug("error resending device command");
+            }
+            if (!communicationActive()) {
+                connectionLost(message);
             }
         }
     }
@@ -791,24 +806,24 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
         if ((profile + "/system/evt").equals(topic)) {
             systemEvt(message);
         } else if ((profile + "/system/rsp").equals(topic)) {
-            logger.debug("Niko Home Control: received topic {}, payload {}", topic, message);
+            logger.debug("received topic {}, payload {}", topic, message);
             systeminfoPublishRsp(message);
         } else if ((profile + "/notification/evt").equals(topic)) {
-            logger.debug("Niko Home Control: received topic {}, payload {}", topic, message);
+            logger.debug("received topic {}, payload {}", topic, message);
             notificationEvt(message);
         } else if ((profile + "/control/devices/evt").equals(topic)) {
-            logger.trace("Niko Home Control: received topic {}, payload {}", topic, message);
+            logger.trace("received topic {}, payload {}", topic, message);
             devicesEvt(message);
         } else if ((profile + "/control/devices/rsp").equals(topic)) {
-            logger.debug("Niko Home Control: received topic {}, payload {}", topic, message);
+            logger.debug("received topic {}, payload {}", topic, message);
             devicesListRsp(message);
         } else if ((profile + "/authentication/rsp").equals(topic)) {
-            logger.debug("Niko Home Control: received topic {}, payload {}", topic, message);
+            logger.debug("received topic {}, payload {}", topic, message);
             servicesListRsp(message);
         } else if ((profile + "/control/devices.error").equals(topic)) {
-            logger.warn("Niko Home Control: received error {}", message);
+            logger.warn("received error {}", message);
         } else {
-            logger.trace("Niko Home Control: not acted on received message topic {}, payload {}", topic, message);
+            logger.trace("not acted on received message topic {}, payload {}", topic, message);
         }
     }
 
@@ -845,10 +860,14 @@ public class NikoHomeControlCommunication2 extends NikoHomeControlCommunication
     public void connectionStateChanged(MqttConnectionState state, @Nullable Throwable error) {
         if (error != null) {
             logger.debug("Connection state: {}", state, error);
-            restartCommunication();
+            String message = error.getMessage();
+            message = (message != null) ? message : "Error communicating with the controller";
+            if (!MqttConnectionState.CONNECTING.equals(state)) {
+                // This is a connection loss, try to restart
+                restartCommunication();
+            }
             if (!communicationActive()) {
-                logger.warn("Niko Home Control: failed to restart communication");
-                connectionLost();
+                connectionLost(message);
             }
         } else {
             logger.trace("Connection state: {}", state);
index c2b637da355d98ddd48f09f109a0f22cdab99dfd..6382d8656b414b2015fe0bdf5bc8a10c27c28c46 100644 (file)
                                <description>Niko Home Control action ID</description>
                                <advanced>false</advanced>
                        </parameter>
-                       <parameter name="step" type="integer" required="true">
+                       <parameter name="step" type="integer">
                                <label>Step Value</label>
                                <description>Step value used for increase/decrease of dimmer brightness, default 10%</description>
                                <default>10</default>
                                <description>Niko Home Control action ID</description>
                                <advanced>false</advanced>
                        </parameter>
+                       <parameter name="invert" type="boolean">
+                               <label>Invert Direction</label>
+                               <description>Invert rollershutter direction</description>
+                               <default>false</default>
+                               <advanced>true</advanced>
+                       </parameter>
                </config-description>
        </thing-type>
        <thing-type id="thermostat">