2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.powermax.internal.message;
15 import org.openhab.binding.powermax.internal.state.PowermaxState;
16 import org.openhab.core.util.HexUtils;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
21 * A base class for handling a message with the Visonic alarm system
23 * @author Laurent Garnier - Initial contribution
25 public class PowermaxBaseMessage {
27 private final Logger logger = LoggerFactory.getLogger(PowermaxBaseMessage.class);
29 private byte[] rawData;
31 private PowermaxSendType sendType;
32 private PowermaxReceiveType receiveType;
37 * @param message the message as a buffer of bytes
39 public PowermaxBaseMessage(byte[] message) {
41 decodeMessage(message);
47 * @param sendType the type of a message to be sent
49 public PowermaxBaseMessage(PowermaxSendType sendType) {
56 * @param sendType the type of a message to be sent
57 * @param param the dynamic part of a message to be sent; null if no dynamic part
59 public PowermaxBaseMessage(PowermaxSendType sendType, byte[] param) {
60 this.sendType = sendType;
61 byte[] message = new byte[sendType.getMessage().length + 3];
63 message[index++] = 0x0D;
64 for (int i = 0; i < sendType.getMessage().length; i++) {
65 if ((param != null) && (sendType.getParamPosition() != null) && (i >= sendType.getParamPosition())
66 && (i < (sendType.getParamPosition() + param.length))) {
67 message[index++] = param[i - sendType.getParamPosition()];
69 message[index++] = sendType.getMessage()[i];
72 message[index++] = 0x00;
73 message[index++] = 0x0A;
74 decodeMessage(message);
78 * Extract information from the buffer of bytes and set class attributes
80 * @param data the message as a buffer of bytes
82 private void decodeMessage(byte[] data) {
84 code = rawData[1] & 0x000000FF;
86 receiveType = PowermaxReceiveType.fromCode((byte) code);
87 } catch (IllegalArgumentException e) {
93 * Work to be done when receiving a message from the Visonic alarm system
95 * @return a new state containing all changes driven by the message
97 public PowermaxState handleMessage(PowermaxCommManager commManager) {
98 // Send an ACK if needed
99 if (isAckRequired() && commManager != null) {
100 commManager.sendAck(this, (byte) 0x02);
103 if (logger.isDebugEnabled()) {
104 logger.debug("{}message handled by class {}: {}", (receiveType == null) ? "Unsupported " : "",
105 this.getClass().getSimpleName(), this);
112 * @return the raw data of the message (buffer of bytes)
114 public byte[] getRawData() {
119 * @return the identifying code of the message (second byte in the buffer)
121 public int getCode() {
126 * @return the type of the message to be sent
128 public PowermaxSendType getSendType() {
132 public void setSendType(PowermaxSendType sendType) {
133 this.sendType = sendType;
137 * @return the type of the received message
139 public PowermaxReceiveType getReceiveType() {
144 * @return true if the received message requires the sending of an ACK
146 public boolean isAckRequired() {
147 return receiveType == null || receiveType.isAckRequired();
151 public String toString() {
152 String str = "\n - Raw data = " + HexUtils.bytesToHex(rawData);
153 str += "\n - type = " + String.format("%02X", code);
154 if (sendType != null) {
155 str += " ( " + sendType.toString() + " )";
156 } else if (receiveType != null) {
157 str += " ( " + receiveType.toString() + " )";
164 * Instantiate a class for handling a received message The class depends on the message.
166 * @param message the received message as a buffer of bytes
168 * @return a new class instance
170 public static PowermaxBaseMessage getMessageHandler(byte[] message) {
171 PowermaxBaseMessage msgHandler;
173 PowermaxReceiveType msgType = PowermaxReceiveType.fromCode(message[1]);
176 msgHandler = new PowermaxAckMessage(message);
179 msgHandler = new PowermaxTimeoutMessage(message);
182 msgHandler = new PowermaxDeniedMessage(message);
185 msgHandler = new PowermaxDownloadRetryMessage(message);
189 msgHandler = new PowermaxSettingsMessage(message);
192 msgHandler = new PowermaxInfoMessage(message);
195 msgHandler = new PowermaxEventLogMessage(message);
198 msgHandler = new PowermaxZonesNameMessage(message);
201 msgHandler = new PowermaxStatusMessage(message);
204 msgHandler = new PowermaxZonesTypeMessage(message);
207 msgHandler = new PowermaxPanelMessage(message);
210 msgHandler = new PowermaxPowerlinkMessage(message);
213 msgHandler = new PowermaxPowerMasterMessage(message);
216 msgHandler = new PowermaxBaseMessage(message);
219 } catch (IllegalArgumentException e) {
220 msgHandler = new PowermaxBaseMessage(message);