]> git.basschouten.com Git - openhab-addons.git/blob
544cb2faedf4e268cbd54ba42fd3aed23500f088
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.rfxcom.internal.messages;
14
15 import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
16
17 import java.nio.charset.StandardCharsets;
18
19 import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
20 import org.openhab.core.types.Type;
21
22 /**
23  * RFXCOM data class for interface message.
24  *
25  * @author Pauli Anttila - Initial contribution
26  * @author Ivan Martinez - Older firmware support (OH1)
27  */
28 public class RFXComInterfaceMessage extends RFXComBaseMessage {
29
30     public enum SubType implements ByteEnumWrapper {
31         UNKNOWN_COMMAND(-1),
32         RESPONSE(0),
33         UNKNOWN_RTS_REMOTE(1),
34         NO_EXTENDED_HW_PRESENT(2),
35         LIST_RFY_REMOTES(3),
36         LIST_ASA_REMOTES(4),
37         START_RECEIVER(7);
38
39         private final int subType;
40
41         SubType(int subType) {
42             this.subType = subType;
43         }
44
45         @Override
46         public byte toByte() {
47             return (byte) subType;
48         }
49     }
50
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
61
62         UNSUPPORTED_COMMAND(-1); // wrong command received from the application
63
64         private final int command;
65
66         Commands(int command) {
67             this.command = command;
68         }
69
70         @Override
71         public byte toByte() {
72             return (byte) command;
73         }
74     }
75
76     public enum TransceiverType implements ByteEnumWrapper {
77         _310MHZ(80),
78         _315MHZ(81),
79         _433_92MHZ_RECEIVER_ONLY(82),
80         _433_92MHZ_TRANSCEIVER(83),
81         _868_00MHZ(85),
82         _868_00MHZ_FSK(86),
83         _868_30MHZ(87),
84         _868_30MHZ_FSK(88),
85         _868_35MHZ(89),
86         _868_35MHZ_FSK(90),
87         _868_95MHZ_FSK(91);
88
89         private final int type;
90
91         TransceiverType(int type) {
92             this.type = type;
93         }
94
95         @Override
96         public byte toByte() {
97             return (byte) type;
98         }
99     }
100
101     public enum FirmwareType implements ByteEnumWrapper {
102         TYPE1_RX_ONLY(0),
103         TYPE1(1),
104         TYPE2(2),
105         EXT(3),
106         EXT2(4);
107
108         private final int type;
109
110         FirmwareType(int type) {
111             this.type = type;
112         }
113
114         @Override
115         public byte toByte() {
116             return (byte) type;
117         }
118     }
119
120     public SubType subType;
121     public Commands command;
122     public String text = "";
123
124     public TransceiverType transceiverType;
125     public int firmwareVersion;
126
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)
135
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)
144
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)
153
154     public boolean enableHomeConfortPackets; // 0x02 - HomeConfort (433.92)
155     public boolean enableKEELOQPackets; // 0x01 - KEELOQ (433.92)
156
157     public byte hardwareVersion1;
158     public byte hardwareVersion2;
159
160     public int outputPower; // -18dBm to +13dBm. N.B. maximum allowed is +10dBm
161
162     public FirmwareType firmwareType;
163
164     public RFXComInterfaceMessage(byte[] data) throws RFXComException {
165         encodeMessage(data);
166     }
167
168     @Override
169     public String toString() {
170         String str = "";
171
172         str += super.toString();
173         str += ", Sub type = " + subType;
174         str += ", Command = " + command;
175
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;
190
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;
199
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;
208
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;
213         }
214
215         return str;
216     }
217
218     @Override
219     public void encodeMessage(byte[] data) throws RFXComException {
220         super.encodeMessage(data);
221
222         subType = fromByte(SubType.class, super.subType);
223
224         if (subType == SubType.RESPONSE) {
225             command = fromByte(Commands.class, data[4]);
226             transceiverType = fromByte(TransceiverType.class, data[5]);
227
228             firmwareVersion = data[6] & 0xFF;
229
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;
238
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;
247
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;
256
257             /*
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.
264              */
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;
269
270                 hardwareVersion1 = data[11];
271                 hardwareVersion2 = data[12];
272
273                 outputPower = data[13] - 18;
274                 firmwareType = fromByte(FirmwareType.class, data[14]);
275             } else {
276                 hardwareVersion1 = data[10];
277                 hardwareVersion2 = data[11];
278             }
279
280             text = "";
281         } else if (subType == SubType.START_RECEIVER) {
282             command = fromByte(Commands.class, data[4]);
283
284             final int len = 16;
285             final int dataOffset = 5;
286
287             byte[] byteArray = new byte[len];
288
289             for (int i = dataOffset; i < (dataOffset + len); i++) {
290                 byteArray[i - dataOffset] += data[i];
291             }
292
293             text = new String(byteArray, StandardCharsets.US_ASCII);
294         } else {
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;
299         }
300     }
301
302     @Override
303     public byte[] decodeMessage() {
304         throw new UnsupportedOperationException();
305     }
306
307     @Override
308     public void convertFromState(String channelId, Type type) {
309         throw new UnsupportedOperationException();
310     }
311 }