--- /dev/null
+# Responses
+
+Record of responses to some commands for working out how things work.
+
+## Interface Message - Status Response
+
+These messages were received when testing different firmwares.
+
+```
+Ext 250 0D0100010253FA0400070001031C
+Ext 251 0D0100010253FB0400070001031C
+Ext 1001 140100010253010400070001031C03000000000000
+Pro1 1044 1401000102532C04000700010300055D0000000000
+Type1 1024 140100010253180000270001031C01000000000000
+Type1 95 0D01000102535F0000270001031C
+Type2 195 0D0100010253C30080270001031C
+Type2 1022 140100010253160080270001031C02000000000000
+```
+
+## RFXMngr mode setting
+
+These messages were sent by RFXMngr when enabling single modes.
+
+On Pro1 firmware 1044 RFXtrx443 at 433.92MHZ
+```
+enableUndecodedPackets 0D 00 00 03 03 53 00 80 00 00 00 00 00 00
+enableImagintronixOpusPackets 0D 00 00 04 03 53 00 40 00 00 00 00 00 00
+enableByronSXPackets 0D 00 00 05 03 53 00 20 00 00 00 00 00 00
+enableRSLPackets 0D 00 00 06 03 53 00 10 00 00 00 00 00 00
+enableLighting4Packets 0D 00 00 07 03 53 00 08 00 00 00 00 00 00
+enableFineOffsetPackets 0D 00 00 08 03 53 00 04 00 00 00 00 00 00
+enableRubicsonPackets 0D 00 00 09 03 53 00 02 00 00 00 00 00 00
+enableAEPackets 0D 00 00 0A 03 53 00 01 00 00 00 00 00 00
+
+enableBlindsT1T2T3T4Packets 0D 00 00 0B 03 53 00 00 80 00 00 00 00 00
+enableBlindsT0Packets 0D 00 00 0C 03 53 00 00 40 00 00 00 00 00
+? Blank in RFXmngr 0D 00 00 0C 03 53 00 00 20 00 00 00 00 00
+Legrand CAD 0D 00 00 0E 03 53 00 00 10 00 00 00 00 00
+enableProGuardPackets Not in RFXmngr
+enableFS20Packets Not in RFXmngr
+enableLaCrossePackets 0D 00 00 0F 03 53 00 00 08 00 00 00 00 00
+enableHidekiUPMPackets 0D 00 00 10 03 53 00 00 04 00 00 00 00 00
+enableADPackets 0D 00 00 11 03 53 00 00 02 00 00 00 00 00
+enableMertikPackets 0D 00 00 12 03 53 00 00 01 00 00 00 00 00
+
+enableVisonicPackets 0D 00 00 13 03 53 00 00 00 80 00 00 00 00
+enableATIPackets 0D 00 00 14 03 53 00 00 00 40 00 00 00 00
+enableOregonPackets 0D 00 00 14 03 53 00 00 00 20 00 00 00 00
+enableMeiantechPackets 0D 00 00 14 03 53 00 00 00 10 00 00 00 00
+enableHomeEasyPackets 0D 00 00 14 03 53 00 00 00 08 00 00 00 00
+enableACPackets 0D 00 00 14 03 53 00 00 00 04 00 00 00 00
+enableARCPackets 0D 00 00 14 03 53 00 00 00 02 00 00 00 00
+enableX10Packets 0D 00 00 14 03 53 00 00 00 01 00 00 00 00
+
+enableHomeConfortPackets 0D 00 00 14 03 53 00 00 00 00 02 00 00 00
+enableKEELOQPackets 0D 00 00 14 03 53 00 00 00 00 01 00 00 00
+```
\ No newline at end of file
import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
+import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
}
public enum TransceiverType implements ByteEnumWrapper {
- _310MHZ(80),
- _315MHZ(81),
- _433_92MHZ_RECEIVER_ONLY(82),
- _433_92MHZ_TRANSCEIVER(83),
- _868_00MHZ(85),
- _868_00MHZ_FSK(86),
- _868_30MHZ(87),
- _868_30MHZ_FSK(88),
- _868_35MHZ(89),
- _868_35MHZ_FSK(90),
- _868_95MHZ_FSK(91);
+ _310MHZ(0x50, "RFXtrx315 operating at 310MHz"),
+ _315MHZ(0x51, "RFXtrx315 operating at 315MHz"),
+ _433_92MHZ_RECEIVER_ONLY(0x52, "RFXrec433 operating at 433.92MHz (receiver only)"),
+ _433_92MHZ_TRANSCEIVER(0x53, "RFXtrx433 operating at 433.92MHz"),
+ _433_42MHZ(0x54, "RFXtrx433 operating at 433.42MHz"),
+ _868_00MHZ(0x55, "RFXtrx868X operating at 868MHz"),
+ _868_00MHZ_FSK(0x56, "RFXtrx868X operating at 868.00MHz FSK"),
+ _868_30MHZ(0x57, "RFXtrx868X operating at 868.30MHz"),
+ _868_30MHZ_FSK(0x58, "RFXtrx868X operating at 868.30MHz FSK"),
+ _868_35MHZ(0x59, "RFXtrx868X operating at 868.35MHz"),
+ _868_35MHZ_FSK(0x5A, "RFXtrx868X operating at 868.35MHz FSK"),
+ _868_95MHZ_FSK(0x5B, "RFXtrx868X operating at 868.95MHz"),
+ _433_92MHZ_IOT(0x5C, "RFXtrxIOT operating at 433.92MHz"),
+ _868_00MHZ_IOT(0x5D, "RFXtrxIOT operating at 868MHz"),
+ _434_50MHZ(0x5F, "RFXtrx433 operating at 434.50MHz");
private final int type;
+ private final String name;
- TransceiverType(int type) {
+ TransceiverType(int type, String name) {
this.type = type;
+ this.name = name;
}
@Override
public byte toByte() {
return (byte) type;
}
+
+ @Override
+ public String toString() {
+ return name;
+ }
}
public enum FirmwareType implements ByteEnumWrapper {
- TYPE1_RX_ONLY(0),
- TYPE1(1),
- TYPE2(2),
- EXT(3),
- EXT2(4);
+ TYPE1_RX_ONLY(0x00, "Type1 RFXrec receive only firmware"),
+ TYPE1(0x01, "Type1"),
+ TYPE2(0x02, "Type2"),
+ EXT(0x03, "Ext"),
+ EXT2(0x04, "Ext2"),
+ PRO1(0x05, "Pro1"),
+ PRO2(0x06, "Pro2"),
+ PROXL1(0x10, "ProXL 1");
private final int type;
+ private final String name;
- FirmwareType(int type) {
+ FirmwareType(int type, String name) {
this.type = type;
+ this.name = name;
}
@Override
public byte toByte() {
return (byte) type;
}
+
+ @Override
+ public String toString() {
+ return name;
+ }
}
public SubType subType;
subType = fromByte(SubType.class, super.subType);
if (subType == SubType.RESPONSE) {
- command = fromByte(Commands.class, data[4]);
- transceiverType = fromByte(TransceiverType.class, data[5]);
-
- firmwareVersion = data[6] & 0xFF;
-
- enableUndecodedPackets = (data[7] & 0x80) != 0;
- enableImagintronixOpusPackets = (data[7] & 0x40) != 0;
- enableByronSXPackets = (data[7] & 0x20) != 0;
- enableRSLPackets = (data[7] & 0x10) != 0;
- enableLighting4Packets = (data[7] & 0x08) != 0;
- enableFineOffsetPackets = (data[7] & 0x04) != 0;
- enableRubicsonPackets = (data[7] & 0x02) != 0;
- enableAEPackets = (data[7] & 0x01) != 0;
-
- enableBlindsT1T2T3T4Packets = (data[8] & 0x80) != 0;
- enableBlindsT0Packets = (data[8] & 0x40) != 0;
- enableProGuardPackets = (data[8] & 0x20) != 0;
- enableFS20Packets = (data[8] & 0x10) != 0;
- enableLaCrossePackets = (data[8] & 0x08) != 0;
- enableHidekiUPMPackets = (data[8] & 0x04) != 0;
- enableADPackets = (data[8] & 0x02) != 0;
- enableMertikPackets = (data[8] & 0x01) != 0;
-
- enableVisonicPackets = (data[9] & 0x80) != 0;
- enableATIPackets = (data[9] & 0x40) != 0;
- enableOregonPackets = (data[9] & 0x20) != 0;
- enableMeiantechPackets = (data[9] & 0x10) != 0;
- enableHomeEasyPackets = (data[9] & 0x08) != 0;
- enableACPackets = (data[9] & 0x04) != 0;
- enableARCPackets = (data[9] & 0x02) != 0;
- enableX10Packets = (data[9] & 0x01) != 0;
-
- /*
- * Different firmware versions have slightly different message formats.
- * The firmware version numbering is unique to each hardware version
- * but the location of the hardware version in the message is one of
- * those things whose position varies. So we have to just look at the
- * firmware version and pray. This condition below is taken from the
- * openhab1-addons binding.
- */
- if ((firmwareVersion >= 95 && firmwareVersion <= 100) || (firmwareVersion >= 195 && firmwareVersion <= 200)
- || (firmwareVersion >= 251)) {
- enableHomeConfortPackets = (data[10] & 0x02) != 0;
- enableKEELOQPackets = (data[10] & 0x01) != 0;
-
- hardwareVersion1 = data[11];
- hardwareVersion2 = data[12];
-
- outputPower = data[13] - 18;
- firmwareType = fromByte(FirmwareType.class, data[14]);
- } else {
- hardwareVersion1 = data[10];
- hardwareVersion2 = data[11];
- }
-
- text = "";
+ encodeResponseMessage(data);
} else if (subType == SubType.START_RECEIVER) {
- command = fromByte(Commands.class, data[4]);
-
- final int len = 16;
- final int dataOffset = 5;
-
- byte[] byteArray = new byte[len];
-
- for (int i = dataOffset; i < (dataOffset + len); i++) {
- byteArray[i - dataOffset] += data[i];
- }
-
- text = new String(byteArray, StandardCharsets.US_ASCII);
+ encodeStartReceiverMessage(data);
} else {
// We don't handle the other subTypes but to avoid null pointer
// exceptions we set command to something. It doesn't really
- // matter what but it may b printed in log messages so...
+ // matter what but it may be printed in log messages so...
command = Commands.UNSUPPORTED_COMMAND;
}
}
+ private void encodeResponseMessage(byte[] data) throws RFXComException {
+ command = fromByte(Commands.class, data[4]);
+ transceiverType = fromByte(TransceiverType.class, data[5]);
+
+ hardwareVersion1 = data[11];
+ hardwareVersion2 = data[12];
+
+ outputPower = data[13] - 18;
+
+ /*
+ * Firmware versions before 1000 did not include a firmware
+ * type in their response. Instead, versions 0-99 were for
+ * Type 1, versions 100-199 were for Type 2, and versions
+ * above 200 were for Ext.
+ *
+ * From version 1000, the response includes a longer message
+ * which adds a byte for firmware type. The version is calculated
+ * from the single byte, to which 1000 is added.
+ *
+ * Discovered through hints in the release notes and experimentation
+ * with RFXmngr. See RESPONSES.md for data.
+ */
+ if (data.length > 14) {
+ firmwareVersion = Byte.toUnsignedInt(data[6]) + 1000;
+ firmwareType = fromByte(FirmwareType.class, data[14]);
+ } else {
+ firmwareVersion = Byte.toUnsignedInt(data[6]);
+
+ if (firmwareVersion < 100) {
+ firmwareType = FirmwareType.TYPE1;
+ } else if (firmwareVersion < 200) {
+ firmwareType = FirmwareType.TYPE2;
+ } else {
+ firmwareType = FirmwareType.EXT;
+ }
+ }
+
+ /*
+ * These are actually dependent on the type of device and
+ * firmware, this list is mainly for RFXtrx443 at 433.92MHz,
+ * which most of our users use.
+ *
+ * TODO: At some point, we should reconcile this with the SDK
+ * and accommodate for other devices and protocols. This is
+ * probably not worth doing until someone needs it and has
+ * suitable devices to test with!
+ */
+ enableUndecodedPackets = (data[7] & 0x80) != 0;
+ enableImagintronixOpusPackets = (data[7] & 0x40) != 0;
+ enableByronSXPackets = (data[7] & 0x20) != 0;
+ enableRSLPackets = (data[7] & 0x10) != 0;
+ enableLighting4Packets = (data[7] & 0x08) != 0;
+ enableFineOffsetPackets = (data[7] & 0x04) != 0;
+ enableRubicsonPackets = (data[7] & 0x02) != 0;
+ enableAEPackets = (data[7] & 0x01) != 0;
+
+ enableBlindsT1T2T3T4Packets = (data[8] & 0x80) != 0;
+ enableBlindsT0Packets = (data[8] & 0x40) != 0;
+ enableProGuardPackets = (data[8] & 0x20) != 0;
+ enableFS20Packets = (data[8] & 0x10) != 0;
+ enableLaCrossePackets = (data[8] & 0x08) != 0;
+ enableHidekiUPMPackets = (data[8] & 0x04) != 0;
+ enableADPackets = (data[8] & 0x02) != 0;
+ enableMertikPackets = (data[8] & 0x01) != 0;
+
+ enableVisonicPackets = (data[9] & 0x80) != 0;
+ enableATIPackets = (data[9] & 0x40) != 0;
+ enableOregonPackets = (data[9] & 0x20) != 0;
+ enableMeiantechPackets = (data[9] & 0x10) != 0;
+ enableHomeEasyPackets = (data[9] & 0x08) != 0;
+ enableACPackets = (data[9] & 0x04) != 0;
+ enableARCPackets = (data[9] & 0x02) != 0;
+ enableX10Packets = (data[9] & 0x01) != 0;
+
+ enableHomeConfortPackets = (data[10] & 0x02) != 0;
+ enableKEELOQPackets = (data[10] & 0x01) != 0;
+
+ text = "";
+ }
+
+ private void encodeStartReceiverMessage(byte[] data) throws RFXComException {
+ command = fromByte(Commands.class, data[4]);
+
+ ByteBuffer text_bytes = ByteBuffer.wrap(data, 5, data.length - 5);
+ text = StandardCharsets.US_ASCII.decode(text_bytes).toString();
+ }
+
@Override
public byte[] decodeMessage() {
throw new UnsupportedOperationException();
package org.openhab.binding.rfxcom.internal.messages;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.Commands.*;
-import static org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.SubType.*;
-import static org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.SubType.START_RECEIVER;
-import static org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.TransceiverType._433_92MHZ_TRANSCEIVER;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
import org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.Commands;
+import org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.FirmwareType;
import org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.SubType;
+import org.openhab.binding.rfxcom.internal.messages.RFXComInterfaceMessage.TransceiverType;
import org.openhab.core.util.HexUtils;
/**
@Test
public void testWelcomeCopyRightMessage() throws RFXComException {
- RFXComInterfaceMessage msg = testMessage("1401070307436F7079726967687420524658434F4D", START_RECEIVER, 3,
- Commands.START_RECEIVER);
+ RFXComInterfaceMessage msg = testMessage("1401070307436F7079726967687420524658434F4D", SubType.START_RECEIVER,
+ 3, Commands.START_RECEIVER);
assertEquals("Copyright RFXCOM", msg.text, "text");
}
@Test
public void testRespondOnUnknownMessage() throws RFXComException {
- testMessage("0D01FF190053E2000C2701020000", UNKNOWN_COMMAND, 25, UNSUPPORTED_COMMAND);
+ testMessage("0D01FF190053E2000C2701020000", SubType.UNKNOWN_COMMAND, 25, Commands.UNSUPPORTED_COMMAND);
+ }
+
+ private void testStatus(String message, TransceiverType transceiverType, FirmwareType firmwareType,
+ int firewareVersion) throws RFXComException {
+ RFXComInterfaceMessage msg = testMessage(message, SubType.RESPONSE, 1, Commands.GET_STATUS);
+
+ assertEquals(transceiverType, msg.transceiverType, "transceiverType");
+ assertEquals(firmwareType, msg.firmwareType, "firmwareType");
+ assertEquals(firewareVersion, msg.firmwareVersion, "firmwareVersion");
}
@Test
- public void testStatusMessage() throws RFXComException {
- RFXComInterfaceMessage msg = testMessage("1401000102530C0800270001031C04524658434F4D", RESPONSE, 1, GET_STATUS);
+ public void testStatus_Rfxtrx443_Ext_250() throws RFXComException {
+ testStatus("0D0100010253FA0400070001031C", TransceiverType._433_92MHZ_TRANSCEIVER, FirmwareType.EXT, 250);
+ }
- assertEquals(_433_92MHZ_TRANSCEIVER, msg.transceiverType, "Command");
+ @Test
+ public void testStatus_Rfxtrx443_Ext_251() throws RFXComException {
+ testStatus("0D0100010253FB0400070001031C", TransceiverType._433_92MHZ_TRANSCEIVER, FirmwareType.EXT, 251);
+ }
- // TODO this is not correct, improvements for this have been made in the OH1 repo
- assertEquals(12, msg.firmwareVersion, "firmwareVersion");
+ @Test
+ public void testStatus_Rfxtrx443_Ext_1001() throws RFXComException {
+ testStatus("140100010253010400070001031C03000000000000", TransceiverType._433_92MHZ_TRANSCEIVER,
+ FirmwareType.EXT, 1001);
+ }
+
+ @Test
+ public void testStatus_Rfxtrx443_Pro1_1044() throws RFXComException {
+ testStatus("1401000102532C04000700010300055D0000000000", TransceiverType._433_92MHZ_TRANSCEIVER,
+ FirmwareType.PRO1, 1044);
+ }
+
+ @Test
+ public void testStatus_Rfxtrx443_Type1_95() throws RFXComException {
+ testStatus("0D01000102535F0000270001031C", TransceiverType._433_92MHZ_TRANSCEIVER, FirmwareType.TYPE1, 95);
+ }
+
+ @Test
+ public void testStatus_Rfxtrx443_Type1_1024() throws RFXComException {
+ testStatus("140100010253180000270001031C01000000000000", TransceiverType._433_92MHZ_TRANSCEIVER,
+ FirmwareType.TYPE1, 1024);
+ }
+
+ @Test
+ public void testStatus_Rfxtrx443_Type2_195() throws RFXComException {
+ testStatus("0D0100010253C30080270001031C", TransceiverType._433_92MHZ_TRANSCEIVER, FirmwareType.TYPE2, 195);
+ }
+
+ @Test
+ public void testStatus_Rfxtrx443_Type2_1022() throws RFXComException {
+ testStatus("140100010253160080270001031C02000000000000", TransceiverType._433_92MHZ_TRANSCEIVER,
+ FirmwareType.TYPE2, 1022);
+ }
+
+ @Test
+ public void testStatus_Rfxtrx443_Ext2_1012() throws RFXComException {
+ testStatus("1401000102530C0800270001031C04524658434F4D", TransceiverType._433_92MHZ_TRANSCEIVER,
+ FirmwareType.EXT2, 1012);
}
}