]> git.basschouten.com Git - openhab-addons.git/commitdiff
[powermax] Add null annotations (#11275)
authorlolodomo <lg.hc@free.fr>
Sun, 10 Oct 2021 08:04:37 +0000 (10:04 +0200)
committerGitHub <noreply@github.com>
Sun, 10 Oct 2021 08:04:37 +0000 (10:04 +0200)
Signed-off-by: Laurent Garnier <lg.hc@free.fr>
46 files changed:
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/config/PowermaxIpConfiguration.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/config/PowermaxSerialConfiguration.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/config/PowermaxX10Configuration.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/config/PowermaxZoneConfiguration.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/connector/PowermaxConnector.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/connector/PowermaxConnectorInterface.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/connector/PowermaxReaderThread.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/connector/PowermaxSerialConnector.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/connector/PowermaxTcpConnector.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/console/PowermaxCommandExtension.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/discovery/PowermaxDiscoveryService.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/handler/PowermaxBridgeHandler.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/handler/PowermaxThingHandler.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxAckMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxBaseMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxCommManager.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxDeniedMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxDownloadRetryMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxEventLogMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxInfoMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxMessageConstants.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxMessageEvent.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxMessageEventListener.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxPanelMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxPowerMasterMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxPowerlinkMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxReceiveType.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxSendType.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxSettingsMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxStatusMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxTimeoutMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxZonesNameMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/message/PowermaxZonesTypeMessage.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermasterSensorType.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxArmMode.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxPanelSettings.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxPanelType.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxSensorType.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxState.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxStateContainer.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxStateEvent.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxStateEventListener.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxX10Settings.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxZoneName.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxZoneSettings.java
bundles/org.openhab.binding.powermax/src/main/java/org/openhab/binding/powermax/internal/state/PowermaxZoneState.java

index 0c8724e3bcc910c517a8359fce96eb5ee78062f5..f812759eff1e4ee7255d55e5d4dad82841ca081b 100644 (file)
  */
 package org.openhab.binding.powermax.internal.config;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * The {@link PowermaxIpConfiguration} is responsible for holding
  * configuration informations associated to a Powermax IP thing type
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxIpConfiguration {
 
-    public String ip;
-    public Integer tcpPort;
-    public Integer motionOffDelay;
-    public Boolean allowArming;
-    public Boolean allowDisarming;
-    public String pinCode;
-    public Boolean forceStandardMode;
-    public String panelType;
-    public Boolean autoSyncTime;
+    public String ip = "";
+    public int tcpPort = 0;
+    public int motionOffDelay = 3;
+    public boolean allowArming = false;
+    public boolean allowDisarming = false;
+    public String pinCode = "";
+    public boolean forceStandardMode = false;
+    public String panelType = "PowerMaxPro";
+    public boolean autoSyncTime = false;
 }
index 6e37f8526db9496e86cd21747c39c411a8abaefd..6975646a95b8d5e8171a46605779ad01e698ce47 100644 (file)
  */
 package org.openhab.binding.powermax.internal.config;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * The {@link PowermaxSerialConfiguration} is responsible for holding
  * configuration informations associated to a Powermax serial thing type
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxSerialConfiguration {
 
-    public String serialPort;
-    public Integer motionOffDelay;
-    public Boolean allowArming;
-    public Boolean allowDisarming;
-    public String pinCode;
-    public Boolean forceStandardMode;
-    public String panelType;
-    public Boolean autoSyncTime;
+    public String serialPort = "";
+    public int motionOffDelay = 3;
+    public boolean allowArming = false;
+    public boolean allowDisarming = false;
+    public String pinCode = "";
+    public boolean forceStandardMode = false;
+    public String panelType = "PowerMaxPro";
+    public boolean autoSyncTime = false;
 }
index 61b6fd1edb645a7a6b8655f04fa99a1ef951c38f..64f1d57893b20a87650b61eebcab764f4875db9d 100644 (file)
  */
 package org.openhab.binding.powermax.internal.config;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * The {@link PowermaxX10Configuration} is responsible for holding
  * configuration informations associated to a Powermax IP thing type
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxX10Configuration {
 
     public static final String DEVICE_NUMBER = "deviceNumber";
 
-    public Integer deviceNumber;
+    public int deviceNumber = -1;
 }
index ac1317cdec16a0817540517befacedf64a84ea8a..a34fd7491653988fe5ca9e6d9c5c8c7ea5cd9bee 100644 (file)
  */
 package org.openhab.binding.powermax.internal.config;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * The {@link PowermaxZoneConfiguration} is responsible for holding
  * configuration informations associated to a Powermax IP thing type
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxZoneConfiguration {
 
     public static final String ZONE_NUMBER = "zoneNumber";
 
-    public Integer zoneNumber;
+    public int zoneNumber = -1;
 }
index 4764c764ad300c874dbbba016949fdd869593e8a..7234304716e746e03042d64535b5e0ce6b4a1739 100644 (file)
@@ -18,6 +18,8 @@ import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.message.PowermaxBaseMessage;
 import org.openhab.binding.powermax.internal.message.PowermaxMessageEvent;
 import org.openhab.binding.powermax.internal.message.PowermaxMessageEventListener;
@@ -30,17 +32,19 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public abstract class PowermaxConnector implements PowermaxConnectorInterface {
 
     private final Logger logger = LoggerFactory.getLogger(PowermaxConnector.class);
 
-    private InputStream input;
-    private OutputStream output;
+    protected final String readerThreadName;
+    private final List<PowermaxMessageEventListener> listeners = new ArrayList<>();
+
+    private @Nullable InputStream input;
+    private @Nullable OutputStream output;
     private boolean connected;
-    protected String readerThreadName;
-    private Thread readerThread;
+    private @Nullable Thread readerThread;
     private long waitingForResponse;
-    private List<PowermaxMessageEventListener> listeners = new ArrayList<>();
 
     public PowermaxConnector(String readerThreadName) {
         this.readerThreadName = readerThreadName;
@@ -58,26 +62,29 @@ public abstract class PowermaxConnector implements PowermaxConnectorInterface {
     protected void cleanup(boolean closeStreams) {
         logger.debug("cleanup(): cleaning up Connection");
 
-        if (readerThread != null) {
-            readerThread.interrupt();
+        Thread thread = readerThread;
+        if (thread != null) {
+            thread.interrupt();
             try {
-                readerThread.join();
+                thread.join();
             } catch (InterruptedException e) {
             }
         }
 
         if (closeStreams) {
-            if (output != null) {
+            OutputStream out = output;
+            if (out != null) {
                 try {
-                    output.close();
+                    out.close();
                 } catch (IOException e) {
                     logger.debug("Error while closing the output stream: {}", e.getMessage());
                 }
             }
 
-            if (input != null) {
+            InputStream in = input;
+            if (in != null) {
                 try {
-                    input.close();
+                    in.close();
                 } catch (IOException e) {
                     logger.debug("Error while closing the input stream: {}", e.getMessage());
                 }
@@ -107,16 +114,20 @@ public abstract class PowermaxConnector implements PowermaxConnectorInterface {
     /**
      * Handles a communication failure
      */
-    public void handleCommunicationFailure(String message) {
+    public void handleCommunicationFailure(@Nullable String message) {
         close();
-        listeners.forEach(listener -> listener.onCommunicationFailure(message));
+        listeners.forEach(listener -> listener.onCommunicationFailure(message != null ? message : ""));
     }
 
     @Override
     public void sendMessage(byte[] data) {
         try {
-            output.write(data);
-            output.flush();
+            OutputStream out = output;
+            if (out == null) {
+                throw new IOException("output stream is undefined");
+            }
+            out.write(data);
+            out.flush();
         } catch (IOException e) {
             logger.debug("sendMessage(): Writing error: {}", e.getMessage(), e);
             handleCommunicationFailure(e.getMessage());
@@ -125,7 +136,11 @@ public abstract class PowermaxConnector implements PowermaxConnectorInterface {
 
     @Override
     public int read(byte[] buffer) throws IOException {
-        return input.read(buffer);
+        InputStream in = input;
+        if (in == null) {
+            throw new IOException("input stream is undefined");
+        }
+        return in.read(buffer);
     }
 
     @Override
@@ -141,7 +156,7 @@ public abstract class PowermaxConnector implements PowermaxConnectorInterface {
     /**
      * @return the input stream
      */
-    public InputStream getInput() {
+    public @Nullable InputStream getInput() {
         return input;
     }
 
@@ -150,14 +165,14 @@ public abstract class PowermaxConnector implements PowermaxConnectorInterface {
      *
      * @param input the input stream
      */
-    public void setInput(InputStream input) {
+    public void setInput(@Nullable InputStream input) {
         this.input = input;
     }
 
     /**
      * @return the output stream
      */
-    public OutputStream getOutput() {
+    public @Nullable OutputStream getOutput() {
         return output;
     }
 
@@ -166,7 +181,7 @@ public abstract class PowermaxConnector implements PowermaxConnectorInterface {
      *
      * @param output the output stream
      */
-    public void setOutput(OutputStream output) {
+    public void setOutput(@Nullable OutputStream output) {
         this.output = output;
     }
 
@@ -190,7 +205,7 @@ public abstract class PowermaxConnector implements PowermaxConnectorInterface {
     /**
      * @return the thread that handles the message reading
      */
-    public Thread getReaderThread() {
+    public @Nullable Thread getReaderThread() {
         return readerThread;
     }
 
index 9cf3241622fa16ecf42d855084b3c55098c61b39..c36f21b58877b0abc9de4c73afeff429b921d6a7 100644 (file)
@@ -14,6 +14,7 @@ package org.openhab.binding.powermax.internal.connector;
 
 import java.io.IOException;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.powermax.internal.message.PowermaxMessageEventListener;
 
 /**
@@ -21,6 +22,7 @@ import org.openhab.binding.powermax.internal.message.PowermaxMessageEventListene
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public interface PowermaxConnectorInterface {
 
     /**
index 9eb94870acfaa549805f982d2d0cbf6b23e0a4c9..25e2999344395a8e252dc2e26da668ff36f3d976 100644 (file)
@@ -16,6 +16,7 @@ import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.util.Arrays;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.powermax.internal.message.PowermaxCommManager;
 import org.openhab.binding.powermax.internal.message.PowermaxReceiveType;
 import org.openhab.core.util.HexUtils;
@@ -27,14 +28,15 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxReaderThread extends Thread {
 
-    private final Logger logger = LoggerFactory.getLogger(PowermaxReaderThread.class);
-
     private static final int READ_BUFFER_SIZE = 20;
     private static final int MAX_MSG_SIZE = 0xC0;
 
-    private PowermaxConnector connector;
+    private final Logger logger = LoggerFactory.getLogger(PowermaxReaderThread.class);
+
+    private final PowermaxConnector connector;
 
     /**
      * Constructor
index 9fa671d8c4bc615381bd8c800c9a64f29d4e09eb..906c842fb64be7eef2033494456268b269750be0 100644 (file)
 package org.openhab.binding.powermax.internal.connector;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.core.io.transport.serial.SerialPort;
 import org.openhab.core.io.transport.serial.SerialPortEvent;
 import org.openhab.core.io.transport.serial.SerialPortEventListener;
@@ -27,6 +31,7 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxSerialConnector extends PowermaxConnector implements SerialPortEventListener {
 
     private final Logger logger = LoggerFactory.getLogger(PowermaxSerialConnector.class);
@@ -34,7 +39,7 @@ public class PowermaxSerialConnector extends PowermaxConnector implements Serial
     private final String serialPortName;
     private final int baudRate;
     private final SerialPortManager serialPortManager;
-    private SerialPort serialPort;
+    private @Nullable SerialPort serialPort;
 
     /**
      * Constructor
@@ -50,7 +55,6 @@ public class PowermaxSerialConnector extends PowermaxConnector implements Serial
         this.serialPortManager = serialPortManager;
         this.serialPortName = serialPortName;
         this.baudRate = baudRate;
-        this.serialPort = null;
     }
 
     @Override
@@ -65,26 +69,31 @@ public class PowermaxSerialConnector extends PowermaxConnector implements Serial
         SerialPort commPort = portIdentifier.open(this.getClass().getName(), 2000);
 
         serialPort = commPort;
-        serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
-        serialPort.enableReceiveThreshold(1);
-        serialPort.enableReceiveTimeout(250);
+        commPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
+        commPort.enableReceiveThreshold(1);
+        commPort.enableReceiveTimeout(250);
 
-        setInput(serialPort.getInputStream());
-        setOutput(serialPort.getOutputStream());
+        InputStream inputStream = commPort.getInputStream();
+        setInput(inputStream);
+        OutputStream outputStream = commPort.getOutputStream();
+        setOutput(outputStream);
 
-        getOutput().flush();
-        if (getInput().markSupported()) {
-            getInput().reset();
+        if (outputStream != null) {
+            outputStream.flush();
+        }
+        if (inputStream != null && inputStream.markSupported()) {
+            inputStream.reset();
         }
 
         // RXTX serial port library causes high CPU load
         // Start event listener, which will just sleep and slow down event
         // loop
-        serialPort.addEventListener(this);
-        serialPort.notifyOnDataAvailable(true);
+        commPort.addEventListener(this);
+        commPort.notifyOnDataAvailable(true);
 
-        setReaderThread(new PowermaxReaderThread(this, readerThreadName));
-        getReaderThread().start();
+        PowermaxReaderThread readerThread = new PowermaxReaderThread(this, readerThreadName);
+        setReaderThread(readerThread);
+        readerThread.start();
 
         setConnected(true);
     }
@@ -93,14 +102,15 @@ public class PowermaxSerialConnector extends PowermaxConnector implements Serial
     public void close() {
         logger.debug("close(): Closing Serial Connection");
 
-        if (serialPort != null) {
-            serialPort.removeEventListener();
+        SerialPort commPort = serialPort;
+        if (commPort != null) {
+            commPort.removeEventListener();
         }
 
         super.cleanup(true);
 
-        if (serialPort != null) {
-            serialPort.close();
+        if (commPort != null) {
+            commPort.close();
         }
 
         serialPort = null;
index 40014a1c1378ad1411ff3ca69cad2c7381363c90..8adf17de378d6ffa945e97b69e5ce5fda7ff274c 100644 (file)
@@ -18,6 +18,8 @@ import java.net.Socket;
 import java.net.SocketAddress;
 import java.net.SocketTimeoutException;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -26,6 +28,7 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxTcpConnector extends PowermaxConnector {
 
     private final Logger logger = LoggerFactory.getLogger(PowermaxTcpConnector.class);
@@ -33,7 +36,7 @@ public class PowermaxTcpConnector extends PowermaxConnector {
     private final String ipAddress;
     private final int tcpPort;
     private final int connectTimeout;
-    private Socket tcpSocket;
+    private @Nullable Socket tcpSocket;
 
     /**
      * Constructor.
@@ -54,16 +57,18 @@ public class PowermaxTcpConnector extends PowermaxConnector {
     public void open() throws Exception {
         logger.debug("open(): Opening TCP Connection");
 
-        tcpSocket = new Socket();
-        tcpSocket.setSoTimeout(250);
+        Socket socket = new Socket();
+        tcpSocket = socket;
+        socket.setSoTimeout(250);
         SocketAddress socketAddress = new InetSocketAddress(ipAddress, tcpPort);
-        tcpSocket.connect(socketAddress, connectTimeout);
+        socket.connect(socketAddress, connectTimeout);
 
-        setInput(tcpSocket.getInputStream());
-        setOutput(tcpSocket.getOutputStream());
+        setInput(socket.getInputStream());
+        setOutput(socket.getOutputStream());
 
-        setReaderThread(new PowermaxReaderThread(this, readerThreadName));
-        getReaderThread().start();
+        PowermaxReaderThread readerThread = new PowermaxReaderThread(this, readerThreadName);
+        setReaderThread(readerThread);
+        readerThread.start();
 
         setConnected(true);
     }
@@ -74,9 +79,10 @@ public class PowermaxTcpConnector extends PowermaxConnector {
 
         super.cleanup(false);
 
-        if (tcpSocket != null) {
+        Socket socket = tcpSocket;
+        if (socket != null) {
             try {
-                tcpSocket.close();
+                socket.close();
             } catch (IOException e) {
                 logger.debug("Error while closing the socket: {}", e.getMessage());
             }
index 3d58f5250eed9e531c7b6e4beb3ba067f3ec6e4b..74df11541e5c5ecd1af6f8f1df9e8a410d356a89 100644 (file)
@@ -15,7 +15,9 @@ package org.openhab.binding.powermax.internal.console;
 import java.util.Arrays;
 import java.util.List;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.binding.powermax.internal.handler.PowermaxBridgeHandler;
+import org.openhab.binding.powermax.internal.state.PowermaxState;
 import org.openhab.core.io.console.Console;
 import org.openhab.core.io.console.extensions.AbstractConsoleCommandExtension;
 import org.openhab.core.io.console.extensions.ConsoleCommandExtension;
@@ -23,6 +25,7 @@ import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingRegistry;
 import org.openhab.core.thing.ThingUID;
 import org.openhab.core.thing.binding.ThingHandler;
+import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
 
@@ -31,6 +34,7 @@ import org.osgi.service.component.annotations.Reference;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 @Component(service = ConsoleCommandExtension.class)
 public class PowermaxCommandExtension extends AbstractConsoleCommandExtension {
 
@@ -38,10 +42,12 @@ public class PowermaxCommandExtension extends AbstractConsoleCommandExtension {
     private static final String DOWNLOAD_SETUP = "download_setup";
     private static final String BRIDGE_STATE = "bridge_state";
 
-    private ThingRegistry thingRegistry;
+    private final ThingRegistry thingRegistry;
 
-    public PowermaxCommandExtension() {
+    @Activate
+    public PowermaxCommandExtension(final @Reference ThingRegistry thingRegistry) {
         super("powermax", "Interact with the Powermax binding.");
+        this.thingRegistry = thingRegistry;
     }
 
     @Override
@@ -83,8 +89,11 @@ public class PowermaxCommandExtension extends AbstractConsoleCommandExtension {
                         console.println("Command '" + args[1] + "' handled.");
                         break;
                     case BRIDGE_STATE:
-                        for (String line : handler.getCurrentState().toString().split("\n")) {
-                            console.println(line);
+                        PowermaxState state = handler.getCurrentState();
+                        if (state != null) {
+                            for (String line : state.toString().split("\n")) {
+                                console.println(line);
+                            }
                         }
                         break;
                     default:
@@ -104,13 +113,4 @@ public class PowermaxCommandExtension extends AbstractConsoleCommandExtension {
                 buildCommandUsage("<bridgeUID> " + DOWNLOAD_SETUP, "download setup"),
                 buildCommandUsage("<bridgeUID> " + BRIDGE_STATE, "show current state") });
     }
-
-    @Reference
-    protected void setThingRegistry(ThingRegistry thingRegistry) {
-        this.thingRegistry = thingRegistry;
-    }
-
-    protected void unsetThingRegistry(ThingRegistry thingRegistry) {
-        this.thingRegistry = null;
-    }
 }
index 9333e6d064170dfea03406f509c1de4a6809de70..feab2c0df3a2b364e88995747cc25c94d42bd1ea 100644 (file)
@@ -48,10 +48,10 @@ import org.slf4j.LoggerFactory;
 public class PowermaxDiscoveryService extends AbstractDiscoveryService
         implements PowermaxPanelSettingsListener, ThingHandlerService {
 
-    private final Logger logger = LoggerFactory.getLogger(PowermaxDiscoveryService.class);
-
     private static final int SEARCH_TIME = 5;
 
+    private final Logger logger = LoggerFactory.getLogger(PowermaxDiscoveryService.class);
+
     private @Nullable PowermaxBridgeHandler bridgeHandler;
 
     /**
index 405c2b97d705f799779b2ea1c3127c80fa4591bb..32c7d327cb70337348619b17df7af8129e7def11 100644 (file)
@@ -23,6 +23,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.config.PowermaxIpConfiguration;
 import org.openhab.binding.powermax.internal.config.PowermaxSerialConfiguration;
 import org.openhab.binding.powermax.internal.discovery.PowermaxDiscoveryService;
@@ -36,6 +38,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
 import org.openhab.binding.powermax.internal.state.PowermaxStateContainer.Value;
 import org.openhab.binding.powermax.internal.state.PowermaxStateEvent;
 import org.openhab.binding.powermax.internal.state.PowermaxStateEventListener;
+import org.openhab.binding.powermax.internal.state.PowermaxZoneSettings;
 import org.openhab.core.i18n.TimeZoneProvider;
 import org.openhab.core.io.transport.serial.SerialPortManager;
 import org.openhab.core.library.types.OnOffType;
@@ -59,18 +62,12 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxBridgeHandler extends BaseBridgeHandler implements PowermaxStateEventListener {
 
-    private final Logger logger = LoggerFactory.getLogger(PowermaxBridgeHandler.class);
-    private final SerialPortManager serialPortManager;
-    private final TimeZoneProvider timeZoneProvider;
-
     private static final long ONE_MINUTE = TimeUnit.MINUTES.toMillis(1);
     private static final long FIVE_MINUTES = TimeUnit.MINUTES.toMillis(5);
 
-    /** Default delay in milliseconds to reset a motion detection */
-    private static final long DEFAULT_MOTION_OFF_DELAY = TimeUnit.MINUTES.toMillis(3);
-
     private static final int NB_EVENT_LOG = 10;
 
     private static final PowermaxPanelType DEFAULT_PANEL_TYPE = PowermaxPanelType.POWERMAX_PRO;
@@ -79,9 +76,14 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
 
     private static final int MAX_DOWNLOAD_ATTEMPTS = 3;
 
-    private ScheduledFuture<?> globalJob;
+    private final Logger logger = LoggerFactory.getLogger(PowermaxBridgeHandler.class);
 
-    private List<PowermaxPanelSettingsListener> listeners = new CopyOnWriteArrayList<>();
+    private final SerialPortManager serialPortManager;
+    private final TimeZoneProvider timeZoneProvider;
+
+    private final List<PowermaxPanelSettingsListener> listeners = new CopyOnWriteArrayList<>();
+
+    private @Nullable ScheduledFuture<?> globalJob;
 
     /** The delay in milliseconds to reset a motion detection */
     private long motionOffDelay;
@@ -96,7 +98,7 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
     private PowermaxState currentState;
 
     /** The object in charge of the communication with the Powermax alarm system */
-    private PowermaxCommManager commManager;
+    private @Nullable PowermaxCommManager commManager;
 
     private int remainingDownloadAttempts;
 
@@ -104,6 +106,8 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         super(thing);
         this.serialPortManager = serialPortManager;
         this.timeZoneProvider = timeZoneProvider;
+        this.pinCode = "";
+        this.currentState = new PowermaxState(new PowermaxPanelSettings(DEFAULT_PANEL_TYPE), timeZoneProvider);
     }
 
     @Override
@@ -111,12 +115,14 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         return Collections.singleton(PowermaxDiscoveryService.class);
     }
 
-    public PowermaxState getCurrentState() {
-        return currentState;
+    public @Nullable PowermaxState getCurrentState() {
+        PowermaxCommManager localCommManager = commManager;
+        return (localCommManager == null) ? null : currentState;
     }
 
-    public PowermaxPanelSettings getPanelSettings() {
-        return (commManager == null) ? null : commManager.getPanelSettings();
+    public @Nullable PowermaxPanelSettings getPanelSettings() {
+        PowermaxCommManager localCommManager = commManager;
+        return (localCommManager == null) ? null : localCommManager.getPanelSettings();
     }
 
     @Override
@@ -137,7 +143,8 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         }
 
         if (errorMsg == null) {
-            if (globalJob == null || globalJob.isCancelled()) {
+            ScheduledFuture<?> job = globalJob;
+            if (job == null || job.isCancelled()) {
                 // Delay the startup in case the handler is restarted immediately
                 globalJob = scheduler.scheduleWithFixedDelay(() -> {
                     try {
@@ -146,7 +153,7 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
                         updateRingingState();
                         if (isConnected()) {
                             checkKeepAlive();
-                            commManager.retryDownloadSetup(remainingDownloadAttempts);
+                            retryDownloadSetup();
                         } else {
                             tryReconnect();
                         }
@@ -160,30 +167,27 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         }
     }
 
-    private String initializeBridgeSerial(PowermaxSerialConfiguration config, String threadName) {
+    private @Nullable String initializeBridgeSerial(PowermaxSerialConfiguration config, String threadName) {
         String errorMsg = null;
-        if (config.serialPort != null && !config.serialPort.trim().isEmpty()
-                && !config.serialPort.trim().startsWith("rfc2217")) {
-            motionOffDelay = getMotionOffDelaySetting(config.motionOffDelay, DEFAULT_MOTION_OFF_DELAY);
-            boolean allowArming = getBooleanSetting(config.allowArming, false);
-            boolean allowDisarming = getBooleanSetting(config.allowDisarming, false);
+        String serialPort = config.serialPort.trim();
+        if (!serialPort.isEmpty() && !serialPort.startsWith("rfc2217")) {
+            motionOffDelay = config.motionOffDelay * ONE_MINUTE;
             pinCode = config.pinCode;
-            forceStandardMode = getBooleanSetting(config.forceStandardMode, false);
+            forceStandardMode = config.forceStandardMode;
             PowermaxPanelType panelType = getPanelTypeSetting(config.panelType, DEFAULT_PANEL_TYPE);
-            boolean autoSyncTime = getBooleanSetting(config.autoSyncTime, false);
 
-            PowermaxArmMode.DISARMED.setAllowedCommand(allowDisarming);
-            PowermaxArmMode.ARMED_HOME.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_AWAY.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_HOME_INSTANT.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_AWAY_INSTANT.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_NIGHT.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_NIGHT_INSTANT.setAllowedCommand(allowArming);
+            PowermaxArmMode.DISARMED.setAllowedCommand(config.allowDisarming);
+            PowermaxArmMode.ARMED_HOME.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_AWAY.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_HOME_INSTANT.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_AWAY_INSTANT.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_NIGHT.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_NIGHT_INSTANT.setAllowedCommand(config.allowArming);
 
-            commManager = new PowermaxCommManager(config.serialPort, panelType, forceStandardMode, autoSyncTime,
+            commManager = new PowermaxCommManager(serialPort, panelType, forceStandardMode, config.autoSyncTime,
                     serialPortManager, threadName, timeZoneProvider);
         } else {
-            if (config.serialPort != null && config.serialPort.trim().startsWith("rfc2217")) {
+            if (serialPort.startsWith("rfc2217")) {
                 errorMsg = "Please use the IP Connection thing type for a serial over IP connection.";
             } else {
                 errorMsg = "serialPort setting must be defined in thing configuration";
@@ -192,26 +196,24 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         return errorMsg;
     }
 
-    private String initializeBridgeIp(PowermaxIpConfiguration config, String threadName) {
+    private @Nullable String initializeBridgeIp(PowermaxIpConfiguration config, String threadName) {
         String errorMsg = null;
-        if (config.ip != null && !config.ip.trim().isEmpty() && config.tcpPort != null) {
-            motionOffDelay = getMotionOffDelaySetting(config.motionOffDelay, DEFAULT_MOTION_OFF_DELAY);
-            boolean allowArming = getBooleanSetting(config.allowArming, false);
-            boolean allowDisarming = getBooleanSetting(config.allowDisarming, false);
+        String ip = config.ip.trim();
+        if (!ip.isEmpty() && config.tcpPort > 0) {
+            motionOffDelay = config.motionOffDelay * ONE_MINUTE;
             pinCode = config.pinCode;
-            forceStandardMode = getBooleanSetting(config.forceStandardMode, false);
+            forceStandardMode = config.forceStandardMode;
             PowermaxPanelType panelType = getPanelTypeSetting(config.panelType, DEFAULT_PANEL_TYPE);
-            boolean autoSyncTime = getBooleanSetting(config.autoSyncTime, false);
 
-            PowermaxArmMode.DISARMED.setAllowedCommand(allowDisarming);
-            PowermaxArmMode.ARMED_HOME.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_AWAY.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_HOME_INSTANT.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_AWAY_INSTANT.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_NIGHT.setAllowedCommand(allowArming);
-            PowermaxArmMode.ARMED_NIGHT_INSTANT.setAllowedCommand(allowArming);
+            PowermaxArmMode.DISARMED.setAllowedCommand(config.allowDisarming);
+            PowermaxArmMode.ARMED_HOME.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_AWAY.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_HOME_INSTANT.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_AWAY_INSTANT.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_NIGHT.setAllowedCommand(config.allowArming);
+            PowermaxArmMode.ARMED_NIGHT_INSTANT.setAllowedCommand(config.allowArming);
 
-            commManager = new PowermaxCommManager(config.ip, config.tcpPort, panelType, forceStandardMode, autoSyncTime,
+            commManager = new PowermaxCommManager(ip, config.tcpPort, panelType, forceStandardMode, config.autoSyncTime,
                     threadName, timeZoneProvider);
         } else {
             errorMsg = "ip and port settings must be defined in thing configuration";
@@ -222,8 +224,9 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
     @Override
     public void dispose() {
         logger.debug("Handler disposed for thing {}", getThing().getUID());
-        if (globalJob != null && !globalJob.isCancelled()) {
-            globalJob.cancel(true);
+        ScheduledFuture<?> job = globalJob;
+        if (job != null && !job.isCancelled()) {
+            job.cancel(true);
             globalJob = null;
         }
         closeConnection();
@@ -236,13 +239,15 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
      * than the value defined by the variable motionOffDelay
      */
     private void updateMotionSensorState() {
-        long now = System.currentTimeMillis();
-        if (currentState != null) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager != null) {
+            long now = System.currentTimeMillis();
             boolean update = false;
-            PowermaxState updateState = commManager.createNewState();
-            PowermaxPanelSettings panelSettings = getPanelSettings();
+            PowermaxState updateState = localCommManager.createNewState();
+            PowermaxPanelSettings panelSettings = localCommManager.getPanelSettings();
             for (int i = 1; i <= panelSettings.getNbZones(); i++) {
-                if (panelSettings.getZoneSettings(i) != null && panelSettings.getZoneSettings(i).isMotionSensor()
+                PowermaxZoneSettings zoneSettings = panelSettings.getZoneSettings(i);
+                if (zoneSettings != null && zoneSettings.isMotionSensor()
                         && currentState.getZone(i).isLastTripBeforeTime(now - motionOffDelay)) {
                     update = true;
                     updateState.getZone(i).tripped.setValue(false);
@@ -259,12 +264,14 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
      * Turn off the Ringing flag when the bell time expires
      */
     private void updateRingingState() {
-        if (currentState != null && Boolean.TRUE.equals(currentState.ringing.getValue())) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager != null && Boolean.TRUE.equals(currentState.ringing.getValue())) {
             long now = System.currentTimeMillis();
-            long bellTime = getPanelSettings().getBellTime() * ONE_MINUTE;
+            long bellTime = localCommManager.getPanelSettings().getBellTime() * ONE_MINUTE;
 
-            if ((currentState.ringingSince.getValue() + bellTime) < now) {
-                PowermaxState updateState = commManager.createNewState();
+            Long ringingSince = currentState.ringingSince.getValue();
+            if (ringingSince != null && (ringingSince + bellTime) < now) {
+                PowermaxState updateState = localCommManager.createNewState();
                 updateState.ringing.setValue(false);
                 updateChannelsFromAlarmState(RINGING, updateState);
                 currentState.merge(updateState);
@@ -276,25 +283,33 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
      * Check that we're actively communicating with the panel
      */
     private void checkKeepAlive() {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            return;
+        }
         long now = System.currentTimeMillis();
-        if (Boolean.TRUE.equals(currentState.powerlinkMode.getValue())
-                && (currentState.lastKeepAlive.getValue() != null)
-                && ((now - currentState.lastKeepAlive.getValue()) > ONE_MINUTE)) {
+        Long lastKeepAlive = currentState.lastKeepAlive.getValue();
+        Long lastMessageTime = currentState.lastMessageTime.getValue();
+        if (Boolean.TRUE.equals(currentState.powerlinkMode.getValue()) && (lastKeepAlive != null)
+                && ((now - lastKeepAlive) > ONE_MINUTE)) {
             // In Powerlink mode: let Powermax know we are alive
-            commManager.sendRestoreMessage();
+            localCommManager.sendRestoreMessage();
             currentState.lastKeepAlive.setValue(now);
-        } else if (!Boolean.TRUE.equals(currentState.downloadMode.getValue())
-                && (currentState.lastMessageTime.getValue() != null)
-                && ((now - currentState.lastMessageTime.getValue()) > FIVE_MINUTES)) {
+        } else if (!Boolean.TRUE.equals(currentState.downloadMode.getValue()) && (lastMessageTime != null)
+                && ((now - lastMessageTime) > FIVE_MINUTES)) {
             // In Standard mode: ping the panel every so often to detect disconnects
-            commManager.sendMessage(PowermaxSendType.STATUS);
+            localCommManager.sendMessage(PowermaxSendType.STATUS);
         }
     }
 
     private void tryReconnect() {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            return;
+        }
         logger.info("Trying to connect or reconnect...");
         closeConnection();
-        currentState = commManager.createNewState();
+        currentState = localCommManager.createNewState();
         try {
             openConnection();
             logger.debug("openConnection(): connected");
@@ -305,7 +320,7 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
                 updateChannelsFromAlarmState(MODE, currentState);
                 processPanelSettings();
             } else {
-                commManager.startDownload();
+                localCommManager.startDownload();
             }
         } catch (Exception e) {
             logger.debug("openConnection(): {}", e.getMessage(), e);
@@ -320,9 +335,10 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
      * @return true if the connection has been opened
      */
     private synchronized void openConnection() throws Exception {
-        if (commManager != null) {
-            commManager.addEventListener(this);
-            commManager.open();
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager != null) {
+            localCommManager.addEventListener(this);
+            localCommManager.open();
         }
         remainingDownloadAttempts = MAX_DOWNLOAD_ATTEMPTS;
     }
@@ -331,15 +347,24 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
      * Close TCP or Serial connection to the Powermax Alarm Panel and remove the Event Listener
      */
     private synchronized void closeConnection() {
-        if (commManager != null) {
-            commManager.close();
-            commManager.removeEventListener(this);
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager != null) {
+            localCommManager.close();
+            localCommManager.removeEventListener(this);
         }
         logger.debug("closeConnection(): disconnected");
     }
 
     private boolean isConnected() {
-        return commManager == null ? false : commManager.isConnected();
+        PowermaxCommManager localCommManager = commManager;
+        return localCommManager == null ? false : localCommManager.isConnected();
+    }
+
+    private void retryDownloadSetup() {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager != null) {
+            localCommManager.retryDownloadSetup(remainingDownloadAttempts);
+        }
     }
 
     @Override
@@ -347,7 +372,7 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         logger.debug("Received command {} from channel {}", command, channelUID.getId());
 
         if (command instanceof RefreshType) {
-            updateChannelsFromAlarmState(channelUID.getId(), currentState);
+            updateChannelsFromAlarmState(channelUID.getId(), getCurrentState());
         } else {
             switch (channelUID.getId()) {
                 case ARM_MODE:
@@ -384,62 +409,81 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
     }
 
     private void armCommand(PowermaxArmMode armMode) {
-        if (!isConnected()) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            logger.debug("Powermax alarm binding not correctly initialized. Arm command is ignored.");
+        } else if (!isConnected()) {
             logger.debug("Powermax alarm binding not connected. Arm command is ignored.");
         } else {
-            commManager.requestArmMode(armMode,
-                    Boolean.TRUE.equals(currentState.powerlinkMode.getValue()) ? getPanelSettings().getFirstPinCode()
+            localCommManager.requestArmMode(armMode,
+                    Boolean.TRUE.equals(currentState.powerlinkMode.getValue())
+                            ? localCommManager.getPanelSettings().getFirstPinCode()
                             : pinCode);
         }
     }
 
     private void pgmCommand(Command command) {
-        if (!isConnected()) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            logger.debug("Powermax alarm binding not correctly initialized. PGM command is ignored.");
+        } else if (!isConnected()) {
             logger.debug("Powermax alarm binding not connected. PGM command is ignored.");
         } else {
-            commManager.sendPGMX10(command, null);
+            localCommManager.sendPGMX10(command, null);
         }
     }
 
     public void x10Command(Byte deviceNr, Command command) {
-        if (!isConnected()) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            logger.debug("Powermax alarm binding not correctly initialized. X10 command is ignored.");
+        } else if (!isConnected()) {
             logger.debug("Powermax alarm binding not connected. X10 command is ignored.");
         } else {
-            commManager.sendPGMX10(command, deviceNr);
+            localCommManager.sendPGMX10(command, deviceNr);
         }
     }
 
     public void zoneBypassed(byte zoneNr, boolean bypassed) {
-        if (!isConnected()) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            logger.debug("Powermax alarm binding not correctly initialized. Zone bypass command is ignored.");
+        } else if (!isConnected()) {
             logger.debug("Powermax alarm binding not connected. Zone bypass command is ignored.");
         } else if (!Boolean.TRUE.equals(currentState.powerlinkMode.getValue())) {
             logger.debug("Powermax alarm binding: Bypass option only supported in Powerlink mode");
-        } else if (!getPanelSettings().isBypassEnabled()) {
+        } else if (!localCommManager.getPanelSettings().isBypassEnabled()) {
             logger.debug("Powermax alarm binding: Bypass option not enabled in panel settings");
         } else {
-            commManager.sendZoneBypass(bypassed, zoneNr, getPanelSettings().getFirstPinCode());
+            localCommManager.sendZoneBypass(bypassed, zoneNr, localCommManager.getPanelSettings().getFirstPinCode());
         }
     }
 
     private void downloadEventLog() {
-        if (!isConnected()) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            logger.debug("Powermax alarm binding not correctly initialized. Event logs command is ignored.");
+        } else if (!isConnected()) {
             logger.debug("Powermax alarm binding not connected. Event logs command is ignored.");
         } else {
-            commManager.requestEventLog(
-                    Boolean.TRUE.equals(currentState.powerlinkMode.getValue()) ? getPanelSettings().getFirstPinCode()
-                            : pinCode);
+            localCommManager.requestEventLog(Boolean.TRUE.equals(currentState.powerlinkMode.getValue())
+                    ? localCommManager.getPanelSettings().getFirstPinCode()
+                    : pinCode);
         }
     }
 
     public void downloadSetup() {
-        if (!isConnected()) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            logger.debug("Powermax alarm binding not correctly initialized. Download setup command is ignored.");
+        } else if (!isConnected()) {
             logger.debug("Powermax alarm binding not connected. Download setup command is ignored.");
         } else if (!Boolean.TRUE.equals(currentState.powerlinkMode.getValue())) {
             logger.debug("Powermax alarm binding: download setup only supported in Powerlink mode");
-        } else if (commManager.isDownloadRunning()) {
+        } else if (localCommManager.isDownloadRunning()) {
             logger.debug("Powermax alarm binding: download setup not started as one is in progress");
         } else {
-            commManager.startDownload();
+            localCommManager.startDownload();
             if (currentState.lastKeepAlive.getValue() != null) {
                 currentState.lastKeepAlive.setValue(System.currentTimeMillis());
             }
@@ -447,11 +491,17 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
     }
 
     public String getInfoSetup() {
-        return (getPanelSettings() == null) ? "" : getPanelSettings().getInfo();
+        PowermaxPanelSettings panelSettings = getPanelSettings();
+        return (panelSettings == null) ? "" : panelSettings.getInfo();
     }
 
     @Override
     public void onNewStateEvent(EventObject event) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            return;
+        }
+
         PowermaxStateEvent stateEvent = (PowermaxStateEvent) event;
         PowermaxState updateState = stateEvent.getState();
 
@@ -459,7 +509,7 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
                 && Boolean.TRUE.equals(updateState.downloadSetupRequired.getValue())) {
             // After Enrolling Powerlink or if a reset is required
             logger.debug("Powermax alarm binding: Reset");
-            commManager.startDownload();
+            localCommManager.startDownload();
             updateState.downloadSetupRequired.setValue(false);
             if (currentState.lastKeepAlive.getValue() != null) {
                 currentState.lastKeepAlive.setValue(System.currentTimeMillis());
@@ -469,12 +519,13 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
             // Were are in standard mode but received a keep alive message
             // so we switch in PowerLink mode
             logger.debug("Powermax alarm binding: Switching to Powerlink mode");
-            commManager.startDownload();
+            localCommManager.startDownload();
         }
 
         boolean doProcessSettings = (updateState.powerlinkMode.getValue() != null);
 
-        getPanelSettings().getZoneRange().forEach(i -> {
+        PowermaxPanelSettings panelSettings = localCommManager.getPanelSettings();
+        panelSettings.getZoneRange().forEach(i -> {
             if (Boolean.TRUE.equals(updateState.getZone(i).armed.getValue())
                     && Boolean.TRUE.equals(currentState.getZone(i).bypassed.getValue())) {
                 updateState.getZone(i).armed.setValue(false);
@@ -485,7 +536,6 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         updateChannelsFromAlarmState(updateState);
         currentState.merge(updateState);
 
-        PowermaxPanelSettings panelSettings = getPanelSettings();
         if (!updateState.getUpdatedZoneNames().isEmpty()) {
             for (Integer zoneIdx : updateState.getUpdatedZoneNames().keySet()) {
                 if (panelSettings.getZoneSettings(zoneIdx) != null) {
@@ -499,7 +549,7 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         if (doProcessSettings) {
             // There is a change of mode (standard or Powerlink)
             processPanelSettings();
-            commManager.exitDownload();
+            localCommManager.exitDownload();
         }
     }
 
@@ -510,9 +560,14 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
     }
 
     private void processPanelSettings() {
-        if (commManager.processPanelSettings(Boolean.TRUE.equals(currentState.powerlinkMode.getValue()))) {
+        PowermaxCommManager localCommManager = commManager;
+        if (localCommManager == null) {
+            return;
+        }
+
+        if (localCommManager.processPanelSettings(Boolean.TRUE.equals(currentState.powerlinkMode.getValue()))) {
             for (PowermaxPanelSettingsListener listener : listeners) {
-                listener.onPanelSettingsUpdated(getPanelSettings());
+                listener.onPanelSettingsUpdated(localCommManager.getPanelSettings());
             }
             remainingDownloadAttempts = 0;
         } else {
@@ -525,10 +580,10 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         updatePropertiesFromPanelSettings();
         if (Boolean.TRUE.equals(currentState.powerlinkMode.getValue())) {
             logger.info("Powermax alarm binding: running in Powerlink mode");
-            commManager.sendRestoreMessage();
+            localCommManager.sendRestoreMessage();
         } else {
             logger.info("Powermax alarm binding: running in Standard mode");
-            commManager.getInfosWhenInStandardMode();
+            localCommManager.getInfosWhenInStandardMode();
         }
     }
 
@@ -537,7 +592,7 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
      *
      * @param state: the alarm system state
      */
-    private void updateChannelsFromAlarmState(PowermaxState state) {
+    private void updateChannelsFromAlarmState(@Nullable PowermaxState state) {
         updateChannelsFromAlarmState(null, state);
     }
 
@@ -547,7 +602,7 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
      * @param channel: filter on a particular channel; if null, consider all channels
      * @param state: the alarm system state
      */
-    private synchronized void updateChannelsFromAlarmState(String channel, PowermaxState state) {
+    private synchronized void updateChannelsFromAlarmState(@Nullable String channel, @Nullable PowermaxState state) {
         if (state == null || !isConnected()) {
             return;
         }
@@ -555,17 +610,16 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         for (Value<?> value : state.getValues()) {
             String vChannel = value.getChannel();
 
-            if (((channel == null) || channel.equals(vChannel)) && (vChannel != null) && isLinked(vChannel)
-                    && (value.getValue() != null)) {
+            if (((channel == null) || channel.equals(vChannel)) && isLinked(vChannel) && (value.getValue() != null)) {
                 updateState(vChannel, value.getState());
             }
         }
 
         for (int i = 1; i <= NB_EVENT_LOG; i++) {
             String channel2 = String.format(EVENT_LOG, i);
-            if (((channel == null) || channel.equals(channel2)) && isLinked(channel2)
-                    && (state.getEventLog(i) != null)) {
-                updateState(channel2, new StringType(state.getEventLog(i)));
+            String log = state.getEventLog(i);
+            if (((channel == null) || channel.equals(channel2)) && isLinked(channel2) && (log != null)) {
+                updateState(channel2, new StringType(log));
             }
         }
 
@@ -574,14 +628,13 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
                 PowermaxThingHandler handler = (PowermaxThingHandler) thing.getHandler();
                 if (handler != null) {
                     if (thing.getThingTypeUID().equals(THING_TYPE_ZONE)) {
-
                         // All of the zone state objects will have the same list of values.
                         // The use of getZone(1) here is just to get any PowermaxZoneState
                         // and use it to get the list of zone channels.
 
                         for (Value<?> value : state.getZone(1).getValues()) {
                             String channelId = value.getChannel();
-                            if ((channelId != null) && ((channel == null) || channel.equals(channelId))) {
+                            if ((channel == null) || channel.equals(channelId)) {
                                 handler.updateChannelFromAlarmState(channelId, state);
                             }
                         }
@@ -606,11 +659,14 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
      * Update properties to match the alarm panel settings
      */
     private void updatePropertiesFromPanelSettings() {
+        PowermaxPanelSettings panelSettings = getPanelSettings();
+        if (panelSettings == null) {
+            return;
+        }
         String value;
         Map<String, String> properties = editProperties();
-        PowermaxPanelSettings panelSettings = getPanelSettings();
-        value = (panelSettings.getPanelType() != null) ? panelSettings.getPanelType().getLabel() : null;
-        if (value != null && !value.isEmpty()) {
+        value = panelSettings.getPanelType().getLabel();
+        if (!value.isEmpty()) {
             properties.put(Thing.PROPERTY_MODEL_ID, value);
         }
         value = panelSettings.getPanelSerial();
@@ -640,25 +696,13 @@ public class PowermaxBridgeHandler extends BaseBridgeHandler implements Powermax
         return listeners.remove(listener);
     }
 
-    private boolean getBooleanSetting(Boolean value, boolean defaultValue) {
-        return value != null ? value.booleanValue() : defaultValue;
-    }
-
-    private long getMotionOffDelaySetting(Integer value, long defaultValue) {
-        return value != null ? value.intValue() * ONE_MINUTE : defaultValue;
-    }
-
     private PowermaxPanelType getPanelTypeSetting(String value, PowermaxPanelType defaultValue) {
         PowermaxPanelType result;
-        if (value != null) {
-            try {
-                result = PowermaxPanelType.fromLabel(value);
-            } catch (IllegalArgumentException e) {
-                result = defaultValue;
-                logger.debug("Powermax alarm binding: panel type not configured correctly");
-            }
-        } else {
+        try {
+            result = PowermaxPanelType.fromLabel(value);
+        } catch (IllegalArgumentException e) {
             result = defaultValue;
+            logger.debug("Powermax alarm binding: panel type not configured correctly");
         }
         return result;
     }
index 1b2f7f179ad825bfe778a31db1326f3901ac8418..77f07e1b23e71d1dc1847bac63e3d212df700516 100644 (file)
@@ -14,6 +14,7 @@ package org.openhab.binding.powermax.internal.handler;
 
 import static org.openhab.binding.powermax.internal.PowermaxBindingConstants.*;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.config.PowermaxX10Configuration;
 import org.openhab.binding.powermax.internal.config.PowermaxZoneConfiguration;
@@ -44,16 +45,17 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPanelSettingsListener {
 
-    private final Logger logger = LoggerFactory.getLogger(PowermaxThingHandler.class);
-
     private static final int ZONE_NR_MIN = 1;
     private static final int ZONE_NR_MAX = 64;
     private static final int X10_NR_MIN = 1;
     private static final int X10_NR_MAX = 16;
 
-    private PowermaxBridgeHandler bridgeHandler;
+    private final Logger logger = LoggerFactory.getLogger(PowermaxThingHandler.class);
+
+    private @Nullable PowermaxBridgeHandler bridgeHandler;
 
     public PowermaxThingHandler(Thing thing) {
         super(thing);
@@ -77,7 +79,7 @@ public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPa
         initializeThingState((bridge == null) ? null : bridge.getHandler(), bridgeStatusInfo.getStatus());
     }
 
-    private void initializeThingState(ThingHandler bridgeHandler, ThingStatus bridgeStatus) {
+    private void initializeThingState(@Nullable ThingHandler bridgeHandler, @Nullable ThingStatus bridgeStatus) {
         if (bridgeHandler != null && bridgeStatus != null) {
             if (bridgeStatus == ThingStatus.ONLINE) {
                 boolean validConfig = false;
@@ -85,8 +87,7 @@ public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPa
 
                 if (getThing().getThingTypeUID().equals(THING_TYPE_ZONE)) {
                     PowermaxZoneConfiguration config = getConfigAs(PowermaxZoneConfiguration.class);
-                    if (config.zoneNumber != null && config.zoneNumber >= ZONE_NR_MIN
-                            && config.zoneNumber <= ZONE_NR_MAX) {
+                    if (config.zoneNumber >= ZONE_NR_MIN && config.zoneNumber <= ZONE_NR_MAX) {
                         validConfig = true;
                     } else {
                         errorMsg = "zoneNumber setting must be defined in thing configuration and set between "
@@ -94,8 +95,7 @@ public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPa
                     }
                 } else if (getThing().getThingTypeUID().equals(THING_TYPE_X10)) {
                     PowermaxX10Configuration config = getConfigAs(PowermaxX10Configuration.class);
-                    if (config.deviceNumber != null && config.deviceNumber >= X10_NR_MIN
-                            && config.deviceNumber <= X10_NR_MAX) {
+                    if (config.deviceNumber >= X10_NR_MIN && config.deviceNumber <= X10_NR_MAX) {
                         validConfig = true;
                     } else {
                         errorMsg = "deviceNumber setting must be defined in thing configuration and set between "
@@ -106,9 +106,10 @@ public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPa
                 if (validConfig) {
                     updateStatus(ThingStatus.UNKNOWN);
                     logger.debug("Set handler status to UNKNOWN for thing {} (bridge ONLINE)", getThing().getUID());
-                    this.bridgeHandler = (PowermaxBridgeHandler) bridgeHandler;
-                    this.bridgeHandler.registerPanelSettingsListener(this);
-                    onPanelSettingsUpdated(this.bridgeHandler.getPanelSettings());
+                    PowermaxBridgeHandler powermaxBridgeHandler = (PowermaxBridgeHandler) bridgeHandler;
+                    this.bridgeHandler = powermaxBridgeHandler;
+                    powermaxBridgeHandler.registerPanelSettingsListener(this);
+                    onPanelSettingsUpdated(powermaxBridgeHandler.getPanelSettings());
                 } else {
                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, errorMsg);
                 }
@@ -133,8 +134,9 @@ public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPa
     @Override
     public void dispose() {
         logger.debug("Handler disposed for thing {}", getThing().getUID());
-        if (bridgeHandler != null) {
-            bridgeHandler.unregisterPanelSettingsListener(this);
+        PowermaxBridgeHandler powermaxBridgeHandler = bridgeHandler;
+        if (powermaxBridgeHandler != null) {
+            powermaxBridgeHandler.unregisterPanelSettingsListener(this);
         }
         super.dispose();
     }
@@ -143,15 +145,18 @@ public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPa
     public void handleCommand(ChannelUID channelUID, Command command) {
         logger.debug("Received command {} from channel {}", command, channelUID.getId());
 
-        if (bridgeHandler == null) {
+        PowermaxBridgeHandler powermaxBridgeHandler = bridgeHandler;
+        if (powermaxBridgeHandler == null) {
             return;
         } else if (command instanceof RefreshType) {
-            updateChannelFromAlarmState(channelUID.getId(), bridgeHandler.getCurrentState());
+            updateChannelFromAlarmState(channelUID.getId(), powermaxBridgeHandler.getCurrentState());
         } else {
             switch (channelUID.getId()) {
                 case BYPASSED:
                     if (command instanceof OnOffType) {
-                        bridgeHandler.zoneBypassed(getConfigAs(PowermaxZoneConfiguration.class).zoneNumber.byteValue(),
+                        powermaxBridgeHandler.zoneBypassed(
+                                Byte.valueOf(
+                                        (byte) (getConfigAs(PowermaxZoneConfiguration.class).zoneNumber & 0x000000FF)),
                                 command.equals(OnOffType.ON));
                     } else {
                         logger.debug("Command of type {} while OnOffType is expected. Command is ignored.",
@@ -159,7 +164,9 @@ public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPa
                     }
                     break;
                 case X10_STATUS:
-                    bridgeHandler.x10Command(getConfigAs(PowermaxX10Configuration.class).deviceNumber.byteValue(),
+                    powermaxBridgeHandler.x10Command(
+                            Byte.valueOf(
+                                    (byte) (getConfigAs(PowermaxX10Configuration.class).deviceNumber & 0x000000FF)),
                             command);
                     break;
                 default:
@@ -175,13 +182,13 @@ public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPa
      * @param channel: the channel
      * @param state: the alarm system state
      */
-    public void updateChannelFromAlarmState(String channel, PowermaxState state) {
-        if (state == null || channel == null || !isLinked(channel)) {
+    public void updateChannelFromAlarmState(String channel, @Nullable PowermaxState state) {
+        if (state == null || !isLinked(channel)) {
             return;
         }
 
         if (getThing().getThingTypeUID().equals(THING_TYPE_ZONE)) {
-            int num = getConfigAs(PowermaxZoneConfiguration.class).zoneNumber.intValue();
+            int num = getConfigAs(PowermaxZoneConfiguration.class).zoneNumber;
 
             for (Value<?> value : state.getZone(num).getValues()) {
                 String vChannel = value.getChannel();
@@ -191,9 +198,10 @@ public class PowermaxThingHandler extends BaseThingHandler implements PowermaxPa
                 }
             }
         } else if (getThing().getThingTypeUID().equals(THING_TYPE_X10)) {
-            int num = getConfigAs(PowermaxX10Configuration.class).deviceNumber.intValue();
-            if (channel.equals(X10_STATUS) && (state.getPGMX10DeviceStatus(num) != null)) {
-                updateState(X10_STATUS, state.getPGMX10DeviceStatus(num) ? OnOffType.ON : OnOffType.OFF);
+            int num = getConfigAs(PowermaxX10Configuration.class).deviceNumber;
+            Boolean status = state.getPGMX10DeviceStatus(num);
+            if (channel.equals(X10_STATUS) && (status != null)) {
+                updateState(X10_STATUS, status ? OnOffType.ON : OnOffType.OFF);
             }
         }
     }
index c17598bd1ccadf1182678b423b4c16352e821922..33c088be5ab2fe74da3a3f2a71b199bb468d6f95 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 
 /**
@@ -19,6 +21,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxAckMessage extends PowermaxBaseMessage {
 
     /**
@@ -32,14 +35,15 @@ public class PowermaxAckMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
 
         PowermaxState updatedState = null;
 
-        if (commManager.getLastSendMsg().getSendType() == PowermaxSendType.EXIT) {
+        PowermaxBaseMessage lastSendMsg = commManager.getLastSendMsg();
+        if (lastSendMsg != null && lastSendMsg.getSendType() == PowermaxSendType.EXIT) {
             updatedState = commManager.createNewState();
             updatedState.powerlinkMode.setValue(true);
             updatedState.downloadMode.setValue(false);
index 334b3a39acfa55c39cddd1df5a472085f1714f45..1a026eeb19c91c470dbc0b5f239d5cde19158e3f 100644 (file)
@@ -12,6 +12,7 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 import org.openhab.core.util.HexUtils;
@@ -23,14 +24,15 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxBaseMessage {
 
     private final Logger logger = LoggerFactory.getLogger(PowermaxBaseMessage.class);
 
-    private byte[] rawData;
+    private final byte[] rawData;
     private int code;
-    private PowermaxSendType sendType;
-    private PowermaxReceiveType receiveType;
+    private @Nullable PowermaxSendType sendType;
+    private @Nullable PowermaxReceiveType receiveType;
     private Object messageType;
 
     /**
@@ -39,9 +41,9 @@ public class PowermaxBaseMessage {
      * @param message the message as a buffer of bytes
      */
     public PowermaxBaseMessage(byte[] message) {
-        this.sendType = null;
+        this.rawData = message;
         this.messageType = "UNKNOWN";
-        decodeMessage(message);
+        decodeMessage();
     }
 
     /**
@@ -59,40 +61,41 @@ public class PowermaxBaseMessage {
      * @param sendType the type of a message to be sent
      * @param param the dynamic part of a message to be sent; null if no dynamic part
      */
-    public PowermaxBaseMessage(PowermaxSendType sendType, byte[] param) {
+    public PowermaxBaseMessage(PowermaxSendType sendType, byte @Nullable [] param) {
         this.sendType = sendType;
         this.messageType = "UNKNOWN";
-        byte[] message = new byte[sendType.getMessage().length + 3];
+        this.rawData = new byte[sendType.getMessage().length + 3];
         int index = 0;
-        message[index++] = 0x0D;
+        rawData[index++] = 0x0D;
         for (int i = 0; i < sendType.getMessage().length; i++) {
-            if ((param != null) && (sendType.getParamPosition() != null) && (i >= sendType.getParamPosition())
-                    && (i < (sendType.getParamPosition() + param.length))) {
-                message[index++] = param[i - sendType.getParamPosition()];
+            Integer paramPosition = sendType.getParamPosition();
+            if ((param != null) && (paramPosition != null) && (i >= paramPosition)
+                    && (i < (paramPosition + param.length))) {
+                rawData[index++] = param[i - paramPosition];
             } else {
-                message[index++] = sendType.getMessage()[i];
+                rawData[index++] = sendType.getMessage()[i];
             }
         }
-        message[index++] = 0x00;
-        message[index++] = 0x0A;
-        decodeMessage(message);
+        rawData[index++] = 0x00;
+        rawData[index++] = 0x0A;
+        decodeMessage();
     }
 
     /**
      * Extract information from the buffer of bytes and set class attributes
-     *
-     * @param data the message as a buffer of bytes
      */
-    private void decodeMessage(byte[] data) {
-        rawData = data;
+    private void decodeMessage() {
         code = rawData[1] & 0x000000FF;
+        PowermaxReceiveType localReceiveType;
         try {
-            receiveType = PowermaxReceiveType.fromCode((byte) code);
+            localReceiveType = PowermaxReceiveType.fromCode((byte) code);
         } catch (IllegalArgumentException e) {
-            receiveType = null;
+            localReceiveType = null;
         }
+        receiveType = localReceiveType;
 
-        messageType = sendType != null ? sendType : receiveType != null ? receiveType : "UNKNOWN";
+        PowermaxSendType localSendType = sendType;
+        messageType = localSendType != null ? localSendType : localReceiveType != null ? localReceiveType : "UNKNOWN";
     }
 
     /**
@@ -100,7 +103,7 @@ public class PowermaxBaseMessage {
      *
      * @return a new state containing all changes driven by the message
      */
-    public final PowermaxState handleMessage(PowermaxCommManager commManager) {
+    public final @Nullable PowermaxState handleMessage(@Nullable PowermaxCommManager commManager) {
         // Send an ACK if needed
         if (isAckRequired() && commManager != null) {
             commManager.sendAck(this, (byte) 0x02);
@@ -119,7 +122,7 @@ public class PowermaxBaseMessage {
         return newState;
     }
 
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         return null;
     }
 
@@ -140,18 +143,18 @@ public class PowermaxBaseMessage {
     /**
      * @return the type of the message to be sent
      */
-    public PowermaxSendType getSendType() {
+    public @Nullable PowermaxSendType getSendType() {
         return sendType;
     }
 
-    public void setSendType(PowermaxSendType sendType) {
+    public void setSendType(@Nullable PowermaxSendType sendType) {
         this.sendType = sendType;
     }
 
     /**
      * @return the type of the received message
      */
-    public PowermaxReceiveType getReceiveType() {
+    public @Nullable PowermaxReceiveType getReceiveType() {
         return receiveType;
     }
 
@@ -159,7 +162,8 @@ public class PowermaxBaseMessage {
      * @return true if the received message requires the sending of an ACK
      */
     public boolean isAckRequired() {
-        return receiveType == null || receiveType.isAckRequired();
+        PowermaxReceiveType localReceiveType = receiveType;
+        return localReceiveType == null || localReceiveType.isAckRequired();
     }
 
     // Debugging helpers
index 175f6879d1c53c020fe8c76ad7c6c35b84d240b5..8de02e3c91873640a0cb03a8d9f5f484e74b2f8f 100644 (file)
@@ -23,6 +23,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.connector.PowermaxConnector;
 import org.openhab.binding.powermax.internal.connector.PowermaxSerialConnector;
 import org.openhab.binding.powermax.internal.connector.PowermaxTcpConnector;
@@ -49,47 +51,49 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxCommManager implements PowermaxMessageEventListener {
 
-    private final Logger logger = LoggerFactory.getLogger(PowermaxCommManager.class);
-
     private static final int DEFAULT_TCP_PORT = 80;
     private static final int TCP_CONNECTION_TIMEOUT = 5000;
     private static final int DEFAULT_BAUD_RATE = 9600;
     private static final int WAITING_DELAY_FOR_RESPONSE = 750;
     private static final long DELAY_BETWEEN_SETUP_DOWNLOADS = TimeUnit.SECONDS.toMillis(45);
 
+    private final Logger logger = LoggerFactory.getLogger(PowermaxCommManager.class);
+
     private final ScheduledExecutorService scheduler;
 
+    private final TimeZoneProvider timeZoneProvider;
+
     /** The object to store the current settings of the Powermax alarm system */
-    private PowermaxPanelSettings panelSettings;
+    private final PowermaxPanelSettings panelSettings;
 
     /** Panel type used when in standard mode */
-    private PowermaxPanelType panelType;
+    private final PowermaxPanelType panelType;
 
-    private boolean forceStandardMode;
-    private boolean autoSyncTime;
-    private final TimeZoneProvider timeZoneProvider;
+    private final boolean forceStandardMode;
+    private final boolean autoSyncTime;
 
-    private List<PowermaxStateEventListener> listeners = new ArrayList<>();
+    private final List<PowermaxStateEventListener> listeners = new ArrayList<>();
 
     /** The serial or TCP connecter used to communicate with the Powermax alarm system */
-    private PowermaxConnector connector;
+    private final PowermaxConnector connector;
 
     /** The last message sent to the the Powermax alarm system */
-    private PowermaxBaseMessage lastSendMsg;
+    private @Nullable PowermaxBaseMessage lastSendMsg;
 
     /** The message queue of messages to be sent to the the Powermax alarm system */
     private ConcurrentLinkedQueue<PowermaxBaseMessage> msgQueue = new ConcurrentLinkedQueue<>();
 
     /** The time in milliseconds the last download of the panel setup was requested */
-    private Long lastTimeDownloadRequested;
+    private long lastTimeDownloadRequested;
 
     /** The boolean indicating if the download of the panel setup is in progress or not */
     private boolean downloadRunning;
 
     /** The time in milliseconds used to set time and date */
-    private Long syncTimeCheck;
+    private long syncTimeCheck;
 
     /**
      * Constructor for Serial Connection
@@ -110,13 +114,8 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
         this.timeZoneProvider = timeZoneProvider;
         this.panelSettings = new PowermaxPanelSettings(panelType);
         this.scheduler = ThreadPoolManager.getScheduledPool(threadName + "-sender");
-        String serialPort = (sPort != null && !sPort.trim().isEmpty()) ? sPort.trim() : null;
-        if (serialPort != null) {
-            connector = new PowermaxSerialConnector(serialPortManager, serialPort, DEFAULT_BAUD_RATE,
-                    threadName + "-reader");
-        } else {
-            connector = null;
-        }
+        this.connector = new PowermaxSerialConnector(serialPortManager, sPort.trim(), DEFAULT_BAUD_RATE,
+                threadName + "-reader");
     }
 
     /**
@@ -138,13 +137,8 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
         this.timeZoneProvider = timeZoneProvider;
         this.panelSettings = new PowermaxPanelSettings(panelType);
         this.scheduler = ThreadPoolManager.getScheduledPool(threadName + "-sender");
-        String ipAddress = (ip != null && !ip.trim().isEmpty()) ? ip.trim() : null;
-        int tcpPort = (port > 0) ? port : DEFAULT_TCP_PORT;
-        if (ipAddress != null) {
-            connector = new PowermaxTcpConnector(ipAddress, tcpPort, TCP_CONNECTION_TIMEOUT, threadName + "-reader");
-        } else {
-            connector = null;
-        }
+        this.connector = new PowermaxTcpConnector(ip.trim(), port > 0 ? port : DEFAULT_TCP_PORT, TCP_CONNECTION_TIMEOUT,
+                threadName + "-reader");
     }
 
     /**
@@ -154,9 +148,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
      */
     public synchronized void addEventListener(PowermaxStateEventListener listener) {
         listeners.add(listener);
-        if (connector != null) {
-            connector.addEventListener(this);
-        }
+        connector.addEventListener(this);
     }
 
     /**
@@ -165,9 +157,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
      * @param listener the listener to be removed
      */
     public synchronized void removeEventListener(PowermaxStateEventListener listener) {
-        if (connector != null) {
-            connector.removeEventListener(this);
-        }
+        connector.removeEventListener(this);
         listeners.remove(listener);
     }
 
@@ -177,9 +167,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
      * @return true if connected or false if not
      */
     public void open() throws Exception {
-        if (connector != null) {
-            connector.open();
-        }
+        connector.open();
         lastSendMsg = null;
         msgQueue = new ConcurrentLinkedQueue<>();
     }
@@ -190,10 +178,8 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
      * @return true if connected or false if not
      */
     public boolean close() {
-        if (connector != null) {
-            connector.close();
-        }
-        lastTimeDownloadRequested = null;
+        connector.close();
+        lastTimeDownloadRequested = 0;
         downloadRunning = false;
         return isConnected();
     }
@@ -202,7 +188,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
      * @return true if connected to the Powermax alarm system or false if not
      */
     public boolean isConnected() {
-        return (connector != null) && connector.isConnected();
+        return connector.isConnected();
     }
 
     /**
@@ -220,7 +206,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
      * @return true if no problem encountered to get all the settings; false if not
      */
     public boolean processPanelSettings(boolean powerlinkMode) {
-        return panelSettings.process(powerlinkMode, panelType, powerlinkMode ? syncTimeCheck : null);
+        return panelSettings.process(powerlinkMode, panelType, powerlinkMode ? syncTimeCheck : 0);
     }
 
     /**
@@ -233,7 +219,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
     /**
      * @return the last message sent to the Powermax alarm system
      */
-    public synchronized PowermaxBaseMessage getLastSendMsg() {
+    public synchronized @Nullable PowermaxBaseMessage getLastSendMsg() {
         return lastSendMsg;
     }
 
@@ -261,8 +247,9 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
 
         updateState.lastMessageTime.setValue(System.currentTimeMillis());
 
-        if (updateState.getUpdateSettings() != null) {
-            panelSettings.updateRawSettings(updateState.getUpdateSettings());
+        byte[] buffer = updateState.getUpdateSettings();
+        if (buffer != null) {
+            panelSettings.updateRawSettings(buffer);
         }
         if (!updateState.getUpdatedZoneNames().isEmpty()) {
             for (Integer zoneIdx : updateState.getUpdatedZoneNames().keySet()) {
@@ -349,7 +336,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
         boolean done = false;
         if (!armMode.isAllowedCommand()) {
             logger.debug("Powermax alarm binding: requested arm mode {} rejected", armMode.getShortName());
-        } else if ((pinCode == null) || (pinCode.length() != 4)) {
+        } else if (pinCode.length() != 4) {
             logger.debug("Powermax alarm binding: requested arm mode {} rejected due to invalid PIN code",
                     armMode.getShortName());
         } else {
@@ -376,7 +363,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
      *
      * @return true if the message was sent or false if not
      */
-    public boolean sendPGMX10(Command action, Byte device) {
+    public boolean sendPGMX10(Command action, @Nullable Byte device) {
         logger.debug("sendPGMX10(): action = {}, device = {}", action, device);
 
         boolean done = false;
@@ -418,7 +405,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
 
         boolean done = false;
 
-        if ((pinCode == null) || (pinCode.length() != 4)) {
+        if (pinCode.length() != 4) {
             logger.debug("Powermax alarm binding: zone bypass rejected due to invalid PIN code");
         } else if ((zone < 1) || (zone > panelSettings.getNbZones())) {
             logger.debug("Powermax alarm binding: invalid zone number: {}", zone);
@@ -483,10 +470,10 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
             } else {
                 logger.info(
                         "Powermax alarm binding: time not synchronized; please correct the date/time of your openHAB server");
-                syncTimeCheck = null;
+                syncTimeCheck = 0;
             }
         } else {
-            syncTimeCheck = null;
+            syncTimeCheck = 0;
         }
         return done;
     }
@@ -503,7 +490,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
 
         boolean done = false;
 
-        if ((pinCode == null) || (pinCode.length() != 4)) {
+        if (pinCode.length() != 4) {
             logger.debug("Powermax alarm binding: requested event log rejected due to invalid PIN code");
         } else {
             try {
@@ -543,7 +530,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
 
     public void retryDownloadSetup(int remainingAttempts) {
         long now = System.currentTimeMillis();
-        if ((remainingAttempts > 0) && !isDownloadRunning() && ((lastTimeDownloadRequested == null)
+        if ((remainingAttempts > 0) && !isDownloadRunning() && ((lastTimeDownloadRequested == 0)
                 || ((now - lastTimeDownloadRequested) >= DELAY_BETWEEN_SETUP_DOWNLOADS))) {
             // We wait at least 45 seconds before each retry to download the panel setup
             logger.debug("Powermax alarm binding: try again downloading setup");
@@ -569,9 +556,9 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
     }
 
     /**
-     * @return the time in milliseconds the last download of the panel setup was requested or null if not yet requested
+     * @return the time in milliseconds the last download of the panel setup was requested or 0 if not yet requested
      */
-    public Long getLastTimeDownloadRequested() {
+    public long getLastTimeDownloadRequested() {
         return lastTimeDownloadRequested;
     }
 
@@ -607,7 +594,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
         return sendMessage(new PowermaxBaseMessage(msgType), false, waitTime);
     }
 
-    private synchronized boolean sendMessage(PowermaxBaseMessage msg, boolean immediate, int waitTime) {
+    private synchronized boolean sendMessage(@Nullable PowermaxBaseMessage msg, boolean immediate, int waitTime) {
         return sendMessage(msg, immediate, waitTime, false);
     }
 
@@ -622,7 +609,7 @@ public class PowermaxCommManager implements PowermaxMessageEventListener {
      * @return true if the message was sent or the sending is delayed; false in other cases
      */
     @SuppressWarnings("PMD.CompareObjectsWithEquals")
-    private synchronized boolean sendMessage(PowermaxBaseMessage msg, boolean immediate, int waitTime,
+    private synchronized boolean sendMessage(@Nullable PowermaxBaseMessage msg, boolean immediate, int waitTime,
             boolean doNotLog) {
         if ((waitTime > 0) && (msg != null)) {
             logger.debug("sendMessage(): delay ({} s) sending message (type {})", waitTime, msg.getSendType());
index 52593acc572b453af4b545184d3d7668a13f2e0f..743e51c776d3e3363ef225643489324afb288921 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -21,6 +23,7 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxDeniedMessage extends PowermaxBaseMessage {
 
     private final Logger logger = LoggerFactory.getLogger(PowermaxDeniedMessage.class);
@@ -36,14 +39,15 @@ public class PowermaxDeniedMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
 
         PowermaxState updatedState = null;
 
-        PowermaxSendType lastSendType = commManager.getLastSendMsg().getSendType();
+        PowermaxBaseMessage lastSendMsg = commManager.getLastSendMsg();
+        PowermaxSendType lastSendType = lastSendMsg == null ? null : lastSendMsg.getSendType();
         if (lastSendType == PowermaxSendType.EVENTLOG || lastSendType == PowermaxSendType.ARM
                 || lastSendType == PowermaxSendType.BYPASS) {
             logger.debug("Powermax alarm binding: invalid PIN code");
index a63ae123ed0bf9cf75069280c70f6c4307258f8f..26d92cfce82fea17279677fa856e3286fa636dd5 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 
 /**
@@ -19,6 +21,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxDownloadRetryMessage extends PowermaxBaseMessage {
 
     /**
@@ -32,7 +35,7 @@ public class PowermaxDownloadRetryMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 05180eeacb62b8e4c325b42852e046b383a98c97..8d30ff1b05efb2d0c8d643d4d6b15b16821be4c7 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxPanelSettings;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 
@@ -20,6 +22,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxEventLogMessage extends PowermaxBaseMessage {
 
     /**
@@ -33,7 +36,7 @@ public class PowermaxEventLogMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 7d6bb8c8196400bd501c81b18ce5599261df9275..8bda7f452c1fc37a4ada131e074225786f054ed8 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxPanelType;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 import org.slf4j.Logger;
@@ -22,6 +24,7 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxInfoMessage extends PowermaxBaseMessage {
 
     private final Logger logger = LoggerFactory.getLogger(PowermaxInfoMessage.class);
@@ -37,7 +40,7 @@ public class PowermaxInfoMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 25592e57ff024f01bb4c2c164a902f91a9c29e85..f1bec2160f1093bb6f7473da11cf12d9761b427f 100644 (file)
@@ -16,11 +16,14 @@ import static java.util.Map.entry;
 
 import java.util.Map;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Constants used in Powermax messages
  *
  * @author Ron Isaacson - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxMessageConstants {
 
     private PowermaxMessageConstants() {
index 77e282f5382aedcd336e78d56179b5030102c190..6456a8b43678416561324acab0a7d87f62290179 100644 (file)
@@ -14,15 +14,18 @@ package org.openhab.binding.powermax.internal.message;
 
 import java.util.EventObject;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Event for messages received from the Visonic alarm panel
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxMessageEvent extends EventObject {
 
     private static final long serialVersionUID = 1L;
-    private PowermaxBaseMessage message;
+    private final PowermaxBaseMessage message;
 
     public PowermaxMessageEvent(Object source, PowermaxBaseMessage message) {
         super(source);
index ce13ad2293ad8dd6b2d370e87d1891ab90559697..23e35c3df44b12eeb7ebb16df6e1018e70e5fb61 100644 (file)
@@ -15,11 +15,14 @@ package org.openhab.binding.powermax.internal.message;
 import java.util.EventListener;
 import java.util.EventObject;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Powermax Alarm Event Listener interface. Handles incoming Powermax Alarm message events
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public interface PowermaxMessageEventListener extends EventListener {
 
     /**
index 711570374c0526e41d1c37cac5e4aced95f2bcd3..e031443e96b6ecdc38af7b9d2b6bcfe7843fc349 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.message.PowermaxMessageConstants.PowermaxSysEvent;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 
@@ -20,6 +22,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxPanelMessage extends PowermaxBaseMessage {
 
     /**
@@ -33,7 +36,7 @@ public class PowermaxPanelMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 5eb286a455f82ded7558a2c49fa561c04d42fd6a..265ffbea6b09c4175681a3264131dfda31102d2d 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 
 /**
@@ -19,6 +21,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxPowerMasterMessage extends PowermaxBaseMessage {
 
     /**
@@ -32,7 +35,7 @@ public class PowermaxPowerMasterMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 795b22ae8b9d4742624babc07a4d957746b4003f..7da22fbce02d1b648ef69ed84cd1d0c46a5f20a3 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -21,6 +23,7 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxPowerlinkMessage extends PowermaxBaseMessage {
 
     private final Logger logger = LoggerFactory.getLogger(PowermaxPowerlinkMessage.class);
@@ -36,7 +39,7 @@ public class PowermaxPowerlinkMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index da7c6072f5604697c1d583b78f7ef80546549835..1e5bfaf95634964437dbca36aa96d5565ad0e414 100644 (file)
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Used to map received messages from the Visonic alarm panel to a ENUM value
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public enum PowermaxReceiveType {
 
     ACK((byte) 0x02, 0, false),
@@ -36,9 +39,9 @@ public enum PowermaxReceiveType {
     POWERMASTER((byte) 0xB0, 0, true),
     F1((byte) 0xF1, 9, false);
 
-    private byte code;
-    private int length;
-    private boolean ackRequired;
+    private final byte code;
+    private final int length;
+    private final boolean ackRequired;
 
     private PowermaxReceiveType(byte code, int length, boolean ackRequired) {
         this.code = code;
index 27dbc2d780e01cf09333b625006d02c2c1db63d7..a218bbc5530f5b540aaa72ad5bc1a09f920ff60a 100644 (file)
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
 /**
  * Used to map messages to be sent to the Visonic alarm panel to a ENUM value
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public enum PowermaxSendType {
 
     INIT(new byte[] { (byte) 0xAB, 0x0A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, null, null),
@@ -107,11 +111,12 @@ public enum PowermaxSendType {
     POWERMASTER_ZONE_TYPE1(new byte[] { (byte) 0xB0, 0x01, 0x2D, 0x02, 0x05, 0x00, 0x43 }, null,
             PowermaxReceiveType.POWERMASTER);
 
-    private byte[] message;
-    private Integer paramPosition;
-    private PowermaxReceiveType expectedResponseType;
+    private final byte[] message;
+    private final @Nullable Integer paramPosition;
+    private final @Nullable PowermaxReceiveType expectedResponseType;
 
-    private PowermaxSendType(byte[] message, Integer paramPosition, PowermaxReceiveType expectedResponseType) {
+    private PowermaxSendType(byte[] message, @Nullable Integer paramPosition,
+            @Nullable PowermaxReceiveType expectedResponseType) {
         this.message = message;
         this.paramPosition = paramPosition;
         this.expectedResponseType = expectedResponseType;
@@ -127,14 +132,14 @@ public enum PowermaxSendType {
     /**
      * @return the position of the parameter in the message buffer
      */
-    public Integer getParamPosition() {
+    public @Nullable Integer getParamPosition() {
         return paramPosition;
     }
 
     /**
      * @return the ENUM value of the expected message as response
      */
-    public PowermaxReceiveType getExpectedResponseType() {
+    public @Nullable PowermaxReceiveType getExpectedResponseType() {
         return expectedResponseType;
     }
 }
index 2ec2f26a5591cc2b6c5b6e812bb7a0ff22697c00..7135e61b82be2bfcaae39e9875f53c8260f88026 100644 (file)
@@ -14,6 +14,8 @@ package org.openhab.binding.powermax.internal.message;
 
 import java.util.Arrays;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -23,6 +25,7 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxSettingsMessage extends PowermaxBaseMessage {
 
     private final Logger logger = LoggerFactory.getLogger(PowermaxSettingsMessage.class);
@@ -38,7 +41,7 @@ public class PowermaxSettingsMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 24c5e65eabe890d1013e6821f1b5edb2f143f227..3a966ccdea5d49ff7246d22d24b78c8a31387d51 100644 (file)
@@ -16,6 +16,8 @@ import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxArmMode;
 import org.openhab.binding.powermax.internal.state.PowermaxPanelSettings;
 import org.openhab.binding.powermax.internal.state.PowermaxSensorType;
@@ -27,6 +29,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxZoneSettings;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxStatusMessage extends PowermaxBaseMessage {
 
     private static byte[] zoneBytes(byte zones1, byte zones9, byte zones17, byte zones25) {
@@ -68,7 +71,7 @@ public class PowermaxStatusMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 9fd572bc807c010981b9901222b1595376171554..55f39bc0b7b038adeee3931021d84cd6f87c5e18 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 
 /**
@@ -19,6 +21,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxTimeoutMessage extends PowermaxBaseMessage {
 
     /**
@@ -32,7 +35,7 @@ public class PowermaxTimeoutMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager != null) {
             commManager.sendMessage(PowermaxSendType.EXIT);
         }
index dfede05dc28299bb67da64fcba045525be771e16..5999611b0f9710804bde6a046b4cc136b489bd19 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 
 /**
@@ -19,6 +21,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxZonesNameMessage extends PowermaxBaseMessage {
 
     /**
@@ -32,7 +35,7 @@ public class PowermaxZonesNameMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 39067405078becb2c3aafde3dbe76a23ee6e9761..21115c288153d99630ca204b2bfb1160065d1481 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.powermax.internal.message;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.state.PowermaxState;
 
 /**
@@ -19,6 +21,7 @@ import org.openhab.binding.powermax.internal.state.PowermaxState;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxZonesTypeMessage extends PowermaxBaseMessage {
 
     /**
@@ -32,7 +35,7 @@ public class PowermaxZonesTypeMessage extends PowermaxBaseMessage {
     }
 
     @Override
-    protected PowermaxState handleMessageInternal(PowermaxCommManager commManager) {
+    protected @Nullable PowermaxState handleMessageInternal(@Nullable PowermaxCommManager commManager) {
         if (commManager == null) {
             return null;
         }
index 7ca7347a4438893c286543f7cf6afd5eeeb9f0c0..16d883cc3dd174e2b905eaeb83cf7b61f07f281f 100644 (file)
  */
 package org.openhab.binding.powermax.internal.state;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * All defined sensor types for Master panels
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public enum PowermasterSensorType {
 
     SENSOR_TYPE_1((byte) 0x01, "Motion"),
@@ -26,8 +29,8 @@ public enum PowermasterSensorType {
     SENSOR_TYPE_5((byte) 0x2A, "Magnet"),
     SENSOR_TYPE_6((byte) 0xFE, "Wired");
 
-    private byte code;
-    private String label;
+    private final byte code;
+    private final String label;
 
     private PowermasterSensorType(byte code, String label) {
         this.code = code;
index 751ec5c77328837b43de163a342e72b0869192db..acf8174719e2335477464d57bf5bc86dd503c329 100644 (file)
  */
 package org.openhab.binding.powermax.internal.state;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * All defined arm modes
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public enum PowermaxArmMode {
 
     DISARMED(0, "Disarmed", "Disarmed", false, (byte) 0x00, false),
@@ -42,11 +45,11 @@ public enum PowermaxArmMode {
     ARMED_HOME_INSTANT(20, "Armed Home Instant", "StayInstant", true, (byte) 0x14, false),
     ARMED_AWAY_INSTANT(21, "Armed Away Instant", "ArmedInstant", true, (byte) 0x15, false);
 
-    private int code;
-    private String name;
-    private String shortName;
-    private boolean armed;
-    private byte commandCode;
+    private final int code;
+    private final String name;
+    private final String shortName;
+    private final boolean armed;
+    private final byte commandCode;
     private boolean allowedCommand;
 
     private PowermaxArmMode(int code, String name, String shortName, boolean armed, byte commandCode,
index 8fed886270c88fee7c0b818b4cf34e5defadb6f8..ba4ef1f5394bd82c0a4c8228a5e99cfee17342b0 100644 (file)
@@ -18,6 +18,8 @@ import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.stream.IntStream;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.message.PowermaxMessageConstants;
 import org.openhab.binding.powermax.internal.message.PowermaxSendType;
 import org.slf4j.Logger;
@@ -28,13 +30,14 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxPanelSettings {
 
-    private final Logger logger = LoggerFactory.getLogger(PowermaxPanelSettings.class);
-
     /** Number of PGM and X10 devices managed by the system */
     private static final int NB_PGM_X10_DEVICES = 16;
 
+    private final Logger logger = LoggerFactory.getLogger(PowermaxPanelSettings.class);
+
     /** Raw buffers for settings */
     private Byte[][] rawSettings;
 
@@ -45,15 +48,15 @@ public class PowermaxPanelSettings {
     private boolean quickArm;
     private boolean bypassEnabled;
     private boolean partitionsEnabled;
-    private String[] pinCodes;
-    private String panelEprom;
-    private String panelSoftware;
-    private String panelSerial;
+    private String @Nullable [] pinCodes;
+    private @Nullable String panelEprom;
+    private @Nullable String panelSoftware;
+    private @Nullable String panelSerial;
     private PowermaxZoneSettings[] zoneSettings;
     private PowermaxX10Settings[] x10Settings;
-    private boolean[] keypad1wEnrolled;
-    private boolean[] keypad2wEnrolled;
-    private boolean[] sirensEnrolled;
+    private boolean @Nullable [] keypad1wEnrolled;
+    private boolean @Nullable [] keypad2wEnrolled;
+    private boolean @Nullable [] sirensEnrolled;
 
     /**
      * Constructor
@@ -108,21 +111,21 @@ public class PowermaxPanelSettings {
     /**
      * @return the panel EEPROM version
      */
-    public String getPanelEprom() {
+    public @Nullable String getPanelEprom() {
         return panelEprom;
     }
 
     /**
      * @return the panel software version
      */
-    public String getPanelSoftware() {
+    public @Nullable String getPanelSoftware() {
         return panelSoftware;
     }
 
     /**
      * @return the panel serial ID
      */
-    public String getPanelSerial() {
+    public @Nullable String getPanelSerial() {
         return panelSerial;
     }
 
@@ -147,7 +150,7 @@ public class PowermaxPanelSettings {
      *
      * @return the settings of the zone
      */
-    public PowermaxZoneSettings getZoneSettings(int zone) {
+    public @Nullable PowermaxZoneSettings getZoneSettings(int zone) {
         return ((zone < 1) || (zone > zoneSettings.length)) ? null : zoneSettings[zone - 1];
     }
 
@@ -158,7 +161,7 @@ public class PowermaxPanelSettings {
      *
      * @return the name of the zone
      */
-    public String getZoneName(int zone) {
+    public @Nullable String getZoneName(int zone) {
         PowermaxZoneSettings zoneSettings = getZoneSettings(zone);
         return (zoneSettings == null) ? null : zoneSettings.getName();
     }
@@ -204,7 +207,7 @@ public class PowermaxPanelSettings {
      *
      * @return the settings of the X10 device
      */
-    public PowermaxX10Settings getX10Settings(int idx) {
+    public @Nullable PowermaxX10Settings getX10Settings(int idx) {
         return ((idx < 1) || (idx >= x10Settings.length)) ? null : x10Settings[idx];
     }
 
@@ -214,8 +217,9 @@ public class PowermaxPanelSettings {
      * @return true if the 1 way keypad is enrolled; false if not
      */
     public boolean isKeypad1wEnrolled(int idx) {
-        return ((keypad1wEnrolled == null) || (idx < 1) || (idx >= keypad1wEnrolled.length)) ? false
-                : keypad1wEnrolled[idx - 1];
+        boolean @Nullable [] localKeypad1wEnrolled = keypad1wEnrolled;
+        return ((localKeypad1wEnrolled == null) || (idx < 1) || (idx >= localKeypad1wEnrolled.length)) ? false
+                : localKeypad1wEnrolled[idx - 1];
     }
 
     /**
@@ -224,8 +228,9 @@ public class PowermaxPanelSettings {
      * @return true if the 2 way keypad is enrolled; false if not
      */
     public boolean isKeypad2wEnrolled(int idx) {
-        return ((keypad2wEnrolled == null) || (idx < 1) || (idx >= keypad2wEnrolled.length)) ? false
-                : keypad2wEnrolled[idx - 1];
+        boolean @Nullable [] localKeypad2wEnrolled = keypad2wEnrolled;
+        return ((localKeypad2wEnrolled == null) || (idx < 1) || (idx >= localKeypad2wEnrolled.length)) ? false
+                : localKeypad2wEnrolled[idx - 1];
     }
 
     /**
@@ -234,19 +239,21 @@ public class PowermaxPanelSettings {
      * @return true if the siren is enrolled; false if not
      */
     public boolean isSirenEnrolled(int idx) {
-        return ((sirensEnrolled == null) || (idx < 1) || (idx >= sirensEnrolled.length)) ? false
-                : sirensEnrolled[idx - 1];
+        boolean @Nullable [] localSirensEnrolled = sirensEnrolled;
+        return ((localSirensEnrolled == null) || (idx < 1) || (idx >= localSirensEnrolled.length)) ? false
+                : localSirensEnrolled[idx - 1];
     }
 
     /**
-     * @return the PIN code of the first user of null if unknown (standard mode)
+     * @return the PIN code of the first user of an empty string if unknown (standard mode)
      */
     public String getFirstPinCode() {
-        return (pinCodes == null) ? null : pinCodes[0];
+        String @Nullable [] localPinCodes = pinCodes;
+        return (localPinCodes == null || localPinCodes.length == 0) ? "" : localPinCodes[0];
     }
 
     public void updateRawSettings(byte[] data) {
-        if ((data == null) || (data.length < 3)) {
+        if (data.length < 3) {
             return;
         }
         int start = 0;
@@ -276,14 +283,14 @@ public class PowermaxPanelSettings {
         }
     }
 
-    private byte[] readSettings(PowermaxSendType msgType, int start, int end) {
+    private byte @Nullable [] readSettings(PowermaxSendType msgType, int start, int end) {
         byte[] message = msgType.getMessage();
         int page = message[2] & 0x000000FF;
         int index = message[1] & 0x000000FF;
         return readSettings(page, index + start, index + end);
     }
 
-    private byte[] readSettings(int page, int start, int end) {
+    private byte @Nullable [] readSettings(int page, int start, int end) {
         int pageMin = page + start / 0x100;
         int indexPageMin = start % 0x100;
         int pageMax = page + end / 0x100;
@@ -332,7 +339,7 @@ public class PowermaxPanelSettings {
         return result;
     }
 
-    private String readSettingsAsString(PowermaxSendType msgType, int start, int end) {
+    private @Nullable String readSettingsAsString(PowermaxSendType msgType, int start, int end) {
         byte[] message = msgType.getMessage();
         int page = message[2] & 0x000000FF;
         int index = message[1] & 0x000000FF;
@@ -381,12 +388,11 @@ public class PowermaxPanelSettings {
      *
      * @param PowerlinkMode true if in Powerlink mode or false if in standard mode
      * @param defaultPanelType the default panel type to consider if not found in the raw buffers
-     * @param timeSet the time in milliseconds used to set time and date; null if no sync time requested
+     * @param timeSet the time in milliseconds used to set time and date; 0 if no sync time requested
      *
      * @return true if no problem encountered to get all the settings; false if not
      */
-    @SuppressWarnings("null")
-    public boolean process(boolean PowerlinkMode, PowermaxPanelType defaultPanelType, Long timeSet) {
+    public boolean process(boolean PowerlinkMode, PowermaxPanelType defaultPanelType, long timeSet) {
         logger.debug("Process settings Powerlink {}", PowerlinkMode);
 
         boolean result = true;
@@ -424,15 +430,15 @@ public class PowermaxPanelSettings {
         quickArm = false;
         bypassEnabled = false;
         partitionsEnabled = false;
-        pinCodes = new String[userCnt];
+        String[] localPinCodes = new String[userCnt];
         panelEprom = null;
         panelSoftware = null;
         panelSerial = null;
         zoneSettings = new PowermaxZoneSettings[zoneCnt];
         x10Settings = new PowermaxX10Settings[NB_PGM_X10_DEVICES];
-        keypad1wEnrolled = new boolean[keypad1wCnt];
-        keypad2wEnrolled = new boolean[keypad2wCnt];
-        sirensEnrolled = new boolean[sirenCnt];
+        boolean[] localKeypad1wEnrolled = new boolean[keypad1wCnt];
+        boolean[] localKeypad2wEnrolled = new boolean[keypad2wCnt];
+        boolean[] localSirensEnrolled = new boolean[sirenCnt];
 
         if (PowerlinkMode) {
             // Check time and date
@@ -453,7 +459,7 @@ public class PowermaxPanelSettings {
                                 cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)));
 
                 // Check if time sync was OK
-                if (timeSet != null) {
+                if (timeSet > 0) {
                     long delta = (timeRead - timeSet) / 1000;
                     if (delta <= 5) {
                         logger.debug("Powermax alarm binding: time sync OK (delta {} s)", delta);
@@ -528,7 +534,8 @@ public class PowermaxPanelSettings {
                     2 * userCnt - 1);
             if (data != null) {
                 for (int i = 0; i < userCnt; i++) {
-                    pinCodes[i] = String.format("%02X%02X", data[i * 2] & 0x000000FF, data[i * 2 + 1] & 0x000000FF);
+                    localPinCodes[i] = String.format("%02X%02X", data[i * 2] & 0x000000FF,
+                            data[i * 2 + 1] & 0x000000FF);
                 }
             } else {
                 logger.debug("Cannot get PIN codes");
@@ -606,22 +613,26 @@ public class PowermaxPanelSettings {
 
                     boolean zoneEnrolled;
                     byte zoneInfo;
-                    byte sensorTypeCode;
                     String sensorTypeStr;
                     if (panelType.isPowerMaster()) {
-                        zoneEnrolled = !Arrays.equals(Arrays.copyOfRange(dataMr, i * 10 + 4, i * 10 + 9), zero5);
                         zoneInfo = data[i];
-                        sensorTypeCode = dataMr[i * 10 + 5];
-                        try {
-                            PowermasterSensorType sensorType = PowermasterSensorType.fromCode(sensorTypeCode);
-                            sensorTypeStr = sensorType.getLabel();
-                        } catch (IllegalArgumentException e) {
+                        if (dataMr != null) {
+                            zoneEnrolled = !Arrays.equals(Arrays.copyOfRange(dataMr, i * 10 + 4, i * 10 + 9), zero5);
+                            byte sensorTypeCode = dataMr[i * 10 + 5];
+                            try {
+                                PowermasterSensorType sensorType = PowermasterSensorType.fromCode(sensorTypeCode);
+                                sensorTypeStr = sensorType.getLabel();
+                            } catch (IllegalArgumentException e) {
+                                sensorTypeStr = null;
+                            }
+                        } else {
+                            zoneEnrolled = false;
                             sensorTypeStr = null;
                         }
                     } else {
                         zoneEnrolled = !Arrays.equals(Arrays.copyOfRange(data, i * 4, i * 4 + 3), zero3);
                         zoneInfo = data[i * 4 + 3];
-                        sensorTypeCode = data[i * 4 + 2];
+                        byte sensorTypeCode = data[i * 4 + 2];
                         try {
                             PowermaxSensorType sensorType = PowermaxSensorType
                                     .fromCode((byte) (sensorTypeCode & 0x0000000F));
@@ -686,7 +697,8 @@ public class PowermaxPanelSettings {
                     byte[] zero5 = new byte[] { 0, 0, 0, 0, 0 };
 
                     for (int i = 0; i < keypad2wCnt; i++) {
-                        keypad2wEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 10 + 4, i * 10 + 9), zero5);
+                        localKeypad2wEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 10 + 4, i * 10 + 9),
+                                zero5);
                     }
                 } else {
                     logger.debug("Cannot get 2 way keypad settings");
@@ -698,7 +710,8 @@ public class PowermaxPanelSettings {
                     byte[] zero5 = new byte[] { 0, 0, 0, 0, 0 };
 
                     for (int i = 0; i < sirenCnt; i++) {
-                        sirensEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 10 + 4, i * 10 + 9), zero5);
+                        localSirensEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 10 + 4, i * 10 + 9),
+                                zero5);
                     }
                 } else {
                     logger.debug("Cannot get siren settings");
@@ -711,7 +724,7 @@ public class PowermaxPanelSettings {
                     byte[] zero2 = new byte[] { 0, 0 };
 
                     for (int i = 0; i < keypad1wCnt; i++) {
-                        keypad1wEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 4, i * 4 + 2), zero2);
+                        localKeypad1wEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 4, i * 4 + 2), zero2);
                     }
                 } else {
                     logger.debug("Cannot get 1 way keypad settings");
@@ -723,7 +736,7 @@ public class PowermaxPanelSettings {
                     byte[] zero3 = new byte[] { 0, 0, 0 };
 
                     for (int i = 0; i < keypad2wCnt; i++) {
-                        keypad2wEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 4, i * 4 + 3), zero3);
+                        localKeypad2wEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 4, i * 4 + 3), zero3);
                     }
                 } else {
                     logger.debug("Cannot get 2 way keypad settings");
@@ -735,7 +748,7 @@ public class PowermaxPanelSettings {
                     byte[] zero3 = new byte[] { 0, 0, 0 };
 
                     for (int i = 0; i < sirenCnt; i++) {
-                        sirensEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 4, i * 4 + 3), zero3);
+                        localSirensEnrolled[i] = !Arrays.equals(Arrays.copyOfRange(data, i * 4, i * 4 + 3), zero3);
                     }
                 } else {
                     logger.debug("Cannot get siren settings");
@@ -758,6 +771,11 @@ public class PowermaxPanelSettings {
             }
         }
 
+        pinCodes = localPinCodes;
+        keypad1wEnrolled = localKeypad1wEnrolled;
+        keypad2wEnrolled = localKeypad2wEnrolled;
+        sirensEnrolled = localSirensEnrolled;
+
         return result;
     }
 
index 61f1d550682b3355e48c830cba6f1058994c3e90..844d3fab06e163c19096f3b679f5e4d5771b34ca 100644 (file)
  */
 package org.openhab.binding.powermax.internal.state;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Used to store main characteristics of each Visonic alarm panel type in an ENUM
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public enum PowermaxPanelType {
 
     POWERMAX((byte) 0, "PowerMax", 1, 250, 8, 8, 2, 2, 8, 0, 28, 2, 0),
@@ -29,19 +32,19 @@ public enum PowermaxPanelType {
     POWERMASTER_10((byte) 7, "PowerMaster10", 3, 250, 8, 0, 8, 4, 8, 8, 29, 1, 5),
     POWERMASTER_30((byte) 8, "PowerMaster30", 3, 1000, 32, 0, 32, 8, 48, 32, 62, 2, 5);
 
-    private byte code;
-    private String label;
-    private int partitions;
-    private int events;
-    private int keyfobs;
-    private int keypads1w;
-    private int keypads2w;
-    private int sirens;
-    private int userCodes;
-    private int prontags;
-    private int wireless;
-    private int wired;
-    private int customZones;
+    private final byte code;
+    private final String label;
+    private final int partitions;
+    private final int events;
+    private final int keyfobs;
+    private final int keypads1w;
+    private final int keypads2w;
+    private final int sirens;
+    private final int userCodes;
+    private final int prontags;
+    private final int wireless;
+    private final int wired;
+    private final int customZones;
 
     private PowermaxPanelType(byte code, String label, int partitions, int events, int keyfobs, int keypads1w,
             int keypads2w, int sirens, int userCodes, int prontags, int wireless, int wired, int customZones) {
index e873b41063786ec95b547e48420b41a86239569b..bb5d2b092e5d8fa477f9dea4509c69f96bd8ef3c 100644 (file)
  */
 package org.openhab.binding.powermax.internal.state;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * All defined sensor types for all panels except Master panels
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public enum PowermaxSensorType {
 
     MOTION_SENSOR_1((byte) 0x03, "Motion"),
@@ -29,8 +32,8 @@ public enum PowermaxSensorType {
     MOTION_SENSOR_3((byte) 0x0C, "Motion"),
     WIRED_SENSOR((byte) 0x0F, "Wired");
 
-    private byte code;
-    private String label;
+    private final byte code;
+    private final String label;
 
     private PowermaxSensorType(byte code, String label) {
         this.code = code;
index b1273073d0a5a786287bb97860c609c471e80795..c27c26c0e322cc4c564bd6fa019a3438c1f2012b 100644 (file)
@@ -19,11 +19,13 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.powermax.internal.message.PowermaxMessageConstants;
 import org.openhab.core.i18n.TimeZoneProvider;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.StringType;
+import org.openhab.core.types.UnDefType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,6 +34,7 @@ import org.slf4j.LoggerFactory;
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxState extends PowermaxStateContainer {
 
     private final Logger logger = LoggerFactory.getLogger(PowermaxState.class);
@@ -58,19 +61,31 @@ public class PowermaxState extends PowermaxStateContainer {
     public DynamicValue<Boolean> isArmed = new DynamicValue<>(this, SYSTEM_ARMED, () -> {
         return isArmed();
     }, () -> {
-        return isArmed() ? OnOffType.ON : OnOffType.OFF;
+        Boolean isArmed = isArmed();
+        if (isArmed == null) {
+            return UnDefType.NULL;
+        }
+        return isArmed ? OnOffType.ON : OnOffType.OFF;
     });
 
     public DynamicValue<String> panelMode = new DynamicValue<>(this, MODE, () -> {
         return getPanelMode();
     }, () -> {
-        return new StringType(getPanelMode());
+        String mode = getPanelMode();
+        if (mode == null) {
+            return UnDefType.NULL;
+        }
+        return new StringType(mode);
     });
 
     public DynamicValue<String> shortArmMode = new DynamicValue<>(this, ARM_MODE, () -> {
         return getShortArmMode();
     }, () -> {
-        return new StringType(getShortArmMode());
+        String mode = getShortArmMode();
+        if (mode == null) {
+            return UnDefType.NULL;
+        }
+        return new StringType(mode);
     });
 
     public DynamicValue<String> activeAlerts = new DynamicValue<>(this, ACTIVE_ALERTS, () -> {
@@ -82,14 +97,18 @@ public class PowermaxState extends PowermaxStateContainer {
     public DynamicValue<Boolean> pgmStatus = new DynamicValue<>(this, PGM_STATUS, () -> {
         return getPGMX10DeviceStatus(0);
     }, () -> {
-        return getPGMX10DeviceStatus(0) ? OnOffType.ON : OnOffType.OFF;
+        Boolean status = getPGMX10DeviceStatus(0);
+        if (status == null) {
+            return UnDefType.NULL;
+        }
+        return status ? OnOffType.ON : OnOffType.OFF;
     });
 
     private PowermaxPanelSettings panelSettings;
     private PowermaxZoneState[] zones;
     private Boolean[] pgmX10DevicesStatus;
-    private byte[] updateSettings;
-    private String[] eventLog;
+    private byte @Nullable [] updateSettings;
+    private String @Nullable [] eventLog;
     private Map<Integer, Byte> updatedZoneNames;
     private Map<Integer, Integer> updatedZoneInfos;
     private List<PowermaxActiveAlert> activeAlertList;
@@ -163,7 +182,7 @@ public class PowermaxState extends PowermaxStateContainer {
      *
      * @return the status (true or false)
      */
-    public Boolean getPGMX10DeviceStatus(int device) {
+    public @Nullable Boolean getPGMX10DeviceStatus(int device) {
         return ((device < 0) || (device >= pgmX10DevicesStatus.length)) ? null : pgmX10DevicesStatus[device];
     }
 
@@ -173,7 +192,7 @@ public class PowermaxState extends PowermaxStateContainer {
      * @param device the index of the PGM/X10 device (0 s for PGM; for X10 device is index 1)
      * @param status true or false
      */
-    public void setPGMX10DeviceStatus(int device, Boolean status) {
+    public void setPGMX10DeviceStatus(int device, @Nullable Boolean status) {
         if ((device >= 0) && (device < pgmX10DevicesStatus.length)) {
             this.pgmX10DevicesStatus[device] = status;
         }
@@ -184,7 +203,7 @@ public class PowermaxState extends PowermaxStateContainer {
      *
      * @return the raw buffer as a table of bytes
      */
-    public byte[] getUpdateSettings() {
+    public byte @Nullable [] getUpdateSettings() {
         return updateSettings;
     }
 
@@ -203,7 +222,8 @@ public class PowermaxState extends PowermaxStateContainer {
      * @return the number of entries
      */
     public int getEventLogSize() {
-        return (eventLog == null) ? 0 : eventLog.length;
+        String @Nullable [] localEventLog = eventLog;
+        return (localEventLog == null) ? 0 : localEventLog.length;
     }
 
     /**
@@ -222,8 +242,10 @@ public class PowermaxState extends PowermaxStateContainer {
      *
      * @return the entry value (event)
      */
-    public String getEventLog(int index) {
-        return ((index < 1) || (index > getEventLogSize())) ? null : eventLog[index - 1];
+    public @Nullable String getEventLog(int index) {
+        String @Nullable [] localEventLog = eventLog;
+        return ((localEventLog == null) || (index < 1) || (index > getEventLogSize())) ? null
+                : localEventLog[index - 1];
     }
 
     /**
@@ -233,8 +255,9 @@ public class PowermaxState extends PowermaxStateContainer {
      * @param event the entry value (event)
      */
     public void setEventLog(int index, String event) {
-        if ((index >= 1) && (index <= getEventLogSize())) {
-            this.eventLog[index - 1] = event;
+        String @Nullable [] localEventLog = eventLog;
+        if ((localEventLog != null) && (index >= 1) && (index <= getEventLogSize())) {
+            localEventLog[index - 1] = event;
         }
     }
 
@@ -329,7 +352,7 @@ public class PowermaxState extends PowermaxStateContainer {
      *
      * @return either Download or Powerlink or Standard
      */
-    public String getPanelMode() {
+    public @Nullable String getPanelMode() {
         String mode = null;
         if (Boolean.TRUE.equals(downloadMode.getValue())) {
             mode = "Download";
@@ -346,7 +369,7 @@ public class PowermaxState extends PowermaxStateContainer {
      *
      * @return true or false
      */
-    public Boolean isArmed() {
+    public @Nullable Boolean isArmed() {
         return isArmed(armMode.getValue());
     }
 
@@ -357,7 +380,7 @@ public class PowermaxState extends PowermaxStateContainer {
      *
      * @return true or false; null if mode is unexpected
      */
-    private static Boolean isArmed(String armMode) {
+    private static @Nullable Boolean isArmed(@Nullable String armMode) {
         Boolean result = null;
         if (armMode != null) {
             try {
@@ -375,7 +398,7 @@ public class PowermaxState extends PowermaxStateContainer {
      *
      * @return the short description
      */
-    public String getShortArmMode() {
+    public @Nullable String getShortArmMode() {
         return getShortArmMode(armMode.getValue());
     }
 
@@ -386,7 +409,7 @@ public class PowermaxState extends PowermaxStateContainer {
      *
      * @return the short name or null if mode is unexpected
      */
-    private static String getShortArmMode(String armMode) {
+    private static @Nullable String getShortArmMode(@Nullable String armMode) {
         String result = null;
         if (armMode != null) {
             try {
@@ -420,8 +443,8 @@ public class PowermaxState extends PowermaxStateContainer {
         }
 
         for (int i = 0; i < pgmX10DevicesStatus.length; i++) {
-            if ((getPGMX10DeviceStatus(i) != null)
-                    && getPGMX10DeviceStatus(i).equals(otherState.getPGMX10DeviceStatus(i))) {
+            Boolean status = getPGMX10DeviceStatus(i);
+            if ((status != null) && status.equals(otherState.getPGMX10DeviceStatus(i))) {
                 setPGMX10DeviceStatus(i, null);
             }
         }
@@ -462,8 +485,9 @@ public class PowermaxState extends PowermaxStateContainer {
         }
 
         for (int i = 0; i < pgmX10DevicesStatus.length; i++) {
-            if (update.getPGMX10DeviceStatus(i) != null) {
-                setPGMX10DeviceStatus(i, update.getPGMX10DeviceStatus(i));
+            Boolean status = update.getPGMX10DeviceStatus(i);
+            if (status != null) {
+                setPGMX10DeviceStatus(i, status);
             }
         }
 
@@ -480,8 +504,9 @@ public class PowermaxState extends PowermaxStateContainer {
             setEventLogSize(update.getEventLogSize());
         }
         for (int i = 1; i <= getEventLogSize(); i++) {
-            if (update.getEventLog(i) != null) {
-                setEventLog(i, update.getEventLog(i));
+            String log = update.getEventLog(i);
+            if (log != null) {
+                setEventLog(i, log);
             }
         }
 
@@ -495,7 +520,7 @@ public class PowermaxState extends PowermaxStateContainer {
         String str = "Bridge state:";
 
         for (Value<?> value : getValues()) {
-            if ((value.getChannel() != null) && (value.getValue() != null)) {
+            if (value.getValue() != null) {
                 String channel = value.getChannel();
                 String vStr = value.getValue().toString();
                 String state = value.getState().toString();
@@ -508,15 +533,16 @@ public class PowermaxState extends PowermaxStateContainer {
         }
 
         for (int i = 0; i < pgmX10DevicesStatus.length; i++) {
-            if (getPGMX10DeviceStatus(i) != null) {
+            Boolean status = getPGMX10DeviceStatus(i);
+            if (status != null) {
                 str += String.format("\n - %s status = %s", (i == 0) ? "PGM device" : String.format("X10 device %d", i),
-                        getPGMX10DeviceStatus(i) ? "ON" : "OFF");
+                        status ? "ON" : "OFF");
             }
         }
 
         for (int i = 1; i <= zones.length; i++) {
             for (Value<?> value : zones[i - 1].getValues()) {
-                if ((value.getChannel() != null) && (value.getValue() != null)) {
+                if (value.getValue() != null) {
                     String channel = value.getChannel();
                     String vStr = value.getValue().toString();
                     String state = value.getState().toString();
@@ -530,13 +556,13 @@ public class PowermaxState extends PowermaxStateContainer {
         }
 
         for (int i = 1; i <= getEventLogSize(); i++) {
-            if (getEventLog(i) != null) {
-                str += "\n - event log " + i + " = " + getEventLog(i);
+            String log = getEventLog(i);
+            if (log != null) {
+                str += "\n - event log " + i + " = " + log;
             }
         }
 
-        String alarms = getActiveAlerts();
-        str += "\n - active alarms/alerts = " + (alarms == null ? "null" : alarms);
+        str += "\n - active alarms/alerts = " + getActiveAlerts();
 
         return str;
     }
index f5cb70b918a4543036ec73c3d07c7cb0e2668fbb..da69de859ac362072e1614e3b065705f1e597c02 100644 (file)
@@ -18,18 +18,21 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Supplier;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.core.i18n.TimeZoneProvider;
 import org.openhab.core.library.types.DateTimeType;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.StringType;
 import org.openhab.core.types.State;
+import org.openhab.core.types.UnDefType;
 
 /**
  * Base class for extensible state objects
  *
  * @author Ron Isaacson - Initial contribution
  */
+@NonNullByDefault
 public abstract class PowermaxStateContainer {
 
     protected final TimeZoneProvider timeZoneProvider;
@@ -46,7 +49,7 @@ public abstract class PowermaxStateContainer {
             parent.getValues().add(this);
         }
 
-        public T getValue() {
+        public @Nullable T getValue() {
             return value;
         }
 
@@ -67,10 +70,10 @@ public abstract class PowermaxStateContainer {
     }
 
     public class DynamicValue<T> extends Value<T> {
-        Supplier<T> valueFunction;
+        Supplier<@Nullable T> valueFunction;
         Supplier<State> stateFunction;
 
-        public DynamicValue(PowermaxStateContainer parent, String channel, Supplier<T> valueFunction,
+        public DynamicValue(PowermaxStateContainer parent, String channel, Supplier<@Nullable T> valueFunction,
                 Supplier<State> stateFunction) {
             super(parent, channel);
             this.valueFunction = valueFunction;
@@ -80,7 +83,7 @@ public abstract class PowermaxStateContainer {
         // Note: setValue() is still valid, but the saved value will be ignored
 
         @Override
-        public T getValue() {
+        public @Nullable T getValue() {
             return valueFunction.get();
         }
 
@@ -106,7 +109,8 @@ public abstract class PowermaxStateContainer {
 
         @Override
         public State getState() {
-            return value ? trueState : falseState;
+            Boolean val = value;
+            return val == null ? UnDefType.NULL : (val ? trueState : falseState);
         }
     }
 
@@ -117,7 +121,8 @@ public abstract class PowermaxStateContainer {
 
         @Override
         public State getState() {
-            return new StringType(value);
+            String val = value;
+            return val == null ? UnDefType.NULL : new StringType(val);
         }
     }
 
@@ -128,7 +133,11 @@ public abstract class PowermaxStateContainer {
 
         @Override
         public State getState() {
-            ZonedDateTime zoned = ZonedDateTime.ofInstant(Instant.ofEpochMilli(value), timeZoneProvider.getTimeZone());
+            Long val = value;
+            if (val == null) {
+                return UnDefType.NULL;
+            }
+            ZonedDateTime zoned = ZonedDateTime.ofInstant(Instant.ofEpochMilli(val), timeZoneProvider.getTimeZone());
             return new DateTimeType(zoned);
         }
     }
index 3c4a209cf04f65fd6904412afcfe1171be3ffd1b..bcdcf153efd0b259bf997776a93326bd333e4127 100644 (file)
@@ -14,15 +14,18 @@ package org.openhab.binding.powermax.internal.state;
 
 import java.util.EventObject;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Event for state received from the Visonic alarm panel
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxStateEvent extends EventObject {
 
     private static final long serialVersionUID = 1L;
-    private PowermaxState state;
+    private final PowermaxState state;
 
     public PowermaxStateEvent(Object source, PowermaxState state) {
         super(source);
index f4e24abc49947face6e865d2270a48168cc439b3..436a4d932f7f4b791681a50bb6bedab3e817d483 100644 (file)
@@ -15,11 +15,14 @@ package org.openhab.binding.powermax.internal.state;
 import java.util.EventListener;
 import java.util.EventObject;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * Powermax Alarm state Listener interface. Handles Powermax Alarm state events
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public interface PowermaxStateEventListener extends EventListener {
 
     /**
index 6029f2f0985e58c83baa9283b37f72b19dc4b055..61eb9ef8382cc30d3515d1732b7894ab20ee92da 100644 (file)
  */
 package org.openhab.binding.powermax.internal.state;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
 /**
  * A class to store the settings of an X10 device
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxX10Settings {
 
-    private String name;
-    private boolean enabled;
+    private final @Nullable String name;
+    private final boolean enabled;
 
-    public PowermaxX10Settings(String name, boolean enabled) {
+    public PowermaxX10Settings(@Nullable String name, boolean enabled) {
         this.name = name;
         this.enabled = enabled;
     }
@@ -30,7 +34,7 @@ public class PowermaxX10Settings {
     /**
      * @return the name of the X10 device
      */
-    public String getName() {
+    public @Nullable String getName() {
         return name;
     }
 
index 68e00cd2c118211dbd418706aa30eb263b0659ed..0b14de930190467d3bf0426efc685e1bc8119fb4 100644 (file)
  */
 package org.openhab.binding.powermax.internal.state;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
 /**
  * All panel zone names
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public enum PowermaxZoneName {
 
     ZONE_0(0, "Attic"),
@@ -52,7 +55,7 @@ public enum PowermaxZoneName {
     ZONE_30(30, "Custom 5"),
     ZONE_31(31, "Not Installed");
 
-    private int id;
+    private final int id;
     private String name;
 
     private PowermaxZoneName(int id, String name) {
index d5802e5394c61266f92196a03a3bf7baa5ea8187..b454f87626a210b376521244ac58841034ca6310 100644 (file)
  */
 package org.openhab.binding.powermax.internal.state;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
 /**
  * A class to store the settings of a zone
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxZoneSettings {
 
     // Note: PowermaxStatusMessage contains hardcoded references to some of these strings
@@ -27,14 +31,16 @@ public class PowermaxZoneSettings {
 
     private static final String[] ZONE_CHIMES = { "Off", "Melody", "Zone" };
 
-    private String name;
-    private String type;
-    private String chime;
-    private String sensorType;
-    private boolean[] partitions;
+    private final @Nullable String chime;
+    private final boolean[] partitions;
+
+    private @Nullable String name;
+    private @Nullable String type;
+    private @Nullable String sensorType;
     private boolean alwaysInAlarm;
 
-    public PowermaxZoneSettings(String name, byte type, byte chime, String sensorType, boolean[] partitions) {
+    public PowermaxZoneSettings(@Nullable String name, byte type, byte chime, @Nullable String sensorType,
+            boolean[] partitions) {
         this.name = name;
         this.type = ((type & 0x000000FF) < ZONE_TYPES.length) ? ZONE_TYPES[type & 0x000000FF] : null;
         this.chime = ((chime & 0x000000FF) < ZONE_CHIMES.length) ? ZONE_CHIMES[chime & 0x000000FF] : null;
@@ -48,7 +54,8 @@ public class PowermaxZoneSettings {
      * @return the zone name
      */
     public String getName() {
-        return (name == null) ? "Unknown" : name;
+        String localName = name;
+        return (localName == null) ? "Unknown" : localName;
     }
 
     /**
@@ -56,7 +63,7 @@ public class PowermaxZoneSettings {
      *
      * @param name the zone name
      */
-    public void setName(String name) {
+    public void setName(@Nullable String name) {
         this.name = name;
     }
 
@@ -64,7 +71,8 @@ public class PowermaxZoneSettings {
      * @return the zone type
      */
     public String getType() {
-        return (type == null) ? "Unknown" : type;
+        String localType = type;
+        return (localType == null) ? "Unknown" : localType;
     }
 
     /**
@@ -79,14 +87,16 @@ public class PowermaxZoneSettings {
     }
 
     public String getChime() {
-        return (chime == null) ? "Unknown" : chime;
+        String localChime = chime;
+        return (localChime == null) ? "Unknown" : localChime;
     }
 
     /**
      * @return the sensor type of this zone
      */
     public String getSensorType() {
-        return (sensorType == null) ? "Unknown" : sensorType;
+        String localSensorType = sensorType;
+        return (localSensorType == null) ? "Unknown" : localSensorType;
     }
 
     /**
index b49fb0e0c641ec67612863e60b46238394bdaf59..598c952cdea53721d80decd83492878c277b8cfb 100644 (file)
@@ -14,14 +14,17 @@ package org.openhab.binding.powermax.internal.state;
 
 import static org.openhab.binding.powermax.internal.PowermaxBindingConstants.*;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.core.i18n.TimeZoneProvider;
 import org.openhab.core.library.types.OpenClosedType;
+import org.openhab.core.types.UnDefType;
 
 /**
  * A class to store the state of a zone
  *
  * @author Laurent Garnier - Initial contribution
  */
+@NonNullByDefault
 public class PowermaxZoneState extends PowermaxStateContainer {
 
     public BooleanValue tripped = new BooleanValue(this, TRIPPED, OpenClosedType.OPEN, OpenClosedType.CLOSED);
@@ -41,7 +44,7 @@ public class PowermaxZoneState extends PowermaxStateContainer {
     }, () -> {
         Boolean isArmed = armed.getValue();
         if (isArmed == null) {
-            return null;
+            return UnDefType.NULL;
         }
         return isArmed ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
     });
@@ -51,7 +54,7 @@ public class PowermaxZoneState extends PowermaxStateContainer {
     }
 
     public boolean isLastTripBeforeTime(long refTime) {
-        return Boolean.TRUE.equals(tripped.getValue()) && (lastTripped.getValue() != null)
-                && (lastTripped.getValue() < refTime);
+        Long lastTrippedValue = lastTripped.getValue();
+        return Boolean.TRUE.equals(tripped.getValue()) && (lastTrippedValue != null) && (lastTrippedValue < refTime);
     }
 }