2 * Copyright (c) 2010-2020 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.RFXComBindingConstants.*;
16 import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
18 import java.util.Arrays;
20 import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
21 import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedChannelException;
22 import org.openhab.binding.rfxcom.internal.exceptions.RFXComUnsupportedValueException;
23 import org.openhab.binding.rfxcom.internal.handler.DeviceState;
24 import org.openhab.core.library.types.OpenClosedType;
25 import org.openhab.core.types.State;
26 import org.openhab.core.types.Type;
29 * RFXCOM data class for Security2 message.
32 * @author Mike Jagdis - Initial contribution
34 public class RFXComSecurity2Message extends RFXComBatteryDeviceMessage<RFXComSecurity2Message.SubType> {
36 public enum SubType implements ByteEnumWrapper {
37 RAW_CLASSIC_KEELOQ(0),
38 ROLLING_CODE_PACKET(1),
40 RAW_CLASS_KEELOQ_WITH_REPEATS(3);
42 private final int subType;
44 SubType(int subType) {
45 this.subType = subType;
49 public byte toByte() {
50 return (byte) subType;
54 public SubType subType;
56 public int buttonStatus;
58 private static final int BUTTON_0_BIT = 0x02;
59 private static final int BUTTON_1_BIT = 0x04;
60 private static final int BUTTON_2_BIT = 0x08;
61 private static final int BUTTON_3_BIT = 0x01;
63 public RFXComSecurity2Message() {
64 super(PacketType.SECURITY2);
67 public RFXComSecurity2Message(byte[] data) throws RFXComException {
72 public String toString() {
73 return super.toString() + ", Sub type = " + subType + ", Device Id = " + getDeviceId() + ", Button status = "
74 + buttonStatus + ", Battery level = " + batteryLevel + ", Signal level = " + signalLevel;
78 public void encodeMessage(byte[] data) throws RFXComException {
79 super.encodeMessage(data);
81 subType = fromByte(SubType.class, super.subType);
83 sensorId = (data[11] & 0x0F) << 24 | (data[10] & 0xFF) << 16 | (data[9] & 0xFF) << 8 | (data[8] & 0xFF);
85 buttonStatus = (data[11] & 0xF0) >> 4;
87 batteryLevel = (byte) ((data[28] & 0xF0) >> 4);
88 signalLevel = (byte) (data[28] & 0x0F);
92 public byte[] decodeMessage() {
93 byte[] data = new byte[29];
95 Arrays.fill(data, (byte) 0);
98 data[1] = RFXComBaseMessage.PacketType.SECURITY2.toByte();
99 data[2] = subType.toByte();
102 data[8] = (byte) (sensorId & 0xFF);
103 data[9] = (byte) ((sensorId >> 8) & 0xFF);
104 data[10] = (byte) ((sensorId >> 16) & 0xFF);
105 data[11] = (byte) ((buttonStatus & 0x0f) << 4 | (sensorId >> 24) & 0x0F);
107 data[28] = (byte) (((batteryLevel & 0x0F) << 4) | (signalLevel & 0x0F));
113 public String getDeviceId() {
114 return String.valueOf(sensorId);
118 public State convertToState(String channelId, DeviceState deviceState) throws RFXComUnsupportedChannelException {
120 case CHANNEL_CONTACT:
121 return ((buttonStatus & BUTTON_0_BIT) == 0) ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
123 case CHANNEL_CONTACT_1:
124 return ((buttonStatus & BUTTON_1_BIT) == 0) ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
126 case CHANNEL_CONTACT_2:
127 return ((buttonStatus & BUTTON_2_BIT) == 0) ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
129 case CHANNEL_CONTACT_3:
130 return ((buttonStatus & BUTTON_3_BIT) == 0) ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
133 return super.convertToState(channelId, deviceState);
138 public void setSubType(SubType subType) {
139 this.subType = subType;
143 public void setDeviceId(String deviceId) {
144 sensorId = Integer.parseInt(deviceId);
148 public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
150 case CHANNEL_CONTACT:
151 if (type instanceof OpenClosedType) {
152 if (type == OpenClosedType.CLOSED) {
153 buttonStatus |= BUTTON_0_BIT;
155 buttonStatus &= ~BUTTON_0_BIT;
159 throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
163 case CHANNEL_CONTACT_1:
164 if (type instanceof OpenClosedType) {
165 if (type == OpenClosedType.CLOSED) {
166 buttonStatus |= BUTTON_1_BIT;
168 buttonStatus &= ~BUTTON_1_BIT;
172 throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
176 case CHANNEL_CONTACT_2:
177 if (type instanceof OpenClosedType) {
178 if (type == OpenClosedType.CLOSED) {
179 buttonStatus |= BUTTON_2_BIT;
181 buttonStatus &= ~BUTTON_2_BIT;
185 throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
189 case CHANNEL_CONTACT_3:
190 if (type instanceof OpenClosedType) {
191 if (type == OpenClosedType.CLOSED) {
192 buttonStatus |= BUTTON_3_BIT;
194 buttonStatus &= ~BUTTON_3_BIT;
198 throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
203 throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
208 public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
209 return ByteEnumUtil.convertSubType(SubType.class, subType);