2 * Copyright (c) 2010-2021 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.rfxcom.internal.messages;
15 import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
17 import java.nio.charset.StandardCharsets;
19 import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
20 import org.openhab.core.types.Type;
23 * RFXCOM data class for interface message.
25 * @author Pauli Anttila - Initial contribution
26 * @author Ivan Martinez - Older firmware support (OH1)
28 public class RFXComInterfaceMessage extends RFXComBaseMessage {
30 public enum SubType implements ByteEnumWrapper {
33 UNKNOWN_RTS_REMOTE(1),
34 NO_EXTENDED_HW_PRESENT(2),
39 private final int subType;
41 SubType(int subType) {
42 this.subType = subType;
46 public byte toByte() {
47 return (byte) subType;
51 public enum Commands implements ByteEnumWrapper {
52 RESET(0), // Reset the receiver/transceiver. No answer is transmitted!
53 GET_STATUS(2), // Get Status, return firmware versions and configuration of the interface
54 SET_MODE(3), // Set mode msg1-msg5, return firmware versions and configuration of the interface
55 ENABLE_ALL(4), // Enable all receiving modes of the receiver/transceiver
56 ENABLE_UNDECODED_PACKETS(5), // Enable reporting of undecoded packets
57 SAVE_RECEIVING_MODES(6), // Save receiving modes of the receiver/transceiver in non-volatile memory
58 START_RECEIVER(7), // Start RFXtrx receiver
59 T1(8), // For internal use by RFXCOM
60 T2(9), // For internal use by RFXCOM
62 UNSUPPORTED_COMMAND(-1); // wrong command received from the application
64 private final int command;
66 Commands(int command) {
67 this.command = command;
71 public byte toByte() {
72 return (byte) command;
76 public enum TransceiverType implements ByteEnumWrapper {
79 _433_92MHZ_RECEIVER_ONLY(82),
80 _433_92MHZ_TRANSCEIVER(83),
89 private final int type;
91 TransceiverType(int type) {
96 public byte toByte() {
101 public enum FirmwareType implements ByteEnumWrapper {
108 private final int type;
110 FirmwareType(int type) {
115 public byte toByte() {
120 public SubType subType;
121 public Commands command;
122 public String text = "";
124 public TransceiverType transceiverType;
125 public int firmwareVersion;
127 public boolean enableUndecodedPackets; // 0x80 - Undecoded packets
128 public boolean enableImagintronixOpusPackets; // 0x40 - Imagintronix/Opus (433.92)
129 public boolean enableByronSXPackets; // 0x20 - Byron SX (433.92)
130 public boolean enableRSLPackets; // 0x10 - RSL (433.92)
131 public boolean enableLighting4Packets; // 0x08 - Lighting4 (433.92)
132 public boolean enableFineOffsetPackets; // 0x04 - FineOffset / Viking (433.92)
133 public boolean enableRubicsonPackets; // 0x02 - Rubicson (433.92)
134 public boolean enableAEPackets; // 0x01 - AE (433.92)
136 public boolean enableBlindsT1T2T3T4Packets; // 0x80 - BlindsT1/T2/T3/T4 (433.92)
137 public boolean enableBlindsT0Packets; // 0x40 - BlindsT0 (433.92)
138 public boolean enableProGuardPackets; // 0x20 - ProGuard (868.35 FSK)
139 public boolean enableFS20Packets; // 0x10 - FS20 (868.35)
140 public boolean enableLaCrossePackets; // 0x08 - La Crosse (433.92/868.30)
141 public boolean enableHidekiUPMPackets; // 0x04 - Hideki/UPM (433.92)
142 public boolean enableADPackets; // 0x02 - AD LightwaveRF (433.92)
143 public boolean enableMertikPackets; // 0x01 - Mertik (433.92)
145 public boolean enableVisonicPackets; // 0x80 - Visonic (315/868.95)
146 public boolean enableATIPackets; // 0x40 - ATI (433.92)
147 public boolean enableOregonPackets; // 0x20 - Oregon Scientific (433.92)
148 public boolean enableMeiantechPackets; // 0x10 - Meiantech (433.92)
149 public boolean enableHomeEasyPackets; // 0x08 - HomeEasy EU (433.92)
150 public boolean enableACPackets; // 0x04 - AC (433.92)
151 public boolean enableARCPackets; // 0x02 - ARC (433.92)
152 public boolean enableX10Packets; // 0x01 - X10 (310/433.92)
154 public boolean enableHomeConfortPackets; // 0x02 - HomeConfort (433.92)
155 public boolean enableKEELOQPackets; // 0x01 - KEELOQ (433.92)
157 public byte hardwareVersion1;
158 public byte hardwareVersion2;
160 public int outputPower; // -18dBm to +13dBm. N.B. maximum allowed is +10dBm
162 public FirmwareType firmwareType;
164 public RFXComInterfaceMessage(byte[] data) throws RFXComException {
169 public String toString() {
172 str += super.toString();
173 str += ", Sub type = " + subType;
174 str += ", Command = " + command;
176 if (subType == SubType.RESPONSE) {
177 str += ", Transceiver type = " + transceiverType;
178 str += ", Hardware version = " + hardwareVersion1 + "." + hardwareVersion2;
179 str += ", Firmware type = " + (firmwareType != null ? firmwareType : "unknown");
180 str += ", Firmware version = " + firmwareVersion;
181 str += ", Output power = " + outputPower + "dBm";
182 str += ", Undecoded packets = " + enableUndecodedPackets;
183 str += ", RFU6 packets = " + enableImagintronixOpusPackets;
184 str += ", Byron SX packets packets (433.92) = " + enableByronSXPackets;
185 str += ", RSL packets packets (433.92) = " + enableRSLPackets;
186 str += ", Lighting4 packets (433.92) = " + enableLighting4Packets;
187 str += ", FineOffset / Viking (433.92) packets = " + enableFineOffsetPackets;
188 str += ", Rubicson (433.92) packets = " + enableRubicsonPackets;
189 str += ", AE (433.92) packets = " + enableAEPackets;
191 str += ", BlindsT1/T2/T3 (433.92) packets = " + enableBlindsT1T2T3T4Packets;
192 str += ", BlindsT0 (433.92) packets = " + enableBlindsT0Packets;
193 str += ", ProGuard (868.35 FSK) packets = " + enableProGuardPackets;
194 str += ", FS20/Legrand CAD (868.35/433.92) packets = " + enableFS20Packets;
195 str += ", La Crosse (433.92/868.30) packets = " + enableLaCrossePackets;
196 str += ", Hideki/UPM (433.92) packets = " + enableHidekiUPMPackets;
197 str += ", AD LightwaveRF (433.92) packets = " + enableADPackets;
198 str += ", Mertik (433.92) packets = " + enableMertikPackets;
200 str += ", Visonic (315/868.95) packets = " + enableVisonicPackets;
201 str += ", ATI (433.92) packets = " + enableATIPackets;
202 str += ", Oregon Scientific (433.92) packets = " + enableOregonPackets;
203 str += ", Meiantech (433.92) packets = " + enableMeiantechPackets;
204 str += ", HomeEasy EU (433.92) packets = " + enableHomeEasyPackets;
205 str += ", AC (433.92) packets = " + enableACPackets;
206 str += ", ARC (433.92) packets = " + enableARCPackets;
207 str += ", X10 (310/433.92) packets = " + enableX10Packets;
209 str += ", HomeConfort (433.92) packets = " + enableHomeConfortPackets;
210 str += ", KEELOQ (433.92/868.95) packets = " + enableKEELOQPackets;
211 } else if (subType == SubType.START_RECEIVER) {
212 str += ", Text = " + text;
219 public void encodeMessage(byte[] data) throws RFXComException {
220 super.encodeMessage(data);
222 subType = fromByte(SubType.class, super.subType);
224 if (subType == SubType.RESPONSE) {
225 command = fromByte(Commands.class, data[4]);
226 transceiverType = fromByte(TransceiverType.class, data[5]);
228 firmwareVersion = data[6] & 0xFF;
230 enableUndecodedPackets = (data[7] & 0x80) != 0;
231 enableImagintronixOpusPackets = (data[7] & 0x40) != 0;
232 enableByronSXPackets = (data[7] & 0x20) != 0;
233 enableRSLPackets = (data[7] & 0x10) != 0;
234 enableLighting4Packets = (data[7] & 0x08) != 0;
235 enableFineOffsetPackets = (data[7] & 0x04) != 0;
236 enableRubicsonPackets = (data[7] & 0x02) != 0;
237 enableAEPackets = (data[7] & 0x01) != 0;
239 enableBlindsT1T2T3T4Packets = (data[8] & 0x80) != 0;
240 enableBlindsT0Packets = (data[8] & 0x40) != 0;
241 enableProGuardPackets = (data[8] & 0x20) != 0;
242 enableFS20Packets = (data[8] & 0x10) != 0;
243 enableLaCrossePackets = (data[8] & 0x08) != 0;
244 enableHidekiUPMPackets = (data[8] & 0x04) != 0;
245 enableADPackets = (data[8] & 0x02) != 0;
246 enableMertikPackets = (data[8] & 0x01) != 0;
248 enableVisonicPackets = (data[9] & 0x80) != 0;
249 enableATIPackets = (data[9] & 0x40) != 0;
250 enableOregonPackets = (data[9] & 0x20) != 0;
251 enableMeiantechPackets = (data[9] & 0x10) != 0;
252 enableHomeEasyPackets = (data[9] & 0x08) != 0;
253 enableACPackets = (data[9] & 0x04) != 0;
254 enableARCPackets = (data[9] & 0x02) != 0;
255 enableX10Packets = (data[9] & 0x01) != 0;
258 * Different firmware versions have slightly different message formats.
259 * The firmware version numbering is unique to each hardware version
260 * but the location of the hardware version in the message is one of
261 * those things whose position varies. So we have to just look at the
262 * firmware version and pray. This condition below is taken from the
263 * openhab1-addons binding.
265 if ((firmwareVersion >= 95 && firmwareVersion <= 100) || (firmwareVersion >= 195 && firmwareVersion <= 200)
266 || (firmwareVersion >= 251)) {
267 enableHomeConfortPackets = (data[10] & 0x02) != 0;
268 enableKEELOQPackets = (data[10] & 0x01) != 0;
270 hardwareVersion1 = data[11];
271 hardwareVersion2 = data[12];
273 outputPower = data[13] - 18;
274 firmwareType = fromByte(FirmwareType.class, data[14]);
276 hardwareVersion1 = data[10];
277 hardwareVersion2 = data[11];
281 } else if (subType == SubType.START_RECEIVER) {
282 command = fromByte(Commands.class, data[4]);
285 final int dataOffset = 5;
287 byte[] byteArray = new byte[len];
289 for (int i = dataOffset; i < (dataOffset + len); i++) {
290 byteArray[i - dataOffset] += data[i];
293 text = new String(byteArray, StandardCharsets.US_ASCII);
295 // We don't handle the other subTypes but to avoid null pointer
296 // exceptions we set command to something. It doesn't really
297 // matter what but it may b printed in log messages so...
298 command = Commands.UNSUPPORTED_COMMAND;
303 public byte[] decodeMessage() {
304 throw new UnsupportedOperationException();
308 public void convertFromState(String channelId, Type type) {
309 throw new UnsupportedOperationException();