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.tapocontrol.internal.device;
15 import static org.openhab.binding.tapocontrol.internal.constants.TapoBindingSettings.*;
16 import static org.openhab.binding.tapocontrol.internal.constants.TapoThingConstants.*;
17 import static org.openhab.binding.tapocontrol.internal.helpers.TapoUtils.*;
19 import java.util.HashMap;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.tapocontrol.internal.structures.TapoDeviceInfo;
23 import org.openhab.binding.tapocontrol.internal.structures.TapoLightEffect;
24 import org.openhab.core.library.types.DecimalType;
25 import org.openhab.core.library.types.HSBType;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.library.types.PercentType;
28 import org.openhab.core.library.unit.Units;
29 import org.openhab.core.thing.ChannelUID;
30 import org.openhab.core.thing.Thing;
31 import org.openhab.core.types.Command;
32 import org.openhab.core.types.RefreshType;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
37 * TAPO Smart-Plug-Device.
39 * @author Christian Wild - Initial contribution
42 public class TapoSmartBulb extends TapoDevice {
43 private final Logger logger = LoggerFactory.getLogger(TapoSmartBulb.class);
48 * @param thing Thing object representing device
50 public TapoSmartBulb(Thing thing) {
55 * handle command sent to device
57 * @param channelUID channelUID command is sent to
58 * @param command command to be sent
61 public void handleCommand(ChannelUID channelUID, Command command) {
62 Boolean refreshInfo = false;
64 String channel = channelUID.getIdWithoutGroup();
65 if (command instanceof RefreshType) {
70 connector.sendDeviceCommand(JSON_KEY_ON, command == OnOffType.ON);
73 case CHANNEL_BRIGHTNESS:
74 if (command instanceof PercentType percentCommand) {
75 Float percent = percentCommand.floatValue();
76 setBrightness(percent.intValue()); // 0..100% = 0..100
78 } else if (command instanceof DecimalType decimalCommand) {
79 setBrightness(decimalCommand.intValue());
83 case CHANNEL_COLOR_TEMP:
84 if (command instanceof DecimalType decimalCommand) {
85 setColorTemp(decimalCommand.intValue());
90 if (command instanceof HSBType hsbCommand) {
96 setLightEffect(command.toString());
99 logger.warn("({}) command type '{}' not supported for channel '{}'", uid, command.toString(),
106 queryDeviceInfo(true);
113 * @param newBrightness percentage 0-100 of new brightness
115 protected void setBrightness(Integer newBrightness) {
116 /* switch off if 0 */
117 if (newBrightness == 0) {
118 connector.sendDeviceCommand(JSON_KEY_ON, false);
120 HashMap<String, Object> newState = new HashMap<>();
121 newState.put(JSON_KEY_ON, true);
122 newState.put(JSON_KEY_BRIGHTNESS, newBrightness);
123 connector.sendDeviceCommands(newState);
132 protected void setColor(HSBType command) {
133 HashMap<String, Object> newState = new HashMap<>();
134 newState.put(JSON_KEY_ON, true);
135 newState.put(JSON_KEY_HUE, command.getHue().intValue());
136 newState.put(JSON_KEY_SATURATION, command.getSaturation().intValue());
137 newState.put(JSON_KEY_BRIGHTNESS, command.getBrightness().intValue());
138 newState.put(JSON_KEY_LIGHTNING_DYNAMIC_ENABLE, false);
139 connector.sendDeviceCommands(newState);
145 * @param colorTemp (Integer) in Kelvin
147 protected void setColorTemp(Integer colorTemp) {
148 HashMap<String, Object> newState = new HashMap<>();
149 colorTemp = limitVal(colorTemp, BULB_MIN_COLORTEMP, BULB_MAX_COLORTEMP);
150 newState.put(JSON_KEY_ON, true);
151 newState.put(JSON_KEY_COLORTEMP, colorTemp);
152 connector.sendDeviceCommands(newState);
158 * @param fxName (String) id of LightEffect
160 protected void setLightEffect(String fxName) {
161 HashMap<String, Object> newState = new HashMap<>();
162 if (fxName.length() > 0 && !fxName.equals(JSON_KEY_LIGHTNING_EFFECT_OFF)) {
163 newState.put(JSON_KEY_LIGHTNING_EFFECT_ENABLE, true);
164 newState.put(JSON_KEY_LIGHTNING_EFFECT_ID, fxName);
166 newState.put(JSON_KEY_LIGHTNING_EFFECT_ENABLE, false);
168 connector.sendDeviceCommands(DEVICE_CMD_SET_LIGHT_FX, newState);
174 * @param deviceInfo TapoDeviceInfo
177 protected void devicePropertiesChanged(TapoDeviceInfo deviceInfo) {
178 super.devicePropertiesChanged(deviceInfo);
179 publishState(getChannelID(CHANNEL_GROUP_ACTUATOR, CHANNEL_OUTPUT), getOnOffType(deviceInfo.isOn()));
180 publishState(getChannelID(CHANNEL_GROUP_ACTUATOR, CHANNEL_BRIGHTNESS),
181 getPercentType(deviceInfo.getBrightness()));
182 publishState(getChannelID(CHANNEL_GROUP_ACTUATOR, CHANNEL_COLOR_TEMP),
183 getDecimalType(deviceInfo.getColorTemp()));
184 publishState(getChannelID(CHANNEL_GROUP_ACTUATOR, CHANNEL_COLOR), deviceInfo.getHSB());
185 publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_WIFI_STRENGTH),
186 getDecimalType(deviceInfo.getSignalLevel()));
187 publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_ONTIME),
188 getTimeType(deviceInfo.getOnTime(), Units.SECOND));
189 publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_OVERHEAT), getOnOffType(deviceInfo.isOverheated()));
191 updateLightEffectChannels(deviceInfo.getLightEffect());
195 * Set light effect channels
199 protected void updateLightEffectChannels(TapoLightEffect lightEffect) {
201 if (lightEffect.getEnable().equals(true)) {
202 fxId = lightEffect.getId();
204 publishState(getChannelID(CHANNEL_GROUP_EFFECTS, CHANNEL_FX_NAME), getStringType(fxId));