]> git.basschouten.com Git - openhab-addons.git/blob
be36533b80ee85e370b0e0f411a86c141cc9136c
[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.enocean.internal.eep.A5_38;
14
15 import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*;
16
17 import java.util.function.Function;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.enocean.internal.eep.Base._4BSMessage;
22 import org.openhab.binding.enocean.internal.messages.ERP1Message;
23 import org.openhab.core.config.core.Configuration;
24 import org.openhab.core.library.types.DecimalType;
25 import org.openhab.core.library.types.OnOffType;
26 import org.openhab.core.library.types.PercentType;
27 import org.openhab.core.library.types.QuantityType;
28 import org.openhab.core.library.types.StopMoveType;
29 import org.openhab.core.library.types.UpDownType;
30 import org.openhab.core.library.unit.Units;
31 import org.openhab.core.types.Command;
32 import org.openhab.core.types.State;
33 import org.openhab.core.types.UnDefType;
34
35 /**
36  *
37  * @author Daniel Weber - Initial contribution
38  */
39 @NonNullByDefault
40 public class A5_38_08_Blinds extends _4BSMessage {
41
42     static final byte COMMAND_ID = 0x07;
43     static final byte POSITION_AND_ANGLE_AVAILABLE = 0x02;
44     static final byte SEND_NEW_STATE = 0x04;
45
46     static final byte FUNCTION_STATUS_REQUEST = 0x00;
47     static final byte FUNCTION_BLIND_STOPS = 0x01;
48     static final byte FUNCTION_BLIND_OPENS = 0x02;
49     static final byte FUNCTION_BLIND_CLOSES = 0x03;
50     static final byte FUNCTION_BLIND_POSITION_ANGLE = 0x04;
51     static final byte FUNCTION_BLIND_OPENS_FOR_TIME = 0x05;
52     static final byte FUNCTION_BLIND_CLOSES_FOR_TIME = 0x06;
53     static final byte FUNCTION_SET_RUNTIME_PARAMETERS = 0x07;
54     static final byte FUNCTION_SET_ANGLE_CONFIGURATIONE = 0x08;
55     static final byte FUNCTION_SET_MIN_MAX = 0x09;
56     static final byte FUNCTION_SET_SLAT_ANGLE = 0x0A;
57     static final byte FUNCTION_SET_POSITION_LOGIC = 0x0B;
58
59     public A5_38_08_Blinds() {
60         super();
61     }
62
63     public A5_38_08_Blinds(ERP1Message packet) {
64         super(packet);
65     }
66
67     @Override
68     protected void convertFromCommandImpl(String channelId, String channelTypeId, Command outputCommand,
69             Function<String, State> getCurrentStateFunc, @Nullable Configuration config) {
70         switch (channelId) {
71             case CHANNEL_ROLLERSHUTTER:
72                 byte db0 = ZERO | SEND_NEW_STATE | TEACHIN_BIT;
73                 byte db1 = ZERO;
74                 byte db2 = ZERO;
75
76                 byte position;
77                 byte angle = 0; // for now, no angle configuration supported
78                 boolean doStop = false;
79
80                 if (outputCommand instanceof DecimalType decimalCommand) {
81                     position = decimalCommand.byteValue();
82                 } else if (outputCommand instanceof OnOffType onOffCommand) {
83                     position = (byte) ((onOffCommand == OnOffType.ON) ? 0 : 100);
84                 } else if (outputCommand instanceof StopMoveType) {
85                     position = ZERO;
86                     doStop = true;
87                 } else if (outputCommand instanceof UpDownType upDownCommand) {
88                     position = (byte) ((upDownCommand == UpDownType.UP) ? 0 : 100);
89                 } else {
90                     logger.warn("Unknown command type {}", outputCommand.getClass().getCanonicalName());
91                     return;
92                 }
93
94                 if (doStop) {
95                     db0 |= FUNCTION_BLIND_STOPS << 4;
96                 } else if (position <= 0) {
97                     db0 |= FUNCTION_BLIND_OPENS << 4;
98                 } else if (position >= 100) {
99                     db0 |= FUNCTION_BLIND_CLOSES << 4;
100                 } else {
101                     db0 |= (FUNCTION_BLIND_POSITION_ANGLE << 4) | POSITION_AND_ANGLE_AVAILABLE;
102
103                     if (angle < 0) {
104                         db1 = (byte) ((0x01 << 7) | ((angle / -2) & 0x7F));
105                     } else {
106                         db1 = (byte) (((angle / 2) & 0x7F));
107                     }
108
109                     db2 = position;
110                 }
111
112                 setData(COMMAND_ID, db2, db1, db0);
113                 return;
114             case CHANNEL_ANGLE:
115                 return; // for now, no angle configuration supported
116         }
117     }
118
119     protected State getPositionData() {
120         byte db0 = getDB0();
121         boolean paf = getBit(db0, 1);
122
123         if (paf) {
124             int bsp = getDB2Value();
125
126             if ((bsp >= 0) && (bsp <= 100)) {
127                 return new PercentType(bsp);
128             }
129         }
130
131         return UnDefType.UNDEF;
132     }
133
134     protected State getAngleData() {
135         byte db0 = getDB0();
136         boolean paf = getBit(db0, 1);
137
138         if (paf) {
139             byte db1 = getDB1();
140
141             boolean as = getBit(db1, 7);
142             int an = (db1 & 0x7F) * 2;
143
144             if ((an >= 0) && (an <= 180)) {
145                 return new QuantityType<>(as ? an * -1 : an, Units.DEGREE_ANGLE);
146             }
147         }
148
149         return UnDefType.UNDEF;
150     }
151
152     @Override
153     public State convertToStateImpl(String channelId, String channelTypeId,
154             Function<String, @Nullable State> getCurrentStateFunc, Configuration config) {
155         switch (channelId) {
156             case CHANNEL_ROLLERSHUTTER:
157                 return getPositionData();
158             case CHANNEL_ANGLE:
159                 return getAngleData();
160         }
161
162         return UnDefType.UNDEF;
163     }
164 }