]> git.basschouten.com Git - openhab-addons.git/blob
b8feccd0a3f81232400b900c706ae45802ab89d4
[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.F6_02;
14
15 import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.openhab.binding.enocean.internal.config.EnOceanChannelRockerSwitchConfigBase.SwitchMode;
20 import org.openhab.binding.enocean.internal.eep.Base._RPSMessage;
21 import org.openhab.binding.enocean.internal.messages.ERP1Message;
22 import org.openhab.core.config.core.Configuration;
23 import org.openhab.core.library.types.OnOffType;
24 import org.openhab.core.library.types.UpDownType;
25 import org.openhab.core.thing.CommonTriggerEvents;
26 import org.openhab.core.types.State;
27 import org.openhab.core.types.UnDefType;
28
29 /**
30  *
31  * @author Daniel Weber - Initial contribution
32  */
33 @NonNullByDefault
34 public abstract class F6_02 extends _RPSMessage {
35
36     protected static final byte AI = 0;
37     protected static final byte A0 = 1;
38     protected static final byte BI = 2;
39     protected static final byte B0 = 3;
40     protected static final byte PRESSED = 16;
41     protected static final byte PRESSED_SEC = 1;
42
43     protected static final String DIR1 = "DIR1";
44     protected static final String DIR2 = "DIR2";
45     protected static final String NODIR = "-";
46
47     int secondByte = -1;
48     int secondStatus = -1;
49
50     public F6_02() {
51         super();
52     }
53
54     public F6_02(ERP1Message packet) {
55         super(packet);
56     }
57
58     private String getChannelADir() {
59         if ((bytes[0] >>> 5) == A0 && (bytes[0] & PRESSED) != 0) {
60             return DIR1;
61         } else if ((bytes[0] >>> 5) == AI && (bytes[0] & PRESSED) != 0) {
62             return DIR2;
63         } else {
64             return NODIR;
65         }
66     }
67
68     private String getChannelBDir() {
69         if ((bytes[0] >>> 5) == B0 && (bytes[0] & PRESSED) != 0) {
70             return DIR1;
71         } else if ((bytes[0] >>> 5) == BI && (bytes[0] & PRESSED) != 0) {
72             return DIR2;
73         } else if (((bytes[0] & 0xf) >>> 1) == B0 && (bytes[0] & PRESSED_SEC) != 0) {
74             return DIR1;
75         } else if (((bytes[0] & 0xf) >>> 1) == BI && (bytes[0] & PRESSED_SEC) != 0) {
76             return DIR2;
77         } else {
78             return NODIR;
79         }
80     }
81
82     protected String getRockerSwitchAction(Configuration config) {
83         String dirA = getChannelADir();
84         String dirB = getChannelBDir();
85
86         return dirA + "|" + dirB;
87     }
88
89     protected @Nullable String getChannelEvent(byte dir1, byte dir2) {
90         if ((bytes[0] & PRESSED_SEC) != 0) {
91             // Do not emit an event if channelA is pressed together with channelB as it is undetermined which one gets
92             // fired first
93             return null;
94         } else if ((bytes[0] >>> 5) == dir1) {
95             return ((bytes[0] & PRESSED) != 0) ? CommonTriggerEvents.DIR1_PRESSED : CommonTriggerEvents.DIR1_RELEASED;
96         } else if ((bytes[0] >>> 5) == dir2) {
97             return ((bytes[0] & PRESSED) != 0) ? CommonTriggerEvents.DIR2_PRESSED : CommonTriggerEvents.DIR2_RELEASED;
98         } else {
99             return null;
100         }
101     }
102
103     protected State getState(byte dir1, byte dir2, boolean handleSecondAction, SwitchMode switchMode,
104             String channelTypeId, State currentState) {
105         // We are just listening on the pressed event here
106         switch (switchMode) {
107             case RockerSwitch:
108                 if ((bytes[0] >>> 5) == dir1) {
109                     if (((bytes[0] & PRESSED) != 0)) {
110                         return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.ON : UpDownType.UP;
111                     }
112                 } else if ((bytes[0] >>> 5) == dir2) {
113                     if (((bytes[0] & PRESSED) != 0)) {
114                         return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.OFF
115                                 : UpDownType.DOWN;
116                     }
117                 } else if (handleSecondAction && ((bytes[0] & 0xf) >>> 1) == dir1) {
118                     if (((bytes[0] & PRESSED_SEC) != 0)) {
119                         return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.ON : UpDownType.UP;
120                     }
121                 } else if (handleSecondAction && ((bytes[0] & 0xf) >>> 1) == dir2) {
122                     if (((bytes[0] & PRESSED_SEC) != 0)) {
123                         return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.OFF
124                                 : UpDownType.DOWN;
125                     }
126                 }
127                 break;
128             case ToggleDir1:
129                 if ((bytes[0] >>> 5) == dir1) {
130                     if (((bytes[0] & PRESSED) != 0)) {
131                         return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
132                                 ? (currentState == UnDefType.UNDEF ? OnOffType.ON : inverse((OnOffType) currentState))
133                                 : (currentState == UnDefType.UNDEF ? UpDownType.UP
134                                         : inverse((UpDownType) currentState));
135                     }
136                 } else if (handleSecondAction && ((bytes[0] & 0xf) >>> 1) == dir1) {
137                     if (((bytes[0] & PRESSED_SEC) != 0)) {
138                         return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
139                                 ? (currentState == UnDefType.UNDEF ? OnOffType.ON : inverse((OnOffType) currentState))
140                                 : (currentState == UnDefType.UNDEF ? UpDownType.UP
141                                         : inverse((UpDownType) currentState));
142                     }
143                 }
144                 break;
145             case ToggleDir2:
146                 if ((bytes[0] >>> 5) == dir2) {
147                     if (((bytes[0] & PRESSED) != 0)) {
148                         return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
149                                 ? (currentState == UnDefType.UNDEF ? OnOffType.ON : inverse((OnOffType) currentState))
150                                 : (currentState == UnDefType.UNDEF ? UpDownType.UP
151                                         : inverse((UpDownType) currentState));
152                     }
153                 } else if (handleSecondAction && ((bytes[0] & 0xf) >>> 1) == dir2) {
154                     if (((bytes[0] & PRESSED_SEC) != 0)) {
155                         return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
156                                 ? (currentState == UnDefType.UNDEF ? OnOffType.ON : inverse((OnOffType) currentState))
157                                 : (currentState == UnDefType.UNDEF ? UpDownType.UP
158                                         : inverse((UpDownType) currentState));
159                     }
160                 }
161                 break;
162             default:
163                 break;
164         }
165
166         return UnDefType.UNDEF;
167     }
168
169     protected State inverse(OnOffType currentState) {
170         return currentState == OnOffType.ON ? OnOffType.OFF : OnOffType.ON;
171     }
172
173     protected State inverse(UpDownType currentState) {
174         return currentState == UpDownType.UP ? UpDownType.DOWN : UpDownType.UP;
175     }
176
177     @Override
178     protected boolean validateData(byte[] bytes) {
179         return super.validateData(bytes) && !getBit(bytes[0], 7);
180     }
181 }