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