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.cm11a.internal.handler;
15 import java.io.IOException;
17 import org.openhab.binding.cm11a.internal.InvalidAddressException;
18 import org.openhab.binding.cm11a.internal.X10Interface;
19 import org.openhab.core.library.types.OnOffType;
20 import org.openhab.core.library.types.PercentType;
21 import org.openhab.core.thing.Bridge;
22 import org.openhab.core.thing.ChannelUID;
23 import org.openhab.core.thing.Thing;
24 import org.openhab.core.thing.ThingStatus;
25 import org.openhab.core.types.Command;
26 import org.openhab.core.types.RefreshType;
27 import org.openhab.core.types.State;
28 import org.openhab.core.types.UnDefType;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 * Handler for Lamp modules. These modules support ON, OFF and brightness level states
35 * @author Bob Raker - Initial contribution
38 public class Cm11aLampHandler extends Cm11aAbstractHandler {
40 private final Logger logger = LoggerFactory.getLogger(Cm11aLampHandler.class);
42 private State desiredState = UnDefType.UNDEF;
45 * Constructor for the Thing
49 public Cm11aLampHandler(Thing thing) {
51 currentState = OnOffType.ON; // Assume it is on. During refresh it will be turned off and the currentState will
52 // be updated appropriately
56 public void handleCommand(ChannelUID channelUID, Command command) {
57 logger.debug("**** Cm11aLampHandler handleCommand command = {}, channelUID = {}", command.toString(),
58 channelUID.getAsString());
61 Bridge bridge = getBridge();
63 logger.debug("Unable to handle command. Bridge is null.");
66 this.channelUID = channelUID;
68 Cm11aBridgeHandler cm11aHandler = (Cm11aBridgeHandler) bridge.getHandler();
69 if (cm11aHandler != null && cm11aHandler.getThing().getStatus().equals(ThingStatus.ONLINE)) {
70 if (OnOffType.ON.equals(command)) {
71 desiredState = OnOffType.ON;
72 } else if (OnOffType.OFF.equals(command)) {
73 desiredState = OnOffType.OFF;
74 } else if (command instanceof PercentType percentCommand) {
75 desiredState = percentCommand;
76 } else if (command instanceof RefreshType) {
77 // Refresh is triggered by framework during startup.
78 // Force the lamp off by indicating it is currently on and we want it off
79 desiredState = PercentType.ZERO; // Start with it off
80 logger.info("Received REFRESH command for switch {}", houseUnitCode);
82 logger.error("Ignoring unknown command received for device: {}", houseUnitCode);
85 if (!(desiredState instanceof UnDefType)) {
86 X10Interface x10Interface = cm11aHandler.getX10Interface();
87 x10Interface.scheduleHWUpdate(this);
90 logger.error("Attempted to change switch {} cm11a is not online", houseUnitCode);
97 * @see org.openhab.binding.cm11a.handler.Cm11aAbstractHandler#updateHardware(org.openhab.binding.cm11a.internal.
101 public void updateHardware(X10Interface x10Interface) throws IOException, InvalidAddressException {
102 if (!desiredState.equals(currentState)) {
103 boolean x10Status = false;
104 if (desiredState.equals(OnOffType.ON)) {
105 x10Status = x10Interface.sendFunction(houseUnitCode, X10Interface.FUNC_ON);
106 } else if (desiredState.equals(OnOffType.OFF)) {
107 x10Status = x10Interface.sendFunction(houseUnitCode, X10Interface.FUNC_OFF);
108 } else if (desiredState instanceof PercentType desiredStatePercent) {
109 // desiredState must be a PercentType if we got here.
110 // Calc how many bright increments we need to send (0 to 22)
111 int desiredPercentFullBright = desiredStatePercent.intValue();
112 int dims = (desiredPercentFullBright * X10_DIM_INCREMENTS) / 100;
113 if (currentState.equals(OnOffType.ON)) {
114 // The current level isn't known because it would have gone to
115 // the same level as when last turned on. Need to go to full dim and then up to desired
117 x10Interface.sendFunction(houseUnitCode, X10Interface.FUNC_DIM, X10_DIM_INCREMENTS);
118 x10Status = x10Interface.sendFunction(houseUnitCode, X10Interface.FUNC_BRIGHT, dims);
119 } else if (currentState.equals(OnOffType.OFF)) {
120 // desiredState must be a PercentType if we got here. And, the light should be off
121 // We should just be able to send the appropriate number if dims
122 x10Status = x10Interface.sendFunction(houseUnitCode, X10Interface.FUNC_BRIGHT, dims);
123 } else if (currentState instanceof PercentType currentStatePercent) {
124 // This is the expected case
125 // Now currentState and desiredState are both PercentType's
126 // Need to calc how much to dim or brighten
127 int currentPercentFullBright = currentStatePercent.intValue();
128 int percentToBrighten = desiredPercentFullBright - currentPercentFullBright;
129 int brightens = (percentToBrighten * X10_DIM_INCREMENTS) / 100;
131 x10Status = x10Interface.sendFunction(houseUnitCode, X10Interface.FUNC_BRIGHT, brightens);
132 } else if (brightens < 0) {
133 x10Status = x10Interface.sendFunction(houseUnitCode, X10Interface.FUNC_DIM, -brightens);
136 // Current state is not as expected
137 logger.warn("Starting state of dimmer was not as expected: {}", currentState.getClass().getName());
141 // Now the hardware should have been updated. If successful update the status
143 // Hardware update was successful so update OpenHAB
144 updateState(channelUID, desiredState);
145 setCurrentState(desiredState);
147 // Hardware update failed, log
148 logger.error("cm11a failed to update device: {}", houseUnitCode);