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.config.core.Configuration;
20 import org.openhab.core.library.types.OnOffType;
21 import org.openhab.core.library.types.PercentType;
22 import org.openhab.core.thing.Bridge;
23 import org.openhab.core.thing.ChannelUID;
24 import org.openhab.core.thing.Thing;
25 import org.openhab.core.thing.ThingStatus;
26 import org.openhab.core.thing.ThingStatusDetail;
27 import org.openhab.core.thing.ThingStatusInfo;
28 import org.openhab.core.thing.binding.BaseThingHandler;
29 import org.openhab.core.types.State;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 * This is an abstract base class for the "Thing" handlers (i.e. Cm11aApplianceHandler and Cm11aLampHandler).
35 * It is not used by the Bridge handler (Cm11aHandler)
37 * @author Bob Raker - Initial contribution
40 public abstract class Cm11aAbstractHandler extends BaseThingHandler {
43 * The House and Unit codes set on the module, i.e. A1, J14
45 protected String houseUnitCode;
50 protected int x10Function;
55 protected ChannelUID channelUID;
58 * The current State of the device
60 protected State currentState;
63 * Number of CM11a dim increments for dimable devices
65 static final int X10_DIM_INCREMENTS = 22;
66 static final String HOUSE_UNIT_CODE = "houseUnitCode";
67 static final String NO_BRIDGE_ERROR = "No bridge found using house unit code ";
69 private final Logger logger = LoggerFactory.getLogger(Cm11aAbstractHandler.class);
74 * @param thing The "Thing" to be handled
76 public Cm11aAbstractHandler(Thing thing) {
81 public void initialize() {
82 Configuration config = thing.getConfiguration();
84 houseUnitCode = (String) config.get(HOUSE_UNIT_CODE);
85 Bridge bridge = getBridge();
87 logger.warn("{}", NO_BRIDGE_ERROR + houseUnitCode);
88 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, NO_BRIDGE_ERROR + houseUnitCode);
92 if (ThingStatus.ONLINE.equals(bridge.getStatus())) {
93 updateStatus(ThingStatus.ONLINE);
95 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
100 public void dispose() {
101 houseUnitCode = null;
105 public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
106 logger.debug("CM11A status changed to {}.", bridgeStatusInfo.getStatus());
108 if (bridgeStatusInfo.getStatus() != ThingStatus.ONLINE) {
109 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
110 logger.debug("CM11A is not online. Bridge status: {}", bridgeStatusInfo.getStatus());
114 if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
115 if (houseUnitCode.length() > 0) {
116 // The config must be present and was set during initialization
117 updateStatus(ThingStatus.ONLINE);
119 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
125 * Will be called by the X10Interface when it is ready for this X10 device to use the X10 bus.
126 * Child classes should override this method with the specific process necessary to update the
127 * hardware with the latest data.
130 * Warning: This will be called in a different thread. It must be thread safe.
134 * Retries in the event of interface problems will be handled by the X10Interface. If a comms
135 * problem occurs and the method throws an exception, this device will be rescheduled again later.
138 public abstract void updateHardware(X10Interface x10Interface) throws IOException, InvalidAddressException;
140 public State getCurrentState() {
144 public void setCurrentState(State currentState) {
145 this.currentState = currentState;
149 * Subtract the specified number of X10 "dims" from the current state
151 * @param dims The number of dims to remove
152 * @return The updated current state
154 public State addDimsToCurrentState(int dims) {
155 if (!(currentState instanceof PercentType)) {
156 if (currentState instanceof OnOffType && currentState == OnOffType.ON) {
157 currentState = PercentType.HUNDRED;
159 currentState = PercentType.ZERO;
162 // The current state is stored in a PercentType object and therefore needs to be converted to an incremental
164 int curPercent = ((PercentType) currentState).intValue();
165 // dims is a number between 0 and 22 which represents the full range of cm11a
166 int dimsPercent = (dims * 100) / X10_DIM_INCREMENTS;
167 int newPercent = curPercent - dimsPercent;
168 newPercent = Math.max(newPercent, 0);
169 newPercent = Math.min(newPercent, 100);
170 currentState = new PercentType(newPercent);
175 * Add the specified number of X10 "dims" from the current state
177 * @param dims The number of dims to remove
178 * @return The updated current state
180 public State addBrightsToCurrentState(int dims) {
181 return addDimsToCurrentState(-dims);