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.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.velbus.internal.VelbusChannelIdentifier;
24 import org.openhab.binding.velbus.internal.VelbusFirstGenerationDeviceModuleAddress;
25 import org.openhab.binding.velbus.internal.VelbusModuleAddress;
26 import org.openhab.binding.velbus.internal.config.VelbusThingConfig;
27 import org.openhab.binding.velbus.internal.packets.VelbusBlindOffPacket;
28 import org.openhab.binding.velbus.internal.packets.VelbusBlindPositionPacket;
29 import org.openhab.binding.velbus.internal.packets.VelbusBlindUpDownPacket;
30 import org.openhab.binding.velbus.internal.packets.VelbusPacket;
31 import org.openhab.binding.velbus.internal.packets.VelbusStatusRequestPacket;
32 import org.openhab.core.library.types.PercentType;
33 import org.openhab.core.library.types.StopMoveType;
34 import org.openhab.core.library.types.UpDownType;
35 import org.openhab.core.thing.ChannelUID;
36 import org.openhab.core.thing.Thing;
37 import org.openhab.core.thing.ThingStatus;
38 import org.openhab.core.thing.ThingStatusDetail;
39 import org.openhab.core.thing.ThingTypeUID;
40 import org.openhab.core.types.Command;
41 import org.openhab.core.types.RefreshType;
44 * The {@link VelbusBlindsHandler} is responsible for handling commands, which are
45 * sent to one of the channels.
47 * @author Cedric Boon - Initial contribution
50 public class VelbusBlindsHandler extends VelbusThingHandler {
51 public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
52 Arrays.asList(THING_TYPE_VMB1BL, THING_TYPE_VMB1BLS, THING_TYPE_VMB2BL, THING_TYPE_VMB2BLE));
54 public VelbusBlindsHandler(Thing thing) {
59 public void handleCommand(ChannelUID channelUID, Command command) {
60 VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
61 if (velbusBridgeHandler == null) {
62 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
66 if (command instanceof RefreshType) {
67 VelbusStatusRequestPacket packet = new VelbusStatusRequestPacket(
68 getModuleAddress().getChannelIdentifier(channelUID));
70 byte[] packetBytes = packet.getBytes();
71 velbusBridgeHandler.sendPacket(packetBytes);
72 } else if (command instanceof UpDownType) {
73 UpDownType s = (UpDownType) command;
74 if (s == UpDownType.UP) {
75 byte commandByte = COMMAND_BLIND_UP;
77 VelbusBlindUpDownPacket packet = new VelbusBlindUpDownPacket(
78 getModuleAddress().getChannelIdentifier(channelUID), commandByte);
80 byte[] packetBytes = packet.getBytes();
81 velbusBridgeHandler.sendPacket(packetBytes);
83 byte commandByte = COMMAND_BLIND_DOWN;
85 VelbusBlindUpDownPacket packet = new VelbusBlindUpDownPacket(
86 getModuleAddress().getChannelIdentifier(channelUID), commandByte);
88 byte[] packetBytes = packet.getBytes();
89 velbusBridgeHandler.sendPacket(packetBytes);
91 } else if (command instanceof StopMoveType) {
92 StopMoveType s = (StopMoveType) command;
93 if (s == StopMoveType.STOP) {
94 VelbusBlindOffPacket packet = new VelbusBlindOffPacket(
95 getModuleAddress().getChannelIdentifier(channelUID));
97 byte[] packetBytes = packet.getBytes();
98 velbusBridgeHandler.sendPacket(packetBytes);
100 } else if (command instanceof PercentType) {
101 VelbusBlindPositionPacket packet = new VelbusBlindPositionPacket(
102 getModuleAddress().getChannelIdentifier(channelUID), ((PercentType) command).byteValue());
104 byte[] packetBytes = packet.getBytes();
105 velbusBridgeHandler.sendPacket(packetBytes);
107 logger.debug("The command '{}' is not supported by this handler.", command.getClass());
112 protected @Nullable VelbusModuleAddress createVelbusModuleAddress(int numberOfSubAddresses) {
113 final VelbusThingConfig velbusThingConfig = this.velbusThingConfig;
114 if (velbusThingConfig != null) {
115 byte address = hexToByte(velbusThingConfig.address);
117 if (isFirstGenerationDevice()) {
118 return new VelbusFirstGenerationDeviceModuleAddress(address);
121 return new VelbusModuleAddress(address, numberOfSubAddresses);
127 private Boolean isFirstGenerationDevice() {
128 ThingTypeUID thingTypeUID = this.getThing().getThingTypeUID();
129 return thingTypeUID.equals(THING_TYPE_VMB1BL) || thingTypeUID.equals(THING_TYPE_VMB2BL);
133 public void onPacketReceived(byte[] packet) {
134 logger.trace("onPacketReceived() was called");
136 if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
137 byte command = packet[4];
139 if (command == COMMAND_BLIND_STATUS && packet.length >= 9) {
140 byte address = packet[2];
141 byte channel = packet[5];
142 byte blindPosition = packet[9];
144 VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address, channel);
145 PercentType state = new PercentType(blindPosition);
146 updateState(getModuleAddress().getChannelId(velbusChannelIdentifier), state);