]> git.basschouten.com Git - openhab-addons.git/blob
b872161ce2e1456c4efc6318ffad9662c5cd175c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.RFXComBindingConstants.*;
16 import static org.openhab.binding.rfxcom.internal.messages.ByteEnumUtil.fromByte;
17
18 import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
19 import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
20 import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidStateException;
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.OnOffType;
25 import org.openhab.core.library.types.OpenClosedType;
26 import org.openhab.core.types.State;
27 import org.openhab.core.types.Type;
28
29 /**
30  * RFXCOM data class for lighting6 message. See Blyss.
31  *
32  * @author Damien Servant - Initial contribution
33  * @author Pauli Anttila - Migrated for OH2
34  */
35 public class RFXComLighting6Message extends RFXComDeviceMessageImpl<RFXComLighting6Message.SubType> {
36
37     public enum SubType implements ByteEnumWrapper {
38         BLYSS(0);
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         ON(0),
54         OFF(1),
55         GROUP_ON(2),
56         GROUP_OFF(3);
57
58         private final int command;
59
60         Commands(int command) {
61             this.command = command;
62         }
63
64         @Override
65         public byte toByte() {
66             return (byte) command;
67         }
68     }
69
70     public SubType subType;
71     public int sensorId;
72     public char groupCode;
73     public byte unitCode;
74     public Commands command;
75
76     public RFXComLighting6Message() {
77         super(PacketType.LIGHTING6);
78     }
79
80     public RFXComLighting6Message(byte[] data) throws RFXComException {
81         encodeMessage(data);
82     }
83
84     @Override
85     public String toString() {
86         String str = "";
87
88         str += super.toString();
89         str += ", Sub type = " + subType;
90         str += ", Device Id = " + getDeviceId();
91         str += ", Command = " + command;
92         str += ", Signal level = " + signalLevel;
93
94         return str;
95     }
96
97     @Override
98     public void encodeMessage(byte[] data) throws RFXComException {
99         super.encodeMessage(data);
100
101         subType = fromByte(SubType.class, super.subType);
102         sensorId = (data[4] & 0xFF) << 8 | (data[5] & 0xFF);
103         groupCode = (char) data[6];
104         unitCode = data[7];
105         command = fromByte(Commands.class, data[8]);
106
107         signalLevel = (byte) ((data[11] & 0xF0) >> 4);
108     }
109
110     @Override
111     public byte[] decodeMessage() {
112         // Example data 0B 15 00 02 01 01 41 01 00 04 8E 00
113         // 0B 15 00 02 01 01 41 01 01 04 8E 00
114
115         byte[] data = new byte[12];
116
117         data[0] = 0x0B;
118         data[1] = RFXComBaseMessage.PacketType.LIGHTING6.toByte();
119         data[2] = subType.toByte();
120         data[3] = seqNbr;
121         data[4] = (byte) ((sensorId >> 8) & 0xFF);
122         data[5] = (byte) (sensorId & 0xFF);
123         data[6] = (byte) groupCode;
124         data[7] = unitCode;
125         data[8] = command.toByte();
126         data[9] = 0x00; // CmdSeqNbr1 - 0 to 4 - Useless for a Blyss Switch
127         data[10] = 0x00; // CmdSeqNbr2 - 0 to 145 - Useless for a Blyss Switch
128         data[11] = (byte) ((signalLevel & 0x0F) << 4);
129
130         return data;
131     }
132
133     @Override
134     public String getDeviceId() {
135         return sensorId + ID_DELIMITER + groupCode + ID_DELIMITER + unitCode;
136     }
137
138     @Override
139     public State convertToState(String channelId, RFXComDeviceConfiguration config, DeviceState deviceState)
140             throws RFXComUnsupportedChannelException, RFXComInvalidStateException {
141         switch (channelId) {
142             case CHANNEL_COMMAND:
143                 switch (command) {
144                     case OFF:
145                     case GROUP_OFF:
146                         return OnOffType.OFF;
147
148                     case ON:
149                     case GROUP_ON:
150                         return OnOffType.ON;
151
152                     default:
153                         throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
154                 }
155
156             case CHANNEL_CONTACT:
157                 switch (command) {
158                     case OFF:
159                     case GROUP_OFF:
160                         return OpenClosedType.CLOSED;
161
162                     case ON:
163                     case GROUP_ON:
164                         return OpenClosedType.OPEN;
165
166                     default:
167                         throw new RFXComUnsupportedChannelException("Can't convert " + command + " for " + channelId);
168                 }
169
170             default:
171                 return super.convertToState(channelId, config, deviceState);
172         }
173     }
174
175     @Override
176     public void setSubType(SubType subType) {
177         this.subType = subType;
178     }
179
180     @Override
181     public void setDeviceId(String deviceId) throws RFXComException {
182         String[] ids = deviceId.split("\\" + ID_DELIMITER);
183         if (ids.length != 3) {
184             throw new RFXComException("Invalid device id '" + deviceId + "'");
185         }
186
187         sensorId = Integer.parseInt(ids[0]);
188         groupCode = ids[1].charAt(0);
189         unitCode = Byte.parseByte(ids[2]);
190     }
191
192     @Override
193     public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
194         switch (channelId) {
195             case CHANNEL_COMMAND:
196                 if (type instanceof OnOffType) {
197                     command = (type == OnOffType.ON ? Commands.ON : Commands.OFF);
198
199                 } else {
200                     throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
201                 }
202                 break;
203
204             default:
205                 throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
206         }
207     }
208
209     @Override
210     public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
211         return ByteEnumUtil.convertSubType(SubType.class, subType);
212     }
213 }