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.tplinksmarthome.internal.device;
15 import static org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeBindingConstants.CHANNELS_BULB_SWITCH;
16 import static org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeBindingConstants.CHANNEL_BRIGHTNESS;
17 import static org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeBindingConstants.CHANNEL_COLOR;
18 import static org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeBindingConstants.CHANNEL_COLOR_TEMPERATURE;
19 import static org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeBindingConstants.CHANNEL_COLOR_TEMPERATURE_ABS;
20 import static org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeBindingConstants.CHANNEL_ENERGY_POWER;
21 import static org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeBindingConstants.CHANNEL_SWITCH;
23 import java.io.IOException;
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.openhab.binding.tplinksmarthome.internal.Commands;
28 import org.openhab.binding.tplinksmarthome.internal.TPLinkSmartHomeThingType;
29 import org.openhab.binding.tplinksmarthome.internal.model.HasErrorResponse;
30 import org.openhab.binding.tplinksmarthome.internal.model.LightState;
31 import org.openhab.core.library.types.DecimalType;
32 import org.openhab.core.library.types.HSBType;
33 import org.openhab.core.library.types.OnOffType;
34 import org.openhab.core.library.types.PercentType;
35 import org.openhab.core.library.types.QuantityType;
36 import org.openhab.core.library.unit.Units;
37 import org.openhab.core.thing.ChannelUID;
38 import org.openhab.core.types.Command;
39 import org.openhab.core.types.State;
40 import org.openhab.core.types.UnDefType;
43 * TP-Link Smart Home Light Bulb.
45 * @author Hilbrand Bouwkamp - Initial contribution
48 public class BulbDevice extends SmartHomeDevice {
50 protected Commands commands = new Commands();
52 private final int colorTempMin;
53 private final int colorTempMax;
54 private final int colorTempRangeFactor;
56 public BulbDevice(final TPLinkSmartHomeThingType type) {
57 this.colorTempMin = type.getColorScales().getWarm();
58 this.colorTempMax = type.getColorScales().getCool();
59 colorTempRangeFactor = (colorTempMax - colorTempMin) / 100;
63 public String getUpdateCommand() {
64 return Commands.getRealtimeBulbAndSysinfo();
68 public boolean handleCommand(final ChannelUID channelUid, final Command command) throws IOException {
69 final String channelId = channelUid.getId();
70 final int transitionPeriod = configuration.transitionPeriod;
71 final HasErrorResponse response;
73 if (command instanceof OnOffType && CHANNELS_BULB_SWITCH.contains(channelId)) {
74 response = handleOnOffType(channelId, (OnOffType) command, transitionPeriod);
75 } else if (command instanceof HSBType && CHANNEL_COLOR.equals(channelId)) {
76 response = handleHSBType(channelId, (HSBType) command, transitionPeriod);
77 } else if (command instanceof DecimalType) {
78 response = handleDecimalType(channelId, (DecimalType) command, transitionPeriod);
82 checkErrors(response);
83 return response != null;
86 protected @Nullable HasErrorResponse handleOnOffType(final String channelID, final OnOffType onOff,
87 final int transitionPeriod) throws IOException {
88 return commands.setTransitionLightStateResponse(
89 connection.sendCommand(commands.setTransitionLightState(onOff, transitionPeriod)));
92 private @Nullable HasErrorResponse handleDecimalType(final String channelID, final DecimalType command,
93 final int transitionPeriod) throws IOException {
94 final int intValue = command.intValue();
96 if (CHANNEL_COLOR.equals(channelID) || CHANNEL_BRIGHTNESS.equals(channelID)) {
97 return handleBrightness(intValue, transitionPeriod);
98 } else if (CHANNEL_COLOR_TEMPERATURE.equals(channelID)) {
99 return handleColorTemperature(convertPercentageToKelvin(intValue), transitionPeriod);
100 } else if (CHANNEL_COLOR_TEMPERATURE_ABS.equals(channelID)) {
101 return handleColorTemperature(guardColorTemperature(intValue), transitionPeriod);
106 protected @Nullable HasErrorResponse handleBrightness(final int brightness, final int transitionPeriod)
108 return commands.setTransitionLightStateResponse(
109 connection.sendCommand(commands.setTransitionLightStateBrightness(brightness, transitionPeriod)));
112 protected @Nullable HasErrorResponse handleColorTemperature(final int colorTemperature, final int transitionPeriod)
114 return commands.setTransitionLightStateResponse(
115 connection.sendCommand(commands.setColorTemperature(colorTemperature, transitionPeriod)));
118 protected @Nullable HasErrorResponse handleHSBType(final String channelID, final HSBType command,
119 final int transitionPeriod) throws IOException {
120 return commands.setTransitionLightStateResponse(
121 connection.sendCommand(commands.setTransitionLightStateColor(command, transitionPeriod)));
125 public State updateChannel(final ChannelUID channelUid, final DeviceState deviceState) {
126 final LightState lightState = deviceState.getSysinfo().getLightState();
129 switch (channelUid.getId()) {
130 case CHANNEL_BRIGHTNESS:
131 state = lightState.getBrightness();
134 state = new HSBType(lightState.getHue(), lightState.getSaturation(), lightState.getBrightness());
136 case CHANNEL_COLOR_TEMPERATURE:
137 state = new PercentType(convertKelvinToPercentage(lightState.getColorTemp()));
139 case CHANNEL_COLOR_TEMPERATURE_ABS:
140 state = new DecimalType(guardColorTemperature(lightState.getColorTemp()));
143 state = lightState.getOnOff();
145 case CHANNEL_ENERGY_POWER:
146 state = new QuantityType<>(deviceState.getRealtime().getPower(), Units.WATT);
149 state = UnDefType.UNDEF;
155 private int convertPercentageToKelvin(final int percentage) {
156 return guardColorTemperature(colorTempMin + colorTempRangeFactor * percentage);
159 private int convertKelvinToPercentage(final int colorTemperature) {
160 return (guardColorTemperature(colorTemperature) - colorTempMin) / colorTempRangeFactor;
163 private int guardColorTemperature(final int colorTemperature) {
164 return Math.max(colorTempMin, Math.min(colorTempMax, colorTemperature));