[miio] Improve yeelight RGB with brightness, introduce substitutions (#10984)
* [miio] add deviceId and timestamp substitutions This will allow to send right commands for gateway and lumi devices Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] update brightness in yeelight RGB channel Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] Use generic way to call the asyncCommunication module Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] Fix mapping yeelight Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] Improve Yeelight colormode mapping Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] yeelight fix unit for delayed off Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com>
This commit is contained in:
@@ -13,8 +13,10 @@
|
||||
package org.openhab.binding.miio.internal.basic;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.slf4j.Logger;
|
||||
@@ -49,6 +51,31 @@ public class Conversions {
|
||||
return bRGB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the brightness info (from separate channel) to a HSV value.
|
||||
* *
|
||||
*
|
||||
* @param RGB
|
||||
* @param map with device variables containing the brightness info
|
||||
* @return HSV
|
||||
*/
|
||||
public static JsonElement addBrightToHSV(JsonElement rgbValue, @Nullable Map<String, Object> deviceVariables)
|
||||
throws ClassCastException, IllegalStateException {
|
||||
int bright = 100;
|
||||
if (deviceVariables != null) {
|
||||
JsonElement lastBright = (JsonElement) deviceVariables.getOrDefault("bright", new JsonPrimitive(100));
|
||||
bright = lastBright.getAsInt();
|
||||
}
|
||||
if (rgbValue.isJsonPrimitive()
|
||||
&& (rgbValue.getAsJsonPrimitive().isNumber() || rgbValue.getAsString().matches("^[0-9]+$"))) {
|
||||
Color rgb = new Color(rgbValue.getAsInt());
|
||||
HSBType hsb = HSBType.fromRGB(rgb.getRed(), rgb.getGreen(), rgb.getBlue());
|
||||
hsb = new HSBType(hsb.getHue(), hsb.getSaturation(), new PercentType(bright));
|
||||
return new JsonPrimitive(hsb.toFullString());
|
||||
}
|
||||
return rgbValue;
|
||||
}
|
||||
|
||||
public static JsonElement secondsToHours(JsonElement seconds) throws ClassCastException {
|
||||
double value = seconds.getAsDouble() / 3600;
|
||||
return new JsonPrimitive(value);
|
||||
@@ -94,9 +121,10 @@ public class Conversions {
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonElement execute(String transfortmation, JsonElement value) {
|
||||
public static JsonElement execute(String transformation, JsonElement value,
|
||||
@Nullable Map<String, Object> deviceVariables) {
|
||||
try {
|
||||
switch (transfortmation.toUpperCase()) {
|
||||
switch (transformation.toUpperCase()) {
|
||||
case "YEELIGHTSCENEID":
|
||||
return yeelightSceneConversion(value);
|
||||
case "SECONDSTOHOURS":
|
||||
@@ -107,14 +135,16 @@ public class Conversions {
|
||||
return divideHundred(value);
|
||||
case "TANKLEVEL":
|
||||
return tankLevel(value);
|
||||
case "ADDBRIGHTTOHSV":
|
||||
return addBrightToHSV(value, deviceVariables);
|
||||
case "BRGBTOHSV":
|
||||
return bRGBtoHSV(value);
|
||||
default:
|
||||
LOGGER.debug("Transformation {} not found. Returning '{}'", transfortmation, value.toString());
|
||||
LOGGER.debug("Transformation {} not found. Returning '{}'", transformation, value.toString());
|
||||
return value;
|
||||
}
|
||||
} catch (ClassCastException | IllegalStateException e) {
|
||||
LOGGER.debug("Transformation {} failed. Returning '{}'", transfortmation, value.toString());
|
||||
LOGGER.debug("Transformation {} failed. Returning '{}'", transformation, value.toString());
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ public class MiIoBasicChannel {
|
||||
|
||||
public Boolean getRefresh() {
|
||||
final @Nullable Boolean rf = refresh;
|
||||
return rf != null && rf.booleanValue() && !getProperty().isEmpty();
|
||||
return rf != null && rf.booleanValue();
|
||||
}
|
||||
|
||||
public void setRefresh(@Nullable Boolean refresh) {
|
||||
|
||||
@@ -15,9 +15,12 @@ package org.openhab.binding.miio.internal.handler;
|
||||
import static org.openhab.binding.miio.internal.MiIoBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
@@ -59,6 +62,7 @@ import org.slf4j.LoggerFactory;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
/**
|
||||
@@ -71,6 +75,7 @@ import com.google.gson.JsonSyntaxException;
|
||||
public abstract class MiIoAbstractHandler extends BaseThingHandler implements MiIoMessageListener {
|
||||
protected static final int MAX_QUEUE = 5;
|
||||
protected static final Gson GSON = new GsonBuilder().create();
|
||||
protected static final String TIMESTAMP = "timestamp";
|
||||
|
||||
protected ScheduledExecutorService miIoScheduler = scheduler;
|
||||
protected @Nullable ScheduledFuture<?> pollingJob;
|
||||
@@ -111,12 +116,13 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
|
||||
public abstract void handleCommand(ChannelUID channelUID, Command command);
|
||||
|
||||
protected boolean handleCommandsChannels(ChannelUID channelUID, Command command) {
|
||||
String cmd = processSubstitutions(command.toString(), deviceVariables);
|
||||
if (channelUID.getId().equals(CHANNEL_COMMAND)) {
|
||||
cmds.put(sendCommand(command.toString()), channelUID.getId());
|
||||
cmds.put(sendCommand(cmd), channelUID.getId());
|
||||
return true;
|
||||
}
|
||||
if (channelUID.getId().equals(CHANNEL_RPC)) {
|
||||
cmds.put(sendCommand(command.toString(), cloudServer), channelUID.getId());
|
||||
cmds.put(sendCommand(cmd, cloudServer), channelUID.getId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -146,6 +152,8 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
|
||||
}
|
||||
this.cloudServer = configuration.cloudServer;
|
||||
isIdentified = false;
|
||||
deviceVariables.put(TIMESTAMP, Instant.now().getEpochSecond());
|
||||
deviceVariables.put(PROPERTY_DID, configuration.deviceId);
|
||||
miIoScheduler.schedule(this::initializeData, 1, TimeUnit.SECONDS);
|
||||
int pollingPeriod = configuration.refreshInterval;
|
||||
if (pollingPeriod > 0) {
|
||||
@@ -216,14 +224,7 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
|
||||
}
|
||||
|
||||
protected int sendCommand(MiIoCommand command, String params) {
|
||||
try {
|
||||
final MiIoAsyncCommunication connection = getConnection();
|
||||
return (connection != null) ? connection.queueCommand(command, params, getCloudServer()) : 0;
|
||||
} catch (MiIoCryptoException | IOException e) {
|
||||
logger.debug("Command {} for {} failed (type: {}): {}", command.toString(), getThing().getUID(),
|
||||
getThing().getThingTypeUID(), e.getLocalizedMessage());
|
||||
}
|
||||
return 0;
|
||||
return sendCommand(command.getCommand(), processSubstitutions(params, deviceVariables), getCloudServer(), "");
|
||||
}
|
||||
|
||||
protected int sendCommand(String commandString) {
|
||||
@@ -241,19 +242,39 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
|
||||
* @return vacuum response
|
||||
*/
|
||||
protected int sendCommand(String commandString, String cloudServer) {
|
||||
final MiIoAsyncCommunication connection = getConnection();
|
||||
String command = commandString.trim();
|
||||
command = processSubstitutions(commandString.trim(), deviceVariables);
|
||||
String param = "[]";
|
||||
int sb = command.indexOf("[");
|
||||
int cb = command.indexOf("{");
|
||||
if (Math.max(sb, cb) > 0) {
|
||||
int loc = (Math.min(sb, cb) > 0 ? Math.min(sb, cb) : Math.max(sb, cb));
|
||||
param = command.substring(loc).trim();
|
||||
command = command.substring(0, loc).trim();
|
||||
}
|
||||
return sendCommand(command, param, cloudServer, "");
|
||||
}
|
||||
|
||||
protected int sendCommand(String command, String params, String cloudServer) {
|
||||
return sendCommand(command, processSubstitutions(params, deviceVariables), cloudServer, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends commands to the {@link MiIoAsyncCommunication} for transmission to the Mi devices or cloud
|
||||
*
|
||||
* @param command (method) to be queued for execution
|
||||
* @param parameters to be send with the command
|
||||
* @param cloud server to be used or empty string for direct sending to the device
|
||||
* @param sending subdevice or empty string for regular device
|
||||
* @return message id
|
||||
*/
|
||||
protected int sendCommand(String command, String params, String cloudServer, String sender) {
|
||||
try {
|
||||
String command = commandString.trim();
|
||||
String param = "[]";
|
||||
int sb = command.indexOf("[");
|
||||
int cb = command.indexOf("{");
|
||||
if (Math.max(sb, cb) > 0) {
|
||||
int loc = (Math.min(sb, cb) > 0 ? Math.min(sb, cb) : Math.max(sb, cb));
|
||||
param = command.substring(loc).trim();
|
||||
command = command.substring(0, loc).trim();
|
||||
}
|
||||
return (connection != null) ? connection.queueCommand(command, param, cloudServer) : 0;
|
||||
final MiIoAsyncCommunication connection = getConnection();
|
||||
return (connection != null) ? connection.queueCommand(command, params, cloudServer, sender) : 0;
|
||||
} catch (MiIoCryptoException | IOException e) {
|
||||
logger.debug("Command {} for {} failed (type: {}): {}", command.toString(), getThing().getUID(),
|
||||
getThing().getThingTypeUID(), e.getLocalizedMessage());
|
||||
disconnected(e.getMessage());
|
||||
}
|
||||
return 0;
|
||||
@@ -414,6 +435,7 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
|
||||
Configuration config = editConfiguration();
|
||||
config.put(PROPERTY_DID, deviceId);
|
||||
updateConfiguration(config);
|
||||
deviceVariables.put(PROPERTY_DID, deviceId);
|
||||
} else {
|
||||
logger.debug("Could not update config with deviceId: {}", deviceId);
|
||||
}
|
||||
@@ -458,6 +480,42 @@ public abstract class MiIoAbstractHandler extends BaseThingHandler implements Mi
|
||||
updateProperties(properties);
|
||||
}
|
||||
|
||||
protected String processSubstitutions(String cmd, Map<String, Object> deviceVariables) {
|
||||
if (!cmd.contains("$")) {
|
||||
return cmd;
|
||||
}
|
||||
String returnCmd = cmd.replace("\"$", "$").replace("$\"", "$");
|
||||
String cmdParts[] = cmd.split("\\$");
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.debug("processSubstitutions {} ", cmd);
|
||||
for (Entry<String, Object> e : deviceVariables.entrySet()) {
|
||||
logger.debug("key, value: {} -> {}", e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
for (String substitute : cmdParts) {
|
||||
if (deviceVariables.containsKey(substitute)) {
|
||||
String replacementString = "";
|
||||
Object replacement = deviceVariables.get(substitute);
|
||||
if (replacement == null) {
|
||||
logger.debug("Replacement for '{}' is null. skipping replacement", substitute);
|
||||
continue;
|
||||
}
|
||||
if (replacement instanceof Integer || replacement instanceof Long || replacement instanceof Double
|
||||
|| replacement instanceof BigDecimal || replacement instanceof Boolean) {
|
||||
replacementString = replacement.toString();
|
||||
} else if (replacement instanceof JsonPrimitive) {
|
||||
replacementString = ((JsonPrimitive) replacement).getAsString();
|
||||
} else if (replacement instanceof String) {
|
||||
replacementString = "\"" + (String) replacement + "\"";
|
||||
} else {
|
||||
replacementString = String.valueOf(replacement);
|
||||
}
|
||||
returnCmd = returnCmd.replace("$" + substitute + "$", replacementString);
|
||||
}
|
||||
}
|
||||
return returnCmd;
|
||||
}
|
||||
|
||||
protected boolean updateThingType(JsonObject miioInfo) {
|
||||
MiIoBindingConfiguration configuration = getConfigAs(MiIoBindingConfiguration.class);
|
||||
String model = miioInfo.get("model").getAsString();
|
||||
|
||||
@@ -17,6 +17,7 @@ import static org.openhab.binding.miio.internal.MiIoBindingConstants.*;
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -122,6 +123,7 @@ public class MiIoBasicHandler extends MiIoAbstractHandler {
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command receivedCommand) {
|
||||
Command command = receivedCommand;
|
||||
deviceVariables.put(TIMESTAMP, Instant.now().getEpochSecond());
|
||||
if (command == RefreshType.REFRESH) {
|
||||
if (updateDataCache.isExpired()) {
|
||||
logger.debug("Refreshing {}", channelUID);
|
||||
@@ -312,6 +314,7 @@ public class MiIoBasicHandler extends MiIoAbstractHandler {
|
||||
}
|
||||
final MiIoBasicDevice midevice = miioDevice;
|
||||
if (midevice != null) {
|
||||
deviceVariables.put(TIMESTAMP, Instant.now().getEpochSecond());
|
||||
refreshProperties(midevice);
|
||||
refreshCustomProperties(midevice);
|
||||
refreshNetwork();
|
||||
@@ -581,13 +584,14 @@ public class MiIoBasicHandler extends MiIoAbstractHandler {
|
||||
|
||||
private void updateChannel(@Nullable MiIoBasicChannel basicChannel, String param, JsonElement value) {
|
||||
JsonElement val = value;
|
||||
deviceVariables.put(param, val);
|
||||
if (basicChannel == null) {
|
||||
logger.debug("Channel not found for {}", param);
|
||||
return;
|
||||
}
|
||||
final String transformation = basicChannel.getTransformation();
|
||||
if (transformation != null) {
|
||||
JsonElement transformed = Conversions.execute(transformation, val);
|
||||
JsonElement transformed = Conversions.execute(transformation, val, deviceVariables);
|
||||
logger.debug("Transformed with '{}': {} {} -> {} ", transformation, basicChannel.getFriendlyName(), val,
|
||||
transformed);
|
||||
val = transformed;
|
||||
@@ -614,7 +618,8 @@ public class MiIoBasicHandler extends MiIoAbstractHandler {
|
||||
} else {
|
||||
String strVal = val.getAsString().toLowerCase();
|
||||
updateState(basicChannel.getChannel(),
|
||||
"on".equals(strVal) || "true".equals(strVal) ? OnOffType.ON : OnOffType.OFF);
|
||||
"on".equals(strVal) || "true".equals(strVal) || "1".equals(strVal) ? OnOffType.ON
|
||||
: OnOffType.OFF);
|
||||
}
|
||||
break;
|
||||
case "color":
|
||||
|
||||
@@ -129,16 +129,7 @@ public class MiIoAsyncCommunication {
|
||||
}
|
||||
}
|
||||
|
||||
public int queueCommand(MiIoCommand command, String cloudServer) throws MiIoCryptoException, IOException {
|
||||
return queueCommand(command, "[]", cloudServer);
|
||||
}
|
||||
|
||||
public int queueCommand(MiIoCommand command, String params, String cloudServer)
|
||||
throws MiIoCryptoException, IOException {
|
||||
return queueCommand(command.getCommand(), params, cloudServer);
|
||||
}
|
||||
|
||||
public int queueCommand(String command, String params, String cloudServer)
|
||||
public int queueCommand(String command, String params, String cloudServer, String sender)
|
||||
throws MiIoCryptoException, IOException, JsonSyntaxException {
|
||||
try {
|
||||
JsonObject fullCommand = new JsonObject();
|
||||
|
||||
@@ -68,7 +68,10 @@
|
||||
"friendlyName": "Shutdown Timer",
|
||||
"channel": "delayoff",
|
||||
"type": "Number:Time",
|
||||
"unit": "seconds",
|
||||
"unit": "minutes",
|
||||
"stateDescription": {
|
||||
"pattern": "%.0f %unit%"
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
|
||||
@@ -80,7 +80,10 @@
|
||||
"friendlyName": "Shutdown Timer",
|
||||
"channel": "delayoff",
|
||||
"type": "Number:Time",
|
||||
"unit": "seconds",
|
||||
"unit": "minutes",
|
||||
"stateDescription": {
|
||||
"pattern": "%.1f %unit%"
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
@@ -142,11 +145,11 @@
|
||||
"label": "Default"
|
||||
},
|
||||
{
|
||||
"value": "1",
|
||||
"value": "2",
|
||||
"label": "CT mode"
|
||||
},
|
||||
{
|
||||
"value": "2",
|
||||
"value": "1",
|
||||
"label": "RGB mode"
|
||||
},
|
||||
{
|
||||
@@ -164,8 +167,48 @@
|
||||
]
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [],
|
||||
"readmeComment": "Value mapping `[\"0\"\u003d\"Default\",\"1\"\u003d\"CT mode\",\"2\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
"actions": [
|
||||
{
|
||||
"command": "set_rgb",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$rgb$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "set_ct_abx",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$ct$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"category": "settings",
|
||||
"tags": [
|
||||
"Control",
|
||||
"Light"
|
||||
],
|
||||
"readmeComment": "Note, currently only supporting switching to RGB or CT mode. Value mapping `[\"0\"\u003d\"Default\",\"2\"\u003d\"CT mode\",\"1\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
},
|
||||
{
|
||||
"property": "name",
|
||||
|
||||
@@ -55,7 +55,10 @@
|
||||
"friendlyName": "Shutdown Timer",
|
||||
"channel": "delayoff",
|
||||
"type": "Number:Time",
|
||||
"unit": "seconds",
|
||||
"unit": "minutes",
|
||||
"stateDescription": {
|
||||
"pattern": "%.0f %unit%"
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
@@ -117,11 +120,11 @@
|
||||
"label": "Default"
|
||||
},
|
||||
{
|
||||
"value": "1",
|
||||
"value": "2",
|
||||
"label": "CT mode"
|
||||
},
|
||||
{
|
||||
"value": "2",
|
||||
"value": "1",
|
||||
"label": "RGB mode"
|
||||
},
|
||||
{
|
||||
@@ -139,8 +142,48 @@
|
||||
]
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [],
|
||||
"readmeComment": "Value mapping `[\"0\"\u003d\"Default\",\"1\"\u003d\"CT mode\",\"2\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
"actions": [
|
||||
{
|
||||
"command": "set_rgb",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$rgb$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "set_ct_abx",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$ct$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"category": "settings",
|
||||
"tags": [
|
||||
"Control",
|
||||
"Light"
|
||||
],
|
||||
"readmeComment": "Note, currently only supporting switching to RGB or CT mode. Value mapping `[\"0\"\u003d\"Default\",\"2\"\u003d\"CT mode\",\"1\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
},
|
||||
{
|
||||
"property": "name",
|
||||
|
||||
@@ -80,7 +80,10 @@
|
||||
"friendlyName": "Shutdown Timer",
|
||||
"channel": "delayoff",
|
||||
"type": "Number:Time",
|
||||
"unit": "seconds",
|
||||
"unit": "minutes",
|
||||
"stateDescription": {
|
||||
"pattern": "%.0f %unit%"
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
@@ -142,11 +145,11 @@
|
||||
"label": "Default"
|
||||
},
|
||||
{
|
||||
"value": "1",
|
||||
"value": "2",
|
||||
"label": "CT mode"
|
||||
},
|
||||
{
|
||||
"value": "2",
|
||||
"value": "1",
|
||||
"label": "RGB mode"
|
||||
},
|
||||
{
|
||||
@@ -164,8 +167,48 @@
|
||||
]
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [],
|
||||
"readmeComment": "Value mapping `[\"0\"\u003d\"Default\",\"1\"\u003d\"CT mode\",\"2\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
"actions": [
|
||||
{
|
||||
"command": "set_rgb",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$rgb$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "set_ct_abx",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$ct$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"category": "settings",
|
||||
"tags": [
|
||||
"Control",
|
||||
"Light"
|
||||
],
|
||||
"readmeComment": "Note, currently only supporting switching to RGB or CT mode. Value mapping `[\"0\"\u003d\"Default\",\"2\"\u003d\"CT mode\",\"1\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
},
|
||||
{
|
||||
"property": "name",
|
||||
|
||||
@@ -65,7 +65,10 @@
|
||||
"friendlyName": "Shutdown Timer",
|
||||
"channel": "delayoff",
|
||||
"type": "Number:Time",
|
||||
"unit": "seconds",
|
||||
"unit": "minutes",
|
||||
"stateDescription": {
|
||||
"pattern": "%.0f %unit%"
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
@@ -112,68 +115,13 @@
|
||||
"Temperature"
|
||||
]
|
||||
},
|
||||
{
|
||||
"property": "color_mode",
|
||||
"friendlyName": "Color Mode",
|
||||
"channel": "colorMode",
|
||||
"type": "Number",
|
||||
"stateDescription": {
|
||||
"minimum": 0,
|
||||
"maximum": 5,
|
||||
"step": 1,
|
||||
"options": [
|
||||
{
|
||||
"value": "0",
|
||||
"label": "Default"
|
||||
},
|
||||
{
|
||||
"value": "1",
|
||||
"label": "CT mode"
|
||||
},
|
||||
{
|
||||
"value": "2",
|
||||
"label": "RGB mode"
|
||||
},
|
||||
{
|
||||
"value": "3",
|
||||
"label": "HSV mode"
|
||||
},
|
||||
{
|
||||
"value": "4",
|
||||
"label": "Color Flow mode"
|
||||
},
|
||||
{
|
||||
"value": "5",
|
||||
"label": "Night Light mode"
|
||||
}
|
||||
]
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
"command": "set_power",
|
||||
"parameterType": "NUMBER",
|
||||
"parameters": [
|
||||
"on",
|
||||
"smooth",
|
||||
500,
|
||||
"$value$"
|
||||
]
|
||||
}
|
||||
],
|
||||
"category": "settings",
|
||||
"tags": [
|
||||
"Control",
|
||||
"Light"
|
||||
],
|
||||
"readmeComment": "Value mapping `[\"0\"\u003d\"Default\",\"1\"\u003d\"CT mode\",\"2\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
},
|
||||
{
|
||||
"property": "rgb",
|
||||
"friendlyName": "RGB Color",
|
||||
"channel": "rgbColor",
|
||||
"type": "Color",
|
||||
"refresh": true,
|
||||
"transformation": "addBrightToHSV",
|
||||
"ChannelGroup": "actions",
|
||||
"actions": [
|
||||
{
|
||||
@@ -209,6 +157,128 @@
|
||||
"Light"
|
||||
]
|
||||
},
|
||||
{
|
||||
"property": "color_mode",
|
||||
"friendlyName": "Color Mode",
|
||||
"channel": "colorMode",
|
||||
"type": "Number",
|
||||
"stateDescription": {
|
||||
"minimum": 0,
|
||||
"maximum": 5,
|
||||
"step": 1,
|
||||
"options": [
|
||||
{
|
||||
"value": "0",
|
||||
"label": "Default"
|
||||
},
|
||||
{
|
||||
"value": "2",
|
||||
"label": "CT mode"
|
||||
},
|
||||
{
|
||||
"value": "1",
|
||||
"label": "RGB mode"
|
||||
},
|
||||
{
|
||||
"value": "3",
|
||||
"label": "HSV mode"
|
||||
},
|
||||
{
|
||||
"value": "4",
|
||||
"label": "Color Flow mode"
|
||||
},
|
||||
{
|
||||
"value": "5",
|
||||
"label": "Night Light mode"
|
||||
}
|
||||
]
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
"command": "set_rgb",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$rgb$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "set_ct_abx",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$ct$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"category": "settings",
|
||||
"tags": [
|
||||
"Control",
|
||||
"Light"
|
||||
],
|
||||
"readmeComment": "Note, currently only supporting switching to RGB or CT mode. Value mapping `[\"0\"\u003d\"Default\",\"2\"\u003d\"CT mode\",\"1\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
},
|
||||
{
|
||||
"property": "flowing",
|
||||
"friendlyName": "Color Flow",
|
||||
"channel": "colorflow",
|
||||
"type": "Switch",
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
"command": "start_cf",
|
||||
"parameterType": "EMPTY",
|
||||
"parameters": [
|
||||
0,
|
||||
0,
|
||||
"500,1,255,100,500,1,5292678,100,500,1,11673869,100,500,1,16776960,100,500,1,7733248,100"
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "ON"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "stop_cf",
|
||||
"parameterType": "EMPTY",
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "OFF"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"category": "switch",
|
||||
"tags": [
|
||||
"Switch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"property": "name",
|
||||
"friendlyName": "Name",
|
||||
|
||||
@@ -71,7 +71,10 @@
|
||||
"friendlyName": "Shutdown Timer",
|
||||
"channel": "delayoff",
|
||||
"type": "Number:Time",
|
||||
"unit": "seconds",
|
||||
"unit": "minutes",
|
||||
"stateDescription": {
|
||||
"pattern": "%.0f %unit%"
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
@@ -133,11 +136,11 @@
|
||||
"label": "Default"
|
||||
},
|
||||
{
|
||||
"value": "1",
|
||||
"value": "2",
|
||||
"label": "CT mode"
|
||||
},
|
||||
{
|
||||
"value": "2",
|
||||
"value": "1",
|
||||
"label": "RGB mode"
|
||||
},
|
||||
{
|
||||
@@ -157,14 +160,38 @@
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
"command": "set_power",
|
||||
"parameterType": "NUMBER",
|
||||
"command": "set_rgb",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"on",
|
||||
"$rgb$",
|
||||
"smooth",
|
||||
500,
|
||||
"$value$"
|
||||
]
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "set_ct_abx",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$ct$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"category": "settings",
|
||||
@@ -172,7 +199,7 @@
|
||||
"Control",
|
||||
"Light"
|
||||
],
|
||||
"readmeComment": "Value mapping `[\"0\"\u003d\"Default\",\"1\"\u003d\"CT mode\",\"2\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
"readmeComment": "Note, currently only supporting switching to RGB or CT mode. Value mapping `[\"0\"\u003d\"Default\",\"2\"\u003d\"CT mode\",\"1\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
},
|
||||
{
|
||||
"property": "name",
|
||||
|
||||
@@ -56,7 +56,10 @@
|
||||
"friendlyName": "Shutdown Timer",
|
||||
"channel": "delayoff",
|
||||
"type": "Number:Time",
|
||||
"unit": "seconds",
|
||||
"unit": "minutes",
|
||||
"stateDescription": {
|
||||
"pattern": "%.0f %unit%"
|
||||
},
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
@@ -119,11 +122,11 @@
|
||||
"label": "Default"
|
||||
},
|
||||
{
|
||||
"value": "1",
|
||||
"value": "2",
|
||||
"label": "CT mode"
|
||||
},
|
||||
{
|
||||
"value": "2",
|
||||
"value": "1",
|
||||
"label": "RGB mode"
|
||||
},
|
||||
{
|
||||
@@ -143,14 +146,38 @@
|
||||
"refresh": true,
|
||||
"actions": [
|
||||
{
|
||||
"command": "set_power",
|
||||
"parameterType": "NUMBER",
|
||||
"command": "set_rgb",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"on",
|
||||
"$rgb$",
|
||||
"smooth",
|
||||
500,
|
||||
"$value$"
|
||||
]
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "set_ct_abx",
|
||||
"parameterType": "NONE",
|
||||
"parameters": [
|
||||
"$ct$",
|
||||
"smooth",
|
||||
500
|
||||
],
|
||||
"condition": {
|
||||
"name": "matchValue",
|
||||
"parameters": [
|
||||
{
|
||||
"matchValue": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"category": "settings",
|
||||
@@ -158,7 +185,7 @@
|
||||
"Control",
|
||||
"Light"
|
||||
],
|
||||
"readmeComment": "Value mapping `[\"0\"\u003d\"Default\",\"1\"\u003d\"CT mode\",\"2\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
"readmeComment": "Note, currently only supporting switching to RGB or CT mode. Value mapping `[\"0\"\u003d\"Default\",\"2\"\u003d\"CT mode\",\"1\"\u003d\"RGB mode\",\"3\"\u003d\"HSV mode\",\"4\"\u003d\"Color Flow mode\",\"5\"\u003d\"Night Light mode\"]`"
|
||||
},
|
||||
{
|
||||
"property": "rgb",
|
||||
|
||||
Reference in New Issue
Block a user