Skip to content

Commit

Permalink
[tapocontrol] support display light effects for L530
Browse files Browse the repository at this point in the history
color change is now possible if effect was already enabled by app

Signed-off-by: Christian Wild <[email protected]>
  • Loading branch information
wildcs committed Mar 15, 2023
1 parent b3d3d20 commit 1486017
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 113 deletions.
29 changes: 15 additions & 14 deletions bundles/org.openhab.binding.tapocontrol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,21 @@ The thing has the following configuration parameters:

All devices support some of the following channels:

| group | channel | type | description | things supporting this channel |
|-----------|----------------- |------------------------|------------------------------|------------------------------------------------------------------|
| actuator | output | Switch | Power device on or off | P100, P105, P110, P115, L510, L530, L610, L630, L900, L920, L930 |
| | output1 | Switch | Power socket 1 on or off | P300 |
| | output2 | Switch | Power socket 2 on or off | P300 |
| | output3 | Switch | Power socket 3 on or off | P300 |
| | brightness | Dimmer | Brightness 0-100% | L510, L530, L610, L630, L900 |
| | colorTemperature | Number | White-Color-Temp 2500-6500K | L510, L530, L610, L630, L900 |
| | color | Color | Color | L530, L630, L900 |
| device | wifiSignal | Number | WiFi-quality-level | P100, P105, P110, P115, L510, L530, L610, L630, L900, L920, L930 |
| | onTime | Number:Time | seconds output is on | P100, P105, P110, P115, L510, L530, L900, L920, L930 |
| energy | actualPower | Number:Power | actual Power (Watt) | P110, P115 |
| | todayEnergyUsage | Number:Energy | used energy today (Wh) | P110, P115 |
| | todayRuntime | Number:Time | seconds output was on today | P110, P115 |
| group | channel | type | description | things supporting this channel |
|-----------|----------------- |------------------------|-------------------------------------|------------------------------------------------------------------|
| actuator | output | Switch | Power device on or off | P100, P105, P110, P115, L510, L530, L610, L630, L900, L920, L930 |
| | output1 | Switch | Power socket 1 on or off | P300 |
| | output2 | Switch | Power socket 2 on or off | P300 |
| | output3 | Switch | Power socket 3 on or off | P300 |
| | brightness | Dimmer | Brightness 0-100% | L510, L530, L610, L630, L900 |
| | colorTemperature | Number | White-Color-Temp 2500-6500K | L510, L530, L610, L630, L900 |
| | color | Color | Color | L530, L630, L900 |
| effects | fxName | String | active lightning effect (readonly) | L530 |
| device | wifiSignal | Number | WiFi-quality-level | P100, P105, P110, P115, L510, L530, L610, L630, L900, L920, L930 |
| | onTime | Number:Time | seconds output is on | P100, P105, P110, P115, L510, L530, L900, L920, L930 |
| energy | actualPower | Number:Power | actual Power (Watt) | P110, P115 |
| | todayEnergyUsage | Number:Energy | used energy today (Wh) | P110, P115 |
| | todayRuntime | Number:Time | seconds output was on today | P110, P115 |


## Channel Refresh
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,23 +214,12 @@ public void queryInfo() {
/**
* Query Info from Device and refresh deviceInfo
*
*
* @param ignoreGap ignore gap to last query. query anyway
*/
public void queryInfo(boolean ignoreGap) {
logger.trace("({}) DeviceConnetor_queryInfo from '{}'", uid, deviceURL);
long now = System.currentTimeMillis();
if (ignoreGap || now > this.lastQuery + TAPO_SEND_MIN_GAP_MS) {
this.lastQuery = now;

/* create payload */
PayloadBuilder plBuilder = new PayloadBuilder();
plBuilder.method = DEVICE_CMD_GETINFO;
String payload = plBuilder.getPayload();

sendSecurePasstrhroug(payload, DEVICE_CMD_GETINFO);
} else {
logger.debug("({}) command not sent becauso of min_gap: {}", uid, now + " <- " + lastQuery);
}
queryCommand(DEVICE_CMD_GETINFO, ignoreGap);
}

/**
Expand All @@ -239,27 +228,37 @@ public void queryInfo(boolean ignoreGap) {
@Override
public void queryChildDevices() {
logger.trace("({}) DeviceConnetor_queryChildDevices from '{}'", uid, deviceURL);

/* create payload */
PayloadBuilder plBuilder = new PayloadBuilder();
plBuilder.method = DEVICE_CMD_CHILD_DEVICE_LIST;
String payload = plBuilder.getPayload();

sendSecurePasstrhroug(payload, DEVICE_CMD_CHILD_DEVICE_LIST);
queryCommand(DEVICE_CMD_CHILD_DEVICE_LIST, false);
}

