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