]> git.basschouten.com Git - openhab-addons.git/blob
72a3a54c82ee415701ab3c0d18f0067f352ba1e8
[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.velbus.internal.handler;
14
15 import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
16
17 import java.util.Arrays;
18 import java.util.HashSet;
19 import java.util.Set;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.velbus.internal.VelbusChannelIdentifier;
23 import org.openhab.binding.velbus.internal.packets.VelbusButtonPacket;
24 import org.openhab.binding.velbus.internal.packets.VelbusFeedbackLEDPacket;
25 import org.openhab.binding.velbus.internal.packets.VelbusPacket;
26 import org.openhab.core.library.types.StringType;
27 import org.openhab.core.thing.ChannelUID;
28 import org.openhab.core.thing.CommonTriggerEvents;
29 import org.openhab.core.thing.Thing;
30 import org.openhab.core.thing.ThingStatus;
31 import org.openhab.core.thing.ThingStatusDetail;
32 import org.openhab.core.thing.ThingTypeUID;
33 import org.openhab.core.types.Command;
34
35 /**
36  * The {@link VelbusSensorHandler} is responsible for handling commands, which are
37  * sent to one of the channels.
38  *
39  * @author Cedric Boon - Initial contribution
40  * @author Daniel Rosengarten - Add button simulation
41  */
42 @NonNullByDefault
43 public class VelbusSensorHandler extends VelbusThingHandler {
44     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
45             Arrays.asList(THING_TYPE_VMB6IN, THING_TYPE_VMB8IR, THING_TYPE_VMB8PB));
46
47     private static final StringType SET_LED = new StringType("SET_LED");
48     private static final StringType SLOW_BLINK_LED = new StringType("SLOW_BLINK_LED");
49     private static final StringType FAST_BLINK_LED = new StringType("FAST_BLINK_LED");
50     private static final StringType VERY_FAST_BLINK_LED = new StringType("VERY_FAST_BLINK_LED");
51     private static final StringType CLEAR_LED = new StringType("CLEAR_LED");
52
53     private static final StringType PRESSED = new StringType("PRESSED");
54     private static final StringType LONG_PRESSED = new StringType("LONG_PRESSED");
55
56     public VelbusSensorHandler(Thing thing) {
57         this(thing, 0);
58     }
59
60     public VelbusSensorHandler(Thing thing, int numberOfSubAddresses) {
61         super(thing, numberOfSubAddresses);
62     }
63
64     @Override
65     public void handleCommand(ChannelUID channelUID, Command command) {
66         VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
67         if (velbusBridgeHandler == null) {
68             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
69             return;
70         }
71
72         if (isFeedbackChannel(channelUID) && command instanceof StringType stringCommand) {
73             byte commandByte;
74             if (stringCommand.equals(SET_LED)) {
75                 commandByte = COMMAND_SET_LED;
76             } else if (stringCommand.equals(SLOW_BLINK_LED)) {
77                 commandByte = COMMAND_SLOW_BLINK_LED;
78             } else if (stringCommand.equals(FAST_BLINK_LED)) {
79                 commandByte = COMMAND_FAST_BLINK_LED;
80             } else if (stringCommand.equals(VERY_FAST_BLINK_LED)) {
81                 commandByte = COMMAND_VERY_FAST_BLINK_LED;
82             } else if (stringCommand.equals(CLEAR_LED)) {
83                 commandByte = COMMAND_CLEAR_LED;
84             } else {
85                 throw new UnsupportedOperationException(
86                         "The command '" + command + "' is not supported on channel '" + channelUID + "'.");
87             }
88
89             VelbusFeedbackLEDPacket packet = new VelbusFeedbackLEDPacket(
90                     getModuleAddress().getChannelIdentifier(channelUID), commandByte);
91
92             byte[] packetBytes = packet.getBytes();
93             velbusBridgeHandler.sendPacket(packetBytes);
94         }
95
96         if (isButtonChannel(channelUID) && command instanceof StringType stringCommand) {
97             if (stringCommand.equals(PRESSED) || stringCommand.equals(LONG_PRESSED)) {
98                 VelbusButtonPacket packet = new VelbusButtonPacket(getModuleAddress().getChannelIdentifier(channelUID));
99
100                 packet.Pressed();
101                 velbusBridgeHandler.sendPacket(packet.getBytes());
102                 triggerChannel("input#CH" + getModuleAddress().getChannelNumber(channelUID),
103                         CommonTriggerEvents.PRESSED);
104
105                 if (stringCommand.equals(LONG_PRESSED)) {
106                     packet.LongPressed();
107                     velbusBridgeHandler.sendPacket(packet.getBytes());
108                     triggerChannel("input#CH" + getModuleAddress().getChannelNumber(channelUID),
109                             CommonTriggerEvents.LONG_PRESSED);
110                 }
111
112                 packet.Released();
113                 velbusBridgeHandler.sendPacket(packet.getBytes());
114                 triggerChannel("input#CH" + getModuleAddress().getChannelNumber(channelUID),
115                         CommonTriggerEvents.RELEASED);
116             } else {
117                 throw new UnsupportedOperationException(
118                         "The command '" + command + "' is not supported on channel '" + channelUID + "'.");
119             }
120         }
121     }
122
123     private boolean isFeedbackChannel(ChannelUID channelUID) {
124         return "feedback".equals(channelUID.getGroupId());
125     }
126
127     private boolean isButtonChannel(ChannelUID channelUID) {
128         return "button".equals(channelUID.getGroupId());
129     }
130
131     @Override
132     public void onPacketReceived(byte[] packet) {
133         logger.trace("onPacketReceived() was called");
134
135         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
136             byte address = packet[2];
137             byte command = packet[4];
138
139             if (command == COMMAND_PUSH_BUTTON_STATUS && packet.length >= 6) {
140                 for (int channel = 0; channel < 8; channel++) {
141                     byte channelMask = (byte) Math.pow(2, channel);
142
143                     byte channelJustPressed = (byte) (packet[5] & channelMask);
144                     if (channelJustPressed != 0) {
145                         VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address,
146                                 channelJustPressed);
147                         triggerChannel("input#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
148                                 CommonTriggerEvents.PRESSED);
149                     }
150
151                     byte channelJustReleased = (byte) (packet[6] & channelMask);
152                     if (channelJustReleased != 0) {
153                         VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address,
154                                 channelJustReleased);
155                         triggerChannel("input#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
156                                 CommonTriggerEvents.RELEASED);
157                     }
158
159                     byte channelLongPressed = (byte) (packet[7] & channelMask);
160                     if (channelLongPressed != 0) {
161                         VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address,
162                                 channelLongPressed);
163                         triggerChannel("input#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
164                                 CommonTriggerEvents.LONG_PRESSED);
165                     }
166                 }
167             }
168         }
169     }
170 }