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.config.VelbusDimmerConfig;
24 import org.openhab.binding.velbus.internal.packets.VelbusDimmerPacket;
25 import org.openhab.binding.velbus.internal.packets.VelbusPacket;
26 import org.openhab.binding.velbus.internal.packets.VelbusStatusRequestPacket;
27 import org.openhab.core.library.types.OnOffType;
28 import org.openhab.core.library.types.PercentType;
29 import org.openhab.core.thing.ChannelUID;
30 import org.openhab.core.thing.Thing;
31 import org.openhab.core.thing.ThingStatus;
32 import org.openhab.core.thing.ThingStatusDetail;
33 import org.openhab.core.thing.ThingTypeUID;
34 import org.openhab.core.types.Command;
35 import org.openhab.core.types.RefreshType;
38 * The {@link VelbusDimmerHandler} is responsible for handling commands, which are
39 * sent to one of the channels.
41 * @author Cedric Boon - Initial contribution
44 public class VelbusDimmerHandler extends VelbusThingHandler {
45 public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(THING_TYPE_VMB1DM,
46 THING_TYPE_VMB1LED, THING_TYPE_VMB4DC, THING_TYPE_VMBDME, THING_TYPE_VMBDMI, THING_TYPE_VMBDMIR));
48 private @NonNullByDefault({}) VelbusDimmerConfig dimmerConfig;
50 public VelbusDimmerHandler(Thing thing) {
55 public void initialize() {
56 this.dimmerConfig = getConfigAs(VelbusDimmerConfig.class);
62 public void handleCommand(ChannelUID channelUID, Command command) {
63 VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
64 if (velbusBridgeHandler == null) {
65 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
69 if (command instanceof RefreshType) {
70 VelbusStatusRequestPacket packet = new VelbusStatusRequestPacket(
71 getModuleAddress().getChannelIdentifier(channelUID));
73 byte[] packetBytes = packet.getBytes();
74 velbusBridgeHandler.sendPacket(packetBytes);
75 } else if (command instanceof PercentType percentCommand) {
76 byte commandByte = COMMAND_SET_VALUE;
78 VelbusDimmerPacket packet = new VelbusDimmerPacket(getModuleAddress().getChannelIdentifier(channelUID),
79 commandByte, percentCommand.byteValue(), this.dimmerConfig.dimspeed, isFirstGenerationDevice());
81 byte[] packetBytes = packet.getBytes();
82 velbusBridgeHandler.sendPacket(packetBytes);
83 } else if (command instanceof OnOffType onOffCommand) {
84 byte commandByte = determineCommandByte(onOffCommand);
86 VelbusDimmerPacket packet = new VelbusDimmerPacket(getModuleAddress().getChannelIdentifier(channelUID),
87 commandByte, (byte) 0x00, this.dimmerConfig.dimspeed, isFirstGenerationDevice());
89 byte[] packetBytes = packet.getBytes();
90 velbusBridgeHandler.sendPacket(packetBytes);
92 logger.debug("The command '{}' is not supported by this handler.", command.getClass());
96 private byte determineCommandByte(OnOffType command) {
97 return (command == OnOffType.ON) ? COMMAND_RESTORE_LAST_DIMVALUE : COMMAND_SET_VALUE;
100 private Boolean isFirstGenerationDevice() {
101 ThingTypeUID thingTypeUID = this.getThing().getThingTypeUID();
102 return thingTypeUID.equals(THING_TYPE_VMB1DM) || thingTypeUID.equals(THING_TYPE_VMB1LED)
103 || thingTypeUID.equals(THING_TYPE_VMBDME);
107 public void onPacketReceived(byte[] packet) {
108 logger.trace("onPacketReceived() was called");
110 if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
111 byte address = packet[2];
112 byte command = packet[4];
114 if ((command == COMMAND_DIMMERCONTROLLER_STATUS) && packet.length >= 8) {
115 byte channel = packet[5];
116 byte dimValue = packet[7];
118 VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address, channel);
119 PercentType state = new PercentType(dimValue);
120 updateState(getModuleAddress().getChannelId(velbusChannelIdentifier), state);
121 } else if ((command == COMMAND_DIMMER_STATUS) && packet.length >= 7) {
122 byte dimValue = packet[6];
124 VelbusChannelIdentifier velbusChannelIdentifier = new VelbusChannelIdentifier(address, (byte) 0x01);
125 PercentType state = new PercentType(dimValue);
126 updateState(getModuleAddress().getChannelId(velbusChannelIdentifier), state);