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