/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.rfxcom.internal.messages; import java.util.List; import org.openhab.binding.rfxcom.RFXComValueSelector; import org.openhab.binding.rfxcom.internal.RFXComException; import org.openhab.core.types.State; import org.openhab.core.types.Type; /** * RFXCOM data class for interface message. * * @author Pauli Anttila * @since 1.2.0 */ public class RFXComInterfaceMessage extends RFXComBaseMessage { public enum SubType { INTERFACE_RESPONSE(0), UNKNOWN(255); private final int subType; SubType(int subType) { this.subType = subType; } SubType(byte subType) { this.subType = subType; } public byte toByte() { return (byte) subType; } public static SubType fromByte(int input) { for (SubType subType : SubType.values()) { if (subType.subType == input) { return subType; } } return SubType.UNKNOWN; } } public enum Commands { RESET(0), // Reset the receiver/transceiver. No answer is transmitted! GET_STATUS(2), // Get Status, return firmware versions and configuration of the interface SET_MODE(3), // Set mode msg1-msg5, return firmware versions and configuration of the interface ENABLE_ALL(4), // Enable all receiving modes of the receiver/transceiver ENABLE_UNDECODED_PACKETS(5), // Enable reporting of undecoded packets SAVE_RECEIVING_MODES(6), // Save receiving modes of the receiver/transceiver in non-volatile memory T1(8), // For internal use by RFXCOM T2(9), // For internal use by RFXCOM UNKNOWN(255); private final int command; Commands(int command) { this.command = command; } Commands(byte command) { this.command = command; } public byte toByte() { return (byte) command; } public static Commands fromByte(int input) { for (Commands command : Commands.values()) { if (command.command == input) { return command; } } return Commands.UNKNOWN; } } public enum TransceiverType { _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), UNKNOWN(255); private final int type; TransceiverType(int type) { this.type = type; } TransceiverType(byte type) { this.type = type; } public byte toByte() { return (byte) type; } public static TransceiverType fromByte(int input) { for (TransceiverType type : TransceiverType.values()) { if (type.type == input) { return type; } } return TransceiverType.UNKNOWN; } } public enum FirmwareType { Type1_RFXRec(0), Type1(1), Type2(2), Ext(3), Ext2(4), UNKNOWN(255); private final int type; FirmwareType(int type) { this.type = type; } FirmwareType(byte type) { this.type = type; } public byte toByte() { return (byte) type; } } public SubType subType = SubType.UNKNOWN; public Commands command = Commands.UNKNOWN; public TransceiverType transceiverType = TransceiverType.UNKNOWN; public short firmwareVersion = 0; public FirmwareType firmwareType = FirmwareType.UNKNOWN; public boolean enableUndecodedPackets = false; // 0x80 - Undecoded packets public boolean enableRFU6Packets = false; // 0x40 - RFU6 public boolean enableRFU5Packets = false; // 0x20 - RFU5 public boolean enableRFU4Packets = false; // 0x10 - RFU4 public boolean enableRFU3Packets = false; // 0x08 - RFU3 public boolean enableFineOffsetPackets = false; // 0x04 - FineOffset / Viking (433.92) public boolean enableRubicsonPackets = false; // 0x02 - Rubicson (433.92) public boolean enableAEPackets = false; // 0x01 - AE (433.92) public boolean enableBlindsT1Packets = false; // 0x80 - BlindsT1/T2/T3 (433.92) public boolean enableBlindsT0Packets = false; // 0x40 - BlindsT0 (433.92) public boolean enableProGuardPackets = false; // 0x20 - ProGuard (868.35 FSK) public boolean enableFS20Packets = false; // 0x10 - FS20 (868.35) public boolean enableLaCrossePackets = false; // 0x08 - La Crosse (433.92/868.30) public boolean enableHidekiPackets = false; // 0x04 - Hideki/UPM (433.92) public boolean enableADPackets = false; // 0x02 - AD (433.92) public boolean enableMertikPackets = false; // 0x01 - Mertik (433.92) public boolean enableVisonicPackets = false; // 0x80 - Visonic (315/868.95) public boolean enableATIPackets = false; // 0x40 - ATI (433.92) public boolean enableOregonPackets = false; // 0x20 - Oregon Scientific (433.92) public boolean enableMeiantechPackets = false; // 0x10 - Meiantech (433.92) public boolean enableHomeEasyPackets = false; // 0x08 - HomeEasy EU (433.92) public boolean enableACPackets = false; // 0x04 - AC (433.92) public boolean enableARCPackets = false; // 0x02 - ARC (433.92) public boolean enableX10Packets = false; // 0x01 - X10 (310/433.92) public boolean enableHomeConfortPackets = false; // 0x02 - HomeConfort (433.92) public boolean enableKeeLoqPackets = false; // 0x01 - KeeLoq (433.92) public byte hardwareVersion1 = 0; public byte hardwareVersion2 = 0; public byte outputPower = 0; public RFXComInterfaceMessage() { } public RFXComInterfaceMessage(byte[] data) { encodeMessage(data); } @Override public String toString() { String str = ""; str += super.toString(); str += "\n - Sub type = " + subType; str += "\n - Command = " + command; str += "\n - Transceiver type = " + transceiverType; str += "\n - Firmware version = " + firmwareVersion; str += "\n - Firmware type = " + firmwareType; str += "\n - Hardware version = " + hardwareVersion1 + "." + hardwareVersion2; str += "\n - Undecoded packets = " + enableUndecodedPackets; str += "\n - RFU6 packets = " + enableRFU6Packets; str += "\n - RFU5 packets = " + enableRFU5Packets; str += "\n - RFU4 packets = " + enableRFU4Packets; str += "\n - RFU3 packets = " + enableRFU3Packets; str += "\n - FineOffset / Viking (433.92) packets = " + enableFineOffsetPackets; str += "\n - Rubicson (433.92) packets = " + enableRubicsonPackets; str += "\n - AE (433.92) packets = " + enableAEPackets; str += "\n - BlindsT1/T2/T3 (433.92) packets = " + enableBlindsT1Packets; str += "\n - BlindsT0 (433.92) packets = " + enableBlindsT0Packets; str += "\n - ProGuard (868.35 FSK) packets = " + enableProGuardPackets; str += "\n - FS20 (868.35) packets = " + enableFS20Packets; str += "\n - La Crosse (433.92/868.30) packets = " + enableLaCrossePackets; str += "\n - Hideki/UPM (433.92) packets = " + enableHidekiPackets; str += "\n - AD (433.92) packets = " + enableADPackets; str += "\n - Mertik (433.92) packets = " + enableMertikPackets; str += "\n - Visonic (315/868.95) packets = " + enableVisonicPackets; str += "\n - ATI (433.92) packets = " + enableATIPackets; str += "\n - Oregon Scientific (433.92) packets = " + enableOregonPackets; str += "\n - Meiantech (433.92) packets = " + enableMeiantechPackets; str += "\n - HomeEasy EU (433.92) packets = " + enableHomeEasyPackets; str += "\n - AC (433.92) packets = " + enableACPackets; str += "\n - ARC (433.92) packets = " + enableARCPackets; str += "\n - X10 (310/433.92) packets = " + enableX10Packets; str += "\n - HomeConfort packets = " + enableHomeConfortPackets; str += "\n - KeeLoq (433.92) packets = " + enableKeeLoqPackets; return str; } /** * The format of message differ in some firmwares * Some messages with 13 bytes(14 with length) have an intermediate format * The firmware version is different for each hardware, * and the hardware version are in different position depending of message format * Actually we dont know how to detect correctly for all hardwares * * Apparently we can consider this versions are using new format * RFXtrx433 version 1 (HW version=1.0 ou 1.1 ?) : 95 * RFXtrx433 version 2 (HW version 1.2??) : 195 * RFXtrx433E (HW version 1.3??) : 251 * */ private boolean isIntermediateFormat() { return (firmwareVersion >= 95 && firmwareVersion <= 100) || (firmwareVersion >= 195 && firmwareVersion <= 200) || (firmwareVersion >= 251); } @Override public void encodeMessage(byte[] data) { super.encodeMessage(data); subType = SubType.fromByte(super.subType); command = Commands.fromByte(data[4]); transceiverType = TransceiverType.fromByte(data[5]); firmwareType = FirmwareType.UNKNOWN; if (data.length > 14) { firmwareVersion = (short) ((data[6] & 0xff) + 1000); for (FirmwareType type : FirmwareType.values()) { if (type.toByte() == data[14]) { firmwareType = type; break; } } } else { firmwareVersion = (short) (data[6] & 0xff); if (transceiverType == TransceiverType._433_92MHZ_RECEIVER_ONLY && firmwareVersion < 162) { firmwareType = FirmwareType.Type1_RFXRec; } else if (transceiverType == TransceiverType._433_92MHZ_TRANSCEIVER && firmwareVersion < 162) { firmwareType = FirmwareType.Type1; } else if (transceiverType == TransceiverType._433_92MHZ_TRANSCEIVER && (firmwareVersion >= 162 && firmwareVersion < 225)) { firmwareType = FirmwareType.Type2; } else { firmwareType = FirmwareType.Ext; } } enableUndecodedPackets = (data[7] & 0x80) != 0 ? true : false; enableRFU6Packets = (data[7] & 0x40) != 0 ? true : false; enableRFU5Packets = (data[7] & 0x20) != 0 ? true : false; enableRFU4Packets = (data[7] & 0x10) != 0 ? true : false; enableRFU3Packets = (data[7] & 0x08) != 0 ? true : false; enableFineOffsetPackets = (data[7] & 0x04) != 0 ? true : false; enableRubicsonPackets = (data[7] & 0x02) != 0 ? true : false; enableAEPackets = (data[7] & 0x01) != 0 ? true : false; enableBlindsT1Packets = (data[8] & 0x80) != 0 ? true : false; enableBlindsT0Packets = (data[8] & 0x40) != 0 ? true : false; enableProGuardPackets = (data[8] & 0x20) != 0 ? true : false; enableFS20Packets = (data[8] & 0x10) != 0 ? true : false; enableLaCrossePackets = (data[8] & 0x08) != 0 ? true : false; enableHidekiPackets = (data[8] & 0x04) != 0 ? true : false; enableADPackets = (data[8] & 0x02) != 0 ? true : false; enableMertikPackets = (data[8] & 0x01) != 0 ? true : false; enableVisonicPackets = (data[9] & 0x80) != 0 ? true : false; enableATIPackets = (data[9] & 0x40) != 0 ? true : false; enableOregonPackets = (data[9] & 0x20) != 0 ? true : false; enableMeiantechPackets = (data[9] & 0x10) != 0 ? true : false; enableHomeEasyPackets = (data[9] & 0x08) != 0 ? true : false; enableACPackets = (data[9] & 0x04) != 0 ? true : false; enableARCPackets = (data[9] & 0x02) != 0 ? true : false; enableX10Packets = (data[9] & 0x01) != 0 ? true : false; if (isIntermediateFormat() || data.length > 14) { enableHomeConfortPackets = (data[10] & 0x02) != 0 ? true : false; enableKeeLoqPackets = (data[10] & 0x01) != 0 ? true : false; hardwareVersion1 = data[11]; hardwareVersion2 = data[12]; outputPower = data[13]; } else { hardwareVersion1 = data[10]; hardwareVersion2 = data[11]; } } @Override public byte[] decodeMessage() { byte[] data = new byte[(firmwareVersion < 1000) ? 14 : 21]; data[0] = (byte) (data.length - 1); data[1] = RFXComBaseMessage.PacketType.INTERFACE_MESSAGE.toByte(); data[2] = subType.toByte(); data[3] = seqNbr; data[4] = command.toByte(); data[5] = transceiverType.toByte(); data[6] = (byte) (((firmwareVersion > 1000) ? (firmwareVersion - 1000) : firmwareVersion) & 0xff); data[7] |= enableUndecodedPackets ? 0x80 : 0x00; data[7] |= enableRFU6Packets ? 0x40 : 0x00; data[7] |= enableRFU5Packets ? 0x20 : 0x00; data[7] |= enableRFU4Packets ? 0x10 : 0x00; data[7] |= enableRFU3Packets ? 0x08 : 0x00; data[7] |= enableFineOffsetPackets ? 0x04 : 0x00; data[7] |= enableRubicsonPackets ? 0x02 : 0x00; data[7] |= enableAEPackets ? 0x01 : 0x00; data[8] |= enableBlindsT1Packets ? 0x80 : 0x00; data[8] |= enableBlindsT0Packets ? 0x40 : 0x00; data[8] |= enableProGuardPackets ? 0x20 : 0x00; data[8] |= enableFS20Packets ? 0x10 : 0x00; data[8] |= enableLaCrossePackets ? 0x08 : 0x00; data[8] |= enableHidekiPackets ? 0x04 : 0x00; data[8] |= enableADPackets ? 0x02 : 0x00; data[8] |= enableMertikPackets ? 0x01 : 0x00; data[9] |= enableVisonicPackets ? 0x80 : 0x00; data[9] |= enableATIPackets ? 0x40 : 0x00; data[9] |= enableOregonPackets ? 0x20 : 0x00; data[9] |= enableMeiantechPackets ? 0x10 : 0x00; data[9] |= enableHomeEasyPackets ? 0x08 : 0x00; data[9] |= enableACPackets ? 0x04 : 0x00; data[9] |= enableARCPackets ? 0x02 : 0x00; data[9] |= enableX10Packets ? 0x01 : 0x00; if (isIntermediateFormat() || firmwareVersion > 1000) { data[10] |= enableHomeConfortPackets ? 0x02 : 0x00; data[10] |= enableKeeLoqPackets ? 0x01 : 0x00; data[11] = hardwareVersion1; data[12] = hardwareVersion2; data[13] = outputPower; if (firmwareVersion > 1000) { data[14] = firmwareType.toByte(); } } else { data[10] = hardwareVersion1; data[11] = hardwareVersion2; } return data; } @Override public State convertToState(RFXComValueSelector valueSelector) throws RFXComException { throw new RFXComException("Not supported"); } @Override public void convertFromState(RFXComValueSelector valueSelector, String id, Object subType, Type type, byte seqNumber) throws RFXComException { throw new RFXComException("Not supported"); } @Override public Object convertSubType(String subType) throws RFXComException { for (SubType s : SubType.values()) { if (s.toString().equals(subType)) { return s; } } throw new RFXComException("Unknown sub type " + subType); } @Override public List<RFXComValueSelector> getSupportedValueSelectors() throws RFXComException { return null; } }