]> git.basschouten.com Git - openhab-addons.git/blob
29e01d5dc3278f6aa78c70d6c25e35f24b063590
[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.OpenClosedType;
25 import org.openhab.core.library.types.StopMoveType;
26 import org.openhab.core.library.types.UpDownType;
27 import org.openhab.core.types.State;
28 import org.openhab.core.types.Type;
29
30 /**
31  * RFXCOM data class for blinds1 message.
32  *
33  * @author Peter Janson / Pål Edman - Initial contribution
34  * @author Pauli Anttila - Migration to OH2
35  * @author Fabien Le Bars - Added support for Cherubini blinds
36  */
37 public class RFXComBlinds1Message extends RFXComBatteryDeviceMessage<RFXComBlinds1Message.SubType> {
38
39     public enum SubType implements ByteEnumWrapper {
40         T0(0), // Hasta new/RollerTrol
41         T1(1), // Hasta Old
42         T2(2), // A-OK RF01
43         T3(3), // A-OK AC114/AC123/Motorlux
44         T4(4), // Raex YR1326
45         T5(5), // MEDIA MOUNT have different direction commands than the rest!! Needs to be fixed.
46         T6(6), // DC106/Rohrmotor24-RMF/Yooda/Dooya/ESMO/Brel/Quitidom
47         T7(7), // Forest
48         T8(8), // Chamberlain CS4330
49         T9(9), // Sunpery/BTX
50         T10(10), // Dolat DLM-1, Topstar
51         T11(11), // ASP
52         T12(12), // Confexx CNF24-2435
53         T13(13), // Screenline
54         T14(14), // Hualite
55         T15(15), // Motostar
56         T16(16), // Zemismart
57         T17(17), // Gaposa
58         T18(18), // Cherubini
59         T19(19), // Louvolite One Touch Vogue motor
60         T20(20); // OZRoll
61
62         private final int subType;
63
64         SubType(int subType) {
65             this.subType = subType;
66         }
67
68         @Override
69         public byte toByte() {
70             return (byte) subType;
71         }
72     }
73
74     public enum Commands implements ByteEnumWrapper {
75         OPEN(0), // MediaMount DOWN(0),
76         CLOSE(1), // MediaMount UPP(1),
77         STOP(2),
78         CONFIRM(3),
79         SET_LIMIT(4), // YR1326 SET_UPPER_LIMIT(4),
80         SET_LOWER_LIMIT(5), // YR1326
81         DELETE_LIMITS(6), // YR1326
82         CHANGE_DIRECTON(7); // YR1326
83
84         private final int command;
85
86         Commands(int command) {
87             this.command = command;
88         }
89
90         @Override
91         public byte toByte() {
92             return (byte) command;
93         }
94     }
95
96     public SubType subType;
97     public int sensorId;
98     public byte unitCode;
99     public Commands command;
100
101     public RFXComBlinds1Message() {
102         super(PacketType.BLINDS1);
103     }
104
105     public RFXComBlinds1Message(byte[] data) throws RFXComException {
106         encodeMessage(data);
107     }
108
109     @Override
110     public String toString() {
111         String str = "";
112
113         str += super.toString();
114         str += ", Sub type = " + subType;
115         str += ", Device Id = " + getDeviceId();
116         str += ", Command = " + command;
117         str += ", Signal level = " + signalLevel;
118         str += ", Battery level = " + batteryLevel;
119
120         return str;
121     }
122
123     @Override
124     public void encodeMessage(byte[] data) throws RFXComException {
125         super.encodeMessage(data);
126
127         subType = fromByte(SubType.class, super.subType);
128
129         if (subType == SubType.T6 || subType == SubType.T7 || subType == SubType.T9) {
130             sensorId = (data[4] & 0xFF) << 20 | (data[5] & 0xFF) << 12 | (data[6] & 0xFF) << 4 | (data[7] & 0xF0) >> 4;
131             unitCode = (byte) (data[7] & 0x0F);
132         } else {
133             sensorId = (data[4] & 0xFF) << 16 | (data[5] & 0xFF) << 8 | (data[6] & 0xFF);
134             unitCode = data[7];
135         }
136
137         command = fromByte(Commands.class, data[8]);
138
139         signalLevel = (byte) ((data[9] & 0xF0) >> 4);
140         batteryLevel = (byte) (data[9] & 0x0F);
141     }
142
143     @Override
144     public byte[] decodeMessage() {
145         // Example data
146         // BLINDS1 09 19 00 06 00 B1 8F 01 00 70
147
148         byte[] data = new byte[10];
149
150         data[0] = 0x09;
151         data[1] = RFXComBaseMessage.PacketType.BLINDS1.toByte();
152         data[2] = subType.toByte();
153         data[3] = seqNbr;
154
155         if (subType == SubType.T6) {
156             data[4] = (byte) ((sensorId >>> 20) & 0xFF);
157             data[5] = (byte) ((sensorId >>> 12) & 0xFF);
158             data[6] = (byte) ((sensorId >>> 4) & 0xFF);
159             data[7] = (byte) (((sensorId & 0x0F) << 4) | (unitCode & 0x0F));
160         } else {
161             data[4] = (byte) ((sensorId >> 16) & 0xFF);
162             data[5] = (byte) ((sensorId >> 8) & 0xFF);
163             data[6] = (byte) (sensorId & 0xFF);
164             data[7] = unitCode;
165         }
166
167         data[8] = command.toByte();
168         data[9] = (byte) (((signalLevel & 0x0F) << 4) | (batteryLevel & 0x0F));
169
170         return data;
171     }
172
173     @Override
174     public String getDeviceId() {
175         return sensorId + ID_DELIMITER + unitCode;
176     }
177
178     @Override
179     public State convertToState(String channelId, RFXComDeviceConfiguration config, DeviceState deviceState)
180             throws RFXComUnsupportedChannelException, RFXComInvalidStateException {
181         if (CHANNEL_COMMAND.equals(channelId)) {
182             return (command == Commands.CLOSE ? OpenClosedType.CLOSED : OpenClosedType.OPEN);
183         } else {
184             return super.convertToState(channelId, config, deviceState);
185         }
186     }
187
188     @Override
189     public void setSubType(SubType subType) {
190         this.subType = subType;
191     }
192
193     @Override
194     public void setDeviceId(String deviceId) throws RFXComException {
195         String[] ids = deviceId.split("\\" + ID_DELIMITER);
196         if (ids.length != 2) {
197             throw new RFXComException("Invalid device id '" + deviceId + "'");
198         }
199
200         sensorId = Integer.parseInt(ids[0]);
201         unitCode = Byte.parseByte(ids[1]);
202     }
203
204     @Override
205     public void convertFromState(String channelId, Type type) throws RFXComUnsupportedChannelException {
206         if (CHANNEL_SHUTTER.equals(channelId)) {
207             if (type instanceof OpenClosedType) {
208                 command = (type == OpenClosedType.CLOSED ? Commands.CLOSE : Commands.OPEN);
209             } else if (type instanceof UpDownType) {
210                 command = (type == UpDownType.UP ? Commands.OPEN : Commands.CLOSE);
211             } else if (type instanceof StopMoveType) {
212                 command = Commands.STOP;
213             } else {
214                 throw new RFXComUnsupportedChannelException("Channel " + channelId + " does not accept " + type);
215             }
216         } else {
217             throw new RFXComUnsupportedChannelException("Channel " + channelId + " is not relevant here");
218         }
219     }
220
221     @Override
222     public SubType convertSubType(String subType) throws RFXComUnsupportedValueException {
223         return ByteEnumUtil.convertSubType(SubType.class, subType);
224     }
225 }