2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.velbus.internal.handler;
15 import static org.openhab.binding.velbus.internal.VelbusBindingConstants.*;
17 import java.util.Arrays;
18 import java.util.HashSet;
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;
36 * The {@link VelbusSensorHandler} is responsible for handling commands, which are
37 * sent to one of the channels.
39 * @author Cedric Boon - Initial contribution
40 * @author Daniel Rosengarten - Add button simulation
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));
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");
53 private static final StringType PRESSED = new StringType("PRESSED");
54 private static final StringType LONG_PRESSED = new StringType("LONG_PRESSED");
56 public VelbusSensorHandler(Thing thing) {
60 public VelbusSensorHandler(Thing thing, int numberOfSubAddresses) {
61 super(thing, numberOfSubAddresses);
65 public void handleCommand(ChannelUID channelUID, Command command) {
66 VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
67 if (velbusBridgeHandler == null) {
68 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
72 if (isFeedbackChannel(channelUID) && command instanceof StringType) {
75 StringType stringTypeCommand = (StringType) command;
76 if (stringTypeCommand.equals(SET_LED)) {
77 commandByte = COMMAND_SET_LED;
78 } else if (stringTypeCommand.equals(SLOW_BLINK_LED)) {
79 commandByte = COMMAND_SLOW_BLINK_LED;
80 } else if (stringTypeCommand.equals(FAST_BLINK_LED)) {
81 commandByte = COMMAND_FAST_BLINK_LED;
82 } else if (stringTypeCommand.equals(VERY_FAST_BLINK_LED)) {
83 commandByte = COMMAND_VERY_FAST_BLINK_LED;
84 } else if (stringTypeCommand.equals(CLEAR_LED)) {
85 commandByte = COMMAND_CLEAR_LED;
87 throw new UnsupportedOperationException(
88 "The command '" + command + "' is not supported on channel '" + channelUID + "'.");
91 VelbusFeedbackLEDPacket packet = new VelbusFeedbackLEDPacket(
92 getModuleAddress().getChannelIdentifier(channelUID), commandByte);
94 byte[] packetBytes = packet.getBytes();
95 velbusBridgeHandler.sendPacket(packetBytes);
98 if (isButtonChannel(channelUID) && command instanceof StringType) {
99 StringType stringTypeCommand = (StringType) command;
101 if (stringTypeCommand.equals(PRESSED) || stringTypeCommand.equals(LONG_PRESSED)) {
102 VelbusButtonPacket packet = new VelbusButtonPacket(getModuleAddress().getChannelIdentifier(channelUID));
105 velbusBridgeHandler.sendPacket(packet.getBytes());
106 triggerChannel("input#CH" + getModuleAddress().getChannelNumber(channelUID),
107 CommonTriggerEvents.PRESSED);
109 if (stringTypeCommand.equals(LONG_PRESSED)) {
110 packet.LongPressed();
111 velbusBridgeHandler.sendPacket(packet.getBytes());
112 triggerChannel("input#CH" + getModuleAddress().getChannelNumber(channelUID),
113 CommonTriggerEvents.LONG_PRESSED);
117 velbusBridgeHandler.sendPacket(packet.getBytes());
118 triggerChannel("input#CH" + getModuleAddress().getChannelNumber(channelUID),
119 CommonTriggerEvents.RELEASED);
121 throw new UnsupportedOperationException(
122 "The command '" + command + "' is not supported on channel '" + channelUID + "'.");
127 private boolean isFeedbackChannel(ChannelUID channelUID) {
128 return "feedback".equals(channelUID.getGroupId());
131 private boolean isButtonChannel(ChannelUID channelUID) {
132 return "button".equals(channelUID.getGroupId());
136 public void onPacketReceived(byte[] packet) {
137 logger.trace("onPacketReceived() was called");
139 if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
140 byte address = packet[2];
141 byte command = packet[4];
143 if (command == COMMAND_PUSH_BUTTON_STATUS && packet.length >= 6) {
144 byte channelJustPressed = packet[5];
145 if (channelJustPressed != 0) {
146 VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address,
148 triggerChannel("input#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
149 CommonTriggerEvents.PRESSED);
152 byte channelJustReleased = packet[6];
153 if (channelJustReleased != 0) {
154 VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address,
155 channelJustReleased);
156 triggerChannel("input#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
157 CommonTriggerEvents.RELEASED);
160 byte channelLongPressed = packet[7];
161 if (channelLongPressed != 0) {
162 VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address,
164 triggerChannel("input#" + getModuleAddress().getChannelId(velbusChannelIdentifier),
165 CommonTriggerEvents.LONG_PRESSED);