]> git.basschouten.com Git - openhab-addons.git/blob
bf09db4bff2821b10cfa270cfae12073fe8ad267
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.ByteBuffer;
18 import java.nio.charset.StandardCharsets;
19
20 import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
21 import org.openhab.core.types.Type;
22
23 /**
24  * RFXCOM data class for interface message.
25  *
26  * @author Pauli Anttila - Initial contribution
27  * @author Ivan Martinez - Older firmware support (OH1)
28  */
29 public class RFXComInterfaceMessage extends RFXComBaseMessage {
30
31     public enum SubType implements ByteEnumWrapper {
32         UNKNOWN_COMMAND(-1),
33         RESPONSE(0),
34         UNKNOWN_RTS_REMOTE(1),
35         NO_EXTENDED_HW_PRESENT(2),
36         LIST_RFY_REMOTES(3),
37         LIST_ASA_REMOTES(4),
38         START_RECEIVER(7);
39
40         private final int subType;
41
42         SubType(int subType) {
43             this.subType = subType;
44         }
45
46         @Override
47         public byte toByte() {
48             return (byte) subType;
49         }
50     }
51
52     public enum Commands implements ByteEnumWrapper {
53         RESET(0), // Reset the receiver/transceiver. No answer is transmitted!
54         GET_STATUS(2), // Get Status, return firmware versions and configuration of the interface
55         SET_MODE(3), // Set mode msg1-msg5, return firmware versions and configuration of the interface
56         ENABLE_ALL(4), // Enable all receiving modes of the receiver/transceiver
57         ENABLE_UNDECODED_PACKETS(5), // Enable reporting of undecoded packets
58         SAVE_RECEIVING_MODES(6), // Save receiving modes of the receiver/transceiver in non-volatile memory
59         START_RECEIVER(7), // Start RFXtrx receiver
60         T1(8), // For internal use by RFXCOM
61         T2(9), // For internal use by RFXCOM
62
63         UNSUPPORTED_COMMAND(-1); // wrong command received from the application
64
65         private final int command;
66
67         Commands(int command) {
68             this.command = command;
69         }
70
71         @Override
72         public byte toByte() {
73             return (byte) command;
74         }
75     }
76
77     public enum TransceiverType implements ByteEnumWrapper {
78         _310MHZ(0x50, "RFXtrx315 operating at 310MHz"),
79         _315MHZ(0x51, "RFXtrx315 operating at 315MHz"),
80         _433_92MHZ_RECEIVER_ONLY(0x52, "RFXrec433 operating at 433.92MHz (receiver only)"),
81         _433_92MHZ_TRANSCEIVER(0x53, "RFXtrx433 operating at 433.92MHz"),
82         _433_42MHZ(0x54, "RFXtrx433 operating at 433.42MHz"),
83         _868_00MHZ(0x55, "RFXtrx868X operating at 868MHz"),
84         _868_00MHZ_FSK(0x56, "RFXtrx868X operating at 868.00MHz FSK"),
85         _868_30MHZ(0x57, "RFXtrx868X operating at 868.30MHz"),
86         _868_30MHZ_FSK(0x58, "RFXtrx868X operating at 868.30MHz FSK"),
87         _868_35MHZ(0x59, "RFXtrx868X operating at 868.35MHz"),
88         _868_35MHZ_FSK(0x5A, "RFXtrx868X operating at 868.35MHz FSK"),
89         _868_95MHZ_FSK(0x5B, "RFXtrx868X operating at 868.95MHz"),
90         _433_92MHZ_IOT(0x5C, "RFXtrxIOT operating at 433.92MHz"),
91         _868_00MHZ_IOT(0x5D, "RFXtrxIOT operating at 868MHz"),
92         _434_50MHZ(0x5F, "RFXtrx433 operating at 434.50MHz");
93
94         private final int type;
95         private final String name;
96
97         TransceiverType(int type, String name) {
98             this.type = type;
99             this.name = name;
100         }
101
102         @Override
103         public byte toByte() {
104             return (byte) type;
105         }
106
107         @Override
108         public String toString() {
109             return name;
110         }
111     }
112
113     public enum FirmwareType implements ByteEnumWrapper {
114         TYPE1_RX_ONLY(0x00, "Type1 RFXrec receive only firmware"),
115         TYPE1(0x01, "Type1"),
116         TYPE2(0x02, "Type2"),
117         EXT(0x03, "Ext"),
118         EXT2(0x04, "Ext2"),
119         PRO1(0x05, "Pro1"),
120         PRO2(0x06, "Pro2"),
121         PROXL1(0x10, "ProXL 1");
122
123         private final int type;
124         private final String name;
125
126         FirmwareType(int type, String name) {
127             this.type = type;
128             this.name = name;
129         }
130
131         @Override
132         public byte toByte() {
133             return (byte) type;
134         }
135
136         @Override
137         public String toString() {
138             return name;
139         }
140     }
141
142     public SubType subType;
143     public Commands command;
144     public String text = "";
145
146     public TransceiverType transceiverType;
147     public int firmwareVersion;
148
149     public boolean enableUndecodedPackets; // 0x80 - Undecoded packets
150     public boolean enableImagintronixOpusPackets; // 0x40 - Imagintronix/Opus (433.92)
151     public boolean enableByronSXPackets; // 0x20 - Byron SX (433.92)
152     public boolean enableRSLPackets; // 0x10 - RSL (433.92)
153     public boolean enableLighting4Packets; // 0x08 - Lighting4 (433.92)
154     public boolean enableFineOffsetPackets; // 0x04 - FineOffset / Viking (433.92)
155     public boolean enableRubicsonPackets; // 0x02 - Rubicson (433.92)
156     public boolean enableAEPackets; // 0x01 - AE (433.92)
157
158     public boolean enableBlindsT1T2T3T4Packets; // 0x80 - BlindsT1/T2/T3/T4 (433.92)
159     public boolean enableBlindsT0Packets; // 0x40 - BlindsT0 (433.92)
160     public boolean enableProGuardPackets; // 0x20 - ProGuard (868.35 FSK)
161     public boolean enableFS20Packets; // 0x10 - FS20 (868.35)
162     public boolean enableLaCrossePackets; // 0x08 - La Crosse (433.92/868.30)
163     public boolean enableHidekiUPMPackets; // 0x04 - Hideki/UPM (433.92)
164     public boolean enableADPackets; // 0x02 - AD LightwaveRF (433.92)
165     public boolean enableMertikPackets; // 0x01 - Mertik (433.92)
166
167     public boolean enableVisonicPackets; // 0x80 - Visonic (315/868.95)
168     public boolean enableATIPackets; // 0x40 - ATI (433.92)
169     public boolean enableOregonPackets; // 0x20 - Oregon Scientific (433.92)
170     public boolean enableMeiantechPackets; // 0x10 - Meiantech (433.92)
171     public boolean enableHomeEasyPackets; // 0x08 - HomeEasy EU (433.92)
172     public boolean enableACPackets; // 0x04 - AC (433.92)
173     public boolean enableARCPackets; // 0x02 - ARC (433.92)
174     public boolean enableX10Packets; // 0x01 - X10 (310/433.92)
175
176     public boolean enableHomeConfortPackets; // 0x02 - HomeConfort (433.92)
177     public boolean enableKEELOQPackets; // 0x01 - KEELOQ (433.92)
178
179     public byte hardwareVersion1;
180     public byte hardwareVersion2;
181
182     public int outputPower; // -18dBm to +13dBm. N.B. maximum allowed is +10dBm
183
184     public FirmwareType firmwareType;
185
186     public RFXComInterfaceMessage(byte[] data) throws RFXComException {
187         encodeMessage(data);
188     }
189
190     @Override
191     public String toString() {
192         String str = "";
193
194         str += super.toString();
195         str += ", Sub type = " + subType;
196         str += ", Command = " + command;
197
198         if (subType == SubType.RESPONSE) {
199             str += ", Transceiver type = " + transceiverType;
200             str += ", Hardware version = " + hardwareVersion1 + "." + hardwareVersion2;
201             str += ", Firmware type = " + (firmwareType != null ? firmwareType : "unknown");
202             str += ", Firmware version = " + firmwareVersion;
203             str += ", Output power = " + outputPower + "dBm";
204             str += ", Undecoded packets = " + enableUndecodedPackets;
205             str += ", RFU6 packets = " + enableImagintronixOpusPackets;
206             str += ", Byron SX packets packets (433.92) = " + enableByronSXPackets;
207             str += ", RSL packets packets (433.92) = " + enableRSLPackets;
208             str += ", Lighting4 packets (433.92) = " + enableLighting4Packets;
209             str += ", FineOffset / Viking (433.92) packets = " + enableFineOffsetPackets;
210             str += ", Rubicson (433.92) packets = " + enableRubicsonPackets;
211             str += ", AE (433.92) packets = " + enableAEPackets;
212
213             str += ", BlindsT1/T2/T3 (433.92) packets = " + enableBlindsT1T2T3T4Packets;
214             str += ", BlindsT0 (433.92) packets = " + enableBlindsT0Packets;
215             str += ", ProGuard (868.35 FSK) packets = " + enableProGuardPackets;
216             str += ", FS20/Legrand CAD (868.35/433.92) packets = " + enableFS20Packets;
217             str += ", La Crosse (433.92/868.30) packets = " + enableLaCrossePackets;
218             str += ", Hideki/UPM (433.92) packets = " + enableHidekiUPMPackets;
219             str += ", AD LightwaveRF (433.92) packets = " + enableADPackets;
220             str += ", Mertik (433.92) packets = " + enableMertikPackets;
221
222             str += ", Visonic (315/868.95) packets = " + enableVisonicPackets;
223             str += ", ATI (433.92) packets = " + enableATIPackets;
224             str += ", Oregon Scientific (433.92) packets = " + enableOregonPackets;
225             str += ", Meiantech (433.92) packets = " + enableMeiantechPackets;
226             str += ", HomeEasy EU (433.92) packets = " + enableHomeEasyPackets;
227             str += ", AC (433.92) packets = " + enableACPackets;
228             str += ", ARC (433.92) packets = " + enableARCPackets;
229             str += ", X10 (310/433.92) packets = " + enableX10Packets;
230
231             str += ", HomeConfort (433.92) packets = " + enableHomeConfortPackets;
232             str += ", KEELOQ (433.92/868.95) packets = " + enableKEELOQPackets;
233         } else if (subType == SubType.START_RECEIVER) {
234             str += ", Text = " + text;
235         }
236
237         return str;
238     }
239
240     @Override
241     public void encodeMessage(byte[] data) throws RFXComException {
242         super.encodeMessage(data);
243
244         subType = fromByte(SubType.class, super.subType);
245
246         if (subType == SubType.RESPONSE) {
247             encodeResponseMessage(data);
248         } else if (subType == SubType.START_RECEIVER) {
249             encodeStartReceiverMessage(data);
250         } else {
251             // We don't handle the other subTypes but to avoid null pointer
252             // exceptions we set command to something. It doesn't really
253             // matter what but it may be printed in log messages so...
254             command = Commands.UNSUPPORTED_COMMAND;
255         }
256     }
257
258     private void encodeResponseMessage(byte[] data) throws RFXComException {
259         command = fromByte(Commands.class, data[4]);
260         transceiverType = fromByte(TransceiverType.class, data[5]);
261
262         hardwareVersion1 = data[11];
263         hardwareVersion2 = data[12];
264
265         outputPower = data[13] - 18;
266
267         /*
268          * Firmware versions before 1000 did not include a firmware
269          * type in their response. Instead, versions 0-99 were for
270          * Type 1, versions 100-199 were for Type 2, and versions
271          * above 200 were for Ext.
272          *
273          * From version 1000, the response includes a longer message
274          * which adds a byte for firmware type. The version is calculated
275          * from the single byte, to which 1000 is added.
276          *
277          * Discovered through hints in the release notes and experimentation
278          * with RFXmngr. See RESPONSES.md for data.
279          */
280         if (data.length > 14) {
281             firmwareVersion = Byte.toUnsignedInt(data[6]) + 1000;
282             firmwareType = fromByte(FirmwareType.class, data[14]);
283         } else {
284             firmwareVersion = Byte.toUnsignedInt(data[6]);
285
286             if (firmwareVersion < 100) {
287                 firmwareType = FirmwareType.TYPE1;
288             } else if (firmwareVersion < 200) {
289                 firmwareType = FirmwareType.TYPE2;
290             } else {
291                 firmwareType = FirmwareType.EXT;
292             }
293         }
294
295         /*
296          * These are actually dependent on the type of device and
297          * firmware, this list is mainly for RFXtrx443 at 433.92MHz,
298          * which most of our users use.
299          *
300          * TODO: At some point, we should reconcile this with the SDK
301          * and accommodate for other devices and protocols. This is
302          * probably not worth doing until someone needs it and has
303          * suitable devices to test with!
304          */
305         enableUndecodedPackets = (data[7] & 0x80) != 0;
306         enableImagintronixOpusPackets = (data[7] & 0x40) != 0;
307         enableByronSXPackets = (data[7] & 0x20) != 0;
308         enableRSLPackets = (data[7] & 0x10) != 0;
309         enableLighting4Packets = (data[7] & 0x08) != 0;
310         enableFineOffsetPackets = (data[7] & 0x04) != 0;
311         enableRubicsonPackets = (data[7] & 0x02) != 0;
312         enableAEPackets = (data[7] & 0x01) != 0;
313
314         enableBlindsT1T2T3T4Packets = (data[8] & 0x80) != 0;
315         enableBlindsT0Packets = (data[8] & 0x40) != 0;
316         enableProGuardPackets = (data[8] & 0x20) != 0;
317         enableFS20Packets = (data[8] & 0x10) != 0;
318         enableLaCrossePackets = (data[8] & 0x08) != 0;
319         enableHidekiUPMPackets = (data[8] & 0x04) != 0;
320         enableADPackets = (data[8] & 0x02) != 0;
321         enableMertikPackets = (data[8] & 0x01) != 0;
322
323         enableVisonicPackets = (data[9] & 0x80) != 0;
324         enableATIPackets = (data[9] & 0x40) != 0;
325         enableOregonPackets = (data[9] & 0x20) != 0;
326         enableMeiantechPackets = (data[9] & 0x10) != 0;
327         enableHomeEasyPackets = (data[9] & 0x08) != 0;
328         enableACPackets = (data[9] & 0x04) != 0;
329         enableARCPackets = (data[9] & 0x02) != 0;
330         enableX10Packets = (data[9] & 0x01) != 0;
331
332         enableHomeConfortPackets = (data[10] & 0x02) != 0;
333         enableKEELOQPackets = (data[10] & 0x01) != 0;
334
335         text = "";
336     }
337
338     private void encodeStartReceiverMessage(byte[] data) throws RFXComException {
339         command = fromByte(Commands.class, data[4]);
340
341         ByteBuffer text_bytes = ByteBuffer.wrap(data, 5, data.length - 5);
342         text = StandardCharsets.US_ASCII.decode(text_bytes).toString();
343     }
344
345     @Override
346     public byte[] decodeMessage() {
347         throw new UnsupportedOperationException();
348     }
349
350     @Override
351     public void convertFromState(String channelId, Type type) {
352         throw new UnsupportedOperationException();
353     }
354 }