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.lutron.internal.handler;
15 import static org.openhab.binding.lutron.internal.LutronBindingConstants.*;
17 import java.math.BigDecimal;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.binding.lutron.internal.config.FanConfig;
21 import org.openhab.binding.lutron.internal.protocol.FanSpeedType;
22 import org.openhab.binding.lutron.internal.protocol.OutputCommand;
23 import org.openhab.binding.lutron.internal.protocol.lip.LutronCommandType;
24 import org.openhab.binding.lutron.internal.protocol.lip.LutronOperation;
25 import org.openhab.binding.lutron.internal.protocol.lip.TargetType;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.library.types.PercentType;
28 import org.openhab.core.library.types.StringType;
29 import org.openhab.core.thing.Bridge;
30 import org.openhab.core.thing.ChannelUID;
31 import org.openhab.core.thing.Thing;
32 import org.openhab.core.thing.ThingStatus;
33 import org.openhab.core.thing.ThingStatusDetail;
34 import org.openhab.core.types.Command;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 * Handler responsible for communicating with ceiling fan speed controllers.
41 * @author Bob Adair - Initial contribution
44 public class FanHandler extends LutronHandler {
45 private final Logger logger = LoggerFactory.getLogger(FanHandler.class);
47 private FanConfig config = new FanConfig();
49 public FanHandler(Thing thing) {
54 public int getIntegrationId() {
55 if (config.integrationId <= 0) {
56 throw new IllegalStateException("handler not initialized");
58 return config.integrationId;
63 public void initialize() {
64 config = getConfigAs(FanConfig.class);
65 if (config.integrationId <= 0) {
66 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "No integrationId configured");
69 logger.debug("Initializing Fan handler for integration ID {}", getIntegrationId());
75 protected void initDeviceState() {
76 logger.debug("Initializing device state for Fan {}", getIntegrationId());
77 Bridge bridge = getBridge();
79 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "No bridge configured");
80 } else if (bridge.getStatus() == ThingStatus.ONLINE) {
81 updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, "Awaiting initial response");
82 queryOutput(TargetType.FAN, OutputCommand.ACTION_ZONELEVEL);
83 // handleUpdate() will set thing status to online when response arrives
85 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
90 public void channelLinked(ChannelUID channelUID) {
91 if (channelUID.getId().equals(CHANNEL_FANSPEED) || channelUID.getId().equals(CHANNEL_FANLEVEL)) {
92 // Refresh state when new item is linked.
93 queryOutput(TargetType.FAN, OutputCommand.ACTION_ZONELEVEL);
98 public void handleCommand(ChannelUID channelUID, Command command) {
99 if (channelUID.getId().equals(CHANNEL_FANLEVEL)) {
100 if (command instanceof Number number) {
101 int level = number.intValue();
102 FanSpeedType speed = FanSpeedType.toFanSpeedType(level);
103 // output(TargetType.FAN, LutronCommand.ACTION_ZONELEVEL, level, null, null);
104 sendCommand(new OutputCommand(TargetType.FAN, LutronOperation.EXECUTE, getIntegrationId(),
105 OutputCommand.ACTION_ZONELEVEL, speed, null, null));
106 } else if (command.equals(OnOffType.ON)) {
107 // output(TargetType.FAN, LutronCommand.ACTION_ZONELEVEL, 100, null, null);
108 sendCommand(new OutputCommand(TargetType.FAN, LutronOperation.EXECUTE, getIntegrationId(),
109 OutputCommand.ACTION_ZONELEVEL, FanSpeedType.HIGH, null, null));
110 } else if (command.equals(OnOffType.OFF)) {
111 // output(TargetType.FAN, LutronCommand.ACTION_ZONELEVEL, 0, null, null);
112 sendCommand(new OutputCommand(TargetType.FAN, LutronOperation.EXECUTE, getIntegrationId(),
113 OutputCommand.ACTION_ZONELEVEL, FanSpeedType.OFF, null, null));
115 } else if (channelUID.getId().equals(CHANNEL_FANSPEED)) {
116 if (command instanceof StringType) {
117 FanSpeedType speed = FanSpeedType.toFanSpeedType(command.toString());
118 sendCommand(new OutputCommand(TargetType.FAN, LutronOperation.EXECUTE, getIntegrationId(),
119 OutputCommand.ACTION_ZONELEVEL, speed, null, null));
125 public void handleUpdate(LutronCommandType type, String... parameters) {
126 if (type == LutronCommandType.OUTPUT && parameters.length > 1
127 && OutputCommand.ACTION_ZONELEVEL.toString().equals(parameters[0])) {
128 BigDecimal level = new BigDecimal(parameters[1]);
129 if (getThing().getStatus() == ThingStatus.UNKNOWN) {
130 updateStatus(ThingStatus.ONLINE);
132 updateState(CHANNEL_FANLEVEL, new PercentType(level));
133 FanSpeedType fanSpeed = FanSpeedType.toFanSpeedType(level.intValue());
134 updateState(CHANNEL_FANSPEED, new StringType(fanSpeed.toString()));