/**
* Get energy usage from device
*/
public void getEnergyUsage() {
logger.trace("({}) DeviceConnetor_getEnergyUsage from '{}'", uid, deviceURL);
queryCommand(DEVICE_CMD_GETENERGY, true);
}

/* create payload */
PayloadBuilder plBuilder = new PayloadBuilder();
plBuilder.method = DEVICE_CMD_GETENERGY;
String payload = plBuilder.getPayload();
/**
* Send Custom DeviceQuery
*
* @param queryCommand Command to be queried
* @param ignoreGap ignore gap to last query. query anyway
*/
public void queryCommand(String queryCommand, boolean ignoreGap) {
logger.trace("({}) DeviceConnetor_queryCommand '{}' from '{}'", uid, queryCommand, deviceURL);
long now = System.currentTimeMillis();
if (ignoreGap || now > this.lastQuery + TAPO_SEND_MIN_GAP_MS) {
this.lastQuery = now;

sendSecurePasstrhroug(payload, DEVICE_CMD_GETENERGY);
/* create payload */
PayloadBuilder plBuilder = new PayloadBuilder();
plBuilder.method = queryCommand;
String payload = plBuilder.getPayload();

sendSecurePasstrhroug(payload, queryCommand);
} else {
logger.debug("({}) command not sent becauso of min_gap: {}", uid, now + " <- " + lastQuery);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ public class TapoThingConstants {
public static final String PROPERTY_LIGHTNING_EFFECT_ENABLE = "enable";
public static final String PROPERTY_LIGHTNING_EFFECT_ID = "id";
public static final String PROPERTY_LIGHTNING_EFFECT_NAME = "name";
public static final String PROPERTY_LIGHTNING_DYNAMIC_ENABLE = "dynamic_light_effect_enable";
public static final String PROPERTY_LIGHTNING_DYNAMIC_ID = "dynamic_light_effect_id";

// energy monitoring
public static final String ENERGY_PROPERTY_POWER = "current_power";
public static final String ENERGY_PROPERTY_RUNTIME_TODAY = "today_runtime";
Expand Down Expand Up @@ -178,12 +181,10 @@ public class TapoThingConstants {
public static final String CHANNEL_NRG_USAGE_TODAY = "todayEnergyUsage";
public static final String CHANNEL_NRG_RUNTIME_TODAY = "todayRuntime";
// channel group effect
public static final String CHANNEL_GROUP_EFFECTS = "effect";
public static final String CHANNEL_FX_BRIGHTNESS = "brightness";
public static final String CHANNEL_FX_COLORS = "displayColors";
public static final String CHANNEL_FX_CUSTOM = "custom";
public static final String CHANNEL_FX_ENABLE = "enable";
public static final String CHANNEL_FX_NAME = "name";
public static final String CHANNEL_GROUP_EFFECTS = "effects";
public static final String CHANNEL_FX_BRIGHTNESS = "fxBrightness";
public static final String CHANNEL_FX_COLORS = "fxColors";
public static final String CHANNEL_FX_NAME = "fxName";

/*** LIST OF PROPERTY NAMES ***/
public static final String PROPERTY_FAMILY = "deviceFamily";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,6 @@ protected void setLightEffect(String channel, Command command) {
case CHANNEL_FX_NAME:
lightEffect.setName(command.toString());
break;
case CHANNEL_FX_ENABLE:
lightEffect.setEnable(command == OnOffType.ON);
break;
}
setLightEffects(lightEffect);
}
Expand Down Expand Up @@ -224,7 +221,5 @@ protected void devicePropertiesChanged(TapoDeviceInfo deviceInfo) {
publishState(getChannelID(CHANNEL_GROUP_EFFECTS, CHANNEL_FX_BRIGHTNESS),
getPercentType(lightEffect.getBrightness()));
publishState(getChannelID(CHANNEL_GROUP_EFFECTS, CHANNEL_FX_NAME), getStringType(lightEffect.getName()));
publishState(getChannelID(CHANNEL_GROUP_EFFECTS, CHANNEL_FX_ENABLE), getOnOffType(lightEffect.getEnable()));
publishState(getChannelID(CHANNEL_GROUP_EFFECTS, CHANNEL_FX_CUSTOM), getOnOffType(lightEffect.getCustom()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.tapocontrol.internal.structures.TapoDeviceInfo;
import org.openhab.binding.tapocontrol.internal.structures.TapoLightEffect;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.OnOffType;
Expand Down Expand Up @@ -90,6 +91,9 @@ public void handleCommand(ChannelUID channelUID, Command command) {
refreshInfo = true;
}
break;
case CHANNEL_FX_NAME:
setLightEffect(command.toString());
break;
default:
logger.warn("({}) command type '{}' not supported for channel '{}'", uid, command.toString(),
channelUID.getId());
Expand Down Expand Up @@ -130,6 +134,7 @@ protected void setColor(HSBType command) {
newState.put(DEVICE_PROPERTY_HUE, command.getHue().intValue());
newState.put(DEVICE_PROPERTY_SATURATION, command.getSaturation().intValue());
newState.put(DEVICE_PROPERTY_BRIGHTNES, command.getBrightness().intValue());
newState.put(PROPERTY_LIGHTNING_DYNAMIC_ENABLE, false);
connector.sendDeviceCommands(newState);
}

Expand All @@ -146,6 +151,24 @@ protected void setColorTemp(Integer colorTemp) {
connector.sendDeviceCommands(newState);
}

/**
* SET LIGHT-EFFECT
*
* @param fxName (String) id of LightEffect
*/
protected void setLightEffect(String fxName) {
HashMap<String, Object> newState = new HashMap<>();
if (fxName.length() > 0) {
newState.put(DEVICE_PROPERTY_ON, true);
newState.put(PROPERTY_LIGHTNING_DYNAMIC_ENABLE, true);
newState.put(PROPERTY_LIGHTNING_DYNAMIC_ID, fxName);
} else {
newState.put(PROPERTY_LIGHTNING_DYNAMIC_ENABLE, false);
newState.put(PROPERTY_LIGHTNING_DYNAMIC_ID, "");
}
connector.sendDeviceCommands(newState);
}

/**
* UPDATE PROPERTIES
*
Expand All @@ -165,5 +188,20 @@ protected void devicePropertiesChanged(TapoDeviceInfo deviceInfo) {
publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_ONTIME),
getTimeType(deviceInfo.getOnTime(), Units.SECOND));
publishState(getChannelID(CHANNEL_GROUP_DEVICE, CHANNEL_OVERHEAT), getOnOffType(deviceInfo.isOverheated()));

updateLightEffectChannels(deviceInfo.getLightEffect());
}

/**
* SET LIGTH EFFECT CHANNELS
*
* @param lightEffect
*/
protected void updateLightEffectChannels(TapoLightEffect lightEffect) {
String fxId = "";
if (lightEffect.getEnable().equals(true)) {
fxId = lightEffect.getId();
}
publishState(getChannelID(CHANNEL_GROUP_EFFECTS, CHANNEL_FX_NAME), getStringType(fxId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private void setData() {
*
************************************/
public Boolean hasLightEffect() {
return this.jsonObject.has(DEVICE_PROPERTY_EFFECT);
return this.jsonObject.has(DEVICE_PROPERTY_EFFECT) || this.jsonObject.has(PROPERTY_LIGHTNING_DYNAMIC_ENABLE);
}

/***********************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
*/
@NonNullByDefault
public class TapoLightEffect {
private Integer enable = 0;
private Boolean enable = false;
private String id = "";
private String name = "";
private Integer custom = 0;
private Boolean custom = false;
private Integer brightness = 0;
private Integer[] colorTempRange = { 9000, 9000 }; // :[9000,9000]
private Color displayColors[] = { Color.WHITE };
Expand All @@ -42,7 +42,6 @@ public class TapoLightEffect {
* INIT
*/
public TapoLightEffect() {
setData();
}

/**
Expand All @@ -62,20 +61,32 @@ public TapoLightEffect(JsonObject jso) {
public TapoLightEffect setData(JsonObject jso) {
/* create empty jsonObject to set efault values if has no lighning effect */
if (jso.has(DEVICE_PROPERTY_EFFECT)) {
this.jsonObject = jso.getAsJsonObject(DEVICE_PROPERTY_EFFECT);
this.enable = jsonObjectToBool(jsonObject, PROPERTY_LIGHTNING_EFFECT_ENABLE);
this.id = jsonObjectToString(jsonObject, PROPERTY_LIGHTNING_EFFECT_ID);
this.name = jsonObjectToString(jsonObject, PROPERTY_LIGHTNING_EFFECT_NAME);
this.custom = jsonObjectToBool(jsonObject, PROPERTY_LIGHTNING_EFFECT_CUSTOM); // jsonObjectToBool
this.brightness = jsonObjectToInt(jsonObject, PROPERTY_LIGHTNING_EFFECT_BRIGHNTESS);
} else if (jso.has(PROPERTY_LIGHTNING_DYNAMIC_ENABLE)) {
this.jsonObject = jso;
this.enable = jsonObjectToBool(jsonObject, PROPERTY_LIGHTNING_DYNAMIC_ENABLE);
this.id = jsonObjectToString(jsonObject, PROPERTY_LIGHTNING_DYNAMIC_ID);
} else {
jsonObject = new JsonObject();
setDefaults();
}
setData();
return this;
}

private void setData() {
this.enable = jsonObjectToInt(jsonObject, PROPERTY_LIGHTNING_EFFECT_ENABLE);
this.id = jsonObjectToString(jsonObject, PROPERTY_LIGHTNING_EFFECT_ID);
this.name = jsonObjectToString(jsonObject, PROPERTY_LIGHTNING_EFFECT_NAME);
this.custom = jsonObjectToInt(jsonObject, PROPERTY_LIGHTNING_EFFECT_CUSTOM); // jsonObjectToBool
this.brightness = jsonObjectToInt(jsonObject, PROPERTY_LIGHTNING_EFFECT_BRIGHNTESS);
/**
* Set default values
*/
private void setDefaults() {
this.jsonObject = new JsonObject();
this.enable = false;
this.id = "";
this.name = "";
this.custom = false;
this.brightness = 100;
}

/***********************************
Expand All @@ -85,15 +96,15 @@ private void setData() {
************************************/

public void setEnable(Boolean enable) {
this.enable = enable ? 1 : 0;
this.enable = enable;
}

public void setName(String value) {
this.name = value;
}

public void setCustom(Boolean enable) {
this.custom = enable ? 1 : 0;
this.custom = enable;
}

public void setBrightness(Integer value) {
Expand All @@ -106,7 +117,7 @@ public void setBrightness(Integer value) {
*
************************************/

public Integer getEnable() {
public Boolean getEnable() {
return this.enable;
}

Expand All @@ -118,7 +129,7 @@ public String getName() {
return this.name;
}

public Integer getCustom() {
public Boolean getCustom() {
return this.custom;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,35 @@
<description>Tapo Smart Multicolor Light-Bulb</description>
<channel-groups>
<channel-group id="actuator" typeId="colorBulb"/>
<channel-group id="effects" typeId="lightEffectL530"/>
<channel-group id="device" typeId="deviceState"/>
</channel-groups>
<representation-property>macAddress</representation-property>

<config-description-ref uri="thing-type:tapo:device"/>
</thing-type>

<!-- Lightning Effect -->
<channel-group-type id="lightEffectL530">
<label>Lightning Effect</label>
<description>Tapo Lightning Effects</description>
<channels>
<channel id="fxName" typeId="l530fxList"/>
</channels>
</channel-group-type>

<!-- effect name -->
<channel-type id="l530fxList">
<item-type>String</item-type>
<label>Ligth Effect Theme</label>
<description>Name of active LightningEffect</description>
<state readOnly="true">
<options>
<option value="">None (No FX)</option>
<option value="custom">Custom</option>
<option value="L1">Party</option>
<option value="L2">Relax</option>
</options>
</state>
</channel-type>
</thing:thing-descriptions>
Loading

0 comments on commit 1486017

Please sign in to comment.