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