diff --git a/bundles/create_openhab_binding_skeleton.cmd b/bundles/create_openhab_binding_skeleton.cmd index 6ecda2fd95c3d..9f5922554aef6 100644 --- a/bundles/create_openhab_binding_skeleton.cmd +++ b/bundles/create_openhab_binding_skeleton.cmd @@ -10,7 +10,7 @@ IF %ARGC% NEQ 3 ( exit /B 1 ) -SET OpenhabVersion="4.3.0-SNAPSHOT" +SET OpenhabVersion="5.0.0-SNAPSHOT" SET BindingIdInCamelCase=%~1 SET BindingIdInLowerCase=%BindingIdInCamelCase% diff --git a/bundles/create_openhab_binding_skeleton.sh b/bundles/create_openhab_binding_skeleton.sh index e035e8a93f2c5..b994a5d3acc29 100755 --- a/bundles/create_openhab_binding_skeleton.sh +++ b/bundles/create_openhab_binding_skeleton.sh @@ -2,7 +2,7 @@ [ $# -lt 3 ] && { echo "Usage: $0 "; exit 1; } -openHABVersion=4.3.0-SNAPSHOT +openHABVersion=5.0.0-SNAPSHOT camelcaseId=$1 id=`echo $camelcaseId | tr '[:upper:]' '[:lower:]'` diff --git a/bundles/org.openhab.automation.jrubyscripting/src/main/java/org/openhab/automation/jrubyscripting/internal/JRubyEngineWrapper.java b/bundles/org.openhab.automation.jrubyscripting/src/main/java/org/openhab/automation/jrubyscripting/internal/JRubyEngineWrapper.java index 07d13577c7f6c..628cb23b79419 100644 --- a/bundles/org.openhab.automation.jrubyscripting/src/main/java/org/openhab/automation/jrubyscripting/internal/JRubyEngineWrapper.java +++ b/bundles/org.openhab.automation.jrubyscripting/src/main/java/org/openhab/automation/jrubyscripting/internal/JRubyEngineWrapper.java @@ -16,8 +16,6 @@ import java.util.Objects; import javax.script.Bindings; -import javax.script.Compilable; -import javax.script.CompiledScript; import javax.script.Invocable; import javax.script.ScriptContext; import javax.script.ScriptEngine; @@ -37,7 +35,9 @@ * @author Jimmy Tanagra - Initial contribution */ @NonNullByDefault -public class JRubyEngineWrapper implements Compilable, Invocable, ScriptEngine { +public class JRubyEngineWrapper implements Invocable, ScriptEngine { + // Don't implement Compilable because there is a bug + // in JRuby's compiled scripts: https://github.com/jruby/jruby/issues/8346 private final JRubyEngine engine; @@ -48,16 +48,6 @@ public class JRubyEngineWrapper implements Compilable, Invocable, ScriptEngine { this.engine = Objects.requireNonNull(engine); } - @Override - public CompiledScript compile(@Nullable String script) throws ScriptException { - return new JRubyCompiledScriptWrapper(engine.compile(script)); - } - - @Override - public CompiledScript compile(@Nullable Reader reader) throws ScriptException { - return new JRubyCompiledScriptWrapper(engine.compile(reader)); - } - @Override public Object eval(@Nullable String script, @Nullable ScriptContext context) throws ScriptException { Object ctx = Objects.requireNonNull(context).getBindings(ScriptContext.ENGINE_SCOPE).get(CONTEXT_VAR_NAME); diff --git a/bundles/org.openhab.automation.jsscripting/pom.xml b/bundles/org.openhab.automation.jsscripting/pom.xml index 02d1894448b34..c8a59c89e16c7 100644 --- a/bundles/org.openhab.automation.jsscripting/pom.xml +++ b/bundles/org.openhab.automation.jsscripting/pom.xml @@ -23,25 +23,37 @@ !jdk.vm.ci.services - 22.0.0.2 + 24.1.1 ${project.version} openhab@5.8.1 - + org.apache.maven.plugins - maven-dependency-plugin + maven-shade-plugin + 3.6.0 - embed-dependencies + package - unpack-dependencies + shade - META-INF/services/com.oracle.truffle.api.TruffleLanguage$Provider + + + org.lastnpe.eea:eea-all + org.apache.karaf.features:framework + + + false + + + + @@ -130,32 +142,29 @@ - org.graalvm.sdk - graal-sdk - ${graal.version} - - - org.graalvm.truffle - truffle-api - ${graal.version} + org.graalvm.polyglot + polyglot + ${graaljs.version} org.graalvm.js js-scriptengine - ${graal.version} + ${graaljs.version} org.graalvm.regex regex - ${graal.version} + ${graaljs.version} - org.graalvm.js - js - ${graal.version} + org.graalvm.polyglot + js-community + ${graaljs.version} + pom + runtime diff --git a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java index b842b3bb0ce41..d3dfb643fd3dc 100644 --- a/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java +++ b/bundles/org.openhab.automation.jsscripting/src/main/java/org/openhab/automation/jsscripting/internal/OpenhabGraalJSScriptEngine.java @@ -163,8 +163,8 @@ public OpenhabGraalJSScriptEngine(boolean injectionEnabled, boolean injectionCac .option("js.nashorn-compat", "true") // Enable Nashorn compat mode as openhab-js relies on // accessors, see // https://github.com/oracle/graaljs/blob/master/docs/user/NashornMigrationGuide.md#accessors - .option("js.ecmascript-version", "2022") // If Nashorn compat is enabled, it will enforce ES5 - // compatibility, we want ECMA2022 + .option("js.ecmascript-version", "2024") // If Nashorn compat is enabled, it will enforce ES5 + // compatibility, we want ECMA2024 .option("js.commonjs-require", "true") // Enable CommonJS module support .hostClassLoader(getClass().getClassLoader()) .fileSystem(new DelegatingFileSystem(FileSystems.getDefault().provider()) { diff --git a/bundles/org.openhab.automation.jsscripting/src/main/resources/META-INF/services/com.oracle.truffle.api.TruffleLanguage$Provider b/bundles/org.openhab.automation.jsscripting/src/main/resources/META-INF/services/com.oracle.truffle.api.TruffleLanguage$Provider deleted file mode 100644 index 1fb86e4d04bc2..0000000000000 --- a/bundles/org.openhab.automation.jsscripting/src/main/resources/META-INF/services/com.oracle.truffle.api.TruffleLanguage$Provider +++ /dev/null @@ -1,2 +0,0 @@ -com.oracle.truffle.regex.RegexLanguageProvider -com.oracle.truffle.js.lang.JavaScriptLanguageProvider diff --git a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerColorTemperatureController.java b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerColorTemperatureController.java index 7e30099775383..85c48c266f27f 100644 --- a/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerColorTemperatureController.java +++ b/bundles/org.openhab.binding.amazonechocontrol/src/main/java/org/openhab/binding/amazonechocontrol/internal/smarthome/HandlerColorTemperatureController.java @@ -26,7 +26,9 @@ import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeCapabilities.SmartHomeCapability; import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.SmartHomeDevice; import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; +import org.openhab.core.library.unit.Units; import org.openhab.core.thing.DefaultSystemChannelTypeProvider; import org.openhab.core.thing.type.ChannelTypeUID; import org.openhab.core.types.Command; @@ -130,15 +132,21 @@ public boolean handleCommand(Connection connection, SmartHomeDevice shd, String if (channelId.equals(COLOR_TEMPERATURE_IN_KELVIN.channelId)) { // WRITING TO THIS CHANNEL DOES CURRENTLY NOT WORK, BUT WE LEAVE THE CODE FOR FUTURE USE! if (containsCapabilityProperty(capabilities, COLOR_TEMPERATURE_IN_KELVIN.propertyName)) { - if (command instanceof DecimalType) { - int intValue = ((DecimalType) command).intValue(); - if (intValue < 1000) { - intValue = 1000; + QuantityType kelvinQuantity = null; + if (command instanceof QuantityType genericQuantity) { + kelvinQuantity = genericQuantity.toInvertibleUnit(Units.KELVIN); + } else if (command instanceof DecimalType decimal) { + kelvinQuantity = QuantityType.valueOf(decimal.intValue(), Units.KELVIN); + } + if (kelvinQuantity != null) { + int kelvin = kelvinQuantity.intValue(); + if (kelvin < 1000) { + kelvin = 1000; } - if (intValue > 10000) { - intValue = 10000; + if (kelvin > 10000) { + kelvin = 10000; } - connection.smartHomeCommand(entityId, "setColorTemperature", "colorTemperatureInKelvin", intValue); + connection.smartHomeCommand(entityId, "setColorTemperature", "colorTemperatureInKelvin", kelvin); return true; } } diff --git a/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/GroupThingHandler.java b/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/GroupThingHandler.java index 1d3c85b0e3472..62f9977ca40e0 100644 --- a/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/GroupThingHandler.java +++ b/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/GroupThingHandler.java @@ -14,7 +14,6 @@ import static org.openhab.binding.deconz.internal.BindingConstants.*; import static org.openhab.binding.deconz.internal.Util.constrainToRange; -import static org.openhab.binding.deconz.internal.Util.kelvinToMired; import java.util.Collection; import java.util.Map; @@ -36,7 +35,9 @@ import org.openhab.core.library.types.HSBType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; +import org.openhab.core.library.unit.Units; import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -139,9 +140,15 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } case CHANNEL_COLOR_TEMPERATURE -> { - if (command instanceof DecimalType decimalCommand) { - int miredValue = kelvinToMired(decimalCommand.intValue()); - newGroupAction.ct = constrainToRange(miredValue, ZCL_CT_MIN, ZCL_CT_MAX); + QuantityType miredQuantity = null; + if (command instanceof QuantityType genericQuantity) { + miredQuantity = genericQuantity.toInvertibleUnit(Units.MIRED); + } else if (command instanceof DecimalType decimal) { + miredQuantity = QuantityType.valueOf(decimal.intValue(), Units.KELVIN) + .toInvertibleUnit(Units.MIRED); + } + if (miredQuantity != null) { + newGroupAction.ct = constrainToRange(miredQuantity.intValue(), ZCL_CT_MIN, ZCL_CT_MAX); newGroupAction.on = true; } } diff --git a/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/LightThingHandler.java b/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/LightThingHandler.java index 2e035dd1374d8..58c0e24eea2ab 100644 --- a/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/LightThingHandler.java +++ b/bundles/org.openhab.binding.deconz/src/main/java/org/openhab/binding/deconz/internal/handler/LightThingHandler.java @@ -245,9 +245,15 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } case CHANNEL_COLOR_TEMPERATURE -> { - if (command instanceof DecimalType) { - int miredValue = kelvinToMired(((DecimalType) command).intValue()); - newLightState.ct = constrainToRange(miredValue, ctMin, ctMax); + QuantityType miredQuantity = null; + if (command instanceof QuantityType genericQuantity) { + miredQuantity = genericQuantity.toInvertibleUnit(Units.MIRED); + } else if (command instanceof DecimalType decimal) { + miredQuantity = QuantityType.valueOf(decimal.intValue(), Units.KELVIN) + .toInvertibleUnit(Units.MIRED); + } + if (miredQuantity != null) { + newLightState.ct = constrainToRange(miredQuantity.intValue(), ctMin, ctMax); newLightState.on = true; } } diff --git a/bundles/org.openhab.binding.exec/README.md b/bundles/org.openhab.binding.exec/README.md index 8ed5aaca7920e..1ffd06b69c0b1 100644 --- a/bundles/org.openhab.binding.exec/README.md +++ b/bundles/org.openhab.binding.exec/README.md @@ -54,7 +54,7 @@ Please note that if the transformation failed or returned `null`, the original d Thing exec:command:uniquename [command="/command/to/execute here", interval=15, timeout=5, autorun=false] ``` -The `command` itself can be enhanced using the well known syntax of the [Java formatter class syntax](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Formatter.html#syntax). +The `command` itself can be enhanced using the well known syntax of the [Java formatter class syntax](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Formatter.html#syntax). The following parameters are automatically added: - the current date (as java.util.Date, example: `%1$tY-%1$tm-%1$td`) diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/FreeAtHomeBindingConstants.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/FreeAtHomeBindingConstants.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/FreeAtHomeBindingConstants.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/FreeAtHomeBindingConstants.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/FreeAtHomeDiscoveryService.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/FreeAtHomeDiscoveryService.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/FreeAtHomeDiscoveryService.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/FreeAtHomeDiscoveryService.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/FreeAtHomeHandlerFactory.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/FreeAtHomeHandlerFactory.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/FreeAtHomeHandlerFactory.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/FreeAtHomeHandlerFactory.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/configuration/FreeAtHomeBridgeHandlerConfiguration.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/configuration/FreeAtHomeBridgeHandlerConfiguration.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/configuration/FreeAtHomeBridgeHandlerConfiguration.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/configuration/FreeAtHomeBridgeHandlerConfiguration.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/configuration/FreeAtHomeDeviceHandlerConfiguration.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/configuration/FreeAtHomeDeviceHandlerConfiguration.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/configuration/FreeAtHomeDeviceHandlerConfiguration.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/configuration/FreeAtHomeDeviceHandlerConfiguration.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/datamodel/FreeAtHomeDatapoint.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/datamodel/FreeAtHomeDatapoint.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/datamodel/FreeAtHomeDatapoint.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/datamodel/FreeAtHomeDatapoint.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/datamodel/FreeAtHomeDatapointGroup.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/datamodel/FreeAtHomeDatapointGroup.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/datamodel/FreeAtHomeDatapointGroup.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/datamodel/FreeAtHomeDatapointGroup.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/datamodel/FreeAtHomeDeviceChannel.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/datamodel/FreeAtHomeDeviceChannel.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/datamodel/FreeAtHomeDeviceChannel.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/datamodel/FreeAtHomeDeviceChannel.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/datamodel/FreeAtHomeDeviceDescription.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/datamodel/FreeAtHomeDeviceDescription.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/datamodel/FreeAtHomeDeviceDescription.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/datamodel/FreeAtHomeDeviceDescription.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/handler/FreeAtHomeBridgeHandler.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/handler/FreeAtHomeBridgeHandler.java similarity index 99% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/handler/FreeAtHomeBridgeHandler.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/handler/FreeAtHomeBridgeHandler.java index cf719f0e71091..e7f82d06e04f8 100644 --- a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/handler/FreeAtHomeBridgeHandler.java +++ b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/handler/FreeAtHomeBridgeHandler.java @@ -429,9 +429,10 @@ public void setDatapointOnWebsocketFeedback(String receivedText) { if (deviceHandler != null) { deviceHandler.onDeviceStateChanged(eventDatapointID, value); + logger.debug("Socket event processed: event-datapoint-ID {} value {}", eventDatapointID, value); + } else { + logger.debug("Socket event not processed: event-datapoint-ID {} value {}", eventDatapointID, value); } - - logger.debug("Socket event processed: event-datapoint-ID {} value {}", eventDatapointID, value); } } } diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/handler/FreeAtHomeDeviceHandler.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/handler/FreeAtHomeDeviceHandler.java similarity index 98% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/handler/FreeAtHomeDeviceHandler.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/handler/FreeAtHomeDeviceHandler.java index 2165ae3cb2dc2..35a7d21e92082 100644 --- a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/handler/FreeAtHomeDeviceHandler.java +++ b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/handler/FreeAtHomeDeviceHandler.java @@ -291,7 +291,6 @@ public void handleCommand(ChannelUID channelUID, Command command) { if (dpg == null) { logger.debug("Handle command for device (but invalid datapointgroup) {} - at channel {} - full command {}", device.getDeviceId(), channelUID.getAsString(), command.toFullString()); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "@text/conf-error.invalid-deviceconfig"); } else { @@ -480,8 +479,7 @@ public void updateChannels() throws FreeAtHomeGeneralException { channelTypeUID = createChannelTypeForDatapointgroup(dpg, channelTypeUID); } - ChannelUID channelUID = new ChannelUID(thingUID, channel.getChannelId(), - dpg.getLabel().substring(4)); + ChannelUID channelUID = createChannelUID(thingUID, channel.getChannelId(), dpg.getLabel()); String channelLabel = String.format("%s", i18nProvider.getText(bundle, dpg.getLabel(), "-", locale)); @@ -568,7 +566,7 @@ private void reloadChannelTypes() throws FreeAtHomeGeneralException { channelTypeUID = createChannelTypeForDatapointgroup(dpg, channelTypeUID); } - ChannelUID channelUID = new ChannelUID(thingUID, channel.getChannelId()); + ChannelUID channelUID = createChannelUID(thingUID, channel.getChannelId(), dpg.getLabel()); FreeAtHomeDatapoint outputDatapoint = dpg.getOutputDatapoint(); @@ -589,6 +587,11 @@ private void reloadChannelTypes() throws FreeAtHomeGeneralException { } } + // Create a channel UID. Makes sure that the channel UID is unique and generated the same way every time + private ChannelUID createChannelUID(ThingUID thingUID, String channelID, String dpgLabel) { + return new ChannelUID(thingUID, channelID, dpgLabel.substring(4)); + } + public void removeChannels() { Bridge bridge = this.getBridge(); diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/handler/FreeAtHomeDeviceStateListener.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/handler/FreeAtHomeDeviceStateListener.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/handler/FreeAtHomeDeviceStateListener.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/handler/FreeAtHomeDeviceStateListener.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/type/FreeAtHomeChannelTypeProvider.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/type/FreeAtHomeChannelTypeProvider.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/type/FreeAtHomeChannelTypeProvider.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/type/FreeAtHomeChannelTypeProvider.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/type/FreeAtHomeChannelTypeProviderImpl.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/type/FreeAtHomeChannelTypeProviderImpl.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/type/FreeAtHomeChannelTypeProviderImpl.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/type/FreeAtHomeChannelTypeProviderImpl.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/type/FreeAtHomeThingTypeProvider.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/type/FreeAtHomeThingTypeProvider.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/type/FreeAtHomeThingTypeProvider.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/type/FreeAtHomeThingTypeProvider.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/type/FreeAtHomeThingTypeProviderImpl.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/type/FreeAtHomeThingTypeProviderImpl.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/type/FreeAtHomeThingTypeProviderImpl.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/type/FreeAtHomeThingTypeProviderImpl.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/FidTranslationUtils.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/FidTranslationUtils.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/FidTranslationUtils.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/FidTranslationUtils.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/FreeAtHomeGeneralException.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/FreeAtHomeGeneralException.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/FreeAtHomeGeneralException.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/FreeAtHomeGeneralException.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/FreeAtHomeHttpCommunicationException.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/FreeAtHomeHttpCommunicationException.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/FreeAtHomeHttpCommunicationException.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/FreeAtHomeHttpCommunicationException.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/PIdContainerClass.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/PIdContainerClass.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/PIdContainerClass.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/PIdContainerClass.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/PidTranslationUtils.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/PidTranslationUtils.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/PidTranslationUtils.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/PidTranslationUtils.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/UidUtils.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/UidUtils.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/util/UidUtils.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/util/UidUtils.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/BinaryValueStateConverter.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/BinaryValueStateConverter.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/BinaryValueStateConverter.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/BinaryValueStateConverter.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/BooleanValueStateConverter.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/BooleanValueStateConverter.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/BooleanValueStateConverter.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/BooleanValueStateConverter.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/DecimalValueStateConverter.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/DecimalValueStateConverter.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/DecimalValueStateConverter.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/DecimalValueStateConverter.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/ShuttercontrolValueStateConverter.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/ShuttercontrolValueStateConverter.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/ShuttercontrolValueStateConverter.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/ShuttercontrolValueStateConverter.java diff --git a/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/ValueStateConverter.java b/bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/ValueStateConverter.java similarity index 100% rename from bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathomesystem/internal/valuestateconverter/ValueStateConverter.java rename to bundles/org.openhab.binding.freeathome/src/main/java/org/openhab/binding/freeathome/internal/valuestateconverter/ValueStateConverter.java diff --git a/bundles/org.openhab.binding.govee/README.md b/bundles/org.openhab.binding.govee/README.md index 459f17aa5f333..25d2c288c4675 100644 --- a/bundles/org.openhab.binding.govee/README.md +++ b/bundles/org.openhab.binding.govee/README.md @@ -20,68 +20,133 @@ While Govee provides probably more than a hundred different lights, only the fol Here is a list of the supported devices (the ones marked with * have been tested by the author) -- H619Z RGBIC Pro LED Strip Lights +- H6042 Govee TV Light Bar #2 +- H6043 Govee TV Light Bars #2 - H6046 RGBIC TV Light Bars - H6047 RGBIC Gaming Light Bars with Smart Controller +- H6051 Aura - Smart Table Lamp +- H6052 Govee Table Lamp +- H6056 H6056 Flow Plus +- H6059 RGBWW Night Light for Kids - H6061 Glide Hexa LED Panels (*) - H6062 Glide Wall Light +- H6063 Gaming Wall Light - H6065 Glide RGBIC Y Lights - H6066 Glide Hexa Pro LED Panel - H6067 Glide Triangle Light Panels (*) +- H606A Glide Hexa Light Panel Ultra - H6072 RGBICWW Corner Floor Lamp (*) -- H6076 RGBICW Smart Corner Floor Lamp (*) - H6073 LED Floor Lamp +- H6076 RGBICW Smart Corner Floor Lamp (*) - H6078 Cylinder Floor Lamp +- H607C Floor Lamp #2 - H6087 RGBIC Smart Wall Sconces -- H6173 RGBIC Outdoor Strip Lights -- H619A RGBIC Strip Lights With Protective Coating 5M -- H619B RGBIC LED Strip Lights With Protective Coating -- H619C LED Strip Lights With Protective Coating -- H619D RGBIC PRO LED Strip Lights -- H619E RGBIC LED Strip Lights With Protective Coating -- H61A0 RGBIC Neon Rope Light 1M -- H61A1 RGBIC Neon Rope Light 2M -- H61A2 RGBIC Neon Rope Light 5M -- H61A3 RGBIC Neon Rope Light -- H61C5 RGBIC LED Neon Rope Lights for Desks (*) -- H61D3 Neon Rope Light 2 3M (*) -- H61D5 Neon Rope Light 2 5M (*) -- H61A5 Neon LED Strip Light 10 -- H61A8Neon Neon Rope Light 10 -- H618A RGBIC Basic LED Strip Lights 5M -- H618C RGBIC Basic LED Strip Lights 5M +- H6088 RGBIC Cube Wall Sconces +- H608A String Downlights 5M +- H608B String Downlights 3M +- H608C String Downlights 2M +- H608D String Downlights 10M +- H60A0 Ceiling Light +- H60A1 Smart Ceiling Light (*) +- H610A Glide Lively Wall Lights +- H610B Music Wall Lights +- H6110 2x5M Multicolor with Alexa - H6117 Dream Color LED Strip Light 10M +- H6141 5M Smart Multicolor Strip Light +- H6143 5M Strip Light +- H6144 2x5M Strip Light - H6159 RGB Light Strip (*) -- H615E LED Strip Lights 30M +- H615A 5M Light Strip with Alexa (*) +- H615B 10M Light Strip with Alexa +- H615C 15M Light Strip with Alexa +- H615D 20M Light Strip with Alexa +- H615E 30M Light Strip with Alexa - H6163 Dreamcolor LED Strip Light 5M -- H610A Glide Lively Wall Lights -- H610B Music Wall Lights +- H6167 TV Backlight 2.4M +- H6168 TV Backlight 2x0.7M+2x1.2M +- H616C Outdoor Strip 10M +- H616D Outdoor Strip 2x7.5M +- H616E Outdoor Strip 2x10M - H6172 Outdoor LED Strip 10m -- H61B2 RGBIC Neon TV Backlight +- H6173 RGBIC Outdoor Strip Lights +- H6175 RGBIC Outdoor Strip Lights 10M +- H6176 RGBIC Outdoor Strip Lights 30M +- H6182 WiFi Multicolor TV Strip Light +- H618A RGBIC Basic LED Strip Lights 5M +- H618C RGBIC Basic LED Strip Lights 5M +- H618E LED Strip Lights 22m +- H618F RGBIC LED Strip Lights +- H619A Strip Lights With Protective Coating 5M +- H619B Strip Lights With Protective Coating 7.5M +- H619C Strip Lights With Protective Coating with Alexa 10M +- H619D PRO LED Strip Lights with Alexa 2x7.5M +- H619E Strip Lights With Protective Coating with Alexa 2x10M +- H619Z Pro LED Strip Lights 3M +- H61A0 RGBIC Neon Rope Light 3M +- H61A1 RGBIC Neon Rope Light 2M +- H61A2 RGBIC Neon Rope Light 5M +- H61A3 RGBIC Neon Rope Light 4M +- H61A5 Neon LED Strip Light 10M +- H61A8 Neon Rope Light 10M +- H61A8 Neon Rope Light 20M +- H61B1 Strip Light with Cover 5M +- H61B2 RGBIC Neon TV Backlight 3M +- H61BA LED Strip Light 5M +- H61BC LED Strip Light 10M +- H61BE LED Strip Light 2x10M +- H61C2 Neon LED Strip Light 2M +- H61C2 Neon LED Strip Light 3M +- H61C2 Neon LED Strip Light 5M +- H61D3 Neon Rope Light 2 3m (*) +- H61D5 Neon Rope Light 2 5m (*) +- H61E0 LED Strip Light M1 - H61E1 LED Strip Light M1 - H7012 Warm White Outdoor String Lights - H7013 Warm White Outdoor String Lights - H7021 RGBIC Warm White Smart Outdoor String - H7028 Lynx Dream LED-Bulb String +- H7033 LED-Bulb String Lights - H7041 LED Outdoor Bulb String Lights - H7042 LED Outdoor Bulb String Lights -- H705A Permanent Outdoor Lights 30M -- H705B Permanent Outdoor Lights 15M - H7050 Outdoor Ground Lights 11M - H7051 Outdoor Ground Lights 15M +- H7052 Outdoor Ground Lights 15M +- H7052 Outdoor Ground Lights 30M - H7055 Pathway Light +- H705A Permanent Outdoor Lights 30M +- H705B Permanent Outdoor Lights 15M +- H705C Permanent Outdoor Lights 45M +- H705D Permanent Outdoor Lights #2 15M +- H705E Permanent Outdoor Lights #2 30M +- H705F Permanent Outdoor Lights #2 45M - H7060 LED Flood Lights (2-Pack) - H7061 LED Flood Lights (4-Pack) - H7062 LED Flood Lights (6-Pack) +- H7063 Outdoor Flood Lights - H7065 Outdoor Spot Lights -- H70C1 Govee Christmas String Lights 10m (*) -- H70C2 Govee Christmas String Lights 20m (*) -- H6051 Aura - Smart Table Lamp -- H6056 H6056 Flow Plus -- H6059 RGBWW Night Light for Kids -- H618F RGBIC LED Strip Lights -- H618E LED Strip Lights 22m -- H6168 TV LED Backlight +- H7066 Outdoor Spot Lights +- H706A Permanent Outdoor Lights Pro 30M +- H706B Permanent Outdoor Lights Pro 45M +- H706C Permanent Outdoor Lights Pro 60M +- H7070 Outdoor Projector Light (*) +- H7075 Outdoor Wall Light +- H70B1 520 LED Curtain Lights +- H70BC 400 LED Curtain Lights +- H70C1 RGBIC String Light 10M (*) +- H70C2 RGBIC String Light 20M (*) +- H805A Permanent Outdoor Lights Elite 30M +- H805B Permanent Outdoor Lights Elite 15M +- H805C Permanent Outdoor Lights Elite 45M + +## Firewall + +Govee devices communicate via multicast and unicast messages over the LAN. +So you must ensure that any firewall on your openHAB server is configured to pass the following traffic: + +- Multicast UDP on 239.255.255.250 port 4001 +- Incoming unicast UDP on port 4002 +- Outgoing unicast UDP on port 4003 + ## Discovery Discovery is done by scanning the devices in the Thing section. @@ -108,11 +173,13 @@ arp -a | grep "MAC_ADDRESS" ### `govee-light` Thing Configuration -| Name | Type | Description | Default | Required | Advanced | -|-----------------|---------|---------------------------------------|---------|----------|----------| -| hostname | text | Hostname or IP address of the device | N/A | yes | no | -| macAddress | text | MAC address of the device | N/A | yes | no | -| refreshInterval | integer | Interval the device is polled in sec. | 5 | no | yes | +| Name | Type | Description | Default | Required | Advanced | +|-----------------|---------|------------------------------------------------------------------|---------|----------|----------| +| hostname | text | Hostname or IP address of the device | N/A | yes | no | +| macAddress | text | MAC address of the device | N/A | yes | no | +| refreshInterval | integer | Interval the device is polled in sec. | 5 | no | yes | +| minKelvin | integer | The minimum color temperature that the light supports in Kelvin. | N/A | no | yes | +| maxKelvin | integer | The maximum color temperature that the light supports in Kelvin. | N/A | no | yes | ## Channels diff --git a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/CommunicationManager.java b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/CommunicationManager.java index c8cdee364b464..abecfb6ab1697 100644 --- a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/CommunicationManager.java +++ b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/CommunicationManager.java @@ -15,13 +15,23 @@ import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; +import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.MulticastSocket; import java.net.NetworkInterface; +import java.net.SocketAddress; +import java.net.StandardProtocolFamily; +import java.net.StandardSocketOptions; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedByInterruptException; +import java.nio.channels.DatagramChannel; +import java.time.Duration; import java.time.Instant; -import java.util.HashMap; +import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -29,6 +39,7 @@ import org.openhab.binding.govee.internal.model.GenericGoveeRequest; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,231 +47,259 @@ import com.google.gson.JsonParseException; /** - * The {@link CommunicationManager} is a thread that handles the answers of all devices. - * Therefore it needs to apply the information to the right thing. - * - * Discovery uses the same response code, so we must not refresh the status during discovery. + * The {@link CommunicationManager} component implements a sender to send commands to Govee devices, + * and implements a thread that handles the notifications from all devices. It applies the status + * information to the right Thing. It supports both discovery and status commands and notifications + * concurrently. * * @author Stefan Höhn - Initial contribution * @author Danny Baumann - Thread-Safe design refactoring + * @author Andrew Fiddian-Green - New threading model using java.nio channel */ @NonNullByDefault @Component(service = CommunicationManager.class) public class CommunicationManager { private final Logger logger = LoggerFactory.getLogger(CommunicationManager.class); private final Gson gson = new Gson(); - // Holds a list of all thing handlers to send them thing updates via the receiver-Thread - private final Map thingHandlers = new HashMap<>(); - @Nullable - private StatusReceiver receiverThread; + + // list of Thing handler listeners that will receive state notifications + private final Map thingHandlerListeners = new ConcurrentHashMap<>(); + + private @Nullable GoveeDiscoveryListener discoveryListener; + private @Nullable Thread serverThread; + private boolean serverStopFlag = false; + + private final Object paramsLock = new Object(); + private final Object serverLock = new Object(); + private final Object senderLock = new Object(); private static final String DISCOVERY_MULTICAST_ADDRESS = "239.255.255.250"; private static final int DISCOVERY_PORT = 4001; private static final int RESPONSE_PORT = 4002; private static final int REQUEST_PORT = 4003; - private static final int INTERFACE_TIMEOUT_SEC = 5; + public static final int SCAN_TIMEOUT_SEC = 5; private static final String DISCOVER_REQUEST = "{\"msg\": {\"cmd\": \"scan\", \"data\": {\"account_topic\": \"reserve\"}}}"; - public interface DiscoveryResultReceiver { - void onResultReceived(DiscoveryResponse result); + private static final InetSocketAddress DISCOVERY_SOCKET_ADDRESS = new InetSocketAddress(DISCOVERY_MULTICAST_ADDRESS, + DISCOVERY_PORT); + + public interface GoveeDiscoveryListener { + void onDiscoveryResponse(DiscoveryResponse discoveryResponse); } @Activate public CommunicationManager() { + serverStart(); + } + + @Deactivate + public void deactivate() { + thingHandlerListeners.clear(); + discoveryListener = null; + serverStop(); } + /** + * Thing handlers register themselves to receive state updates when they are initialized. + */ public void registerHandler(GoveeHandler handler) { - synchronized (thingHandlers) { - thingHandlers.put(handler.getHostname(), handler); - if (receiverThread == null) { - receiverThread = new StatusReceiver(); - receiverThread.start(); - } - } + thingHandlerListeners.put(ipAddressFrom(handler.getHostname()), handler); } + /** + * Thing handlers unregister themselves when they are destroyed. + */ public void unregisterHandler(GoveeHandler handler) { - synchronized (thingHandlers) { - thingHandlers.remove(handler.getHostname()); - if (thingHandlers.isEmpty()) { - StatusReceiver receiver = receiverThread; - if (receiver != null) { - receiver.stopReceiving(); - } - receiverThread = null; - } - } + thingHandlerListeners.remove(ipAddressFrom(handler.getHostname())); } + /** + * Send a unicast command request to the device. + */ public void sendRequest(GoveeHandler handler, GenericGoveeRequest request) throws IOException { - final String hostname = handler.getHostname(); - final DatagramSocket socket = new DatagramSocket(); - socket.setReuseAddress(true); - final String message = gson.toJson(request); - final byte[] data = message.getBytes(); - final InetAddress address = InetAddress.getByName(hostname); - DatagramPacket packet = new DatagramPacket(data, data.length, address, REQUEST_PORT); - logger.trace("Sending {} to {}", message, hostname); - socket.send(packet); - socket.close(); + serverStart(); + synchronized (senderLock) { + try (DatagramSocket socket = new DatagramSocket()) { + socket.setReuseAddress(true); + String message = gson.toJson(request); + byte[] data = message.getBytes(); + String hostname = handler.getHostname(); + InetAddress address = InetAddress.getByName(hostname); + DatagramPacket packet = new DatagramPacket(data, data.length, address, REQUEST_PORT); + socket.send(packet); + logger.trace("Sent request to {} on {} with content = {}", handler.getThing().getUID(), + address.getHostAddress(), message); + } + } } - public void runDiscoveryForInterface(NetworkInterface intf, DiscoveryResultReceiver receiver) throws IOException { - synchronized (receiver) { - StatusReceiver localReceiver = null; - StatusReceiver activeReceiver = null; + /** + * Send discovery multicast pings on any ipv4 address bound to any network interface in the given + * list and then sleep for sufficient time until responses may have been received. + */ + public void runDiscoveryForInterfaces(List interfaces, GoveeDiscoveryListener listener) { + serverStart(); + try { + discoveryListener = listener; + Instant sleepUntil = Instant.now().plusSeconds(SCAN_TIMEOUT_SEC); - try { - if (receiverThread == null) { - localReceiver = new StatusReceiver(); - localReceiver.start(); - activeReceiver = localReceiver; - } else { - activeReceiver = receiverThread; - } + interfaces.parallelStream() // send on all interfaces in parallel + .forEach(interFace -> Collections.list(interFace.getInetAddresses()).stream() + .filter(address -> address instanceof Inet4Address).map(address -> address.getHostAddress()) + .forEach(ipv4Address -> sendPing(interFace, ipv4Address))); - if (activeReceiver != null) { - activeReceiver.setDiscoveryResultsReceiver(receiver); + Duration sleepDuration = Duration.between(Instant.now(), sleepUntil); + if (!sleepDuration.isNegative()) { + try { + Thread.sleep(sleepDuration.toMillis()); + } catch (InterruptedException e) { + // just return } + } + } finally { + discoveryListener = null; + } + } + + /** + * This method gets executed on the server thread. It uses a {@link DatagramChannel} to listen on port + * 4002 and it processes any notifications received. The task runs continuously in a loop until the + * thread is externally interrupted. + * + *
  • In case of status notifications it forwards the message to the Thing handler listener.
  • + *
  • In case of discovery notifications it forwards the message to the discovery listener.
  • + *
  • If there is neither a Thing handler listener, nor a discovery listener, it logs an error.
  • + */ + private void serverThreadTask() { + synchronized (serverLock) { + try { + logger.trace("Server thread started."); + ByteBuffer buffer = ByteBuffer.allocate(1024); - final InetAddress broadcastAddress = InetAddress.getByName(DISCOVERY_MULTICAST_ADDRESS); - final InetSocketAddress socketAddress = new InetSocketAddress(broadcastAddress, RESPONSE_PORT); - final Instant discoveryStartTime = Instant.now(); - final Instant discoveryEndTime = discoveryStartTime.plusSeconds(INTERFACE_TIMEOUT_SEC); + while (!serverStopFlag) { + try (DatagramChannel channel = DatagramChannel.open() + .setOption(StandardSocketOptions.SO_REUSEADDR, true) + .bind(new InetSocketAddress(RESPONSE_PORT))) { - try (MulticastSocket sendSocket = new MulticastSocket(socketAddress)) { - sendSocket.setSoTimeout(INTERFACE_TIMEOUT_SEC * 1000); - sendSocket.setReuseAddress(true); - sendSocket.setBroadcast(true); - sendSocket.setTimeToLive(2); - sendSocket.joinGroup(new InetSocketAddress(broadcastAddress, RESPONSE_PORT), intf); + while (!serverStopFlag) { + String sourceIp = ""; + try { + SocketAddress socketAddress = channel.receive(buffer.clear()); + if ((socketAddress instanceof InetSocketAddress inetSocketAddress) + && (inetSocketAddress.getAddress() instanceof InetAddress inetAddress)) { + sourceIp = inetAddress.getHostAddress(); + } else { + logger.debug("Receive() - bad socketAddress={}", socketAddress); + return; + } + } catch (ClosedByInterruptException e) { + // thrown if 'Thread.interrupt()' is called during 'channel.receive()' + logger.debug("Receive ClosedByInterruptException, isInterrupted={}, serverStopFlag={}", + Thread.currentThread().isInterrupted(), serverStopFlag); + Thread.interrupted(); // clear 'interrupted' flag + break; + } catch (IOException e) { + logger.debug("Receive unexpected exception={}", e.getMessage()); + break; + } - byte[] requestData = DISCOVER_REQUEST.getBytes(); + String message = new String(buffer.array(), 0, buffer.position()); + logger.trace("Receive from sourceIp={}, message={}", sourceIp, message); - DatagramPacket request = new DatagramPacket(requestData, requestData.length, broadcastAddress, - DISCOVERY_PORT); - sendSocket.send(request); - } + GoveeHandler handler = thingHandlerListeners.get(sourceIp); + boolean devStatus = message.contains("devStatus"); + if (handler != null && devStatus) { + logger.debug("Notifying status of thing={} on sourcecIp={}", + handler.getThing().getUID(), sourceIp); + handler.handleIncomingStatus(message); + continue; + } - do { - try { - receiver.wait(INTERFACE_TIMEOUT_SEC * 1000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + GoveeDiscoveryListener discoveryListener = this.discoveryListener; + if (!devStatus && discoveryListener != null) { + try { + DiscoveryResponse response = gson.fromJson(message, DiscoveryResponse.class); + if (response != null) { + logger.debug("Notifying discovery of device on sourceIp={}", sourceIp); + discoveryListener.onDiscoveryResponse(response); + } + } catch (JsonParseException e) { + logger.debug("Discovery notification parse exception={}", e.getMessage()); + } + continue; + } + + logger.warn( + "Unhandled message with sourceIp={}, devStatus={}, handler={}, discoveryListener={}", + sourceIp, devStatus, handler, discoveryListener); + } // end of inner while loop + } catch (IOException e) { + logger.debug("Datagram channel create exception={}", e.getMessage()); } - } while (Instant.now().isBefore(discoveryEndTime)); + } // end of outer while loop } finally { - if (activeReceiver != null) { - activeReceiver.setDiscoveryResultsReceiver(null); - } - if (localReceiver != null) { - localReceiver.stopReceiving(); - } + serverThread = null; + serverStopFlag = false; + logger.trace("Server thread terminated."); } } } - private class StatusReceiver extends Thread { - private final Logger logger = LoggerFactory.getLogger(CommunicationManager.class); - private boolean stopped = false; - private @Nullable DiscoveryResultReceiver discoveryResultReceiver; - - private @Nullable MulticastSocket socket; - - StatusReceiver() { - super("GoveeStatusReceiver"); - } - - synchronized void setDiscoveryResultsReceiver(@Nullable DiscoveryResultReceiver receiver) { - discoveryResultReceiver = receiver; + /** + * Get the resolved IP address from the given host name. + */ + private static String ipAddressFrom(String host) { + try { + return InetAddress.getByName(host).getHostAddress(); + } catch (UnknownHostException e) { } + return host; + } - void stopReceiving() { - stopped = true; - interrupt(); - if (socket != null) { - socket.close(); + /** + * Starts the server thread if it is not already running. + */ + private void serverStart() { + synchronized (paramsLock) { + Thread serverthread = serverThread; + if (serverthread == null) { + serverthread = new Thread(this::serverThreadTask, "OH-binding-" + GoveeBindingConstants.BINDING_ID); + serverThread = serverthread; + serverStopFlag = false; + serverthread.start(); } + } + } - try { - join(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + /** + * Stops the server thread. + */ + private void serverStop() { + synchronized (paramsLock) { + serverStopFlag = true; + Thread serverthread = serverThread; + if (serverthread != null) { + serverthread.interrupt(); } } + } - @Override - public void run() { - while (!stopped) { - try { - socket = new MulticastSocket(RESPONSE_PORT); - byte[] buffer = new byte[10240]; - socket.setReuseAddress(true); - while (!stopped) { - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - if (!socket.isClosed()) { - socket.receive(packet); - } else { - logger.warn("Socket was unexpectedly closed"); - break; - } - if (stopped) { - break; - } - - String response = new String(packet.getData(), packet.getOffset(), packet.getLength()); - String deviceIPAddress = packet.getAddress().toString().replace("/", ""); - logger.trace("Response from {} = {}", deviceIPAddress, response); - - final DiscoveryResultReceiver discoveryReceiver; - synchronized (this) { - discoveryReceiver = discoveryResultReceiver; - } - if (discoveryReceiver != null) { - // We're in discovery mode: try to parse result as discovery message and signal the receiver - // if parsing was successful - try { - DiscoveryResponse result = gson.fromJson(response, DiscoveryResponse.class); - if (result != null) { - synchronized (discoveryReceiver) { - discoveryReceiver.onResultReceived(result); - discoveryReceiver.notifyAll(); - } - } - } catch (JsonParseException e) { - logger.debug( - "JsonParseException when trying to parse the response, probably a status message", - e); - } - } else { - final @Nullable GoveeHandler handler; - synchronized (thingHandlers) { - handler = thingHandlers.get(deviceIPAddress); - } - if (handler == null) { - logger.warn("thing Handler for {} couldn't be found.", deviceIPAddress); - } else { - logger.debug("processing status updates for thing {} ", handler.getThing().getLabel()); - handler.handleIncomingStatus(response); - } - } - } - } catch (IOException e) { - logger.warn("exception when receiving status packet", e); - // as we haven't received a packet we also don't know where it should have come from - // hence, we don't know which thing put offline. - // a way to monitor this would be to keep track in a list, which device answers we expect - // and supervise an expected answer within a given time but that will make the whole - // mechanism much more complicated and may be added in the future - } finally { - if (socket != null) { - socket.close(); - socket = null; - } - } - } + /** + * Send discovery ping multicast on the given network interface and ipv4 address. + */ + private void sendPing(NetworkInterface interFace, String ipv4Address) { + try (DatagramChannel channel = (DatagramChannel) DatagramChannel.open(StandardProtocolFamily.INET) + .setOption(StandardSocketOptions.SO_REUSEADDR, true) + .setOption(StandardSocketOptions.IP_MULTICAST_TTL, 64) + .setOption(StandardSocketOptions.IP_MULTICAST_IF, interFace) + .bind(new InetSocketAddress(ipv4Address, DISCOVERY_PORT)).configureBlocking(false)) { + channel.send(ByteBuffer.wrap(DISCOVER_REQUEST.getBytes()), DISCOVERY_SOCKET_ADDRESS); + logger.trace("Sent ping from {}:{} ({}) to {}:{} with content = {}", ipv4Address, DISCOVERY_PORT, + interFace.getDisplayName(), DISCOVERY_MULTICAST_ADDRESS, DISCOVERY_PORT, DISCOVER_REQUEST); + } catch (IOException e) { + logger.debug("Network error", e); } } } diff --git a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeBindingConstants.java b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeBindingConstants.java index 35ca13bb647b1..713ac70e9bd51 100644 --- a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeBindingConstants.java +++ b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeBindingConstants.java @@ -31,7 +31,7 @@ public class GoveeBindingConstants { public static final String PRODUCT_NAME = "productName"; public static final String HW_VERSION = "wifiHardwareVersion"; public static final String SW_VERSION = "wifiSoftwareVersion"; - private static final String BINDING_ID = "govee"; + public static final String BINDING_ID = "govee"; // List of all Thing Type UIDs public static final ThingTypeUID THING_TYPE_LIGHT = new ThingTypeUID(BINDING_ID, "govee-light"); @@ -44,4 +44,7 @@ public class GoveeBindingConstants { // Limit values of channels public static final Double COLOR_TEMPERATURE_MIN_VALUE = 2000.0; public static final Double COLOR_TEMPERATURE_MAX_VALUE = 9000.0; + + public static final String PROPERTY_COLOR_TEMPERATURE_MIN = "minKelvin"; + public static final String PROPERTY_COLOR_TEMPERATURE_MAX = "maxKelvin"; } diff --git a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeConfiguration.java b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeConfiguration.java index 23932e8440da3..fe2d0d6a8d197 100644 --- a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeConfiguration.java +++ b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeConfiguration.java @@ -13,6 +13,7 @@ package org.openhab.binding.govee.internal; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; /** * The {@link GoveeConfiguration} contains thing values that are used by the Thing Handler @@ -24,4 +25,7 @@ public class GoveeConfiguration { public String hostname = ""; public int refreshInterval = 5; // in seconds + + public @Nullable Integer minKelvin; + public @Nullable Integer maxKelvin; } diff --git a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeDiscoveryService.java b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeDiscoveryService.java index ef5a62b69fd6b..3d22c007f031e 100644 --- a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeDiscoveryService.java +++ b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeDiscoveryService.java @@ -12,16 +12,18 @@ */ package org.openhab.binding.govee.internal; -import java.io.IOException; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.govee.internal.CommunicationManager.GoveeDiscoveryListener; import org.openhab.binding.govee.internal.model.DiscoveryData; import org.openhab.binding.govee.internal.model.DiscoveryResponse; import org.openhab.core.config.discovery.AbstractDiscoveryService; @@ -79,17 +81,22 @@ */ @NonNullByDefault @Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.govee") -public class GoveeDiscoveryService extends AbstractDiscoveryService { +public class GoveeDiscoveryService extends AbstractDiscoveryService implements GoveeDiscoveryListener { + + private static final int BACKGROUND_SCAN_INTERVAL_SECONDS = 300; + private final Logger logger = LoggerFactory.getLogger(GoveeDiscoveryService.class); - private CommunicationManager communicationManager; + private final CommunicationManager communicationManager; + private @Nullable ScheduledFuture backgroundScanTask; private static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(GoveeBindingConstants.THING_TYPE_LIGHT); @Activate - public GoveeDiscoveryService(@Reference TranslationProvider i18nProvider, @Reference LocaleProvider localeProvider, - @Reference CommunicationManager communicationManager) { - super(SUPPORTED_THING_TYPES_UIDS, 0, false); + public GoveeDiscoveryService(final @Reference TranslationProvider i18nProvider, + final @Reference LocaleProvider localeProvider, + final @Reference CommunicationManager communicationManager) { + super(SUPPORTED_THING_TYPES_UIDS, CommunicationManager.SCAN_TIMEOUT_SEC, true); this.i18nProvider = i18nProvider; this.localeProvider = localeProvider; this.communicationManager = communicationManager; @@ -103,23 +110,8 @@ public GoveeDiscoveryService(CommunicationManager communicationManager) { @Override protected void startScan() { - logger.debug("starting Scan"); - - getLocalNetworkInterfaces().forEach(localNetworkInterface -> { - logger.debug("Discovering Govee devices on {} ...", localNetworkInterface); - try { - communicationManager.runDiscoveryForInterface(localNetworkInterface, response -> { - DiscoveryResult result = responseToResult(response); - if (result != null) { - thingDiscovered(result); - } - }); - logger.trace("After runDiscoveryForInterface"); - } catch (IOException e) { - logger.debug("Discovery with IO exception: {}", e.getMessage()); - } - logger.trace("After try"); - }); + logger.debug("Starting scan"); + scheduler.schedule(this::doDiscovery, 0, TimeUnit.MILLISECONDS); } public @Nullable DiscoveryResult responseToResult(DiscoveryResponse response) { @@ -165,11 +157,11 @@ protected void startScan() { } String hwVersion = data.wifiVersionHard(); - if (hwVersion != null) { + if (!hwVersion.isEmpty()) { builder.withProperty(GoveeBindingConstants.HW_VERSION, hwVersion); } String swVersion = data.wifiVersionSoft(); - if (swVersion != null) { + if (!swVersion.isEmpty()) { builder.withProperty(GoveeBindingConstants.SW_VERSION, swVersion); } @@ -194,4 +186,41 @@ private List getLocalNetworkInterfaces() { } return result; } + + /** + * Command the {@link CommunicationManager) to run the scans. + */ + private void doDiscovery() { + communicationManager.runDiscoveryForInterfaces(getLocalNetworkInterfaces(), this); + } + + /** + * This method is called back by the {@link CommunicationManager} when it receives a {@link DiscoveryResponse} + * notification carrying information about potential newly discovered Things. + */ + @Override + public synchronized void onDiscoveryResponse(DiscoveryResponse discoveryResponse) { + DiscoveryResult discoveryResult = responseToResult(discoveryResponse); + if (discoveryResult != null) { + thingDiscovered(discoveryResult); + } + } + + @Override + protected void startBackgroundDiscovery() { + ScheduledFuture backgroundScanTask = this.backgroundScanTask; + if (backgroundScanTask == null || backgroundScanTask.isCancelled()) { + this.backgroundScanTask = scheduler.scheduleWithFixedDelay(this::doDiscovery, 0, + BACKGROUND_SCAN_INTERVAL_SECONDS, TimeUnit.SECONDS); + } + } + + @Override + protected void stopBackgroundDiscovery() { + ScheduledFuture backgroundScanTask = this.backgroundScanTask; + if (backgroundScanTask != null) { + backgroundScanTask.cancel(true); + this.backgroundScanTask = null; + } + } } diff --git a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeHandler.java b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeHandler.java index 6c8f51b1ab069..7fd81c6953aea 100644 --- a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeHandler.java +++ b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeHandler.java @@ -15,6 +15,11 @@ import static org.openhab.binding.govee.internal.GoveeBindingConstants.*; import java.io.IOException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Callable; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -24,10 +29,12 @@ import org.openhab.binding.govee.internal.model.Color; import org.openhab.binding.govee.internal.model.ColorData; import org.openhab.binding.govee.internal.model.EmptyValueQueryStatusData; +import org.openhab.binding.govee.internal.model.GenericGoveeData; import org.openhab.binding.govee.internal.model.GenericGoveeMsg; import org.openhab.binding.govee.internal.model.GenericGoveeRequest; import org.openhab.binding.govee.internal.model.StatusResponse; import org.openhab.binding.govee.internal.model.ValueIntData; +import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.HSBType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; @@ -40,6 +47,7 @@ import org.openhab.core.thing.binding.BaseThingHandler; import org.openhab.core.types.Command; import org.openhab.core.types.RefreshType; +import org.openhab.core.types.UnDefType; import org.openhab.core.util.ColorUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -71,47 +79,73 @@ * https://app-h5.govee.com/user-manual/wlan-guide * * @author Stefan Höhn - Initial contribution + * @author Andrew Fiddian-Green - Added sequential task processing */ @NonNullByDefault public class GoveeHandler extends BaseThingHandler { - /* - * Messages to be sent to the Govee devices - */ private static final Gson GSON = new Gson(); + private static final int REFRESH_SECONDS_MIN = 2; + private static final int INTER_COMMAND_DELAY_MILLISEC = 100; private final Logger logger = LoggerFactory.getLogger(GoveeHandler.class); + protected ScheduledExecutorService executorService = scheduler; - @Nullable - private ScheduledFuture triggerStatusJob; // send device status update job + private @Nullable ScheduledFuture thingTaskSenderTask; private GoveeConfiguration goveeConfiguration = new GoveeConfiguration(); - private CommunicationManager communicationManager; + private final CommunicationManager communicationManager; + private final GoveeStateDescriptionProvider stateDescriptionProvider; + private final List> taskQueue = new ArrayList<>(); - private int lastOnOff; - private int lastBrightness; + private OnOffType lastSwitch = OnOffType.OFF; private HSBType lastColor = new HSBType(); - private int lastColorTempInKelvin = COLOR_TEMPERATURE_MIN_VALUE.intValue(); + + private int lastKelvin; + private int minKelvin; + private int maxKelvin; + + private int refreshIntervalSeconds; + private Instant nextRefreshDueTime = Instant.EPOCH; /** - * This thing related job thingRefreshSender triggers an update to the Govee device. - * The device sends it back to the common port and the response is - * then received by the common #refreshStatusReceiver + * This thing related job thingTaskSender sends the next queued command (if any) + * to the Govee device. If there is no queued command and a regular refresh is due then + * sends the command to trigger a status refresh. + * + * The device may send a reply to the common port and if so the response is received by + * the refresh status receiver. */ - private final Runnable thingRefreshSender = () -> { - try { - triggerDeviceStatusRefresh(); - updateStatus(ThingStatus.ONLINE); - } catch (IOException e) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, - "@text/offline.communication-error.could-not-query-device [\"" + goveeConfiguration.hostname - + "\"]"); + private final Runnable thingTaskSender = () -> { + synchronized (taskQueue) { + if (taskQueue.isEmpty() && Instant.now().isBefore(nextRefreshDueTime)) { + return; // no queued command nor pending refresh + } + if (taskQueue.isEmpty()) { + taskQueue.add(() -> triggerDeviceStatusRefresh()); + nextRefreshDueTime = Instant.now().plusSeconds(refreshIntervalSeconds); + } else if (taskQueue.size() > 20) { + logger.info("Command task queue size:{} exceeds limit:20", taskQueue.size()); + } + try { + if (taskQueue.remove(0).call()) { + updateStatus(ThingStatus.ONLINE); + } + } catch (IndexOutOfBoundsException e) { + logger.warn("Unexpected List.remove() exception:{}", e.getMessage()); + } catch (Exception e) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "@text/offline.communication-error.could-not-query-device [\"" + goveeConfiguration.hostname + + "\"]"); + } } }; - public GoveeHandler(Thing thing, CommunicationManager communicationManager) { + public GoveeHandler(Thing thing, CommunicationManager communicationManager, + GoveeStateDescriptionProvider stateDescriptionProvider) { super(thing); this.communicationManager = communicationManager; + this.stateDescriptionProvider = stateDescriptionProvider; } public String getHostname() { @@ -128,140 +162,176 @@ public void initialize() { "@text/offline.configuration-error.ip-address.missing"); return; } + + minKelvin = Objects.requireNonNullElse(goveeConfiguration.minKelvin, COLOR_TEMPERATURE_MIN_VALUE.intValue()); + maxKelvin = Objects.requireNonNullElse(goveeConfiguration.maxKelvin, COLOR_TEMPERATURE_MAX_VALUE.intValue()); + if ((minKelvin < COLOR_TEMPERATURE_MIN_VALUE) || (maxKelvin > COLOR_TEMPERATURE_MAX_VALUE) + || (minKelvin >= maxKelvin)) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "@text/offline.configuration-error.invalid-color-temperature-range"); + return; + } + + thing.setProperty(PROPERTY_COLOR_TEMPERATURE_MIN, Integer.toString(minKelvin)); + thing.setProperty(PROPERTY_COLOR_TEMPERATURE_MAX, Integer.toString(maxKelvin)); + stateDescriptionProvider.setMinMaxKelvin(new ChannelUID(thing.getUID(), CHANNEL_COLOR_TEMPERATURE_ABS), + minKelvin, maxKelvin); + + refreshIntervalSeconds = goveeConfiguration.refreshInterval; + if (refreshIntervalSeconds < REFRESH_SECONDS_MIN) { + logger.warn("Config Param refreshInterval={} too low, minimum={}", refreshIntervalSeconds, + REFRESH_SECONDS_MIN); + refreshIntervalSeconds = REFRESH_SECONDS_MIN; + } + updateStatus(ThingStatus.UNKNOWN); communicationManager.registerHandler(this); - if (triggerStatusJob == null) { - logger.debug("Starting refresh trigger job for thing {} ", thing.getLabel()); - triggerStatusJob = executorService.scheduleWithFixedDelay(thingRefreshSender, 100, - goveeConfiguration.refreshInterval * 1000L, TimeUnit.MILLISECONDS); + if (thingTaskSenderTask == null) { + logger.debug("Starting refresh trigger job for thing {} ", thing.getLabel()); + thingTaskSenderTask = executorService.scheduleWithFixedDelay(thingTaskSender, INTER_COMMAND_DELAY_MILLISEC, + INTER_COMMAND_DELAY_MILLISEC, TimeUnit.MILLISECONDS); } } @Override public void dispose() { super.dispose(); - - ScheduledFuture triggerStatusJobFuture = triggerStatusJob; - if (triggerStatusJobFuture != null) { - triggerStatusJobFuture.cancel(true); - triggerStatusJob = null; + taskQueue.clear(); + ScheduledFuture job = thingTaskSenderTask; + if (job != null) { + job.cancel(true); + thingTaskSenderTask = null; } communicationManager.unregisterHandler(this); } @Override - public void handleCommand(ChannelUID channelUID, Command command) { - try { + public void handleCommand(ChannelUID channelUID, Command commandParam) { + Command command = commandParam; + + synchronized (taskQueue) { + logger.debug("handleCommand({}, {})", channelUID, command); + if (command instanceof RefreshType) { - // we are refreshing all channels at once, as we get all information at the same time - triggerDeviceStatusRefresh(); - logger.debug("Triggering Refresh"); + taskQueue.add(() -> triggerDeviceStatusRefresh()); } else { - logger.debug("Channel ID {} type {}", channelUID.getId(), command.getClass()); switch (channelUID.getId()) { case CHANNEL_COLOR: - if (command instanceof HSBType hsbCommand) { - int[] rgb = ColorUtil.hsbToRgb(hsbCommand); - sendColor(new Color(rgb[0], rgb[1], rgb[2])); - } else if (command instanceof PercentType percent) { - sendBrightness(percent.intValue()); - } else if (command instanceof OnOffType onOffCommand) { - sendOnOff(onOffCommand); + if (command instanceof HSBType hsb) { + taskQueue.add(() -> sendColor(hsb)); + command = hsb.getBrightness(); // fall through + } + if (command instanceof PercentType percent) { + taskQueue.add(() -> sendBrightness(percent)); + command = OnOffType.from(percent.intValue() > 0); // fall through + } + if (command instanceof OnOffType onOff) { + taskQueue.add(() -> sendOnOff(onOff)); + taskQueue.add(() -> triggerDeviceStatusRefresh()); } break; + case CHANNEL_COLOR_TEMPERATURE: if (command instanceof PercentType percent) { - logger.debug("COLOR_TEMPERATURE: Color Temperature change with Percent Type {}", command); - Double colorTemp = (COLOR_TEMPERATURE_MIN_VALUE + percent.intValue() - * (COLOR_TEMPERATURE_MAX_VALUE - COLOR_TEMPERATURE_MIN_VALUE) / 100.0); - lastColorTempInKelvin = colorTemp.intValue(); - logger.debug("lastColorTempInKelvin {}", lastColorTempInKelvin); - sendColorTemp(lastColorTempInKelvin); + taskQueue.add(() -> sendKelvin(percentToKelvin(percent))); + taskQueue.add(() -> triggerDeviceStatusRefresh()); } break; + case CHANNEL_COLOR_TEMPERATURE_ABS: - if (command instanceof QuantityType quantity) { - logger.debug("Color Temperature Absolute change with Percent Type {}", command); - lastColorTempInKelvin = quantity.intValue(); - logger.debug("COLOR_TEMPERATURE_ABS: lastColorTempInKelvin {}", lastColorTempInKelvin); - int lastColorTempInPercent = ((Double) ((lastColorTempInKelvin - - COLOR_TEMPERATURE_MIN_VALUE) - / (COLOR_TEMPERATURE_MAX_VALUE - COLOR_TEMPERATURE_MIN_VALUE) * 100.0)).intValue(); - logger.debug("computed lastColorTempInPercent {}", lastColorTempInPercent); - sendColorTemp(lastColorTempInKelvin); + if (command instanceof QuantityType genericQuantity) { + QuantityType kelvin = genericQuantity.toInvertibleUnit(Units.KELVIN); + if (kelvin == null) { + logger.warn("handleCommand() invalid QuantityType:{}", genericQuantity); + break; + } + taskQueue.add(() -> sendKelvin(kelvin.intValue())); + taskQueue.add(() -> triggerDeviceStatusRefresh()); + } else if (command instanceof DecimalType kelvin) { + taskQueue.add(() -> sendKelvin(kelvin.intValue())); + taskQueue.add(() -> triggerDeviceStatusRefresh()); } break; } } - updateStatus(ThingStatus.ONLINE); - } catch (IOException e) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, - "@text/offline.communication-error.could-not-query-device [\"" + goveeConfiguration.hostname - + "\"]"); } } /** - * Initiate a refresh to our thing devicee - * + * Initiate a refresh to our thing device */ - private void triggerDeviceStatusRefresh() throws IOException { - logger.debug("trigger Refresh Status of device {}", thing.getLabel()); - GenericGoveeRequest lightQuery = new GenericGoveeRequest( - new GenericGoveeMsg("devStatus", new EmptyValueQueryStatusData())); - communicationManager.sendRequest(this, lightQuery); + private boolean triggerDeviceStatusRefresh() throws IOException { + logger.debug("triggerDeviceStatusRefresh() to {}", thing.getUID()); + GenericGoveeData data = new EmptyValueQueryStatusData(); + GenericGoveeRequest request = new GenericGoveeRequest(new GenericGoveeMsg("devStatus", data)); + communicationManager.sendRequest(this, request); + return true; } - public void sendColor(Color color) throws IOException { - lastColor = ColorUtil.rgbToHsb(new int[] { color.r(), color.g(), color.b() }); - - GenericGoveeRequest lightColor = new GenericGoveeRequest( - new GenericGoveeMsg("colorwc", new ColorData(color, 0))); - communicationManager.sendRequest(this, lightColor); + /** + * Send the normalized RGB color parameters. + */ + public boolean sendColor(HSBType color) throws IOException { + logger.debug("sendColor({}) to {}", color, thing.getUID()); + int[] normalRGB = ColorUtil.hsbToRgb(new HSBType(color.getHue(), color.getSaturation(), PercentType.HUNDRED)); + GenericGoveeData data = new ColorData(new Color(normalRGB[0], normalRGB[1], normalRGB[2]), 0); + GenericGoveeRequest request = new GenericGoveeRequest(new GenericGoveeMsg("colorwc", data)); + communicationManager.sendRequest(this, request); + return true; } - public void sendBrightness(int brightness) throws IOException { - lastBrightness = brightness; - GenericGoveeRequest lightBrightness = new GenericGoveeRequest( - new GenericGoveeMsg("brightness", new ValueIntData(brightness))); - communicationManager.sendRequest(this, lightBrightness); + /** + * Send the brightness parameter. + */ + public boolean sendBrightness(PercentType brightness) throws IOException { + logger.debug("sendBrightness({}) to {}", brightness, thing.getUID()); + GenericGoveeData data = new ValueIntData(brightness.intValue()); + GenericGoveeRequest request = new GenericGoveeRequest(new GenericGoveeMsg("brightness", data)); + communicationManager.sendRequest(this, request); + return true; } - private void sendOnOff(OnOffType switchValue) throws IOException { - lastOnOff = (switchValue == OnOffType.ON) ? 1 : 0; - GenericGoveeRequest switchLight = new GenericGoveeRequest( - new GenericGoveeMsg("turn", new ValueIntData(lastOnOff))); - communicationManager.sendRequest(this, switchLight); + /** + * Send the on-off parameter. + */ + private boolean sendOnOff(OnOffType onOff) throws IOException { + logger.debug("sendOnOff({}) to {}", onOff, thing.getUID()); + GenericGoveeData data = new ValueIntData(onOff == OnOffType.ON ? 1 : 0); + GenericGoveeRequest request = new GenericGoveeRequest(new GenericGoveeMsg("turn", data)); + communicationManager.sendRequest(this, request); + return true; } - private void sendColorTemp(int colorTemp) throws IOException { - lastColorTempInKelvin = colorTemp; - logger.debug("sendColorTemp {}", colorTemp); - GenericGoveeRequest lightColor = new GenericGoveeRequest( - new GenericGoveeMsg("colorwc", new ColorData(new Color(0, 0, 0), colorTemp))); - communicationManager.sendRequest(this, lightColor); + /** + * Set the color temperature (Kelvin) parameter. + */ + private boolean sendKelvin(int kelvin) throws IOException { + logger.debug("sendKelvin({}) to {}", kelvin, thing.getUID()); + GenericGoveeData data = new ColorData(new Color(0, 0, 0), kelvin); + GenericGoveeRequest request = new GenericGoveeRequest(new GenericGoveeMsg("colorwc", data)); + communicationManager.sendRequest(this, request); + return true; } /** - * Creates a Color state by using the last color information from lastColor - * The brightness is overwritten either by the provided lastBrightness - * or if lastOnOff = 0 (off) then the brightness is set 0 + * Build an {@link HSBType} from the given normalized {@link Color} RGB parameters, brightness, and on-off state + * parameters. If the on parameter is true then use the brightness parameter, otherwise use a brightness of zero. * - * @see #lastColor - * @see #lastBrightness - * @see #lastOnOff + * @param normalRgbParams record containing the lamp's normalized RGB parameters (0..255) + * @param brightnessParam the lamp brightness in range 0..100 + * @param onParam the lamp on-off state * - * @return the computed state + * @return the respective HSBType */ - private HSBType getColorState(Color color, int brightness) { - PercentType computedBrightness = lastOnOff == 0 ? new PercentType(0) : new PercentType(brightness); - int[] rgb = { color.r(), color.g(), color.b() }; - HSBType hsb = ColorUtil.rgbToHsb(rgb); - return new HSBType(hsb.getHue(), hsb.getSaturation(), computedBrightness); + private static HSBType buildHSB(Color normalRgbParams, int brightnessParam, boolean onParam) { + HSBType normalColor = ColorUtil + .rgbToHsb(new int[] { normalRgbParams.r(), normalRgbParams.g(), normalRgbParams.b() }); + PercentType brightness = onParam ? new PercentType(brightnessParam) : PercentType.ZERO; + return new HSBType(normalColor.getHue(), normalColor.getSaturation(), brightness); } - void handleIncomingStatus(String response) { + public void handleIncomingStatus(String response) { if (response.isEmpty()) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "@text/offline.communication-error.empty-response"); @@ -284,47 +354,52 @@ public void updateDeviceState(@Nullable StatusResponse message) { return; } - logger.trace("Receiving Device State"); - int newOnOff = message.msg().data().onOff(); - logger.trace("newOnOff = {}", newOnOff); - int newBrightness = message.msg().data().brightness(); - logger.trace("newBrightness = {}", newBrightness); - Color newColor = message.msg().data().color(); - logger.trace("newColor = {}", newColor); - int newColorTempInKelvin = message.msg().data().colorTemInKelvin(); - logger.trace("newColorTempInKelvin = {}", newColorTempInKelvin); - - newColorTempInKelvin = (newColorTempInKelvin < COLOR_TEMPERATURE_MIN_VALUE) - ? COLOR_TEMPERATURE_MIN_VALUE.intValue() - : newColorTempInKelvin; - newColorTempInKelvin = (newColorTempInKelvin > COLOR_TEMPERATURE_MAX_VALUE) - ? COLOR_TEMPERATURE_MAX_VALUE.intValue() - : newColorTempInKelvin; - - int newColorTempInPercent = ((Double) ((newColorTempInKelvin - COLOR_TEMPERATURE_MIN_VALUE) - / (COLOR_TEMPERATURE_MAX_VALUE - COLOR_TEMPERATURE_MIN_VALUE) * 100.0)).intValue(); - - HSBType adaptedColor = getColorState(newColor, newBrightness); - - logger.trace("HSB old: {} vs adaptedColor: {}", lastColor, adaptedColor); - // avoid noise by only updating if the value has changed on the device - if (!adaptedColor.equals(lastColor)) { - logger.trace("UPDATING HSB old: {} != {}", lastColor, adaptedColor); - updateState(CHANNEL_COLOR, adaptedColor); + logger.debug("updateDeviceState() for {}", thing.getUID()); + + OnOffType sw = OnOffType.from(message.msg().data().onOff() == 1); + int brightness = message.msg().data().brightness(); + Color normalRGB = message.msg().data().color(); + int kelvin = message.msg().data().colorTemInKelvin(); + + logger.trace("Update values: switch:{}, brightness:{}, normalRGB:{}, kelvin:{}", sw, brightness, normalRGB, + kelvin); + + HSBType color = buildHSB(normalRGB, brightness, true); + + logger.trace("Compare hsb old:{} to new:{}, switch old:{} to new:{}", lastColor, color, lastSwitch, sw); + if ((sw != lastSwitch) || !color.equals(lastColor)) { + logger.trace("Update hsb old:{} to new:{}, switch old:{} to new:{}", lastColor, color, lastSwitch, sw); + updateState(CHANNEL_COLOR, buildHSB(normalRGB, brightness, sw == OnOffType.ON)); + lastSwitch = sw; + lastColor = color; } - // avoid noise by only updating if the value has changed on the device - logger.trace("Color-Temperature Status: old: {} K {}% vs new: {} K", lastColorTempInKelvin, - newColorTempInPercent, newColorTempInKelvin); - if (newColorTempInKelvin != lastColorTempInKelvin) { - logger.trace("Color-Temperature Status: old: {} K {}% vs new: {} K", lastColorTempInKelvin, - newColorTempInPercent, newColorTempInKelvin); - updateState(CHANNEL_COLOR_TEMPERATURE_ABS, new QuantityType<>(lastColorTempInKelvin, Units.KELVIN)); - updateState(CHANNEL_COLOR_TEMPERATURE, new PercentType(newColorTempInPercent)); + logger.trace("Compare kelvin old:{} to new:{}", lastKelvin, kelvin); + if (kelvin != lastKelvin) { + logger.trace("Update kelvin old:{} to new:{}", lastKelvin, kelvin); + if (kelvin != 0) { + kelvin = Math.round(Math.min(maxKelvin, Math.max(minKelvin, kelvin))); + updateState(CHANNEL_COLOR_TEMPERATURE, kelvinToPercent(kelvin)); + updateState(CHANNEL_COLOR_TEMPERATURE_ABS, QuantityType.valueOf(kelvin, Units.KELVIN)); + } else { + updateState(CHANNEL_COLOR_TEMPERATURE, UnDefType.UNDEF); + updateState(CHANNEL_COLOR_TEMPERATURE_ABS, UnDefType.UNDEF); + } + lastKelvin = kelvin; } + } - lastOnOff = newOnOff; - lastColor = adaptedColor; - lastBrightness = newBrightness; + /** + * Convert PercentType to Kelvin. + */ + private int percentToKelvin(PercentType percent) { + return (int) Math.round((((maxKelvin - minKelvin) * percent.doubleValue() / 100.0) + minKelvin)); + } + + /** + * Convert Kelvin to PercentType. + */ + private PercentType kelvinToPercent(int kelvin) { + return new PercentType((int) Math.round((kelvin - minKelvin) * 100.0 / (maxKelvin - minKelvin))); } } diff --git a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeHandlerFactory.java b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeHandlerFactory.java index 907c3d41426d9..a9b5ec5e9babc 100644 --- a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeHandlerFactory.java +++ b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeHandlerFactory.java @@ -38,11 +38,14 @@ public class GoveeHandlerFactory extends BaseThingHandlerFactory { private static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_LIGHT); - private CommunicationManager communicationManager; + private final CommunicationManager communicationManager; + private final GoveeStateDescriptionProvider stateDescriptionProvider; @Activate - public GoveeHandlerFactory(@Reference CommunicationManager communicationManager) { + public GoveeHandlerFactory(final @Reference CommunicationManager communicationManager, + final @Reference GoveeStateDescriptionProvider stateDescriptionProvider) { this.communicationManager = communicationManager; + this.stateDescriptionProvider = stateDescriptionProvider; } @Override @@ -55,7 +58,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if (THING_TYPE_LIGHT.equals(thingTypeUID)) { - return new GoveeHandler(thing, communicationManager); + return new GoveeHandler(thing, communicationManager, stateDescriptionProvider); } return null; diff --git a/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeStateDescriptionProvider.java b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeStateDescriptionProvider.java new file mode 100644 index 0000000000000..b35e3e8ef4e6f --- /dev/null +++ b/bundles/org.openhab.binding.govee/src/main/java/org/openhab/binding/govee/internal/GoveeStateDescriptionProvider.java @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2010-2024 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.govee.internal; + +import java.math.BigDecimal; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.events.EventPublisher; +import org.openhab.core.thing.Channel; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider; +import org.openhab.core.thing.events.ThingEventFactory; +import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService; +import org.openhab.core.thing.link.ItemChannelLinkRegistry; +import org.openhab.core.thing.type.DynamicStateDescriptionProvider; +import org.openhab.core.types.StateDescription; +import org.openhab.core.types.StateDescriptionFragment; +import org.openhab.core.types.StateDescriptionFragmentBuilder; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * The {@link GoveeStateDescriptionProvider} provides state descriptions for different color temperature ranges. + * + * @author Andrew Fiddian-Green - Initial contribution + * + */ +@NonNullByDefault +@Component(service = { DynamicStateDescriptionProvider.class, GoveeStateDescriptionProvider.class }) +public class GoveeStateDescriptionProvider extends BaseDynamicStateDescriptionProvider { + + private final Map stateDescriptionFragments = new ConcurrentHashMap<>(); + + @Activate + public GoveeStateDescriptionProvider(final @Reference EventPublisher eventPublisher, + final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry, + final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) { + this.eventPublisher = eventPublisher; + this.itemChannelLinkRegistry = itemChannelLinkRegistry; + this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService; + } + + @Override + public @Nullable StateDescription getStateDescription(Channel channel, @Nullable StateDescription original, + @Nullable Locale locale) { + StateDescriptionFragment stateDescriptionFragment = stateDescriptionFragments.get(channel.getUID()); + return stateDescriptionFragment != null ? stateDescriptionFragment.toStateDescription() + : super.getStateDescription(channel, original, locale); + } + + /** + * Set the state description minimum and maximum values and pattern in Kelvin for the given channel UID + */ + public void setMinMaxKelvin(ChannelUID channelUID, long minKelvin, long maxKelvin) { + StateDescriptionFragment oldStateDescriptionFragment = stateDescriptionFragments.get(channelUID); + StateDescriptionFragment newStateDescriptionFragment = StateDescriptionFragmentBuilder.create() + .withMinimum(BigDecimal.valueOf(minKelvin)).withMaximum(BigDecimal.valueOf(maxKelvin)) + .withStep(BigDecimal.valueOf(100)).withPattern("%.0f K").build(); + if (!newStateDescriptionFragment.equals(oldStateDescriptionFragment)) { + stateDescriptionFragments.put(channelUID, newStateDescriptionFragment); + ItemChannelLinkRegistry itemChannelLinkRegistry = this.itemChannelLinkRegistry; + postEvent(ThingEventFactory.createChannelDescriptionChangedEvent(channelUID, + itemChannelLinkRegistry != null ? itemChannelLinkRegistry.getLinkedItemNames(channelUID) : Set.of(), + newStateDescriptionFragment, oldStateDescriptionFragment)); + } + } +} diff --git a/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/config/config.xml index e153efa4d8067..9ddf0f4c14d61 100644 --- a/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/config/config.xml @@ -14,11 +14,21 @@ MAC Address of the device - + The amount of time that passes until the device is refreshed (in seconds) 2 + + + The minimum color temperature that the light supports (in Kelvin) + true + + + + The maximum color temperature that the light supports (in Kelvin) + true + diff --git a/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/i18n/govee.properties b/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/i18n/govee.properties index b0a015db28f82..d9c7d3a4b29bd 100644 --- a/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/i18n/govee.properties +++ b/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/i18n/govee.properties @@ -1,5 +1,28 @@ # add-on +addon.govee.name = Govee Lan-API Binding +addon.govee.description = This is the binding for handling Govee Lights via the LAN-API interface. + +# thing types + +thing-type.govee.govee-light.label = Govee Light +thing-type.govee.govee-light.description = Govee light controllable via LAN API + +# thing types config + +thing-type.config.govee.govee-light.hostname.label = Hostname/IP Address +thing-type.config.govee.govee-light.hostname.description = Hostname or IP address of the device +thing-type.config.govee.govee-light.macAddress.label = MAC Address +thing-type.config.govee.govee-light.macAddress.description = MAC Address of the device +thing-type.config.govee.govee-light.maxKelvin.label = Maximum Color Temperature +thing-type.config.govee.govee-light.maxKelvin.description = The maximum color temperature that the light supports (in Kelvin) +thing-type.config.govee.govee-light.minKelvin.label = Minimum Color Temperature +thing-type.config.govee.govee-light.minKelvin.description = The minimum color temperature that the light supports (in Kelvin) +thing-type.config.govee.govee-light.refreshInterval.label = Light Refresh Interval +thing-type.config.govee.govee-light.refreshInterval.description = The amount of time that passes until the device is refreshed (in seconds) + +# add-on + addon.name = Govee Binding addon.description = This is the binding for handling Govee Lights via the LAN-API interface. @@ -15,68 +38,127 @@ thing-type.config.govee-light.refreshInterval.description = The amount of time t # product names -discovery.govee-light.H619Z = H619Z RGBIC Pro LED Strip Lights +discovery.govee-light.H6042 = H6042 Govee TV Light Bar #2 +discovery.govee-light.H6043 = H6043 Govee TV Light Bars #2 discovery.govee-light.H6046 = H6046 RGBIC TV Light Bars discovery.govee-light.H6047 = H6047 RGBIC Gaming Light Bars with Smart Controller +discovery.govee-light.H6051 = H6051 Aura - Smart Table Lamp +discovery.govee-light.H6052 = H6052 Govee Table Lamp +discovery.govee-light.H6056 = H6056 H6056 Flow Plus +discovery.govee-light.H6059 = H6059 RGBWW Night Light for Kids discovery.govee-light.H6061 = H6061 Glide Hexa LED Panels discovery.govee-light.H6062 = H6062 Glide Wall Light +discovery.govee-light.H6063 = H6063 Gaming Wall Light discovery.govee-light.H6065 = H6065 Glide RGBIC Y Lights discovery.govee-light.H6066 = H6066 Glide Hexa Pro LED Panel discovery.govee-light.H6067 = H6067 Glide Triangle Light Panels +discovery.govee-light.H606A = H606A Glide Hexa Light Panel Ultra discovery.govee-light.H6072 = H6072 RGBICWW Corner Floor Lamp -discovery.govee-light.H6076 = H6076 RGBICW Smart Corner Floor Lamp discovery.govee-light.H6073 = H6073 LED Floor Lamp +discovery.govee-light.H6076 = H6076 RGBICW Smart Corner Floor Lamp discovery.govee-light.H6078 = H6078 Cylinder Floor Lamp +discovery.govee-light.H607C = H607C Floor Lamp #2 discovery.govee-light.H6087 = H6087 RGBIC Smart Wall Sconces +discovery.govee-light.H6088 = H6088 RGBIC Cube Wall Sconces +discovery.govee-light.H608A = H608A String Downlights 5M +discovery.govee-light.H608B = H608B String Downlights 3M +discovery.govee-light.H608C = H608C String Downlights 2M +discovery.govee-light.H608D = H608D String Downlights 10M +discovery.govee-light.H60A0 = H60A0 Ceiling Light +discovery.govee-light.H60A1 = H60A1 Smart Ceiling Light +discovery.govee-light.H610A = H610A Glide Lively Wall Lights +discovery.govee-light.H610B = H610B Music Wall Lights +discovery.govee-light.H6110 = H6110 2x5M Multicolor with Alexa +discovery.govee-light.H6117 = H6117 Dream Color LED Strip Light 10M +discovery.govee-light.H6141 = H6141 5M Smart Multicolor Strip Light +discovery.govee-light.H6143 = H6143 5M Strip Light +discovery.govee-light.H6144 = H6144 2x5M Strip Light +discovery.govee-light.H6159 = H6159 RGB Light Strip +discovery.govee-light.H615A = H615A 5M Light Strip with Alexa +discovery.govee-light.H615B = H615B 10M Light Strip with Alexa +discovery.govee-light.H615C = H615C 15M Light Strip with Alexa +discovery.govee-light.H615D = H615D 20M Light Strip with Alexa +discovery.govee-light.H615E = H615E 30M Light Strip with Alexa +discovery.govee-light.H6163 = H6163 Dreamcolor LED Strip Light 5M +discovery.govee-light.H6167 = H6167 TV Backlight 2.4M +discovery.govee-light.H6168 = H6168 TV Backlight 2x0.7M+2x1.2M +discovery.govee-light.H616C = H616C Outdoor Strip 10M +discovery.govee-light.H616D = H616D Outdoor Strip 2x7.5M +discovery.govee-light.H616E = H616E Outdoor Strip 2x10M +discovery.govee-light.H6172 = H6172 Outdoor LED Strip 10m discovery.govee-light.H6173 = H6173 RGBIC Outdoor Strip Lights -discovery.govee-light.H619A = H619A RGBIC Strip Lights With Protective Coating 5M -discovery.govee-light.H619B = H619B RGBIC LED Strip Lights With Protective Coating -discovery.govee-light.H619C = H619C LED Strip Lights With Protective Coating -discovery.govee-light.H619D = H619D RGBIC PRO LED Strip Lights -discovery.govee-light.H619E = H619E RGBIC LED Strip Lights With Protective Coating -discovery.govee-light.H61A0 = H61A0 RGBIC Neon Rope Light 1M +discovery.govee-light.H6175 = H6175 RGBIC Outdoor Strip Lights 10M +discovery.govee-light.H6176 = H6176 RGBIC Outdoor Strip Lights 30M +discovery.govee-light.H6182 = H6182 WiFi Multicolor TV Strip Light +discovery.govee-light.H618A = H618A RGBIC Basic LED Strip Lights 5M +discovery.govee-light.H618C = H618C RGBIC Basic LED Strip Lights 5M +discovery.govee-light.H618E = H618E LED Strip Lights 22m +discovery.govee-light.H618F = H618F RGBIC LED Strip Lights +discovery.govee-light.H619A = H619A Strip Lights With Protective Coating 5M +discovery.govee-light.H619B = H619B Strip Lights With Protective Coating 7.5M +discovery.govee-light.H619C = H619C Strip Lights With Protective Coating with Alexa 10M +discovery.govee-light.H619D = H619D PRO LED Strip Lights with Alexa 2x7.5M +discovery.govee-light.H619E = H619E Strip Lights With Protective Coating with Alexa 2x10M +discovery.govee-light.H619Z = H619Z Pro LED Strip Lights 3M +discovery.govee-light.H61A0 = H61A0 RGBIC Neon Rope Light 3M discovery.govee-light.H61A1 = H61A1 RGBIC Neon Rope Light 2M discovery.govee-light.H61A2 = H61A2 RGBIC Neon Rope Light 5M -discovery.govee-light.H61A3 = H61A3 RGBIC Neon Rope Light +discovery.govee-light.H61A3 = H61A3 RGBIC Neon Rope Light 4M +discovery.govee-light.H61A5 = H61A5 Neon LED Strip Light 10M +discovery.govee-light.H61A8 = H61A8 Neon Rope Light 10M +discovery.govee-light.H61A9 = H61A8 Neon Rope Light 20M +discovery.govee-light.H61B1 = H61B1 Strip Light with Cover 5M +discovery.govee-light.H61B2 = H61B2 RGBIC Neon TV Backlight 3M +discovery.govee-light.H61BA = H61BA LED Strip Light 5M +discovery.govee-light.H61BC = H61BC LED Strip Light 10M +discovery.govee-light.H61BE = H61BE LED Strip Light 2x10M +discovery.govee-light.H61C2 = H61C2 Neon LED Strip Light 2M +discovery.govee-light.H61C3 = H61C2 Neon LED Strip Light 3M +discovery.govee-light.H61C5 = H61C2 Neon LED Strip Light 5M discovery.govee-light.H61D3 = H61D3 Neon Rope Light 2 3m discovery.govee-light.H61D5 = H61D5 Neon Rope Light 2 5m -discovery.govee-light.H61A5 = H61A5 Neon LED Strip Light 10 -discovery.govee-light.H61A8 = H61A8 Neon Rope Light 10 -discovery.govee-light.H618A = H618A RGBIC Basic LED Strip Lights 5M -discovery.govee-light.H618C = H618C RGBIC Basic LED Strip Lights 5M -discovery.govee-light.H6117 = H6117 Dream Color LED Strip Light 10M -discovery.govee-light.H6159 = H6159 RGB Light Strip -discovery.govee-light.H615E = H615E LED Strip Lights 30M -discovery.govee-light.H6163 = H6163 Dreamcolor LED Strip Light 5M -discovery.govee-light.H610A = H610A Glide Lively Wall Lights -discovery.govee-light.H610B = H610B Music Wall Lights -discovery.govee-light.H6172 = H6172 Outdoor LED Strip 10m -discovery.govee-light.H61B2 = H61B2 RGBIC Neon TV Backlight +discovery.govee-light.H61E0 = H61E0 LED Strip Light M1 discovery.govee-light.H61E1 = H61E1 LED Strip Light M1 discovery.govee-light.H7012 = H7012 Warm White Outdoor String Lights discovery.govee-light.H7013 = H7013 Warm White Outdoor String Lights discovery.govee-light.H7021 = H7021 RGBIC Warm White Smart Outdoor String discovery.govee-light.H7028 = H7028 Lynx Dream LED-Bulb String +discovery.govee-light.H7033 = H7033 LED-Bulb String Lights discovery.govee-light.H7041 = H7041 LED Outdoor Bulb String Lights discovery.govee-light.H7042 = H7042 LED Outdoor Bulb String Lights -discovery.govee-light.H705A = H705A Permanent Outdoor Lights 30M -discovery.govee-light.H705B = H705B Permanent Outdoor Lights 15M discovery.govee-light.H7050 = H7050 Outdoor Ground Lights 11M discovery.govee-light.H7051 = H7051 Outdoor Ground Lights 15M +discovery.govee-light.H7052 = H7052 Outdoor Ground Lights 15M +discovery.govee-light.H7053 = H7052 Outdoor Ground Lights 30M discovery.govee-light.H7055 = H7055 Pathway Light +discovery.govee-light.H705A = H705A Permanent Outdoor Lights 30M +discovery.govee-light.H705B = H705B Permanent Outdoor Lights 15M +discovery.govee-light.H705C = H705C Permanent Outdoor Lights 45M +discovery.govee-light.H705D = H705D Permanent Outdoor Lights #2 15M +discovery.govee-light.H705E = H705E Permanent Outdoor Lights #2 30M +discovery.govee-light.H705F = H705F Permanent Outdoor Lights #2 45M discovery.govee-light.H7060 = H7060 LED Flood Lights (2-Pack) discovery.govee-light.H7061 = H7061 LED Flood Lights (4-Pack) discovery.govee-light.H7062 = H7062 LED Flood Lights (6-Pack) +discovery.govee-light.H7063 = H7063 Outdoor Flood Lights discovery.govee-light.H7065 = H7065 Outdoor Spot Lights -discovery.govee-light.H6051 = H6051 Aura - Smart Table Lamp -discovery.govee-light.H6056 = H6056 H6056 Flow Plus -discovery.govee-light.H6059 = H6059 RGBWW Night Light for Kids -discovery.govee-light.H618F = H618F RGBIC LED Strip Lights -discovery.govee-light.H618E = H618E LED Strip Lights 22m -discovery.govee-light.H6168 = H6168 TV LED Backlight +discovery.govee-light.H7066 = H7066 Outdoor Spot Lights +discovery.govee-light.H706A = H706A Permanent Outdoor Lights Pro 30M +discovery.govee-light.H706B = H706B Permanent Outdoor Lights Pro 45M +discovery.govee-light.H706C = H706C Permanent Outdoor Lights Pro 60M +discovery.govee-light.H7070 = H7070 Outdoor Projector Light +discovery.govee-light.H7075 = H7075 Outdoor Wall Light +discovery.govee-light.H70B1 = H70B1 520 LED Curtain Lights +discovery.govee-light.H70BC = H70BC 400 LED Curtain Lights +discovery.govee-light.H70C1 = H70C1 RGBIC String Light 10M +discovery.govee-light.H70C2 = H70C2 RGBIC String Light 20M +discovery.govee-light.H805A = H805A Permanent Outdoor Lights Elite 30M +discovery.govee-light.H805B = H805B Permanent Outdoor Lights Elite 15M +discovery.govee-light.H805C = H805C Permanent Outdoor Lights Elite 45M # thing status descriptions offline.communication-error.could-not-query-device = Could not control/query device at IP address {0} offline.configuration-error.ip-address.missing = IP address is missing offline.communication-error.empty-response = Empty response received +offline.configuration-error.invalid-color-temperature-range = Invalid color temperature range diff --git a/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/thing/thing-types.xml index 1a49746b3158a..b96fbc8d57fc4 100644 --- a/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/thing/thing-types.xml @@ -11,22 +11,14 @@ - + - - + + 1 + - - Number:Temperature - - Controls the color temperature of the light in Kelvin - ColorLight - - Control - ColorTemperature - - - + + diff --git a/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/update/instructions.xml new file mode 100644 index 0000000000000..9317395b6a8de --- /dev/null +++ b/bundles/org.openhab.binding.govee/src/main/resources/OH-INF/update/instructions.xml @@ -0,0 +1,14 @@ + + + + + + + system:color-temperature-abs + + + + + diff --git a/bundles/org.openhab.binding.govee/src/test/java/org/openhab/binding/govee/internal/GoveeHandlerMock.java b/bundles/org.openhab.binding.govee/src/test/java/org/openhab/binding/govee/internal/GoveeHandlerMock.java index 7f048867a118f..f3374b2453ea8 100644 --- a/bundles/org.openhab.binding.govee/src/test/java/org/openhab/binding/govee/internal/GoveeHandlerMock.java +++ b/bundles/org.openhab.binding.govee/src/test/java/org/openhab/binding/govee/internal/GoveeHandlerMock.java @@ -12,8 +12,7 @@ */ package org.openhab.binding.govee.internal; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.doAnswer; import java.util.concurrent.ScheduledExecutorService; @@ -26,14 +25,15 @@ /** * The {@link GoveeHandlerMock} is responsible for mocking {@link GoveeHandler} - * + * * @author Leo Siepel - Initial contribution */ @NonNullByDefault public class GoveeHandlerMock extends GoveeHandler { - public GoveeHandlerMock(Thing thing, CommunicationManager communicationManager) { - super(thing, communicationManager); + public GoveeHandlerMock(Thing thing, CommunicationManager communicationManager, + GoveeStateDescriptionProvider stateDescriptionProvider) { + super(thing, communicationManager, stateDescriptionProvider); executorService = Mockito.mock(ScheduledExecutorService.class); doAnswer((InvocationOnMock invocation) -> { diff --git a/bundles/org.openhab.binding.govee/src/test/java/org/openhab/binding/govee/internal/GoveeSerializeGoveeHandlerTest.java b/bundles/org.openhab.binding.govee/src/test/java/org/openhab/binding/govee/internal/GoveeSerializeGoveeHandlerTest.java index cb92a7478062f..46565a1a66a68 100644 --- a/bundles/org.openhab.binding.govee/src/test/java/org/openhab/binding/govee/internal/GoveeSerializeGoveeHandlerTest.java +++ b/bundles/org.openhab.binding.govee/src/test/java/org/openhab/binding/govee/internal/GoveeSerializeGoveeHandlerTest.java @@ -12,12 +12,8 @@ */ package org.openhab.binding.govee.internal; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; import java.util.Arrays; import java.util.List; @@ -87,7 +83,10 @@ private static Channel mockChannel(final ThingUID thingId, final String channelI private static GoveeHandlerMock createAndInitHandler(final ThingHandlerCallback callback, final Thing thing) { CommunicationManager communicationManager = mock(CommunicationManager.class); - final GoveeHandlerMock handler = spy(new GoveeHandlerMock(thing, communicationManager)); + GoveeStateDescriptionProvider stateDescriptionProvider = mock(GoveeStateDescriptionProvider.class); + + final GoveeHandlerMock handler = spy( + new GoveeHandlerMock(thing, communicationManager, stateDescriptionProvider)); handler.setCallback(callback); handler.initialize(); @@ -135,7 +134,7 @@ public void testInvalidResponseMessage() { verify(callback).stateUpdated( new ChannelUID(thing.getUID(), GoveeBindingConstants.CHANNEL_COLOR_TEMPERATURE_ABS), - getState(2000, Units.KELVIN)); + getState(9000, Units.KELVIN)); } finally { handler.dispose(); } diff --git a/bundles/org.openhab.binding.guntamatic/README.md b/bundles/org.openhab.binding.guntamatic/README.md index 745b6ca3def45..35ad6f124d7ae 100644 --- a/bundles/org.openhab.binding.guntamatic/README.md +++ b/bundles/org.openhab.binding.guntamatic/README.md @@ -4,7 +4,7 @@ The Guntamatic Binding can be used to monitor and control [Guntamatic Heating Sy ## Supported Things -The Guntamatic Binding was developed and tested using Guntamatic Biostar 15kW Pellets Heating System, running Firmware 3.2d. +The Guntamatic Binding was developed and tested using Guntamatic Biostar 15kW Pellets Heating System, running Firmware 3.3d. It should work for all other Guntamatic Heating Systems as well, that support the same web interface (Pellets, WoodChips, EnergyGrain as well as Log Heating Systems). ## Things @@ -13,13 +13,13 @@ Guntamatic Heating Systems supported as Thing Types: | Name | Thing Type ID | Heating System Type | Binding Development Status | | --------- | ------------- | -------------------- | ------------------------------------------------ | -| Biostar | `biostar` | Pellets | tested via 15kW, firmware 3.2d, German & English | +| Biostar | `biostar` | Pellets | tested via 15kW, firmware 3.3d, German & English | | Biosmart | `biosmart` | Logs | tested via 22kW, firmware 3.2f, German | | Powerchip | `powerchip` | WoodChips | tested via 100kW, firmware 3.2d, French | -| Powercorn | `powercorn` | EnergyGrain | untested | -| Biocom | `biocom` | Pellets | untested | -| Pro | `pro` | Pellets or WoodChips | untested | -| Therm | `therm` | Pellets | untested | +| Powercorn | `powercorn` | EnergyGrain | untested (no user feedback) | +| Biocom | `biocom` | Pellets | untested (no user feedback) | +| Pro | `pro` | Pellets or WoodChips | untested (no user feedback) | +| Therm | `therm` | Pellets | untested (no user feedback) | | Generic | `generic` | - | use, if none from above | ### Thing Configuration @@ -33,13 +33,13 @@ Guntamatic Heating Systems supported as Thing Types: ### Properties -| Property | Description | Supported | -| ----------------- | --------------------------------------------------- | ------------------------------------------------- | -| `extraWwHeat` | Parameter used by `controlExtraWwHeat` channels | all | -| `boilerApproval` | Parameter used by `controlBoilerApproval` channel | Biostar, Powerchip, Powercorn, Biocom, Pro, Therm | -| `heatCircProgram` | Parameter used by `controlHeatCircProgram` channels | all | -| `program` | Parameter used by `controlProgram` channel | all | -| `wwHeat` | Parameter used by `controlWwHeat` channels | all | +| Property | Description | Supported | +| ----------------- | ---------------------------------------------- | ------------------------------------------------- | +| `extraWwHeat` | Parameter used by `extra-ww-heat` channels | all | +| `boilerApproval` | Parameter used by `boiler-approval` channel | Biostar, Powerchip, Powercorn, Biocom, Pro, Therm | +| `heatCircProgram` | Parameter used by `heat-circ-program` channels | all | +| `program` | Parameter used by `program` channel | all | +| `wwHeat` | Parameter used by `ww-heat` channels | all | ## Channels @@ -47,151 +47,153 @@ Guntamatic Heating Systems supported as Thing Types: The Guntamatic Heating System can be controlled using the following channels: -| Channel | Description | Type | Unit | Security Access Level | ReadOnly | Advanced | -| ------------------------- | ------------------------------------------------------------------------------- | -------- | :--: | :-------------------: | :------: | :------: | -| `controlBoilerApproval` | Set Boiler Approval (`AUTO`, `OFF`, `ON`) | `String` | | 🔐 W1 | R/W | true | -| `controlProgram` | Set Program (`OFF`, `NORMAL`, `WARMWATER`, `MANUAL`[1](#f1)) | `String` | | 🔐 W1 | R/W | false | -| `controlHeatCircProgram0` | Set Heat Circle 0 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | -| `controlHeatCircProgram1` | Set Heat Circle 1 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | -| `controlHeatCircProgram2` | Set Heat Circle 2 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | -| `controlHeatCircProgram3` | Set Heat Circle 3 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | -| `controlHeatCircProgram4` | Set Heat Circle 4 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | -| `controlHeatCircProgram5` | Set Heat Circle 5 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | -| `controlHeatCircProgram6` | Set Heat Circle 6 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | -| `controlHeatCircProgram7` | Set Heat Circle 7 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | -| `controlHeatCircProgram8` | Set Heat Circle 8 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | -| `controlWwHeat0` | Trigger Warm Water Circle 0 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | -| `controlWwHeat1` | Trigger Warm Water Circle 1 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | -| `controlWwHeat2` | Trigger Warm Water Circle 2 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | -| `controlExtraWwHeat0` | Trigger Extra Warm Water Circle 0 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | -| `controlExtraWwHeat1` | Trigger Extra Warm Water Circle 1 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | -| `controlExtraWwHeat2` | Trigger Extra Warm Water Circle 2 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | - -- 1) ... `MANUAL` is supported by Biostar, Powerchip, Powercorn, Biocom, Pro as well as Therm only [↩](#a1) +| Channel | Description | Type | Unit | Security Access Level | ReadOnly | Advanced | +| --------------------- | ------------------------------------------------------------------------------- | -------- | :--: | :-------------------: | :------: | :------: | +| `boiler-approval` | Set Boiler Approval (`AUTO`, `OFF`, `ON`)[1](#f1)) | `String` | | 🔐 W1 | R/W | true | +| `program` | Set Program (`OFF`, `NORMAL`, `WARMWATER`, `MANUAL`[2](#f2)) | `String` | | 🔐 W1 | R/W | false | +| `heat-circ-program-0` | Set Heat Circuit 0 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | +| `heat-circ-program-1` | Set Heat Circuit 1 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | +| `heat-circ-program-2` | Set Heat Circuit 2 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | +| `heat-circ-program-3` | Set Heat Circuit 3 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | +| `heat-circ-program-4` | Set Heat Circuit 4 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | +| `heat-circ-program-5` | Set Heat Circuit 5 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | +| `heat-circ-program-6` | Set Heat Circuit 6 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | +| `heat-circ-program-7` | Set Heat Circuit 7 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | +| `heat-circ-program-8` | Set Heat Circuit 8 Program (`OFF`, `NORMAL`, `HEAT`, `LOWER`) | `String` | | 🔐 W1 | R/W | true | +| `ww-heat-0` | Trigger Warm Water Circuit 0 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | +| `ww-heat-1` | Trigger Warm Water Circuit 1 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | +| `ww-heat-2` | Trigger Warm Water Circuit 2 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | +| `extra-ww-heat-0` | Trigger Extra Warm Water Circuit 0 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | +| `extra-ww-heat-1` | Trigger Extra Warm Water Circuit 1 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | +| `extra-ww-heat-2` | Trigger Extra Warm Water Circuit 2 (`RECHARGE`) | `String` | | 🔐 W1 | R/W | true | + +- 1) ... Channel is supported by Biostar, Powerchip, Powercorn, Biocom, Pro as well as Therm only [↩](#a1) +- 2) ... `MANUAL` is supported by Biostar, Powerchip, Powercorn, Biocom, Pro as well as Therm only [↩](#a2) #### Response of Control Channels - `{"ack":"confirmation message"}` ... in case of success - `{"err":"error message"}` ... in case of error -The reaction of the Guntamatic Heating System can be monitored via the corresponding data channel. E.g. `programHc1` if you triggered `controlHeatCircProgram1`. The data channel gets updated with the next cyclic update (according to the `refreshInterval` configuration). +The reaction of the Guntamatic Heating System can be monitored via the corresponding data channel. E.g. `program-hc-1` if you triggered `heat-circ-program-1`. The data channel gets updated with the next cyclic update (according to the `refreshInterval` configuration). -### Monitoring Channels +### Status Channels The Binding dynamically generates Channels, derived from the data provided from the actual Guntamatic Heating System. Example list of Channels using a Guntamatic Biostar 15kW Pellets Heating System running firmware 3.2d and Guntamatic System Language configured to English: -| Channel | Description | Type | Unit | Security Access Level | ReadOnly | Advanced | -| -------------------- | ---------------------- | ---------------------- | :--: | :-------------------: | :------: | :------: | -| `running` | Running | `String` | | 🔓 W0 | R/O | false | -| `outsideTemp` | Outside Temp. | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `blrTargetTemp` | Blr.Target Temp | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `boilerTemperature` | Boiler Temperature | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `flueGasUtilisation` | Flue gas utilisation | `Number:Dimensionless` | `%` | 🔐 W1 | R/O | false | -| `output` | Output | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | -| `returnTemp` | Return temp | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `co2Target` | CO2 Target | `Number:Dimensionless` | `%` | 🔐 W1 | R/O | false | -| `co2Content` | CO2 Content | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | -| `returnTempTarget` | Return temp target | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `statusCode` | Status code | `Number` | | 🔐 W1 | R/O | false | -| `efficiency` | Efficiency | `Number:Dimensionless` | `%` | 🔐 W1 | R/O | false | -| `extractorSystem` | Extractor System | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | -| `feedTurbine` | Feed Turbine | `String` | | 🔐 W1 | R/O | false | -| `dischargeMotor` | Discharge motor | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | -| `g1Target` | G1 Target | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | -| `bufferTop` | Buffer Top | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `bufferMid` | Buffer Mid | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `bufferBtm` | Buffer Btm | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `pumpHp0` | Pump HP0 | `Switch` | | 🔓 W0 | R/O | false | -| `dhw0` | DHW 0 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `bDhw0` | B DHW 0 | `Switch` | | 🔓 W0 | R/O | false | -| `dhw1` | DHW 1 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `bDhw1` | B DHW 1 | `Switch` | | 🔓 W0 | R/O | false | -| `dhw2` | DHW 2 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `bDhw2` | B DHW 2 | `Switch` | | 🔓 W0 | R/O | false | -| `roomTempHc0` | Room Temp:HC 0 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `heatCirc0` | Heat Circ. 0 | `Switch` | | 🔓 W0 | R/O | false | -| `roomTempHc1` | Room Temp:HC 1 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `flowTarget1` | Flow Target 1 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `flowIs1` | Flow is 1 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `mixer1` | Mixer 1 | `String` | | 🔐 W1 | R/O | false | -| `heatCirc1` | Heat Circ. 1 | `Switch` | | 🔐 W1 | R/O | false | -| `roomTempHc2` | Room Temp:HC 2 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `flowTarget2` | Flow Target 2 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `flowIs2` | Flow is 2 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `mixer2` | Mixer 2 | `String` | | 🔐 W1 | R/O | false | -| `heatCirc2` | Heat Circ. 2 | `Switch` | | 🔓 W0 | R/O | false | -| `roomTempHc3` | Room Temp:HC 3 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `heatCirc3` | Heat Circ. 3 | `Switch` | | 🔓 W0 | R/O | false | -| `roomTempHc4` | Room Temp:HC 4 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `flowTarget4` | Flow Target 4 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `flowIs4` | Flow is 4 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `mixer4` | Mixer 4 | `String` | | 🔐 W1 | R/O | false | -| `heatCirc4` | Heat Circ. 4 | `Switch` | | 🔓 W0 | R/O | false | -| `roomTempHc5` | Room Temp:HC 5 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `flowTarget5` | Flow Target 5 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `flowIs5` | Flow is 5 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `mixer5` | Mixer 5 | `String` | | 🔐 W1 | R/O | false | -| `heatCirc5` | Heat Circ. 5 | `Switch` | | 🔓 W0 | R/O | false | -| `roomTempHc6` | Room Temp:HC 6 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `heatCirc6` | Heat Circ. 6 | `Switch` | | 🔓 W0 | R/O | false | -| `roomTempHc7` | Room Temp:HC 7 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `flowTarget7` | Flow Target 7 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `flowIs7` | Flow is 7 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `mixer7` | Mixer 7 | `String` | | 🔐 W1 | R/O | false | -| `heatCirc7` | Heat Circ. 7 | `Switch` | | 🔓 W0 | R/O | false | -| `roomTempHc8` | Room Temp:HC 8 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `flowTarget8` | Flow Target 8 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `flowIs8` | Flow is 8 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `mixer8` | Mixer 8 | `String` | | 🔐 W1 | R/O | false | -| `heatCirc8` | Heat Circ. 8 | `Switch` | | 🔓 W0 | R/O | false | -| `fuelLevel` | Fuel Level | `String` | | 🔐 W1 | R/O | false | -| `stb` | STB | `String` | | 🔐 W1 | R/O | false | -| `tks` | TKS | `String` | | 🔐 W1 | R/O | false | -| `boilerApproval` | Boiler approval | `Switch` | | 🔐 W1 | R/O | false | -| `programme` | Programme | `String` | | 🔓 W0 | R/O | false | -| `programHc0` | Program HC0 | `String` | | 🔓 W0 | R/O | false | -| `programHc1` | Program HC1 | `String` | | 🔓 W0 | R/O | false | -| `programHc2` | Program HC2 | `String` | | 🔓 W0 | R/O | false | -| `programHc3` | Program HC3 | `String` | | 🔓 W0 | R/O | false | -| `programHc4` | Program HC4 | `String` | | 🔓 W0 | R/O | false | -| `programHc5` | Program HC5 | `String` | | 🔓 W0 | R/O | false | -| `programHc6` | Program HC6 | `String` | | 🔓 W0 | R/O | false | -| `programHc7` | Program HC7 | `String` | | 🔓 W0 | R/O | false | -| `programHc8` | Program HC8 | `String` | | 🔓 W0 | R/O | false | -| `interuption0` | Interuption 0 | `String` | | 🔓 W0 | R/O | false | -| `interuption1` | Interuption 1 | `String` | | 🔓 W0 | R/O | false | -| `serial` | Serial | `Number` | | 🔓 W0 | R/O | false | -| `version` | Version | `String` | | 🔓 W0 | R/O | false | -| `runningTime` | Running Time | `Number:Time` | `h` | 🔓 W0 | R/O | false | -| `serviceHrs` | Service Hrs | `Number:Time` | `d` | 🔓 W0 | R/O | false | -| `emptyAshIn` | Empty ash in | `Number:Time` | `h` | 🔓 W0 | R/O | false | -| `flowIs0` | Flow is 0 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `flowIs3` | Flow is 3 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `flowIs6` | Flow is 6 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `fuelCounter` | Fuel counter | `Number:Volume` | `m³` | 🔐 W1 | R/O | false | -| `bufferLoad` | Buffer load. | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | -| `bufferTop0` | Buffer Top 0 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `bufferBtm0` | Buffer Btm 0 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `bufferTop1` | Buffer Top 1 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `bufferBtm1` | Buffer Btm 1 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `bufferTop2` | Buffer Top 2 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `bufferBtm2` | Buffer Btm 2 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | -| `bExtraWw0` | B extra-WW. 0 | `Switch` | | 🔐 W1 | R/O | false | -| `bExtraWw1` | B extra-WW. 1 | `Switch` | | 🔐 W1 | R/O | false | -| `bExtraWw2` | B extra-WW. 2 | `Switch` | | 🔐 W1 | R/O | false | -| `auxiliaryPump0` | Auxiliary pump 0 | `Switch` | | 🔐 W1 | R/O | false | -| `auxiliaryPump1` | Auxiliary pump 1 | `Switch` | | 🔐 W1 | R/O | false | -| `auxiliaryPump2` | Auxiliary pump 2 | `Switch` | | 🔐 W1 | R/O | false | -| `boilersConditionNo` | Boiler´s condition no. | `String` | | 🔐 W1 | R/O | false | -| `bufferT5` | Buffer T5 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `bufferT6` | Buffer T6 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `bufferT7` | Buffer T7 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `extraWw0` | Extra-WW. 0 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `extraWw1` | Extra-WW. 1 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `extraWw2` | Extra-WW. 2 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | -| `grate` | Grate | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | +| Channel | Description | Type | Unit | Security Access Level | ReadOnly | Advanced | +|----------------------------|------------------------|------------------------|-:--:-|-:-------------------:-|-:------:-|-:------:-| +| `000-running` | Running | `String` | | 🔓 W0 | R/O | false | +| `001-outside-temp` | Outside Temp. | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `002-blr-target-temp` | Blr.Target Temp | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `003-boiler-temperature` | Boiler Temperature | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `004-flue-gas-utilisation` | Flue gas utilisation | `Number:Dimensionless` | `%` | 🔐 W1 | R/O | false | +| `005-output` | Output | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | +| `006-return-temp` | Return temp | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `007-co2-target` | CO2 Target | `Number:Dimensionless` | `%` | 🔐 W1 | R/O | false | +| `008-co2-content` | CO2 Content | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | +| `009-return-temp-target` | Return temp target | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `010-status-code` | Status code | `Number` | | 🔐 W1 | R/O | false | +| `011-efficiency` | Efficiency | `Number:Dimensionless` | `%` | 🔐 W1 | R/O | false | +| `012-output` | Output | `Number:Dimensionless` | `%` | 🔐 W1 | R/O | false | +| `013-extractor-system` | Extractor System | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | +| `014-feed-turbine` | Feed Turbine | `String` | | 🔐 W1 | R/O | false | +| `015-discharge-motor` | Discharge motor | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | +| `016-g1-target` | G1 Target | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | +| `017-buffer-top` | Buffer Top | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `018-buffer-mid` | Buffer Mid | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `019-buffer-btm` | Buffer Btm | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `020-pump-hp0` | Pump HP0 | `Switch` | | 🔓 W0 | R/O | false | +| `021-dhw-0` | DHW 0 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `022-b-dhw-0` | B DHW 0 | `Switch` | | 🔓 W0 | R/O | false | +| `023-dhw-1` | DHW 1 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `024-b-dhw-1` | B DHW 1 | `Switch` | | 🔓 W0 | R/O | false | +| `025-dhw-2` | DHW 2 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `026-b-dhw-2` | B DHW 2 | `Switch` | | 🔓 W0 | R/O | false | +| `027-room-temp-hc-0` | Room Temp:HC 0 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `028-heat-circ-0` | Heat Circ. 0 | `Switch` | | 🔓 W0 | R/O | false | +| `029-room-temp-hc-1` | Room Temp:HC 1 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `030-flow-target-1` | Flow Target 1 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `031-flow-is-1` | Flow is 1 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `032-mixer-1` | Mixer 1 | `String` | | 🔐 W1 | R/O | false | +| `033-heat-circ-1` | Heat Circ. 1 | `Switch` | | 🔐 W1 | R/O | false | +| `034-room-temp-hc-2` | Room Temp:HC 2 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `035-flow-target-2` | Flow Target 2 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `036-flow-is-2` | Flow is 2 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `037-mixer-2` | Mixer 2 | `String` | | 🔐 W1 | R/O | false | +| `038-heat-circ-2` | Heat Circ. 2 | `Switch` | | 🔓 W0 | R/O | false | +| `039-room-temp-hc-3` | Room Temp:HC 3 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `040-heat-circ-3` | Heat Circ. 3 | `Switch` | | 🔓 W0 | R/O | false | +| `041-room-temp-hc-4` | Room Temp:HC 4 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `042-flow-target-4` | Flow Target 4 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `043-flow-is-4` | Flow is 4 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `044-mixer-4` | Mixer 4 | `String` | | 🔐 W1 | R/O | false | +| `045-heat-circ-4` | Heat Circ. 4 | `Switch` | | 🔓 W0 | R/O | false | +| `046-room-temp-hc-5` | Room Temp:HC 5 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `047-flow-target-5` | Flow Target 5 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `048-flow-is-5` | Flow is 5 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `049-mixer-5` | Mixer 5 | `String` | | 🔐 W1 | R/O | false | +| `050-heat-circ-5` | Heat Circ. 5 | `Switch` | | 🔓 W0 | R/O | false | +| `051-room-temp-hc-6` | Room Temp:HC 6 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `052-heat-circ-6` | Heat Circ. 6 | `Switch` | | 🔓 W0 | R/O | false | +| `053-room-temp-hc-7` | Room Temp:HC 7 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `054-flow-target-7` | Flow Target 7 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `055-flow-is-7` | Flow is 7 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `056-mixer-7` | Mixer 7 | `String` | | 🔐 W1 | R/O | false | +| `057-heat-circ-7` | Heat Circ. 7 | `Switch` | | 🔓 W0 | R/O | false | +| `058-room-temp-hc-8` | Room Temp:HC 8 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `059-flow-target-8` | Flow Target 8 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `060-flow-is-8` | Flow is 8 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `061-mixer-8` | Mixer 8 | `String` | | 🔐 W1 | R/O | false | +| `062-heat-circ-8` | Heat Circ. 8 | `Switch` | | 🔓 W0 | R/O | false | +| `065-fuel-level` | Fuel Level | `String` | | 🔐 W1 | R/O | false | +| `066-stb` | STB | `String` | | 🔐 W1 | R/O | false | +| `067-tks` | TKS | `String` | | 🔐 W1 | R/O | false | +| `068-boiler-approval` | Boiler approval | `Switch` | | 🔐 W1 | R/O | false | +| `069-programme` | Programme | `String` | | 🔓 W0 | R/O | false | +| `070-program-hc0` | Program HC0 | `String` | | 🔓 W0 | R/O | false | +| `071-program-hc1` | Program HC1 | `String` | | 🔓 W0 | R/O | false | +| `072-program-hc2` | Program HC2 | `String` | | 🔓 W0 | R/O | false | +| `073-program-hc3` | Program HC3 | `String` | | 🔓 W0 | R/O | false | +| `074-program-hc4` | Program HC4 | `String` | | 🔓 W0 | R/O | false | +| `075-program-hc5` | Program HC5 | `String` | | 🔓 W0 | R/O | false | +| `076-program-hc6` | Program HC6 | `String` | | 🔓 W0 | R/O | false | +| `077-program-hc7` | Program HC7 | `String` | | 🔓 W0 | R/O | false | +| `078-program-hc8` | Program HC8 | `String` | | 🔓 W0 | R/O | false | +| `079-interuption-0` | Interuption 0 | `String` | | 🔓 W0 | R/O | false | +| `080-interuption-1` | Interuption 1 | `String` | | 🔓 W0 | R/O | false | +| `081-serial` | Serial | `Number` | | 🔓 W0 | R/O | false | +| `082-version` | Version | `String` | | 🔓 W0 | R/O | false | +| `083-running-time` | Running Time | `Number:Time` | `h` | 🔓 W0 | R/O | false | +| `084-service-hrs` | Service Hrs | `Number:Time` | `d` | 🔓 W0 | R/O | false | +| `085-empty-ash-in` | Empty ash in | `Number:Time` | `h` | 🔓 W0 | R/O | false | +| `086-flow-is-0` | Flow is 0 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `087-flow-is-3` | Flow is 3 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `088-flow-is-6` | Flow is 6 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `089-fuel-counter` | Fuel counter | `Number:Volume` | `m³` | 🔐 W1 | R/O | false | +| `090-buffer-load` | Buffer load. | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | +| `091-buffer-top-0` | Buffer Top 0 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `092-buffer-btm-0` | Buffer Btm 0 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `093-buffer-top-1` | Buffer Top 1 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `094-buffer-btm-1` | Buffer Btm 1 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `095-buffer-top-2` | Buffer Top 2 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `096-buffer-btm-2` | Buffer Btm 2 | `Number:Temperature` | `°C` | 🔐 W1 | R/O | false | +| `097-b-extra-ww-0` | B extra-WW. 0 | `Switch` | | 🔐 W1 | R/O | false | +| `098-b-extra-ww-1` | B extra-WW. 1 | `Switch` | | 🔐 W1 | R/O | false | +| `099-b-extra-ww-2` | B extra-WW. 2 | `Switch` | | 🔐 W1 | R/O | false | +| `100-auxiliary-pump-0` | Auxiliary pump 0 | `Switch` | | 🔐 W1 | R/O | false | +| `101-auxiliary-pump-1` | Auxiliary pump 1 | `Switch` | | 🔐 W1 | R/O | false | +| `102-auxiliary-pump-2` | Auxiliary pump 2 | `Switch` | | 🔐 W1 | R/O | false | +| `104-boilers-condition-no` | Boiler´s condition no. | `String` | | 🔐 W1 | R/O | false | +| `108-buffer-t5` | Buffer T5 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `109-buffer-t6` | Buffer T6 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `110-buffer-t7` | Buffer T7 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `111-extra-ww-0` | Extra-WW. 0 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `112-extra-ww-1` | Extra-WW. 1 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `113-extra-ww-2` | Extra-WW. 2 | `Number:Temperature` | `°C` | 🔓 W0 | R/O | false | +| `114-grate` | Grate | `Number:Dimensionless` | `%` | 🔓 W0 | R/O | false | #### Security Access Levels @@ -210,131 +212,117 @@ Thing guntamatic:biostar:mybiostar "Guntamatic Biostar" [ hostname="192.1 ### Item File ```java -String Biostar_ControlBoilerApproval "Set Boiler Approval" { channel="guntamatic:biostar:mybiostar:controlBoilerApproval" } -String Biostar_ControlProgram "Set Program" { channel="guntamatic:biostar:mybiostar:controlProgram" } -String Biostar_ControlHeatCircProgram0 "Set Heat Circle 0 Program" { channel="guntamatic:biostar:mybiostar:controlHeatCircProgram0" } -String Biostar_ControlHeatCircProgram1 "Set Heat Circle 1 Program" { channel="guntamatic:biostar:mybiostar:controlHeatCircProgram1" } -String Biostar_ControlHeatCircProgram2 "Set Heat Circle 2 Program" { channel="guntamatic:biostar:mybiostar:controlHeatCircProgram2" } -String Biostar_ControlHeatCircProgram3 "Set Heat Circle 3 Program" { channel="guntamatic:biostar:mybiostar:controlHeatCircProgram3" } -String Biostar_ControlHeatCircProgram4 "Set Heat Circle 4 Program" { channel="guntamatic:biostar:mybiostar:controlHeatCircProgram4" } -String Biostar_ControlHeatCircProgram5 "Set Heat Circle 5 Program" { channel="guntamatic:biostar:mybiostar:controlHeatCircProgram5" } -String Biostar_ControlHeatCircProgram6 "Set Heat Circle 6 Program" { channel="guntamatic:biostar:mybiostar:controlHeatCircProgram6" } -String Biostar_ControlHeatCircProgram7 "Set Heat Circle 7 Program" { channel="guntamatic:biostar:mybiostar:controlHeatCircProgram7" } -String Biostar_ControlHeatCircProgram8 "Set Heat Circle 8 Program" { channel="guntamatic:biostar:mybiostar:controlHeatCircProgram8" } -String Biostar_ControlWwHeat0 "Trigger Warm Water Circle 0" { channel="guntamatic:biostar:mybiostar:controlWwHeat0" } -String Biostar_ControlWwHeat1 "Trigger Warm Water Circle 1" { channel="guntamatic:biostar:mybiostar:controlWwHeat1" } -String Biostar_ControlWwHeat2 "Trigger Warm Water Circle 2" { channel="guntamatic:biostar:mybiostar:controlWwHeat2" } -String Biostar_ControlExtraWwHeat0 "Trigger Extra Warm Water Circle 0" { channel="guntamatic:biostar:mybiostar:controlExtraWwHeat0" } -String Biostar_ControlExtraWwHeat1 "Trigger Extra Warm Water Circle 1" { channel="guntamatic:biostar:mybiostar:controlExtraWwHeat1" } -String Biostar_ControlExtraWwHeat2 "Trigger Extra Warm Water Circle 2" { channel="guntamatic:biostar:mybiostar:controlExtraWwHeat2" } -String Biostar_Running "Running" { channel="guntamatic:biostar:mybiostar:running" } -Number:Temperature Biostar_OutsideTemp "Outside Temp." { channel="guntamatic:biostar:mybiostar:outsideTemp" } -Number:Temperature Biostar_BlrTargetTemp "Blr.Target Temp" { channel="guntamatic:biostar:mybiostar:blrTargetTemp" } -Number:Temperature Biostar_BoilerTemperature "Boiler Temperature" { channel="guntamatic:biostar:mybiostar:boilerTemperature" } -Number:Dimensionless Biostar_FlueGasUtilisation "Flue gas utilisation" { channel="guntamatic:biostar:mybiostar:flueGasUtilisation" } -Number:Dimensionless Biostar_Output "Output" { channel="guntamatic:biostar:mybiostar:output" } -Number:Temperature Biostar_ReturnTemp "Return temp" { channel="guntamatic:biostar:mybiostar:returnTemp" } -Number:Dimensionless Biostar_Co2Target "CO2 Target" { channel="guntamatic:biostar:mybiostar:co2Target" } -Number:Dimensionless Biostar_Co2Content "CO2 Content" { channel="guntamatic:biostar:mybiostar:co2Content" } -Number:Temperature Biostar_ReturnTempTarget "Return temp target" { channel="guntamatic:biostar:mybiostar:returnTempTarget" } -Number Biostar_StatusCode "Status code" { channel="guntamatic:biostar:mybiostar:statusCode" } -Number:Dimensionless Biostar_Efficiency "Efficiency" { channel="guntamatic:biostar:mybiostar:efficiency" } -Number:Dimensionless Biostar_ExtractorSystem "Extractor System" { channel="guntamatic:biostar:mybiostar:extractorSystem" } -String Biostar_FeedTurbine "Feed Turbine" { channel="guntamatic:biostar:mybiostar:feedTurbine" } -Number:Dimensionless Biostar_DischargeMotor "Discharge motor" { channel="guntamatic:biostar:mybiostar:dischargeMotor" } -Number:Dimensionless Biostar_G1Target "G1 Target" { channel="guntamatic:biostar:mybiostar:g1Target" } -Number:Temperature Biostar_BufferTop "Buffer Top" { channel="guntamatic:biostar:mybiostar:bufferTop" } -Number:Temperature Biostar_BufferMid "Buffer Mid" { channel="guntamatic:biostar:mybiostar:bufferMid" } -Number:Temperature Biostar_BufferBtm "Buffer Btm" { channel="guntamatic:biostar:mybiostar:bufferBtm" } -Switch Biostar_PumpHp0 "Pump HP0" { channel="guntamatic:biostar:mybiostar:pumpHp0" } -Number:Temperature Biostar_Dhw0 "DHW 0" { channel="guntamatic:biostar:mybiostar:dhw0" } -Switch Biostar_BDhw0 "B DHW 0" { channel="guntamatic:biostar:mybiostar:bDhw0" } -Number:Temperature Biostar_Dhw1 "DHW 1" { channel="guntamatic:biostar:mybiostar:dhw1" } -Switch Biostar_BDhw1 "B DHW 1" { channel="guntamatic:biostar:mybiostar:bDhw1" } -Number:Temperature Biostar_Dhw2 "DHW 2" { channel="guntamatic:biostar:mybiostar:dhw2" } -Switch Biostar_BDhw2 "B DHW 2" { channel="guntamatic:biostar:mybiostar:bDhw2" } -Number:Temperature Biostar_RoomTempHc0 "Room Temp:HC 0" { channel="guntamatic:biostar:mybiostar:roomTempHc0" } -Switch Biostar_HeatCirc0 "Heat Circ. 0" { channel="guntamatic:biostar:mybiostar:heatCirc0" } -Number:Temperature Biostar_RoomTempHc1 "Room Temp:HC 1" { channel="guntamatic:biostar:mybiostar:roomTempHc1" } -Number:Temperature Biostar_FlowTarget1 "Flow Target 1" { channel="guntamatic:biostar:mybiostar:flowTarget1" } -Number:Temperature Biostar_FlowIs1 "Flow is 1" { channel="guntamatic:biostar:mybiostar:flowIs1" } -String Biostar_Mixer1 "Mixer 1" { channel="guntamatic:biostar:mybiostar:mixer1" } -Switch Biostar_HeatCirc1 "Heat Circ. 1" { channel="guntamatic:biostar:mybiostar:heatCirc1" } -Number:Temperature Biostar_RoomTempHc2 "Room Temp:HC 2" { channel="guntamatic:biostar:mybiostar:roomTempHc2" } -Number:Temperature Biostar_FlowTarget2 "Flow Target 2" { channel="guntamatic:biostar:mybiostar:flowTarget2" } -Number:Temperature Biostar_FlowIs2 "Flow is 2" { channel="guntamatic:biostar:mybiostar:flowIs2" } -String Biostar_Mixer2 "Mixer 2" { channel="guntamatic:biostar:mybiostar:mixer2" } -Switch Biostar_HeatCirc2 "Heat Circ. 2" { channel="guntamatic:biostar:mybiostar:heatCirc2" } -Number:Temperature Biostar_RoomTempHc3 "Room Temp:HC 3" { channel="guntamatic:biostar:mybiostar:roomTempHc3" } -Switch Biostar_HeatCirc3 "Heat Circ. 3" { channel="guntamatic:biostar:mybiostar:heatCirc3" } -Number:Temperature Biostar_RoomTempHc4 "Room Temp:HC 4" { channel="guntamatic:biostar:mybiostar:roomTempHc4" } -Number:Temperature Biostar_FlowTarget4 "Flow Target 4" { channel="guntamatic:biostar:mybiostar:flowTarget4" } -Number:Temperature Biostar_FlowIs4 "Flow is 4" { channel="guntamatic:biostar:mybiostar:flowIs4" } -String Biostar_Mixer4 "Mixer 4" { channel="guntamatic:biostar:mybiostar:mixer4" } -Switch Biostar_HeatCirc4 "Heat Circ. 4" { channel="guntamatic:biostar:mybiostar:heatCirc4" } -Number:Temperature Biostar_RoomTempHc5 "Room Temp:HC 5" { channel="guntamatic:biostar:mybiostar:roomTempHc5" } -Number:Temperature Biostar_FlowTarget5 "Flow Target 5" { channel="guntamatic:biostar:mybiostar:flowTarget5" } -Number:Temperature Biostar_FlowIs5 "Flow is 5" { channel="guntamatic:biostar:mybiostar:flowIs5" } -String Biostar_Mixer5 "Mixer 5" { channel="guntamatic:biostar:mybiostar:mixer5" } -Switch Biostar_HeatCirc5 "Heat Circ. 5" { channel="guntamatic:biostar:mybiostar:heatCirc5" } -Number:Temperature Biostar_RoomTempHc6 "Room Temp:HC 6" { channel="guntamatic:biostar:mybiostar:roomTempHc6" } -Switch Biostar_HeatCirc6 "Heat Circ. 6" { channel="guntamatic:biostar:mybiostar:heatCirc6" } -Number:Temperature Biostar_RoomTempHc7 "Room Temp:HC 7" { channel="guntamatic:biostar:mybiostar:roomTempHc7" } -Number:Temperature Biostar_FlowTarget7 "Flow Target 7" { channel="guntamatic:biostar:mybiostar:flowTarget7" } -Number:Temperature Biostar_FlowIs7 "Flow is 7" { channel="guntamatic:biostar:mybiostar:flowIs7" } -String Biostar_Mixer7 "Mixer 7" { channel="guntamatic:biostar:mybiostar:mixer7" } -Switch Biostar_HeatCirc7 "Heat Circ. 7" { channel="guntamatic:biostar:mybiostar:heatCirc7" } -Number:Temperature Biostar_RoomTempHc8 "Room Temp:HC 8" { channel="guntamatic:biostar:mybiostar:roomTempHc8" } -Number:Temperature Biostar_FlowTarget8 "Flow Target 8" { channel="guntamatic:biostar:mybiostar:flowTarget8" } -Number:Temperature Biostar_FlowIs8 "Flow is 8" { channel="guntamatic:biostar:mybiostar:flowIs8" } -String Biostar_Mixer8 "Mixer 8" { channel="guntamatic:biostar:mybiostar:mixer8" } -Switch Biostar_HeatCirc8 "Heat Circ. 8" { channel="guntamatic:biostar:mybiostar:heatCirc8" } -String Biostar_FuelLevel "Fuel Level" { channel="guntamatic:biostar:mybiostar:fuelLevel" } -String Biostar_Stb "STB" { channel="guntamatic:biostar:mybiostar:stb" } -String Biostar_Tks "TKS" { channel="guntamatic:biostar:mybiostar:tks" } -Switch Biostar_BoilerApproval "Boiler approval" { channel="guntamatic:biostar:mybiostar:boilerApproval" } -String Biostar_Programme "Programme" { channel="guntamatic:biostar:mybiostar:programme" } -String Biostar_ProgramHc0 "Program HC0" { channel="guntamatic:biostar:mybiostar:programHc0" } -String Biostar_ProgramHc1 "Program HC1" { channel="guntamatic:biostar:mybiostar:programHc1" } -String Biostar_ProgramHc2 "Program HC2" { channel="guntamatic:biostar:mybiostar:programHc2" } -String Biostar_ProgramHc3 "Program HC3" { channel="guntamatic:biostar:mybiostar:programHc3" } -String Biostar_ProgramHc4 "Program HC4" { channel="guntamatic:biostar:mybiostar:programHc4" } -String Biostar_ProgramHc5 "Program HC5" { channel="guntamatic:biostar:mybiostar:programHc5" } -String Biostar_ProgramHc6 "Program HC6" { channel="guntamatic:biostar:mybiostar:programHc6" } -String Biostar_ProgramHc7 "Program HC7" { channel="guntamatic:biostar:mybiostar:programHc7" } -String Biostar_ProgramHc8 "Program HC8" { channel="guntamatic:biostar:mybiostar:programHc8" } -String Biostar_Interuption0 "Interuption 0" { channel="guntamatic:biostar:mybiostar:interuption0" } -String Biostar_Interuption1 "Interuption 1" { channel="guntamatic:biostar:mybiostar:interuption1" } -Number Biostar_Serial "Serial" { channel="guntamatic:biostar:mybiostar:serial" } -String Biostar_Version "Version" { channel="guntamatic:biostar:mybiostar:version" } -Number:Time Biostar_RunningTime "Running Time" { channel="guntamatic:biostar:mybiostar:runningTime" } -Number:Time Biostar_ServiceHrs "Service Hrs" { channel="guntamatic:biostar:mybiostar:serviceHrs" } -Number:Time Biostar_EmptyAshIn "Empty ash in" { channel="guntamatic:biostar:mybiostar:emptyAshIn" } -Number:Temperature Biostar_FlowIs0 "Flow is 0" { channel="guntamatic:biostar:mybiostar:flowIs0" } -Number:Temperature Biostar_FlowIs3 "Flow is 3" { channel="guntamatic:biostar:mybiostar:flowIs3" } -Number:Temperature Biostar_FlowIs6 "Flow is 6" { channel="guntamatic:biostar:mybiostar:flowIs6" } -Number:Volume Biostar_FuelCounter "Fuel counter" { channel="guntamatic:biostar:mybiostar:fuelCounter" } -Number:Dimensionless Biostar_BufferLoad "Buffer load." { channel="guntamatic:biostar:mybiostar:bufferLoad" } -Number:Temperature Biostar_BufferTop0 "Buffer Top 0" { channel="guntamatic:biostar:mybiostar:bufferTop0" } -Number:Temperature Biostar_BufferBtm0 "Buffer Btm 0" { channel="guntamatic:biostar:mybiostar:bufferBtm0" } -Number:Temperature Biostar_BufferTop1 "Buffer Top 1" { channel="guntamatic:biostar:mybiostar:bufferTop1" } -Number:Temperature Biostar_BufferBtm1 "Buffer Btm 1" { channel="guntamatic:biostar:mybiostar:bufferBtm1" } -Number:Temperature Biostar_BufferTop2 "Buffer Top 2" { channel="guntamatic:biostar:mybiostar:bufferTop2" } -Number:Temperature Biostar_BufferBtm2 "Buffer Btm 2" { channel="guntamatic:biostar:mybiostar:bufferBtm2" } -Switch Biostar_BExtraWw0 "B extra-WW. 0" { channel="guntamatic:biostar:mybiostar:bExtraWw0" } -Switch Biostar_BExtraWw1 "B extra-WW. 1" { channel="guntamatic:biostar:mybiostar:bExtraWw1" } -Switch Biostar_BExtraWw2 "B extra-WW. 2" { channel="guntamatic:biostar:mybiostar:bExtraWw2" } -Switch Biostar_AuxiliaryPump0 "Auxiliary pump 0" { channel="guntamatic:biostar:mybiostar:auxiliaryPump0" } -Switch Biostar_AuxiliaryPump1 "Auxiliary pump 1" { channel="guntamatic:biostar:mybiostar:auxiliaryPump1" } -Switch Biostar_AuxiliaryPump2 "Auxiliary pump 2" { channel="guntamatic:biostar:mybiostar:auxiliaryPump2" } -String Biostar_BoilersConditionNo "Boiler´s condition no." { channel="guntamatic:biostar:mybiostar:boilersConditionNo" } -Number:Temperature Biostar_BufferT5 "Buffer T5" { channel="guntamatic:biostar:mybiostar:bufferT5" } -Number:Temperature Biostar_BufferT6 "Buffer T6" { channel="guntamatic:biostar:mybiostar:bufferT6" } -Number:Temperature Biostar_BufferT7 "Buffer T7" { channel="guntamatic:biostar:mybiostar:bufferT7" } -Number:Temperature Biostar_ExtraWw0 "Extra-WW. 0" { channel="guntamatic:biostar:mybiostar:extraWw0" } -Number:Temperature Biostar_ExtraWw1 "Extra-WW. 1" { channel="guntamatic:biostar:mybiostar:extraWw1" } -Number:Temperature Biostar_ExtraWw2 "Extra-WW. 2" { channel="guntamatic:biostar:mybiostar:extraWw2" } -Number:Dimensionless Biostar_Grate "Grate" { channel="guntamatic:biostar:mybiostar:grate" } +String Biostar_ControlProgram "Control Program" { channel="guntamatic:biostar:mybiostar:control#program" } + +String               Biostar_Running                 "Running"                            { channel="guntamatic:biostar:mybiostar:status#000-running" } +Number:Temperature   Biostar_OutsideTemp             "Outside Temp."                      { channel="guntamatic:biostar:mybiostar:status#001-outside-temp" } +Number:Temperature   Biostar_BlrTargetTemp           "Blr.Target Temp"                    { channel="guntamatic:biostar:mybiostar:status#002-blr-target-temp" } +Number:Temperature   Biostar_BoilerTemperature       "Boiler Temperature"                 { channel="guntamatic:biostar:mybiostar:status#003-boiler-temperature" } +Number:Dimensionless Biostar_FlueGasUtilisation      "Flue gas utilisation"               { channel="guntamatic:biostar:mybiostar:status#004-flue-gas-utilisation" } +Number:Dimensionless Biostar_Output                  "Output"                             { channel="guntamatic:biostar:mybiostar:status#005-output" } +Number:Temperature   Biostar_ReturnTemp              "Return temp"                        { channel="guntamatic:biostar:mybiostar:status#006-return-temp" } +Number:Dimensionless Biostar_Co2Target               "CO2 Target"                         { channel="guntamatic:biostar:mybiostar:status#007-co2-target" } +Number:Dimensionless Biostar_Co2Content              "CO2 Content"                        { channel="guntamatic:biostar:mybiostar:status#008-co2-content" } +Number:Temperature   Biostar_ReturnTempTarget        "Return temp target"                 { channel="guntamatic:biostar:mybiostar:status#009-return-temp-target" } +Number               Biostar_StatusCode              "Status code"                        { channel="guntamatic:biostar:mybiostar:status#010-status-code" } +Number:Dimensionless Biostar_Efficiency              "Efficiency"                         { channel="guntamatic:biostar:mybiostar:status#011-efficiency" } +Number:Dimensionless Biostar_Output2                 "Output"                             { channel="guntamatic:biostar:mybiostar:status#012-output" } +Number:Dimensionless Biostar_ExtractorSystem         "Extractor System"                   { channel="guntamatic:biostar:mybiostar:status#013-extractor-system" } +String               Biostar_FeedTurbine             "Feed Turbine"                       { channel="guntamatic:biostar:mybiostar:status#014-feed-turbine" } +Number:Dimensionless Biostar_DischargeMotor          "Discharge motor"                    { channel="guntamatic:biostar:mybiostar:status#015-discharge-motor" } +Number:Dimensionless Biostar_G1Target                "G1 Target"                          { channel="guntamatic:biostar:mybiostar:status#016-g1-target" } +Number:Temperature   Biostar_BufferTop               "Buffer Top"                         { channel="guntamatic:biostar:mybiostar:status#017-buffer-top" } +Number:Temperature   Biostar_BufferMid               "Buffer Mid"                         { channel="guntamatic:biostar:mybiostar:status#018-buffer-mid" } +Number:Temperature   Biostar_BufferBtm               "Buffer Btm"                         { channel="guntamatic:biostar:mybiostar:status#019-buffer-btm" } +Switch               Biostar_PumpHp0                 "Pump HP0"                           { channel="guntamatic:biostar:mybiostar:status#020-pump-hp0" } +Number:Temperature   Biostar_Dhw0                    "DHW 0"                              { channel="guntamatic:biostar:mybiostar:status#021-dhw-0" } +Switch               Biostar_BDhw0                   "B DHW 0"                            { channel="guntamatic:biostar:mybiostar:status#022-b-dhw-0" } +Number:Temperature   Biostar_Dhw1                    "DHW 1"                              { channel="guntamatic:biostar:mybiostar:status#023-dhw-1" } +Switch               Biostar_BDhw1                   "B DHW 1"                            { channel="guntamatic:biostar:mybiostar:status#024-b-dhw-1" } +Number:Temperature   Biostar_Dhw2                    "DHW 2"                              { channel="guntamatic:biostar:mybiostar:status#025-dhw-2" } +Switch               Biostar_BDhw2                   "B DHW 2"                            { channel="guntamatic:biostar:mybiostar:status#026-b-dhw-2" } +Number:Temperature   Biostar_RoomTempHc0             "Room Temp:HC 0"                     { channel="guntamatic:biostar:mybiostar:status#027-room-temp-hc-0" } +Switch               Biostar_HeatCirc0               "Heat Circ. 0"                       { channel="guntamatic:biostar:mybiostar:status#028-heat-circ-0" } +Number:Temperature   Biostar_RoomTempHc1             "Room Temp:HC 1"                     { channel="guntamatic:biostar:mybiostar:status#029-room-temp-hc-1" } +Number:Temperature   Biostar_FlowTarget1             "Flow Target 1"                      { channel="guntamatic:biostar:mybiostar:status#030-flow-target-1" } +Number:Temperature   Biostar_FlowIs1                 "Flow is 1"                          { channel="guntamatic:biostar:mybiostar:status#031-flow-is-1" } +String               Biostar_Mixer1                  "Mixer 1"                            { channel="guntamatic:biostar:mybiostar:status#032-mixer-1" } +Switch               Biostar_HeatCirc1               "Heat Circ. 1"                       { channel="guntamatic:biostar:mybiostar:status#033-heat-circ-1" } +Number:Temperature   Biostar_RoomTempHc2             "Room Temp:HC 2"                     { channel="guntamatic:biostar:mybiostar:status#034-room-temp-hc-2" } +Number:Temperature   Biostar_FlowTarget2             "Flow Target 2"                      { channel="guntamatic:biostar:mybiostar:status#035-flow-target-2" } +Number:Temperature   Biostar_FlowIs2                 "Flow is 2"                          { channel="guntamatic:biostar:mybiostar:status#036-flow-is-2" } +String               Biostar_Mixer2                  "Mixer 2"                            { channel="guntamatic:biostar:mybiostar:status#037-mixer-2" } +Switch               Biostar_HeatCirc2               "Heat Circ. 2"                       { channel="guntamatic:biostar:mybiostar:status#038-heat-circ-2" } +Number:Temperature   Biostar_RoomTempHc3             "Room Temp:HC 3"                     { channel="guntamatic:biostar:mybiostar:status#039-room-temp-hc-3" } +Switch               Biostar_HeatCirc3               "Heat Circ. 3"                       { channel="guntamatic:biostar:mybiostar:status#040-heat-circ-3" } +Number:Temperature   Biostar_RoomTempHc4             "Room Temp:HC 4"                     { channel="guntamatic:biostar:mybiostar:status#041-room-temp-hc-4" } +Number:Temperature   Biostar_FlowTarget4             "Flow Target 4"                      { channel="guntamatic:biostar:mybiostar:status#042-flow-target-4" } +Number:Temperature   Biostar_FlowIs4                 "Flow is 4"                          { channel="guntamatic:biostar:mybiostar:status#043-flow-is-4" } +String               Biostar_Mixer4                  "Mixer 4"                            { channel="guntamatic:biostar:mybiostar:status#044-mixer-4" } +Switch               Biostar_HeatCirc4               "Heat Circ. 4"                       { channel="guntamatic:biostar:mybiostar:status#045-heat-circ-4" } +Number:Temperature   Biostar_RoomTempHc5             "Room Temp:HC 5"                     { channel="guntamatic:biostar:mybiostar:status#046-room-temp-hc-5" } +Number:Temperature   Biostar_FlowTarget5             "Flow Target 5"                      { channel="guntamatic:biostar:mybiostar:status#047-flow-target-5" } +Number:Temperature   Biostar_FlowIs5                 "Flow is 5"                          { channel="guntamatic:biostar:mybiostar:status#048-flow-is-5" } +String               Biostar_Mixer5                  "Mixer 5"                            { channel="guntamatic:biostar:mybiostar:status#049-mixer-5" } +Switch               Biostar_HeatCirc5               "Heat Circ. 5"                       { channel="guntamatic:biostar:mybiostar:status#050-heat-circ-5" } +Number:Temperature   Biostar_RoomTempHc6             "Room Temp:HC 6"                     { channel="guntamatic:biostar:mybiostar:status#051-room-temp-hc-6" } +Switch               Biostar_HeatCirc6               "Heat Circ. 6"                       { channel="guntamatic:biostar:mybiostar:status#052-heat-circ-6" } +Number:Temperature   Biostar_RoomTempHc7             "Room Temp:HC 7"                     { channel="guntamatic:biostar:mybiostar:status#053-room-temp-hc-7" } +Number:Temperature   Biostar_FlowTarget7             "Flow Target 7"                      { channel="guntamatic:biostar:mybiostar:status#054-flow-target-7" } +Number:Temperature   Biostar_FlowIs7                 "Flow is 7"                          { channel="guntamatic:biostar:mybiostar:status#055-flow-is-7" } +String               Biostar_Mixer7                  "Mixer 7"                            { channel="guntamatic:biostar:mybiostar:status#056-mixer-7" } +Switch               Biostar_HeatCirc7               "Heat Circ. 7"                       { channel="guntamatic:biostar:mybiostar:status#057-heat-circ-7" } +Number:Temperature   Biostar_RoomTempHc8             "Room Temp:HC 8"                     { channel="guntamatic:biostar:mybiostar:status#058-room-temp-hc-8" } +Number:Temperature   Biostar_FlowTarget8             "Flow Target 8"                      { channel="guntamatic:biostar:mybiostar:status#059-flow-target-8" } +Number:Temperature   Biostar_FlowIs8                 "Flow is 8"                          { channel="guntamatic:biostar:mybiostar:status#060-flow-is-8" } +String               Biostar_Mixer8                  "Mixer 8"                            { channel="guntamatic:biostar:mybiostar:status#061-mixer-8" } +Switch               Biostar_HeatCirc8               "Heat Circ. 8"                       { channel="guntamatic:biostar:mybiostar:status#062-heat-circ-8" } +String               Biostar_FuelLevel               "Fuel Level"                         { channel="guntamatic:biostar:mybiostar:status#065-fuel-level" } +String               Biostar_Stb                     "STB"                                { channel="guntamatic:biostar:mybiostar:status#066-stb" } +String               Biostar_Tks                     "TKS"                                { channel="guntamatic:biostar:mybiostar:status#067-tks" } +Switch               Biostar_BoilerApproval          "Boiler approval"                    { channel="guntamatic:biostar:mybiostar:status#068-boiler-approval" } +String               Biostar_Programme               "Programme"                          { channel="guntamatic:biostar:mybiostar:status#069-programme" } +String               Biostar_ProgramHc0              "Program HC0"                        { channel="guntamatic:biostar:mybiostar:status#070-program-hc0" } +String               Biostar_ProgramHc1              "Program HC1"                        { channel="guntamatic:biostar:mybiostar:status#071-program-hc1" } +String               Biostar_ProgramHc2              "Program HC2"                        { channel="guntamatic:biostar:mybiostar:status#072-program-hc2" } +String               Biostar_ProgramHc3              "Program HC3"                        { channel="guntamatic:biostar:mybiostar:status#073-program-hc3" } +String               Biostar_ProgramHc4              "Program HC4"                        { channel="guntamatic:biostar:mybiostar:status#074-program-hc4" } +String               Biostar_ProgramHc5              "Program HC5"                        { channel="guntamatic:biostar:mybiostar:status#075-program-hc5" } +String               Biostar_ProgramHc6              "Program HC6"                        { channel="guntamatic:biostar:mybiostar:status#076-program-hc6" } +String               Biostar_ProgramHc7              "Program HC7"                        { channel="guntamatic:biostar:mybiostar:status#077-program-hc7" } +String               Biostar_ProgramHc8              "Program HC8"                        { channel="guntamatic:biostar:mybiostar:status#078-program-hc8" } +String               Biostar_Interuption0            "Interuption 0"                      { channel="guntamatic:biostar:mybiostar:status#079-interuption-0" } +String               Biostar_Interuption1            "Interuption 1"                      { channel="guntamatic:biostar:mybiostar:status#080-interuption-1" } +Number               Biostar_Serial                  "Serial"                             { channel="guntamatic:biostar:mybiostar:status#081-serial" } +String               Biostar_Version                 "Version"                            { channel="guntamatic:biostar:mybiostar:status#082-version" } +Number:Time          Biostar_RunningTime             "Running Time"                       { channel="guntamatic:biostar:mybiostar:status#083-running-time" } +Number:Time          Biostar_ServiceHrs              "Service Hrs"                        { channel="guntamatic:biostar:mybiostar:status#084-service-hrs" } +Number:Time          Biostar_EmptyAshIn              "Empty ash in"                       { channel="guntamatic:biostar:mybiostar:status#085-empty-ash-in" } +Number:Temperature   Biostar_FlowIs0                 "Flow is 0"                          { channel="guntamatic:biostar:mybiostar:status#086-flow-is-0" } +Number:Temperature   Biostar_FlowIs3                 "Flow is 3"                          { channel="guntamatic:biostar:mybiostar:status#087-flow-is-3" } +Number:Temperature   Biostar_FlowIs6                 "Flow is 6"                          { channel="guntamatic:biostar:mybiostar:status#088-flow-is-6" } +Number:Volume        Biostar_FuelCounter             "Fuel counter"                       { channel="guntamatic:biostar:mybiostar:status#089-fuel-counter" } +Number:Dimensionless Biostar_BufferLoad              "Buffer load."                       { channel="guntamatic:biostar:mybiostar:status#090-buffer-load" } +Number:Temperature   Biostar_BufferTop0              "Buffer Top 0"                       { channel="guntamatic:biostar:mybiostar:status#091-buffer-top-0" } +Number:Temperature   Biostar_BufferBtm0              "Buffer Btm 0"                       { channel="guntamatic:biostar:mybiostar:status#092-buffer-btm-0" } +Number:Temperature   Biostar_BufferTop1              "Buffer Top 1"                       { channel="guntamatic:biostar:mybiostar:status#093-buffer-top-1" } +Number:Temperature   Biostar_BufferBtm1              "Buffer Btm 1"                       { channel="guntamatic:biostar:mybiostar:status#094-buffer-btm-1" } +Number:Temperature   Biostar_BufferTop2              "Buffer Top 2"                       { channel="guntamatic:biostar:mybiostar:status#095-buffer-top-2" } +Number:Temperature   Biostar_BufferBtm2              "Buffer Btm 2"                       { channel="guntamatic:biostar:mybiostar:status#096-buffer-btm-2" } +Switch               Biostar_BExtraWw0               "B extra-WW. 0"                      { channel="guntamatic:biostar:mybiostar:status#097-b-extra-ww-0" } +Switch               Biostar_BExtraWw1               "B extra-WW. 1"                      { channel="guntamatic:biostar:mybiostar:status#098-b-extra-ww-1" } +Switch               Biostar_BExtraWw2               "B extra-WW. 2"                      { channel="guntamatic:biostar:mybiostar:status#099-b-extra-ww-2" } +Switch               Biostar_AuxiliaryPump0          "Auxiliary pump 0"                   { channel="guntamatic:biostar:mybiostar:status#100-auxiliary-pump-0" } +Switch               Biostar_AuxiliaryPump1          "Auxiliary pump 1"                   { channel="guntamatic:biostar:mybiostar:status#101-auxiliary-pump-1" } +Switch               Biostar_AuxiliaryPump2          "Auxiliary pump 2"                   { channel="guntamatic:biostar:mybiostar:status#102-auxiliary-pump-2" } +String               Biostar_BoilersConditionNo      "Boiler´s condition no."             { channel="guntamatic:biostar:mybiostar:status#104-boilers-condition-no" } +Number:Temperature   Biostar_BufferT5                "Buffer T5"                          { channel="guntamatic:biostar:mybiostar:status#108-buffer-t5" } +Number:Temperature   Biostar_BufferT6                "Buffer T6"                          { channel="guntamatic:biostar:mybiostar:status#109-buffer-t6" } +Number:Temperature   Biostar_BufferT7                "Buffer T7"                          { channel="guntamatic:biostar:mybiostar:status#110-buffer-t7" } +Number:Temperature   Biostar_ExtraWw0                "Extra-WW. 0"                        { channel="guntamatic:biostar:mybiostar:status#111-extra-ww-0" } +Number:Temperature   Biostar_ExtraWw1                "Extra-WW. 1"                        { channel="guntamatic:biostar:mybiostar:status#112-extra-ww-1" } +Number:Temperature   Biostar_ExtraWw2                "Extra-WW. 2"                        { channel="guntamatic:biostar:mybiostar:status#113-extra-ww-2" } +Number:Dimensionless Biostar_Grate                   "Grate"                              { channel="guntamatic:biostar:mybiostar:status#114-grate" } ``` ### Rule @@ -360,7 +348,7 @@ end ## Your feedback is required -The Guntamatic Binding was developed and tested using Guntamatic Biostar 15kW Pellets Heating System, running Firmware 3.2d. +The Guntamatic Binding was developed and tested using Guntamatic Biostar 15kW Pellets Heating System, running Firmware 3.3d. Please provide feedback (👍 as well as 👎) when using the Binding for other Guntamatic Heating Systems. Forum topic for feedback: diff --git a/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticBindingConstants.java b/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticBindingConstants.java index 912f8bf07128b..30040284cb083 100644 --- a/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticBindingConstants.java +++ b/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticBindingConstants.java @@ -39,38 +39,42 @@ public class GuntamaticBindingConstants { public static final ThingTypeUID THING_TYPE_THERM = new ThingTypeUID(BINDING_ID, "therm"); public static final ThingTypeUID THING_TYPE_GENERIC = new ThingTypeUID(BINDING_ID, "generic"); + public static final String GROUP_CONTROL = "control#"; + // List of all Channel ids - public static final String CHANNEL_CONTROLBOILERAPPROVAL = "controlBoilerApproval"; - public static final String CHANNEL_CONTROLPROGRAM = "controlProgram"; - public static final String CHANNEL_CONTROLHEATCIRCPROGRAM0 = "controlHeatCircProgram0"; - public static final String CHANNEL_CONTROLHEATCIRCPROGRAM1 = "controlHeatCircProgram1"; - public static final String CHANNEL_CONTROLHEATCIRCPROGRAM2 = "controlHeatCircProgram2"; - public static final String CHANNEL_CONTROLHEATCIRCPROGRAM3 = "controlHeatCircProgram3"; - public static final String CHANNEL_CONTROLHEATCIRCPROGRAM4 = "controlHeatCircProgram4"; - public static final String CHANNEL_CONTROLHEATCIRCPROGRAM5 = "controlHeatCircProgram5"; - public static final String CHANNEL_CONTROLHEATCIRCPROGRAM6 = "controlHeatCircProgram6"; - public static final String CHANNEL_CONTROLHEATCIRCPROGRAM7 = "controlHeatCircProgram7"; - public static final String CHANNEL_CONTROLHEATCIRCPROGRAM8 = "controlHeatCircProgram8"; - public static final String CHANNEL_CONTROLWWHEAT0 = "controlWwHeat0"; - public static final String CHANNEL_CONTROLWWHEAT1 = "controlWwHeat1"; - public static final String CHANNEL_CONTROLWWHEAT2 = "controlWwHeat2"; - public static final String CHANNEL_CONTROLEXTRAWWHEAT0 = "controlExtraWwHeat0"; - public static final String CHANNEL_CONTROLEXTRAWWHEAT1 = "controlExtraWwHeat1"; - public static final String CHANNEL_CONTROLEXTRAWWHEAT2 = "controlExtraWwHeat2"; + public static final String CHANNEL_CONTROL_BOILERAPPROVAL = GROUP_CONTROL + "boiler-approval"; + public static final String CHANNEL_CONTROL_PROGRAM = GROUP_CONTROL + "program"; + public static final String CHANNEL_CONTROL_HEATCIRCPROGRAM0 = GROUP_CONTROL + "heat-circ-program-0"; + public static final String CHANNEL_CONTROL_HEATCIRCPROGRAM1 = GROUP_CONTROL + "heat-circ-program-1"; + public static final String CHANNEL_CONTROL_HEATCIRCPROGRAM2 = GROUP_CONTROL + "heat-circ-program-2"; + public static final String CHANNEL_CONTROL_HEATCIRCPROGRAM3 = GROUP_CONTROL + "heat-circ-program-3"; + public static final String CHANNEL_CONTROL_HEATCIRCPROGRAM4 = GROUP_CONTROL + "heat-circ-program-4"; + public static final String CHANNEL_CONTROL_HEATCIRCPROGRAM5 = GROUP_CONTROL + "heat-circ-program-5"; + public static final String CHANNEL_CONTROL_HEATCIRCPROGRAM6 = GROUP_CONTROL + "heat-circ-program-6"; + public static final String CHANNEL_CONTROL_HEATCIRCPROGRAM7 = GROUP_CONTROL + "heat-circ-program-7"; + public static final String CHANNEL_CONTROL_HEATCIRCPROGRAM8 = GROUP_CONTROL + "heat-circ-program-8"; + public static final String CHANNEL_CONTROL_WWHEAT0 = GROUP_CONTROL + "ww-heat-0"; + public static final String CHANNEL_CONTROL_WWHEAT1 = GROUP_CONTROL + "ww-heat-1"; + public static final String CHANNEL_CONTROL_WWHEAT2 = GROUP_CONTROL + "ww-heat-2"; + public static final String CHANNEL_CONTROL_EXTRAWWHEAT0 = GROUP_CONTROL + "extra-ww-heat-0"; + public static final String CHANNEL_CONTROL_EXTRAWWHEAT1 = GROUP_CONTROL + "extra-ww-heat-1"; + public static final String CHANNEL_CONTROL_EXTRAWWHEAT2 = GROUP_CONTROL + "extra-ww-heat-2"; + + public static final List STATIC_CHANNEL_IDS = Arrays.asList(CHANNEL_CONTROL_BOILERAPPROVAL, + CHANNEL_CONTROL_PROGRAM, CHANNEL_CONTROL_HEATCIRCPROGRAM0, CHANNEL_CONTROL_HEATCIRCPROGRAM1, + CHANNEL_CONTROL_HEATCIRCPROGRAM2, CHANNEL_CONTROL_HEATCIRCPROGRAM3, CHANNEL_CONTROL_HEATCIRCPROGRAM4, + CHANNEL_CONTROL_HEATCIRCPROGRAM5, CHANNEL_CONTROL_HEATCIRCPROGRAM6, CHANNEL_CONTROL_HEATCIRCPROGRAM7, + CHANNEL_CONTROL_HEATCIRCPROGRAM8, CHANNEL_CONTROL_WWHEAT0, CHANNEL_CONTROL_WWHEAT1, CHANNEL_CONTROL_WWHEAT2, + CHANNEL_CONTROL_EXTRAWWHEAT0, CHANNEL_CONTROL_EXTRAWWHEAT1, CHANNEL_CONTROL_EXTRAWWHEAT2); - public static final List STATIC_CHANNEL_IDS = Arrays.asList(CHANNEL_CONTROLBOILERAPPROVAL, - CHANNEL_CONTROLPROGRAM, CHANNEL_CONTROLHEATCIRCPROGRAM0, CHANNEL_CONTROLHEATCIRCPROGRAM1, - CHANNEL_CONTROLHEATCIRCPROGRAM2, CHANNEL_CONTROLHEATCIRCPROGRAM3, CHANNEL_CONTROLHEATCIRCPROGRAM4, - CHANNEL_CONTROLHEATCIRCPROGRAM5, CHANNEL_CONTROLHEATCIRCPROGRAM6, CHANNEL_CONTROLHEATCIRCPROGRAM7, - CHANNEL_CONTROLHEATCIRCPROGRAM8, CHANNEL_CONTROLWWHEAT0, CHANNEL_CONTROLWWHEAT1, CHANNEL_CONTROLWWHEAT2, - CHANNEL_CONTROLEXTRAWWHEAT0, CHANNEL_CONTROLEXTRAWWHEAT1, CHANNEL_CONTROLEXTRAWWHEAT2); + public static final List STATIC_CHANNEL_IDS_WOBOILERAPP = Arrays.asList(CHANNEL_CONTROL_PROGRAM, + CHANNEL_CONTROL_HEATCIRCPROGRAM0, CHANNEL_CONTROL_HEATCIRCPROGRAM1, CHANNEL_CONTROL_HEATCIRCPROGRAM2, + CHANNEL_CONTROL_HEATCIRCPROGRAM3, CHANNEL_CONTROL_HEATCIRCPROGRAM4, CHANNEL_CONTROL_HEATCIRCPROGRAM5, + CHANNEL_CONTROL_HEATCIRCPROGRAM6, CHANNEL_CONTROL_HEATCIRCPROGRAM7, CHANNEL_CONTROL_HEATCIRCPROGRAM8, + CHANNEL_CONTROL_WWHEAT0, CHANNEL_CONTROL_WWHEAT1, CHANNEL_CONTROL_WWHEAT2, CHANNEL_CONTROL_EXTRAWWHEAT0, + CHANNEL_CONTROL_EXTRAWWHEAT1, CHANNEL_CONTROL_EXTRAWWHEAT2); - public static final List STATIC_CHANNEL_IDS_WOBOILERAPP = Arrays.asList(CHANNEL_CONTROLPROGRAM, - CHANNEL_CONTROLHEATCIRCPROGRAM0, CHANNEL_CONTROLHEATCIRCPROGRAM1, CHANNEL_CONTROLHEATCIRCPROGRAM2, - CHANNEL_CONTROLHEATCIRCPROGRAM3, CHANNEL_CONTROLHEATCIRCPROGRAM4, CHANNEL_CONTROLHEATCIRCPROGRAM5, - CHANNEL_CONTROLHEATCIRCPROGRAM6, CHANNEL_CONTROLHEATCIRCPROGRAM7, CHANNEL_CONTROLHEATCIRCPROGRAM8, - CHANNEL_CONTROLWWHEAT0, CHANNEL_CONTROLWWHEAT1, CHANNEL_CONTROLWWHEAT2, CHANNEL_CONTROLEXTRAWWHEAT0, - CHANNEL_CONTROLEXTRAWWHEAT1, CHANNEL_CONTROLEXTRAWWHEAT2); + public static final String GROUP_STATUS = "status#"; public static final String PARAMETER_BOILERAPPROVAL = "boilerApproval"; public static final String PARAMETER_PROGRAM = "program"; diff --git a/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticChannelTypeProvider.java b/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticChannelTypeProvider.java deleted file mode 100644 index 889bd2005ee72..0000000000000 --- a/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticChannelTypeProvider.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2010-2024 Contributors to the openHAB project - * - * See the NOTICE file(s) distributed with this work for additional - * information. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.openhab.binding.guntamatic.internal; - -import java.util.Collection; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.thing.type.ChannelType; -import org.openhab.core.thing.type.ChannelTypeBuilder; -import org.openhab.core.thing.type.ChannelTypeProvider; -import org.openhab.core.thing.type.ChannelTypeUID; -import org.openhab.core.thing.type.StateChannelTypeBuilder; -import org.openhab.core.types.StateDescriptionFragmentBuilder; -import org.osgi.service.component.annotations.Component; - -/** - * Provide channelTypes for Guntamatic Heating Systems - * - * @author Weger Michael - Initial contribution - */ -@Component(service = { ChannelTypeProvider.class, GuntamaticChannelTypeProvider.class }) -@NonNullByDefault -public class GuntamaticChannelTypeProvider implements ChannelTypeProvider { - private final Map channelTypes = new ConcurrentHashMap<>(); - - @Override - public Collection getChannelTypes(@Nullable Locale locale) { - return channelTypes.values(); - } - - @Override - public @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID, @Nullable Locale locale) { - return channelTypes.get(channelTypeUID.getAsString()); // returns null if not found - } - - public void addChannelType(ChannelTypeUID channelTypeUID, String label, String itemType, String description, - boolean advanced, String pattern) { - StateDescriptionFragmentBuilder stateDescriptionFragmentBuilder = StateDescriptionFragmentBuilder.create() - .withReadOnly(true); - if (!pattern.isEmpty()) { - stateDescriptionFragmentBuilder.withPattern(pattern); - } - StateChannelTypeBuilder stateChannelTypeBuilder = ChannelTypeBuilder.state(channelTypeUID, label, itemType) - .withDescription(description).isAdvanced(advanced) - .withStateDescriptionFragment(stateDescriptionFragmentBuilder.build()); - channelTypes.put(channelTypeUID.getAsString(), stateChannelTypeBuilder.build()); - } -} diff --git a/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticDynamicTypeProvider.java b/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticDynamicTypeProvider.java new file mode 100644 index 0000000000000..4c8d3a7284727 --- /dev/null +++ b/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticDynamicTypeProvider.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2010-2024 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.guntamatic.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.storage.StorageService; +import org.openhab.core.thing.ThingUID; +import org.openhab.core.thing.binding.AbstractStorageBasedTypeProvider; +import org.openhab.core.thing.type.ChannelType; +import org.openhab.core.thing.type.ChannelTypeProvider; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +/** + * The {@link GuntamaticDynamicTypeProvider} is an instance of a {@link AbstractStorageBasedTypeProvider} for the + * Guntamatic Binding + * + * @author Weger Michael - Initial contribution + */ +@Component(service = { GuntamaticDynamicTypeProvider.class, ChannelTypeProvider.class }) +@NonNullByDefault +public class GuntamaticDynamicTypeProvider extends AbstractStorageBasedTypeProvider { + + @Activate + public GuntamaticDynamicTypeProvider(@Reference StorageService storageService) { + super(storageService); + } + + public void removeChannelTypesForThing(ThingUID uid) { + String thingUid = uid.getAsString() + ":"; + getChannelTypes(null).stream().map(ChannelType::getUID).filter(c -> c.getAsString().startsWith(thingUid)) + .forEach(this::removeChannelType); + } +} diff --git a/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticHandler.java b/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticHandler.java index 8ede496ea7ef7..0d4ee55eb0e28 100644 --- a/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticHandler.java +++ b/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticHandler.java @@ -52,10 +52,13 @@ import org.openhab.core.thing.binding.builder.ChannelBuilder; import org.openhab.core.thing.binding.builder.ThingBuilder; import org.openhab.core.thing.type.ChannelKind; +import org.openhab.core.thing.type.ChannelType; +import org.openhab.core.thing.type.ChannelTypeBuilder; import org.openhab.core.thing.type.ChannelTypeUID; import org.openhab.core.types.Command; import org.openhab.core.types.RefreshType; import org.openhab.core.types.State; +import org.openhab.core.types.StateDescriptionFragmentBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -101,16 +104,16 @@ public class GuntamaticHandler extends BaseThingHandler { private List staticChannelIDs; private GuntamaticConfiguration config = new GuntamaticConfiguration(); private Boolean channelsInitialized = false; - private GuntamaticChannelTypeProvider guntamaticChannelTypeProvider; + private GuntamaticDynamicTypeProvider typeProvider; private Map channels = new HashMap<>(); private Map types = new HashMap<>(); private Map> units = new HashMap<>(); - public GuntamaticHandler(Thing thing, HttpClient httpClient, - GuntamaticChannelTypeProvider guntamaticChannelTypeProvider, List staticChannelIDs) { + public GuntamaticHandler(Thing thing, HttpClient httpClient, GuntamaticDynamicTypeProvider typeProvider, + List staticChannelIDs) { super(thing); this.httpClient = httpClient; - this.guntamaticChannelTypeProvider = guntamaticChannelTypeProvider; + this.typeProvider = typeProvider; this.staticChannelIDs = staticChannelIDs; } @@ -122,11 +125,11 @@ public void handleCommand(ChannelUID channelUID, Command command) { Map map; String channelID = channelUID.getId(); switch (channelID) { - case CHANNEL_CONTROLBOILERAPPROVAL: + case CHANNEL_CONTROL_BOILERAPPROVAL: param = getThing().getProperties().get(PARAMETER_BOILERAPPROVAL); map = MAP_COMMAND_PARAM_APPROVAL; break; - case CHANNEL_CONTROLPROGRAM: + case CHANNEL_CONTROL_PROGRAM: param = getThing().getProperties().get(PARAMETER_PROGRAM); ThingTypeUID thingTypeUID = getThing().getThingTypeUID(); @@ -137,31 +140,30 @@ public void handleCommand(ChannelUID channelUID, Command command) { } else { map = MAP_COMMAND_PARAM_PROG_WOMANU; } - break; - case CHANNEL_CONTROLHEATCIRCPROGRAM0: - case CHANNEL_CONTROLHEATCIRCPROGRAM1: - case CHANNEL_CONTROLHEATCIRCPROGRAM2: - case CHANNEL_CONTROLHEATCIRCPROGRAM3: - case CHANNEL_CONTROLHEATCIRCPROGRAM4: - case CHANNEL_CONTROLHEATCIRCPROGRAM5: - case CHANNEL_CONTROLHEATCIRCPROGRAM6: - case CHANNEL_CONTROLHEATCIRCPROGRAM7: - case CHANNEL_CONTROLHEATCIRCPROGRAM8: + case CHANNEL_CONTROL_HEATCIRCPROGRAM0: + case CHANNEL_CONTROL_HEATCIRCPROGRAM1: + case CHANNEL_CONTROL_HEATCIRCPROGRAM2: + case CHANNEL_CONTROL_HEATCIRCPROGRAM3: + case CHANNEL_CONTROL_HEATCIRCPROGRAM4: + case CHANNEL_CONTROL_HEATCIRCPROGRAM5: + case CHANNEL_CONTROL_HEATCIRCPROGRAM6: + case CHANNEL_CONTROL_HEATCIRCPROGRAM7: + case CHANNEL_CONTROL_HEATCIRCPROGRAM8: param = getThing().getProperties().get(PARAMETER_HEATCIRCPROGRAM).replace("x", channelID.substring(channelID.length() - 1)); map = MAP_COMMAND_PARAM_HC; break; - case CHANNEL_CONTROLWWHEAT0: - case CHANNEL_CONTROLWWHEAT1: - case CHANNEL_CONTROLWWHEAT2: + case CHANNEL_CONTROL_WWHEAT0: + case CHANNEL_CONTROL_WWHEAT1: + case CHANNEL_CONTROL_WWHEAT2: param = getThing().getProperties().get(PARAMETER_WWHEAT).replace("x", channelID.substring(channelID.length() - 1)); map = MAP_COMMAND_PARAM_WW; break; - case CHANNEL_CONTROLEXTRAWWHEAT0: - case CHANNEL_CONTROLEXTRAWWHEAT1: - case CHANNEL_CONTROLEXTRAWWHEAT2: + case CHANNEL_CONTROL_EXTRAWWHEAT0: + case CHANNEL_CONTROL_EXTRAWWHEAT1: + case CHANNEL_CONTROL_EXTRAWWHEAT2: param = getThing().getProperties().get(PARAMETER_EXTRAWWHEAT).replace("x", channelID.substring(channelID.length() - 1)); map = MAP_COMMAND_PARAM_WW; @@ -197,8 +199,9 @@ private void parseAndUpdate(String html) { String channel = channels.get(i); Unit unit = units.get(i); if ((channel != null) && (i < daqdata.length)) { + String channelId = GROUP_STATUS + String.format("%03d", i) + "-" + channel; String value = daqdata[i]; - Channel chn = thing.getChannel(channel); + Channel chn = thing.getChannel(channelId); if ((chn != null) && (value != null)) { value = value.trim(); String typeName = chn.getAcceptedItemType(); @@ -234,7 +237,7 @@ private void parseAndUpdate(String html) { } } if (newState != null) { - updateState(channel, newState); + updateState(channelId, newState); } else { logger.warn("Data for unknown typeName '{}' or unknown unit received", typeName); } @@ -268,6 +271,9 @@ private void parseAndJsonInit(String html) { private void parseAndInit(String html) { String[] daqdesc = html.split("\\n"); List channelList = new ArrayList<>(); + for (Channel chn : thing.getChannels()) { + logger.debug("Static Channel '{}' present", chn.getUID()); + } // make sure that static channels are present for (String channelID : staticChannelIDs) { @@ -285,67 +291,76 @@ private void parseAndInit(String html) { String label = param[0].replace("C02", "CO2"); if (!"reserved".equals(label)) { - String channel = toLowerCamelCase(replaceUmlaut(label)); + String channel = toLowerCaseHyphen(replaceUmlaut(label)); label = label.substring(0, 1).toUpperCase() + label.substring(1); String unitStr = ((param.length == 1) || param[1].isBlank()) ? "" : param[1].trim(); Unit unit = guessUnit(unitStr); - boolean channelInitialized = channels.containsValue(channel); - if (!channelInitialized) { - String itemType; - String pattern; - String type = types.get(i); - if (type == null) { - type = ""; - } + String itemType; + String pattern; + String type = types.get(i); + if (type == null) { + type = ""; + } - if ("boolean".equals(type)) { - itemType = CoreItemFactory.SWITCH; - pattern = ""; - } else if ("integer".equals(type)) { - itemType = guessItemType(unit); - pattern = "%d"; - if (unit != null) { - pattern += " %unit%"; - } - } else if ("float".equals(type)) { + if ("boolean".equals(type)) { + itemType = CoreItemFactory.SWITCH; + pattern = ""; + } else if ("integer".equals(type)) { + itemType = guessItemType(unit); + pattern = "%d"; + if (unit != null) { + pattern += " %unit%"; + } + } else if ("float".equals(type)) { + itemType = guessItemType(unit); + pattern = "%.2f"; + if (unit != null) { + pattern += " %unit%"; + } + } else if ("string".equals(type)) { + itemType = CoreItemFactory.STRING; + pattern = "%s"; + } else { + if (unitStr.isBlank()) { + itemType = CoreItemFactory.STRING; + pattern = "%s"; + } else { itemType = guessItemType(unit); pattern = "%.2f"; if (unit != null) { pattern += " %unit%"; } - } else if ("string".equals(type)) { - itemType = CoreItemFactory.STRING; - pattern = "%s"; - } else { - if (unitStr.isBlank()) { - itemType = CoreItemFactory.STRING; - pattern = "%s"; - } else { - itemType = guessItemType(unit); - pattern = "%.2f"; - if (unit != null) { - pattern += " %unit%"; - } - } } + } - ChannelTypeUID channelTypeUID = new ChannelTypeUID(BINDING_ID, channel); - guntamaticChannelTypeProvider.addChannelType(channelTypeUID, channel, itemType, - "Guntamatic " + label, false, pattern); - Channel newChannel = ChannelBuilder.create(new ChannelUID(thing.getUID(), channel), itemType) - .withType(channelTypeUID).withKind(ChannelKind.STATE).withLabel(label).build(); - channelList.add(newChannel); - channels.put(i, channel); - if (unit != null) { - units.put(i, unit); - } + String channelId = String.format("%03d", i) + "-" + channel; + ChannelTypeUID channelTypeUID = new ChannelTypeUID(BINDING_ID, channelId); + StateDescriptionFragmentBuilder stateDescriptionFragmentBuilder = StateDescriptionFragmentBuilder + .create().withReadOnly(true); + if (!pattern.isEmpty()) { + stateDescriptionFragmentBuilder.withPattern(pattern); + } - logger.debug( - "Supported Channel: Idx: '{}', Name: '{}'/'{}', Type: '{}'/'{}', Unit: '{}', Pattern '{}' ", - String.format("%03d", i), label, channel, type, itemType, unitStr, pattern); + ChannelType channelType = ChannelTypeBuilder.state(channelTypeUID, label, itemType) + .withDescription("Guntamatic " + label) + .withStateDescriptionFragment(stateDescriptionFragmentBuilder.build()).build(); + + typeProvider.putChannelType(channelType); + + Channel newChannel = ChannelBuilder + .create(new ChannelUID(thing.getUID(), GROUP_STATUS + channelId), itemType) + .withType(channelTypeUID).withKind(ChannelKind.STATE).withLabel(label).build(); + channelList.add(newChannel); + channels.put(i, channel); + if (unit != null) { + units.put(i, unit); } + + logger.debug( + "Supported Channel: Idx: '{}', Name: '{}'/'{}', Type: '{}'/'{}', Unit: '{}', Pattern '{}' ", + String.format("%03d", i), label, GROUP_STATUS + channelId, type, itemType, unitStr, pattern); } } ThingBuilder thingBuilder = editThing(); @@ -385,28 +400,14 @@ private static String replaceUmlaut(String input) { return output; } - private String toLowerCamelCase(String input) { - char delimiter = ' '; - String output = input.replace("´", "").replaceAll("[^\\w]", String.valueOf(delimiter)); - - StringBuilder builder = new StringBuilder(); - boolean nextCharLow = true; - - for (int i = 0; i < output.length(); i++) { - char currentChar = output.charAt(i); - if (delimiter == currentChar) { - nextCharLow = false; - } else if (nextCharLow) { - builder.append(Character.toLowerCase(currentChar)); - } else { - builder.append(Character.toUpperCase(currentChar)); - nextCharLow = true; - } - } - return builder.toString(); + private String toLowerCaseHyphen(String input) { + return input.replaceAll("[^a-zA-Z0-9\\s]", "").trim().replaceAll("([a-z])([A-Z0-9])", "$1-$2") + .replaceAll("\\s+", "-").toLowerCase(); } private @Nullable String sendGetRequest(String url, String... params) { + logger.debug("sendGetRequest '{}'", url); + String errorReason = ""; String req = "http://" + config.hostname + url; @@ -436,13 +437,13 @@ private String toLowerCamelCase(String input) { String response = new String(contentResponse.getContent(), Charset.forName(config.encoding)); if (url.equals(DAQEXTDESC_URL)) { parseAndJsonInit(response); - } else if (url.equals(DAQDATA_URL)) { - parseAndUpdate(response); } else if (url.equals(DAQDESC_URL)) { parseAndInit(response); + } else if (url.equals(DAQDATA_URL)) { + parseAndUpdate(response); } else { - logger.debug(req); - // PARSET_URL via return + logger.debug("parset request: {}", req); + // PARSET_URL request is handled via return value only } return response; } catch (IllegalArgumentException e) { @@ -471,7 +472,10 @@ private void pollGuntamatic() { sendGetRequest(DAQEXTDESC_URL); } sendGetRequest(DAQDESC_URL); - } else { + } + + // above intialization usually changes channelsInitialized to TRUE + if (channelsInitialized) { sendGetRequest(DAQDATA_URL); } } @@ -497,4 +501,10 @@ public void dispose() { } channelsInitialized = false; } + + @Override + public void handleRemoval() { + typeProvider.removeChannelTypesForThing(getThing().getUID()); + super.handleRemoval(); + } } diff --git a/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticHandlerFactory.java b/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticHandlerFactory.java index 95d657361e256..c822900a69672 100644 --- a/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticHandlerFactory.java +++ b/bundles/org.openhab.binding.guntamatic/src/main/java/org/openhab/binding/guntamatic/internal/GuntamaticHandlerFactory.java @@ -45,13 +45,13 @@ public class GuntamaticHandlerFactory extends BaseThingHandlerFactory { THING_TYPE_GENERIC); private final HttpClient httpClient; - private GuntamaticChannelTypeProvider guntamaticChannelTypeProvider; + private GuntamaticDynamicTypeProvider dynamicTypeProvider; @Activate public GuntamaticHandlerFactory(@Reference HttpClientFactory httpClientFactory, - @Reference GuntamaticChannelTypeProvider guntamaticChannelTypeProvider) { + @Reference GuntamaticDynamicTypeProvider dynamicTypeProvider) { this.httpClient = httpClientFactory.getCommonHttpClient(); - this.guntamaticChannelTypeProvider = guntamaticChannelTypeProvider; + this.dynamicTypeProvider = dynamicTypeProvider; } @Override @@ -73,7 +73,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { } if (supportsThingType(thingTypeUID)) { - return new GuntamaticHandler(thing, httpClient, guntamaticChannelTypeProvider, staticChannelIDs); + return new GuntamaticHandler(thing, httpClient, dynamicTypeProvider, staticChannelIDs); } return null; diff --git a/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/i18n/guntamatic.properties b/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/i18n/guntamatic.properties index e7ea9ea912209..1e1e6621c091e 100644 --- a/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/i18n/guntamatic.properties +++ b/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/i18n/guntamatic.properties @@ -7,6 +7,104 @@ addon.guntamatic.description = Binding for Guntamatic Heating Systems. thing-type.guntamatic.biocom.label = Guntamatic Biocom thing-type.guntamatic.biocom.description = Guntamatic Biocom Pellets Heating System. Untested! Please provide Feedback! +thing-type.guntamatic.biosmart.label = Guntamatic Biosmart +thing-type.guntamatic.biosmart.description = Guntamatic Biosmart Log Heating System +thing-type.guntamatic.biostar.label = Guntamatic Biostar +thing-type.guntamatic.biostar.description = Guntamatic Biostar Pellets Heating System +thing-type.guntamatic.generic.label = Guntamatic Generic +thing-type.guntamatic.generic.description = Generic Guntamatic Heating System. Use this type, if your Heating System is none of the others. Please provide Feedback! +thing-type.guntamatic.powerchip.label = Guntamatic Powerchip +thing-type.guntamatic.powerchip.description = Guntamatic Powerchip WoodChip Heating System +thing-type.guntamatic.powercorn.label = Guntamatic Powercorn +thing-type.guntamatic.powercorn.description = Guntamatic Powercorn EnergyGrain Heating System. Untested! Please provide Feedback! +thing-type.guntamatic.pro.label = Guntamatic Pro +thing-type.guntamatic.pro.description = Guntamatic Pro Pellets or WoodChip Heating System. Untested! Please provide Feedback! +thing-type.guntamatic.therm.label = Guntamatic Therm +thing-type.guntamatic.therm.description = Guntamatic Therm Pellets Heating System. Untested! Please provide Feedback! + +# thing types config + +thing-type.config.guntamatic.heatingsystem.encoding.label = Encoding +thing-type.config.guntamatic.heatingsystem.encoding.description = Code page used by the Guntamatic Heating System. Default: 'windows-1252' +thing-type.config.guntamatic.heatingsystem.hostname.label = Hostname +thing-type.config.guntamatic.heatingsystem.hostname.description = Hostname or IP address of the Guntamatic Heating System +thing-type.config.guntamatic.heatingsystem.key.label = Key +thing-type.config.guntamatic.heatingsystem.key.description = Optional, but required to read protected parameters and to control the Guntamatic Heating System. The key needs to be reqested from Guntamatic support. +thing-type.config.guntamatic.heatingsystem.refreshInterval.label = Refresh Interval +thing-type.config.guntamatic.heatingsystem.refreshInterval.description = Interval the Guntamatic Heating System is polled in seconds. Default: 60s + +# channel group types + +channel-group-type.guntamatic.controlGroupType.label = Control +channel-group-type.guntamatic.controlGroupType.channel.boilerApproval.label = Set Boiler Approval +channel-group-type.guntamatic.controlGroupType.channel.extraWwHeat0.label = Trigger Extra Warm Water Circle 0 +channel-group-type.guntamatic.controlGroupType.channel.extraWwHeat1.label = Trigger Extra Warm Water Circle 1 +channel-group-type.guntamatic.controlGroupType.channel.extraWwHeat2.label = Trigger Extra Warm Water Circle 2 +channel-group-type.guntamatic.controlGroupType.channel.heatCircProgram0.label = Set Heat Circle 0 Program +channel-group-type.guntamatic.controlGroupType.channel.heatCircProgram1.label = Set Heat Circle 1 Program +channel-group-type.guntamatic.controlGroupType.channel.heatCircProgram2.label = Set Heat Circle 2 Program +channel-group-type.guntamatic.controlGroupType.channel.heatCircProgram3.label = Set Heat Circle 3 Program +channel-group-type.guntamatic.controlGroupType.channel.heatCircProgram4.label = Set Heat Circle 4 Program +channel-group-type.guntamatic.controlGroupType.channel.heatCircProgram5.label = Set Heat Circle 5 Program +channel-group-type.guntamatic.controlGroupType.channel.heatCircProgram6.label = Set Heat Circle 6 Program +channel-group-type.guntamatic.controlGroupType.channel.heatCircProgram7.label = Set Heat Circle 7 Program +channel-group-type.guntamatic.controlGroupType.channel.heatCircProgram8.label = Set Heat Circle 8 Program +channel-group-type.guntamatic.controlGroupType.channel.program.label = Set Program +channel-group-type.guntamatic.controlGroupType.channel.wwHeat0.label = Trigger Warm Water Circle 0 +channel-group-type.guntamatic.controlGroupType.channel.wwHeat1.label = Trigger Warm Water Circle 1 +channel-group-type.guntamatic.controlGroupType.channel.wwHeat2.label = Trigger Warm Water Circle 2 +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.label = Control +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.extraWwHeat0.label = Trigger Extra Warm Water Circle 0 +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.extraWwHeat1.label = Trigger Extra Warm Water Circle 1 +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.extraWwHeat2.label = Trigger Extra Warm Water Circle 2 +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.heatCircProgram0.label = Set Heat Circle 0 Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.heatCircProgram1.label = Set Heat Circle 1 Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.heatCircProgram2.label = Set Heat Circle 2 Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.heatCircProgram3.label = Set Heat Circle 3 Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.heatCircProgram4.label = Set Heat Circle 4 Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.heatCircProgram5.label = Set Heat Circle 5 Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.heatCircProgram6.label = Set Heat Circle 6 Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.heatCircProgram7.label = Set Heat Circle 7 Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.heatCircProgram8.label = Set Heat Circle 8 Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.program.label = Set Program +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.wwHeat0.label = Trigger Warm Water Circle 0 +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.wwHeat1.label = Trigger Warm Water Circle 1 +channel-group-type.guntamatic.controlGroupTypeWOBoilerApp.channel.wwHeat2.label = Trigger Warm Water Circle 2 +channel-group-type.guntamatic.statusGroupType.label = Status + +# channel types + +channel-type.guntamatic.controlBoilerApproval.label = Set Boiler Approval +channel-type.guntamatic.controlBoilerApproval.description = Set Boiler Approval of the Guntamatic Heating System (AUTO, OFF, ON) +channel-type.guntamatic.controlBoilerApproval.state.option.0 = AUTO +channel-type.guntamatic.controlBoilerApproval.state.option.1 = OFF +channel-type.guntamatic.controlBoilerApproval.state.option.2 = ON +channel-type.guntamatic.controlExtraWwHeat.label = Trigger Extra Warm Water Circle +channel-type.guntamatic.controlExtraWwHeat.description = Trigger Extra Warm Water Circle of the Guntamatic Heating System (RECHARGE) +channel-type.guntamatic.controlExtraWwHeat.state.option.0 = RECHARGE +channel-type.guntamatic.controlHeatCircProgram.label = Set Heat Circle Program +channel-type.guntamatic.controlHeatCircProgram.description = Set Heat Circle of the Guntamatic Heating System (OFF, NORMAL, HEAT, LOWER) +channel-type.guntamatic.controlHeatCircProgram.state.option.0 = OFF +channel-type.guntamatic.controlHeatCircProgram.state.option.1 = NORMAL +channel-type.guntamatic.controlHeatCircProgram.state.option.2 = HEAT +channel-type.guntamatic.controlHeatCircProgram.state.option.3 = LOWER +channel-type.guntamatic.controlProgram.label = Set Program +channel-type.guntamatic.controlProgram.description = Set Program of the Guntamatic Heating System (OFF, NORMAL, WARMWATER, MANUAL) +channel-type.guntamatic.controlProgram.state.option.0 = OFF +channel-type.guntamatic.controlProgram.state.option.1 = NORMAL +channel-type.guntamatic.controlProgram.state.option.2 = WARMWATER +channel-type.guntamatic.controlProgram.state.option.8 = MANUAL +channel-type.guntamatic.controlProgramWOManu.label = Set Program +channel-type.guntamatic.controlProgramWOManu.description = Set Program of the Guntamatic Heating System (OFF, NORMAL, WARMWATER) +channel-type.guntamatic.controlProgramWOManu.state.option.0 = OFF +channel-type.guntamatic.controlProgramWOManu.state.option.1 = NORMAL +channel-type.guntamatic.controlProgramWOManu.state.option.2 = WARMWATER +channel-type.guntamatic.controlWwHeat.label = Trigger Warm Water Circle +channel-type.guntamatic.controlWwHeat.description = Trigger Warm Water Circle of the Guntamatic Heating System (RECHARGE) +channel-type.guntamatic.controlWwHeat.state.option.0 = RECHARGE + +# thing types + thing-type.guntamatic.biocom.channel.controlBoilerApproval.label = Set Boiler Approval thing-type.guntamatic.biocom.channel.controlExtraWwHeat0.label = Trigger Extra Warm Water Circle 0 thing-type.guntamatic.biocom.channel.controlExtraWwHeat1.label = Trigger Extra Warm Water Circle 1 @@ -24,8 +122,6 @@ thing-type.guntamatic.biocom.channel.controlProgram.label = Set Program thing-type.guntamatic.biocom.channel.controlWwHeat0.label = Trigger Warm Water Circle 0 thing-type.guntamatic.biocom.channel.controlWwHeat1.label = Trigger Warm Water Circle 1 thing-type.guntamatic.biocom.channel.controlWwHeat2.label = Trigger Warm Water Circle 2 -thing-type.guntamatic.biosmart.label = Guntamatic Biosmart -thing-type.guntamatic.biosmart.description = Guntamatic Biosmart Log Heating System thing-type.guntamatic.biosmart.channel.controlExtraWwHeat0.label = Trigger Extra Warm Water Circle 0 thing-type.guntamatic.biosmart.channel.controlExtraWwHeat1.label = Trigger Extra Warm Water Circle 1 thing-type.guntamatic.biosmart.channel.controlExtraWwHeat2.label = Trigger Extra Warm Water Circle 2 @@ -42,8 +138,6 @@ thing-type.guntamatic.biosmart.channel.controlProgram.label = Set Program thing-type.guntamatic.biosmart.channel.controlWwHeat0.label = Trigger Warm Water Circle 0 thing-type.guntamatic.biosmart.channel.controlWwHeat1.label = Trigger Warm Water Circle 1 thing-type.guntamatic.biosmart.channel.controlWwHeat2.label = Trigger Warm Water Circle 2 -thing-type.guntamatic.biostar.label = Guntamatic Biostar -thing-type.guntamatic.biostar.description = Guntamatic Biostar Pellets Heating System thing-type.guntamatic.biostar.channel.controlBoilerApproval.label = Set Boiler Approval thing-type.guntamatic.biostar.channel.controlExtraWwHeat0.label = Trigger Extra Warm Water Circle 0 thing-type.guntamatic.biostar.channel.controlExtraWwHeat1.label = Trigger Extra Warm Water Circle 1 @@ -61,8 +155,6 @@ thing-type.guntamatic.biostar.channel.controlProgram.label = Set Program thing-type.guntamatic.biostar.channel.controlWwHeat0.label = Trigger Warm Water Circle 0 thing-type.guntamatic.biostar.channel.controlWwHeat1.label = Trigger Warm Water Circle 1 thing-type.guntamatic.biostar.channel.controlWwHeat2.label = Trigger Warm Water Circle 2 -thing-type.guntamatic.generic.label = Guntamatic Generic -thing-type.guntamatic.generic.description = Generic Guntamatic Heating System. Use this type, if your Heating System is none of the others. Please provide Feedback! thing-type.guntamatic.generic.channel.controlExtraWwHeat0.label = Trigger Extra Warm Water Circle 0 thing-type.guntamatic.generic.channel.controlExtraWwHeat1.label = Trigger Extra Warm Water Circle 1 thing-type.guntamatic.generic.channel.controlExtraWwHeat2.label = Trigger Extra Warm Water Circle 2 @@ -79,8 +171,6 @@ thing-type.guntamatic.generic.channel.controlProgram.label = Set Program thing-type.guntamatic.generic.channel.controlWwHeat0.label = Trigger Warm Water Circle 0 thing-type.guntamatic.generic.channel.controlWwHeat1.label = Trigger Warm Water Circle 1 thing-type.guntamatic.generic.channel.controlWwHeat2.label = Trigger Warm Water Circle 2 -thing-type.guntamatic.powerchip.label = Guntamatic Powerchip -thing-type.guntamatic.powerchip.description = Guntamatic Powerchip WoodChip Heating System thing-type.guntamatic.powerchip.channel.controlBoilerApproval.label = Set Boiler Approval thing-type.guntamatic.powerchip.channel.controlExtraWwHeat0.label = Trigger Extra Warm Water Circle 0 thing-type.guntamatic.powerchip.channel.controlExtraWwHeat1.label = Trigger Extra Warm Water Circle 1 @@ -98,8 +188,6 @@ thing-type.guntamatic.powerchip.channel.controlProgram.label = Set Program thing-type.guntamatic.powerchip.channel.controlWwHeat0.label = Trigger Warm Water Circle 0 thing-type.guntamatic.powerchip.channel.controlWwHeat1.label = Trigger Warm Water Circle 1 thing-type.guntamatic.powerchip.channel.controlWwHeat2.label = Trigger Warm Water Circle 2 -thing-type.guntamatic.powercorn.label = Guntamatic Powercorn -thing-type.guntamatic.powercorn.description = Guntamatic Powercorn EnergyGrain Heating System. Untested! Please provide Feedback! thing-type.guntamatic.powercorn.channel.controlBoilerApproval.label = Set Boiler Approval thing-type.guntamatic.powercorn.channel.controlExtraWwHeat0.label = Trigger Extra Warm Water Circle 0 thing-type.guntamatic.powercorn.channel.controlExtraWwHeat1.label = Trigger Extra Warm Water Circle 1 @@ -117,8 +205,6 @@ thing-type.guntamatic.powercorn.channel.controlProgram.label = Set Program thing-type.guntamatic.powercorn.channel.controlWwHeat0.label = Trigger Warm Water Circle 0 thing-type.guntamatic.powercorn.channel.controlWwHeat1.label = Trigger Warm Water Circle 1 thing-type.guntamatic.powercorn.channel.controlWwHeat2.label = Trigger Warm Water Circle 2 -thing-type.guntamatic.pro.label = Guntamatic Pro -thing-type.guntamatic.pro.description = Guntamatic Pro Pellets or WoodChip Heating System. Untested! Please provide Feedback! thing-type.guntamatic.pro.channel.controlBoilerApproval.label = Set Boiler Approval thing-type.guntamatic.pro.channel.controlExtraWwHeat0.label = Trigger Extra Warm Water Circle 0 thing-type.guntamatic.pro.channel.controlExtraWwHeat1.label = Trigger Extra Warm Water Circle 1 @@ -136,8 +222,6 @@ thing-type.guntamatic.pro.channel.controlProgram.label = Set Program thing-type.guntamatic.pro.channel.controlWwHeat0.label = Trigger Warm Water Circle 0 thing-type.guntamatic.pro.channel.controlWwHeat1.label = Trigger Warm Water Circle 1 thing-type.guntamatic.pro.channel.controlWwHeat2.label = Trigger Warm Water Circle 2 -thing-type.guntamatic.therm.label = Guntamatic Therm -thing-type.guntamatic.therm.description = Guntamatic Therm Pellets Heating System. Untested! Please provide Feedback! thing-type.guntamatic.therm.channel.controlBoilerApproval.label = Set Boiler Approval thing-type.guntamatic.therm.channel.controlExtraWwHeat0.label = Trigger Extra Warm Water Circle 0 thing-type.guntamatic.therm.channel.controlExtraWwHeat1.label = Trigger Extra Warm Water Circle 1 @@ -155,45 +239,3 @@ thing-type.guntamatic.therm.channel.controlProgram.label = Set Program thing-type.guntamatic.therm.channel.controlWwHeat0.label = Trigger Warm Water Circle 0 thing-type.guntamatic.therm.channel.controlWwHeat1.label = Trigger Warm Water Circle 1 thing-type.guntamatic.therm.channel.controlWwHeat2.label = Trigger Warm Water Circle 2 - -# thing types config - -thing-type.config.guntamatic.heatingsystem.encoding.label = Encoding -thing-type.config.guntamatic.heatingsystem.encoding.description = Code page used by the Guntamatic Heating System. Default: 'windows-1252' -thing-type.config.guntamatic.heatingsystem.hostname.label = Hostname -thing-type.config.guntamatic.heatingsystem.hostname.description = Hostname or IP address of the Guntamatic Heating System -thing-type.config.guntamatic.heatingsystem.key.label = Key -thing-type.config.guntamatic.heatingsystem.key.description = Optional, but required to read protected parameters and to control the Guntamatic Heating System. The key needs to be reqested from Guntamatic support. -thing-type.config.guntamatic.heatingsystem.refreshInterval.label = Refresh Interval -thing-type.config.guntamatic.heatingsystem.refreshInterval.description = Interval the Guntamatic Heating System is polled in seconds. Default: 60s - -# channel types - -channel-type.guntamatic.controlBoilerApproval.label = Set Boiler Approval -channel-type.guntamatic.controlBoilerApproval.description = Set Boiler Approval of the Guntamatic Heating System (AUTO, OFF, ON) -channel-type.guntamatic.controlBoilerApproval.state.option.0 = AUTO -channel-type.guntamatic.controlBoilerApproval.state.option.1 = OFF -channel-type.guntamatic.controlBoilerApproval.state.option.2 = ON -channel-type.guntamatic.controlExtraWwHeat.label = Trigger Extra Warm Water Circle -channel-type.guntamatic.controlExtraWwHeat.description = Trigger Extra Warm Water Circle of the Guntamatic Heating System (RECHARGE) -channel-type.guntamatic.controlExtraWwHeat.state.option.0 = RECHARGE -channel-type.guntamatic.controlHeatCircProgram.label = Set Heat Circle Program -channel-type.guntamatic.controlHeatCircProgram.description = Set Heat Circle of the Guntamatic Heating System (OFF, NORMAL, HEAT, LOWER) -channel-type.guntamatic.controlHeatCircProgram.state.option.0 = OFF -channel-type.guntamatic.controlHeatCircProgram.state.option.1 = NORMAL -channel-type.guntamatic.controlHeatCircProgram.state.option.2 = HEAT -channel-type.guntamatic.controlHeatCircProgram.state.option.3 = LOWER -channel-type.guntamatic.controlProgram.label = Set Program -channel-type.guntamatic.controlProgram.description = Set Program of the Guntamatic Heating System (OFF, NORMAL, WARMWATER, MANUAL) -channel-type.guntamatic.controlProgram.state.option.0 = OFF -channel-type.guntamatic.controlProgram.state.option.1 = NORMAL -channel-type.guntamatic.controlProgram.state.option.2 = WARMWATER -channel-type.guntamatic.controlProgram.state.option.8 = MANUAL -channel-type.guntamatic.controlProgramWOManu.label = Set Program -channel-type.guntamatic.controlProgramWOManu.description = Set Program of the Guntamatic Heating System (OFF, NORMAL, WARMWATER) -channel-type.guntamatic.controlProgramWOManu.state.option.0 = OFF -channel-type.guntamatic.controlProgramWOManu.state.option.1 = NORMAL -channel-type.guntamatic.controlProgramWOManu.state.option.2 = WARMWATER -channel-type.guntamatic.controlWwHeat.label = Trigger Warm Water Circle -channel-type.guntamatic.controlWwHeat.description = Trigger Warm Water Circle of the Guntamatic Heating System (RECHARGE) -channel-type.guntamatic.controlWwHeat.state.option.0 = RECHARGE diff --git a/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/thing/thing-types.xml index 676cb34deb504..c717018341343 100644 --- a/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/thing/thing-types.xml @@ -5,536 +5,280 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - Guntamatic Biostar Pellets Heating System - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + K0010 PR001 HKx01 BKx06 ZKx06 + 1 - + Guntamatic Biosmart Log Heating System - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + PR001 HKx01 BKx06 ZKx06 + 1 - + Guntamatic Powerchip WoodChip Heating System - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + PK002 PR001 HKx01 BKx06 ZKx06 + 1 - + Guntamatic Powercorn EnergyGrain Heating System. Untested! Please provide Feedback! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + PK002 PR001 HKx01 BKx06 ZKx06 + 1 - + Guntamatic Biocom Pellets Heating System. Untested! Please provide Feedback! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + PK002 PR001 HKx01 BKx06 ZKx06 + 1 - + Guntamatic Pro Pellets or WoodChip Heating System. Untested! Please provide Feedback! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + PK002 PR001 HKx01 BKx06 ZKx06 + 1 - + Guntamatic Therm Pellets Heating System. Untested! Please provide Feedback! + + + + + + + K0010 + PR001 + HKx01 + BKx06 + ZKx06 + 1 + + + + + + + Generic Guntamatic Heating System. Use this type, if your Heating System is none of the others. Please + provide Feedback! + + + + + + + + PR001 + HKx01 + BKx06 + ZKx06 + 1 + + + + + + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - K0010 - PR001 - HKx01 - BKx06 - ZKx06 - - - - - - - Generic Guntamatic Heating System. Use this type, if your Heating System is none of the others. Please - provide Feedback! + + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - PR001 - HKx01 - BKx06 - ZKx06 - - - + + + + + - + String Set Program of the Guntamatic Heating System (OFF, NORMAL, WARMWATER, MANUAL) @@ -547,7 +291,7 @@ - + String Set Program of the Guntamatic Heating System (OFF, NORMAL, WARMWATER) @@ -559,7 +303,7 @@ - + String Set Boiler Approval of the Guntamatic Heating System (AUTO, OFF, ON) @@ -571,10 +315,10 @@ - + String - - Set Heat Circle of the Guntamatic Heating System (OFF, NORMAL, HEAT, LOWER) + + Set Heat Circuit of the Guntamatic Heating System (OFF, NORMAL, HEAT, LOWER) @@ -584,20 +328,20 @@ - + String - - Trigger Warm Water Circle of the Guntamatic Heating System (RECHARGE) + + Trigger Warm Water Circuit of the Guntamatic Heating System (RECHARGE) - + String - - Trigger Extra Warm Water Circle of the Guntamatic Heating System (RECHARGE) + + Trigger Extra Warm Water Circuit of the Guntamatic Heating System (RECHARGE) diff --git a/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/update/update.xml b/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/update/update.xml new file mode 100644 index 0000000000000..9bfa82a0fd392 --- /dev/null +++ b/bundles/org.openhab.binding.guntamatic/src/main/resources/OH-INF/update/update.xml @@ -0,0 +1,589 @@ + + + + + + + + + + + + + + + + + + + + + + + + + guntamatic:control-boiler-approval + + + guntamatic:control-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + + + + + + + + + + + + + + + + + + + + + + + guntamatic:control-program-wo-manu + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + + + + + + + + + + + + + + + + + + + + + + + + guntamatic:control-boiler-approval + + + guntamatic:control-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + + + + + + + + + + + + + + + + + + + + + + + + guntamatic:control-boiler-approval + + + guntamatic:control-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + + + + + + + + + + + + + + + + + + + + + + + + guntamatic:control-boiler-approval + + + guntamatic:control-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + + + + + + + + + + + + + + + + + + + + + + + + guntamatic:control-boiler-approval + + + guntamatic:control-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + + + + + + + + + + + + + + + + + + + + + + + + guntamatic:control-boiler-approval + + + guntamatic:control-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + + + + + + + + + + + + + + + + + + + + + + + guntamatic:control-program-wo-manu + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-heat-circ-program + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + guntamatic:control-extra-ww-heat + + + + diff --git a/bundles/org.openhab.binding.http/README.md b/bundles/org.openhab.binding.http/README.md index 4aae71596be70..9eda9e021bd46 100644 --- a/bundles/org.openhab.binding.http/README.md +++ b/bundles/org.openhab.binding.http/README.md @@ -159,7 +159,7 @@ All values that are not `upValue`, `downValue`, `stopValue`, `moveValue` are int ## URL Formatting -After concatenation of the `baseURL` and the `commandExtension` or the `stateExtension` (if provided) the URL is formatted using the [java.util.Formatter](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Formatter.html). +After concatenation of the `baseURL` and the `commandExtension` or the `stateExtension` (if provided) the URL is formatted using the [java.util.Formatter](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Formatter.html). The URL is used as format string and two parameters are added: - the current date (referenced as `%1$`) diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java index 641bab0fd4070..bd49dddf08180 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java @@ -22,8 +22,6 @@ import java.util.Objects; import java.util.Set; -import javax.measure.Unit; - import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hue.internal.api.dto.clip2.Alerts; @@ -97,23 +95,13 @@ public static Resource setAlert(Resource target, Command command, @Nullable Reso * @return the target resource. */ public static Resource setColorTemperatureAbsolute(Resource target, Command command, @Nullable Resource source) { - QuantityType mirek; - if (command instanceof QuantityType quantity) { - Unit unit = quantity.getUnit(); - if (Units.KELVIN.equals(unit)) { - mirek = quantity.toInvertibleUnit(Units.MIRED); - } else if (Units.MIRED.equals(unit)) { - mirek = quantity; - } else { - QuantityType kelvin = quantity.toInvertibleUnit(Units.KELVIN); - mirek = Objects.nonNull(kelvin) ? kelvin.toInvertibleUnit(Units.MIRED) : null; - } + QuantityType mirekQuantity = null; + if (command instanceof QuantityType genericQuantity) { + mirekQuantity = genericQuantity.toInvertibleUnit(Units.MIRED); } else if (command instanceof DecimalType decimal) { - mirek = QuantityType.valueOf(decimal.doubleValue(), Units.KELVIN).toInvertibleUnit(Units.MIRED); - } else { - mirek = null; + mirekQuantity = QuantityType.valueOf(decimal.intValue(), Units.KELVIN).toInvertibleUnit(Units.MIRED); } - if (Objects.nonNull(mirek)) { + if (Objects.nonNull(mirekQuantity)) { MirekSchema schema = target.getMirekSchema(); schema = Objects.nonNull(schema) ? schema : Objects.nonNull(source) ? source.getMirekSchema() : null; schema = Objects.nonNull(schema) ? schema : MirekSchema.DEFAULT_SCHEMA; @@ -121,7 +109,7 @@ public static Resource setColorTemperatureAbsolute(Resource target, Command comm colorTemperature = Objects.nonNull(colorTemperature) ? colorTemperature : new ColorTemperature(); double min = schema.getMirekMinimum(); double max = schema.getMirekMaximum(); - double val = Math.max(min, Math.min(max, mirek.doubleValue())); + double val = Math.max(min, Math.min(max, mirekQuantity.doubleValue())); target.setColorTemperature(colorTemperature.setMirek(val)); } return target; diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/HubIOStream.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/HubIOStream.java index 2c31660bc321b..0b9d48d8ce95e 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/HubIOStream.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/HubIOStream.java @@ -16,7 +16,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Objects; @@ -34,8 +33,6 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.openhab.binding.insteon.internal.utils.HexUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Implements IOStream for an Insteon Hub 2 @@ -47,10 +44,8 @@ */ @NonNullByDefault public class HubIOStream extends IOStream { - private final Logger logger = LoggerFactory.getLogger(HubIOStream.class); - - private static final String BS_START = ""; - private static final String BS_END = ""; + private static final String BUFFER_TAG_START = ""; + private static final String BUFFER_TAG_END = ""; private static final int REQUEST_TIMEOUT = 30; // in seconds private String host; @@ -61,7 +56,7 @@ public class HubIOStream extends IOStream { private ScheduledExecutorService scheduler; private @Nullable ScheduledFuture job; // index of the last byte we have read in the buffer - private int bufferIdx = -1; + private volatile int bufferIdx = -1; /** * Constructor @@ -84,14 +79,9 @@ public HubIOStream(String host, int port, String username, String password, int this.scheduler = scheduler; } - @Override - public boolean isOpen() { - return job != null; - } - @Override public boolean open() { - if (isOpen()) { + if (job != null) { logger.warn("hub stream is already open"); return false; } @@ -120,93 +110,65 @@ public boolean open() { @Override public void close() { + super.close(); + ScheduledFuture job = this.job; if (job != null) { job.cancel(true); this.job = null; } - - InputStream in = this.in; - if (in != null) { - try { - in.close(); - } catch (IOException e) { - logger.debug("failed to close input stream", e); - } - this.in = null; - } - - OutputStream out = this.out; - if (out != null) { - try { - out.close(); - } catch (IOException e) { - logger.debug("failed to close output stream", e); - } - this.out = null; - } } /** - * Fetches the latest status buffer from the Hub + * Returns the latest buffer from the Hub * - * @return string with status buffer + * @return the buffer string * @throws IOException */ - private synchronized String bufferStatus() throws IOException { + private String getBuffer() throws IOException { String result = getURL("/buffstatus.xml"); - int start = result.indexOf(BS_START); - if (start == -1) { - throw new IOException("malformed bufferstatus.xml"); - } - start += BS_START.length(); - - int end = result.indexOf(BS_END, start); - if (end == -1) { - throw new IOException("malformed bufferstatus.xml"); + int start = result.indexOf(BUFFER_TAG_START); + int end = result.indexOf(BUFFER_TAG_END, start); + if (start == -1 || end == -1) { + throw new IOException("malformed buffstatus.xml"); } + start += BUFFER_TAG_START.length(); return result.substring(start, end).trim(); } /** - * Sends command to Hub to clear the status buffer + * Clears the Hub buffer * * @throws IOException */ - private synchronized void clearBuffer() throws IOException { + private void clearBuffer() throws IOException { logger.trace("clearing buffer"); getURL("/1?XB=M=1"); bufferIdx = 0; } /** - * Sends Insteon message (byte array) as a readable ascii string to the Hub + * Sends a message to the Hub * - * @param msg byte array representing the Insteon message - * @throws IOException in case of I/O error + * @param b byte array representing the Insteon message + * @throws IOException */ - public synchronized void write(ByteBuffer msg) throws IOException { - poll(); // fetch the status buffer before we send out commands - - StringBuilder b = new StringBuilder(); - while (msg.remaining() > 0) { - b.append(String.format("%02x", msg.get())); - } - String hexMsg = b.toString(); - logger.trace("writing a message"); - getURL("/3?" + hexMsg + "=I=3"); + private void sendMessage(byte[] b) throws IOException { + poll(); // poll the status buffer before we send the message + logger.trace("sending a message"); + getURL("/3?" + HexUtils.getHexString(b) + "=I=3"); bufferIdx = 0; } /** - * Polls the Hub web interface to fetch the status buffer + * Polls the Hub buffer and add to input stream * - * @throws IOException if something goes wrong with I/O + * @throws IOException */ - private synchronized void poll() throws IOException { - String buffer = bufferStatus(); // fetch via http call + private void poll() throws IOException { + String buffer = getBuffer(); logger.trace("poll: {}", buffer); // The Hub maintains a ring buffer where the last two digits (in hex!) represent // the position of the last byte read. @@ -249,10 +211,9 @@ private synchronized void poll() throws IOException { logger.trace("no wrap: appending new data: {}", msg); } if (msg.length() != 0) { - byte[] array = HexUtils.toByteArray(msg.toString()); - ByteBuffer buf = ByteBuffer.wrap(array); + byte[] b = HexUtils.toByteArray(msg.toString()); if (in instanceof HubInputStream hubInput) { - hubInput.handle(buf); + hubInput.add(b); } else { logger.debug("hub input stream is null"); } @@ -310,10 +271,10 @@ public class HubInputStream extends InputStream { // A buffer to keep bytes while we are waiting for the inputstream to read private ReadByteBuffer buffer = new ReadByteBuffer(1024); - public void handle(ByteBuffer b) throws IOException { + public void add(byte[] b) throws IOException { // Make sure we cleanup as much space as possible buffer.makeCompact(); - buffer.add(b.array()); + buffer.add(b); } @Override @@ -342,18 +303,18 @@ public class HubOutputStream extends OutputStream { @Override public void write(int b) throws IOException { out.write(b); - flushBuffer(); + flush(); } @Override public void write(byte @Nullable [] b, int off, int len) throws IOException { out.write(b, off, len); - flushBuffer(); + flush(); } - private void flushBuffer() throws IOException { - ByteBuffer buffer = ByteBuffer.wrap(out.toByteArray()); - HubIOStream.this.write(buffer); + @Override + public void flush() throws IOException { + sendMessage(out.toByteArray()); out.reset(); } } diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/IOStream.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/IOStream.java index 1e2cb90646db5..a51a3ac69f0db 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/IOStream.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/IOStream.java @@ -26,6 +26,8 @@ import org.openhab.binding.insteon.internal.config.InsteonHub2Configuration; import org.openhab.binding.insteon.internal.config.InsteonPLMConfiguration; import org.openhab.core.io.transport.serial.SerialPortManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Abstract class for implementation for I/O stream with anything that looks @@ -38,6 +40,7 @@ */ @NonNullByDefault public abstract class IOStream { + protected final Logger logger = LoggerFactory.getLogger(getClass()); protected @Nullable InputStream in; protected @Nullable OutputStream out; @@ -47,20 +50,17 @@ public abstract class IOStream { * * @param b byte array (output) * @return number of bytes read + * @throws InterruptedException + * @throws IOException */ public int read(byte @Nullable [] b) throws InterruptedException, IOException { + InputStream in = this.in; + if (in == null) { + throw new IOException("input stream not defined"); + } int len = 0; while (len == 0) { - if (!isOpen()) { - throw new IOException("io stream not open"); - } - - InputStream in = this.in; - if (in != null) { - len = in.read(b); - } else { - throw new IOException("input stream not defined"); - } + len = in.read(b); if (Thread.interrupted()) { throw new InterruptedException(); @@ -77,27 +77,16 @@ public int read(byte @Nullable [] b) throws InterruptedException, IOException { * Writes data to IOStream * * @param b byte array to write + * @throws IOException */ - public void write(byte @Nullable [] b) throws InterruptedException, IOException { - if (!isOpen()) { - throw new IOException("io stream not open"); - } - + public void write(byte @Nullable [] b) throws IOException { OutputStream out = this.out; - if (out != null) { - out.write(b); - } else { + if (out == null) { throw new IOException("output stream not defined"); } + out.write(b); } - /** - * Returns if IOStream is open - * - * @return true if stream is open, false if not - */ - public abstract boolean isOpen(); - /** * Opens the IOStream * @@ -108,7 +97,27 @@ public void write(byte @Nullable [] b) throws InterruptedException, IOException /** * Closes the IOStream */ - public abstract void close(); + public void close() { + InputStream in = this.in; + if (in != null) { + try { + in.close(); + } catch (IOException e) { + logger.debug("failed to close input stream", e); + } + this.in = null; + } + + OutputStream out = this.out; + if (out != null) { + try { + out.close(); + } catch (IOException e) { + logger.debug("failed to close output stream", e); + } + this.out = null; + } + } /** * Creates an IOStream from an insteon bridge config object diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/LegacyPort.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/LegacyPort.java index 6d8ba6166db5c..4ed258a917946 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/LegacyPort.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/LegacyPort.java @@ -205,9 +205,7 @@ public void stop() { mdbb.stop(); } - if (ioStream.isOpen()) { - ioStream.close(); - } + ioStream.close(); ScheduledFuture readJob = this.readJob; if (readJob != null) { diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/Port.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/Port.java index f57d15da7c953..ad51cadd7324e 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/Port.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/Port.java @@ -135,9 +135,7 @@ public void stop() { connected.set(false); - if (ioStream.isOpen()) { - ioStream.close(); - } + ioStream.close(); ScheduledFuture readJob = this.readJob; if (readJob != null) { diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/SerialIOStream.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/SerialIOStream.java index c7eef6348fa6d..4295986021885 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/SerialIOStream.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/SerialIOStream.java @@ -13,8 +13,6 @@ package org.openhab.binding.insteon.internal.transport; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -24,8 +22,6 @@ import org.openhab.core.io.transport.serial.SerialPortIdentifier; import org.openhab.core.io.transport.serial.SerialPortManager; import org.openhab.core.io.transport.serial.UnsupportedCommOperationException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Implements IOStream for serial devices @@ -37,8 +33,6 @@ */ @NonNullByDefault public class SerialIOStream extends IOStream { - private final Logger logger = LoggerFactory.getLogger(SerialIOStream.class); - private String name; private int baudRate; private SerialPortManager serialPortManager; @@ -50,14 +44,9 @@ public SerialIOStream(String name, int baudRate, SerialPortManager serialPortMan this.serialPortManager = serialPortManager; } - @Override - public boolean isOpen() { - return port != null; - } - @Override public boolean open() { - if (isOpen()) { + if (port != null) { logger.warn("serial port is already open"); return false; } @@ -93,25 +82,7 @@ public boolean open() { @Override public void close() { - InputStream in = this.in; - if (in != null) { - try { - in.close(); - } catch (IOException e) { - logger.debug("failed to close input stream", e); - } - this.in = null; - } - - OutputStream out = this.out; - if (out != null) { - try { - out.close(); - } catch (IOException e) { - logger.debug("failed to close output stream", e); - } - this.out = null; - } + super.close(); SerialPort port = this.port; if (port != null) { diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/TcpIOStream.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/TcpIOStream.java index 9f6bcb578599d..06bbda45c2bd1 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/TcpIOStream.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/TcpIOStream.java @@ -13,15 +13,11 @@ package org.openhab.binding.insteon.internal.transport; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Implements IOStream for an Insteon Legacy Hub @@ -33,8 +29,6 @@ */ @NonNullByDefault public class TcpIOStream extends IOStream { - private final Logger logger = LoggerFactory.getLogger(TcpIOStream.class); - private String host; private int port; private @Nullable Socket socket; @@ -50,14 +44,9 @@ public TcpIOStream(String host, int port) { this.port = port; } - @Override - public boolean isOpen() { - return socket != null; - } - @Override public boolean open() { - if (isOpen()) { + if (socket != null) { logger.warn("socket is already open"); return false; } @@ -79,25 +68,7 @@ public boolean open() { @Override public void close() { - InputStream in = this.in; - if (in != null) { - try { - in.close(); - } catch (IOException e) { - logger.debug("failed to close input stream", e); - } - this.in = null; - } - - OutputStream out = this.out; - if (out != null) { - try { - out.close(); - } catch (IOException e) { - logger.debug("failed to close output stream", e); - } - this.out = null; - } + super.close(); Socket socket = this.socket; if (socket != null) { diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/message/MsgFactory.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/message/MsgFactory.java index 0555e04cce30f..ba9e50ac7cef1 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/message/MsgFactory.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/transport/message/MsgFactory.java @@ -78,7 +78,7 @@ public void addData(byte[] data, int len) { end += l; // copy the incoming data to the end of the buffer if (logger.isTraceEnabled()) { - logger.trace("read buffer: len {} data: {}", end, HexUtils.getHexString(buf, end, false)); + logger.trace("read buffer: len {} data: {}", end, HexUtils.getHexString(buf, end)); } } @@ -136,7 +136,7 @@ public void addData(byte[] data, int len) { done = true; } if (logger.isTraceEnabled()) { - logger.trace("keeping buffer len {} data: {}", end, HexUtils.getHexString(buf, end, false)); + logger.trace("keeping buffer len {} data: {}", end, HexUtils.getHexString(buf, end)); } return msg; } diff --git a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/utils/HexUtils.java b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/utils/HexUtils.java index dbb2b1fa29bbf..cb7b7b43026cb 100644 --- a/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/utils/HexUtils.java +++ b/bundles/org.openhab.binding.insteon/src/main/java/org/openhab/binding/insteon/internal/utils/HexUtils.java @@ -72,32 +72,28 @@ public static String getHexString(int i, int len, boolean addPrefix) { } /** - * Returns a hex string for a given byte array and length + * Returns a hex string for a given byte array * * @param bytes the byte array - * @param len the string length * @return the formatted hex string */ - public static String getHexString(byte[] bytes, int len) { - return getHexString(bytes, len, true); + public static String getHexString(byte[] bytes) { + return getHexString(bytes, bytes.length); } /** - * Returns a hex string for a given byte array, length and prefix flag + * Returns a hex string for a given byte array and length * * @param bytes the byte array * @param len the string length - * @param addPrefix if hex prefix should be added * @return the formatted hex string + * @throws ArrayIndexOutOfBoundsException */ - public static String getHexString(byte[] bytes, int len, boolean addPrefix) { + public static String getHexString(byte[] bytes, int len) throws ArrayIndexOutOfBoundsException { String s = ""; - for (int i = 0; i < bytes.length && i < len; i++) { + for (int i = 0; i < len; i++) { s += String.format("%02X", bytes[i] & 0xFF); } - if (!s.isEmpty() && addPrefix) { - s = "0x" + s; - } return s; } diff --git a/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/util/LifxMessageUtil.java b/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/util/LifxMessageUtil.java index eeb8858bd9e95..055510b64d93a 100644 --- a/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/util/LifxMessageUtil.java +++ b/bundles/org.openhab.binding.lifx/src/main/java/org/openhab/binding/lifx/internal/util/LifxMessageUtil.java @@ -128,7 +128,7 @@ public static int percentTypeToKelvin(PercentType temperature, TemperatureRange temperatureRange.getMaximum() - (temperature.floatValue() * (temperatureRange.getRange() / 100))); } - public static int quantityTypeToKelvin(QuantityType temperature, TemperatureRange temperatureRange) { + public static int quantityTypeToKelvin(QuantityType temperature, TemperatureRange temperatureRange) { QuantityType asKelvin = temperature.toInvertibleUnit(Units.KELVIN); if (asKelvin == null) { throw new IllegalStateException( diff --git a/bundles/org.openhab.binding.logreader/README.md b/bundles/org.openhab.binding.logreader/README.md index a31e218e283b1..b1e067ddd2d28 100644 --- a/bundles/org.openhab.binding.logreader/README.md +++ b/bundles/org.openhab.binding.logreader/README.md @@ -27,7 +27,7 @@ The `reader` Thing has the following configuration parameters: | `customPatterns` | String | no | | Search patterns separated by \| character for custom events. | | `customBlacklistingPatterns` | String | no | | Search patterns for blacklisting unwanted custom events separated by \| character. | -Search patterns follows [Java regular expression syntax](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html). +Search patterns follows [Java regular expression syntax](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/regex/Pattern.html). Be aware that search patterns are case sensitive. ## Channels diff --git a/bundles/org.openhab.binding.miio/README.md b/bundles/org.openhab.binding.miio/README.md index bc7e7f8ccc245..25da12c4d4e4a 100644 --- a/bundles/org.openhab.binding.miio/README.md +++ b/bundles/org.openhab.binding.miio/README.md @@ -559,6 +559,7 @@ Currently the miio binding supports more than 360 different models. | Xiaomi Smart Air Purifier 4 Compact | miio:basic | [zhimi.airp.cpa4](#zhimi-airp-cpa4) | Experimental | Experimental support. Please report back if all channels are functional. Preferably share the debug log of property refresh and command responses | | Mi Air Purifier 3C | miio:basic | [zhimi.airp.mb4a](#zhimi-airp-mb4a) | Yes | | | Xiaomi Smart Air Purifier 4 | miio:basic | [zhimi.airp.mb5](#zhimi-airp-mb5) | Experimental | Experimental support. Please report back if all channels are functional. Preferably share the debug log of property refresh and command responses | +| Xiaomi Smart Air Purifier 4 Lite | miio:basic | [zhimi.airp.rmb1](#zhimi-airp-rmb1) | Experimental | This device may not work with direct connection hence require cloud connection
    Experimental support. Please report back if all channels are functional. Preferably share the debug log of property refresh and command responses | | Xiaomi Smart Air Purifier 4 Pro | miio:basic | [zhimi.airp.vb4](#zhimi-airp-vb4) | Yes | | | Mi Air Purifier 2 (mini) | miio:basic | [zhimi.airpurifier.m1](#zhimi-airpurifier-m1) | Yes | | | Mi Air Purifier 2 | miio:basic | [zhimi.airpurifier.m2](#zhimi-airpurifier-m2) | Yes | | @@ -1682,7 +1683,7 @@ Note, not all the values need to be in the json file, e.g. a subset of the param | Channel | Type | Description | Comment | |----------------------------|----------------------|------------------------------------------|------------| -| actions | String | Actions | | +| actions | String | Actions | Value mapping `["vacuum-start-sweep"="Vacuum Start Sweep","vacuum-stop-sweeping"="Vacuum Stop Sweeping","vacuum-start-room-sweep"="Vacuum Start Room Sweep","battery-start-charge"="Battery Start Charge","brush-cleaner-reset-brush-life"="Brush Cleaner Reset Brush Life","brush-cleaner-reset-brush-life"="Brush Cleaner Reset Brush Life","filter-reset-filter-life"="Filter Reset Filter Life","vacuum-extend-start-clean"="Vacuum Extend Start Clean","vacuum-extend-stop-clean"="Vacuum Extend Stop Clean","map-map-req"="Map Map Req","map-update-map"="Map Update Map","audio-position"="Audio Position","audio-play-sound"="Audio Play Sound","time-delete-timer"="Time Delete Timer","collect-dust-start-collect"="Collect Dust Start Collect"]` | | status | Number | Robot Cleaner - Status | Value mapping `["1"="Sweeping","2"="Idle","3"="Paused","4"="Error","5"="Go Charging","6"="Charging","7"="Mopping","11"="Building","13"="Charging Completed"]` | | fault | Number | Robot Cleaner - Device Fault | | | mode | Number | Robot Cleaner - Mode | Value mapping `["0"="Silent","1"="Basic","2"="Strong","3"="Full Speed"]` | @@ -5459,6 +5460,29 @@ Note, not all the values need to be in the json file, e.g. a subset of the param | average_aqi | Number | Aqi - Average Aqi | | | aqi_state | Number | Aqi - Aqi State | Value mapping `["0"="AQI-GOOD-L","1"="AQI-GOOD-H","2"="AQI-MID-L","3"="AQI-MID-H","4"="AQI-BAD-L","5"="AQI-BAD-H"]` | +### Xiaomi Smart Air Purifier 4 Lite (zhimi.airp.rmb1) Channels + +| Channel | Type | Description | Comment | +|----------------------------|----------------------|------------------------------------------|------------| +| actions | String | Actions | Value mapping `["air-purifier-toggle"="Air Purifier Toggle","filter-reset-filter-life"="Filter Reset Filter Life","custom-service-toggle-mode"="Custom Service Toggle Mode"]` | +| on | Switch | Air Purifier - Switch Status | | +| fault | Number | Air Purifier - Device Fault | Value mapping `["0"="No Faults","2"="Motor Stop","3"="Sensor Lost"]` | +| mode | Number | Mode | Value mapping `["0"="Auto","1"="Sleep","2"="Favorite"]` | +| relative_humidity | Number:Dimensionless | Environment - Relative Humidity | | +| pm2_5_density | Number | Environment - PM2 5 Density | | +| temperature | Number:Temperature | Temperature | | +| filter_life_level | Number:Dimensionless | Filter - Filter Life Level | | +| filter_used_time | Number:Time | Filter - Filter Used Time | | +| filter_left_time | Number:Time | Filter - Filter Left Time | | +| alarm | Switch | Alarm - Alarm | | +| physical_controls_locked | Switch | Physical Control Locked - Physical Control Locked | | +| brightness | Number | Screen - Brightness | Value mapping `["0"="Close","1"="Bright","2"="Brightest"]` | +| temperature_display_unit | Number | Device Display Unit - Temperature Display Unit | Value mapping `["1"="Celsius","2"="Fahrenheit"]` | +| moto_speed_rpm | Number | Custom Service - Moto Speed Rpm | | +| country_code | Number | Custom Service - Country Code | Value mapping `["2"="EU","1"="US","82"="KR","886"="TW","66"="TH","44"="UK","91"="IN"]` | +| favorite_level | Number | Custom Service - Favorite Level | | +| aqi_updata_heartbeat | Number | Aqi - Aqi Updata Heartbeat | | + ### Xiaomi Smart Air Purifier 4 Pro (zhimi.airp.vb4) Channels | Channel | Type | Description | Comment | @@ -12068,6 +12092,32 @@ Number average_aqi "Aqi - Average Aqi" (G_airp) {channel="miio:basic:airp:averag Number aqi_state "Aqi - Aqi State" (G_airp) {channel="miio:basic:airp:aqi_state"} ``` +### Xiaomi Smart Air Purifier 4 Lite (zhimi.airp.rmb1) item file lines + +note: Autogenerated example. Replace the id (airp) in the channel with your own. Replace `basic` with `generic` in the thing UID depending on how your thing was discovered. + +```java +Group G_airp "Xiaomi Smart Air Purifier 4 Lite" +String actions "Actions" (G_airp) {channel="miio:basic:airp:actions"} +Switch on "Air Purifier - Switch Status" (G_airp) {channel="miio:basic:airp:on"} +Number fault "Air Purifier - Device Fault" (G_airp) {channel="miio:basic:airp:fault"} +Number mode "Mode" (G_airp) {channel="miio:basic:airp:mode"} +Number:Dimensionless relative_humidity "Environment - Relative Humidity" (G_airp) {channel="miio:basic:airp:relative_humidity"} +Number pm2_5_density "Environment - PM2 5 Density" (G_airp) {channel="miio:basic:airp:pm2_5_density"} +Number:Temperature temperature "Temperature" (G_airp) {channel="miio:basic:airp:temperature"} +Number:Dimensionless filter_life_level "Filter - Filter Life Level" (G_airp) {channel="miio:basic:airp:filter_life_level"} +Number:Time filter_used_time "Filter - Filter Used Time" (G_airp) {channel="miio:basic:airp:filter_used_time"} +Number:Time filter_left_time "Filter - Filter Left Time" (G_airp) {channel="miio:basic:airp:filter_left_time"} +Switch alarm "Alarm - Alarm" (G_airp) {channel="miio:basic:airp:alarm"} +Switch physical_controls_locked "Physical Control Locked - Physical Control Locked" (G_airp) {channel="miio:basic:airp:physical_controls_locked"} +Number brightness "Screen - Brightness" (G_airp) {channel="miio:basic:airp:brightness"} +Number temperature_display_unit "Device Display Unit - Temperature Display Unit" (G_airp) {channel="miio:basic:airp:temperature_display_unit"} +Number moto_speed_rpm "Custom Service - Moto Speed Rpm" (G_airp) {channel="miio:basic:airp:moto_speed_rpm"} +Number country_code "Custom Service - Country Code" (G_airp) {channel="miio:basic:airp:country_code"} +Number favorite_level "Custom Service - Favorite Level" (G_airp) {channel="miio:basic:airp:favorite_level"} +Number aqi_updata_heartbeat "Aqi - Aqi Updata Heartbeat" (G_airp) {channel="miio:basic:airp:aqi_updata_heartbeat"} +``` + ### Xiaomi Smart Air Purifier 4 Pro (zhimi.airp.vb4) item file lines note: Autogenerated example. Replace the id (airp) in the channel with your own. Replace `basic` with `generic` in the thing UID depending on how your thing was discovered. diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/MiIoDevices.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/MiIoDevices.java index c8a7eda18eba2..907f2d4cb117e 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/MiIoDevices.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/MiIoDevices.java @@ -410,6 +410,7 @@ public enum MiIoDevices { ZHIMI_AIRP_CPA4("zhimi.airp.cpa4", "Xiaomi Smart Air Purifier 4 Compact", THING_TYPE_BASIC), ZHIMI_AIRP_MB4A("zhimi.airp.mb4a", "Mi Air Purifier 3C", THING_TYPE_BASIC), ZHIMI_AIRP_MB5("zhimi.airp.mb5", "Xiaomi Smart Air Purifier 4", THING_TYPE_BASIC), + ZHIMI_AIRP_RMB1("zhimi.airp.rmb1", "Xiaomi Smart Air Purifier 4 Lite", THING_TYPE_BASIC), ZHIMI_AIRP_VB4("zhimi.airp.vb4", "Xiaomi Smart Air Purifier 4 Pro", THING_TYPE_BASIC), ZHIMI_AIRPURIFIER_M1("zhimi.airpurifier.m1", "Mi Air Purifier 2 (mini)", THING_TYPE_BASIC), ZHIMI_AIRPURIFIER_M2("zhimi.airpurifier.m2", "Mi Air Purifier 2", THING_TYPE_BASIC), diff --git a/bundles/org.openhab.binding.miio/src/main/resources/OH-INF/i18n/basic.properties b/bundles/org.openhab.binding.miio/src/main/resources/OH-INF/i18n/basic.properties index dff4d7d4751bf..f9c8cfc9644dc 100644 --- a/bundles/org.openhab.binding.miio/src/main/resources/OH-INF/i18n/basic.properties +++ b/bundles/org.openhab.binding.miio/src/main/resources/OH-INF/i18n/basic.properties @@ -351,6 +351,7 @@ thing.zhimi.airmonitor.v1 = Mi PM2.5 Air Quality Monitor thing.zhimi.airp.cpa4 = Xiaomi Smart Air Purifier 4 Compact thing.zhimi.airp.mb4a = Mi Air Purifier 3C thing.zhimi.airp.mb5 = Xiaomi Smart Air Purifier 4 +thing.zhimi.airp.rmb1 = Xiaomi Smart Air Purifier 4 Lite thing.zhimi.airp.vb4 = Xiaomi Smart Air Purifier 4 Pro thing.zhimi.airpurifier.m1 = Mi Air Purifier 2 (mini) thing.zhimi.airpurifier.m2 = Mi Air Purifier 2 @@ -1986,6 +1987,24 @@ ch.zhimi.airp.mb5-miot.reboot_cause = Custom Service - Reboot Cause ch.zhimi.airp.mb5-miot.relative_humidity = Environment - Relative Humidity ch.zhimi.airp.mb5-miot.temperature = Temperature ch.zhimi.airp.mb5-miot.temperature_display_unit = Device Display Unit - Temperature Display Unit +ch.zhimi.airp.rmb1-miot.actions = Actions +ch.zhimi.airp.rmb1-miot.alarm = Alarm - Alarm +ch.zhimi.airp.rmb1-miot.aqi_updata_heartbeat = Aqi - Aqi Updata Heartbeat +ch.zhimi.airp.rmb1-miot.brightness = Screen - Brightness +ch.zhimi.airp.rmb1-miot.country_code = Custom Service - Country Code +ch.zhimi.airp.rmb1-miot.fault = Air Purifier - Device Fault +ch.zhimi.airp.rmb1-miot.favorite_level = Custom Service - Favorite Level +ch.zhimi.airp.rmb1-miot.filter_left_time = Filter - Filter Left Time +ch.zhimi.airp.rmb1-miot.filter_life_level = Filter - Filter Life Level +ch.zhimi.airp.rmb1-miot.filter_used_time = Filter - Filter Used Time +ch.zhimi.airp.rmb1-miot.mode = Mode +ch.zhimi.airp.rmb1-miot.moto_speed_rpm = Custom Service - Moto Speed Rpm +ch.zhimi.airp.rmb1-miot.on = Air Purifier - Switch Status +ch.zhimi.airp.rmb1-miot.physical_controls_locked = Physical Control Locked - Physical Control Locked +ch.zhimi.airp.rmb1-miot.pm2_5_density = Environment - PM2 5 Density +ch.zhimi.airp.rmb1-miot.relative_humidity = Environment - Relative Humidity +ch.zhimi.airp.rmb1-miot.temperature = Temperature +ch.zhimi.airp.rmb1-miot.temperature_display_unit = Device Display Unit - Temperature Display Unit ch.zhimi.airp.vb4-miot.actions = Actions ch.zhimi.airp.vb4-miot.alarm = Alarm ch.zhimi.airp.vb4-miot.anion = Air Purifier - Anion @@ -4090,6 +4109,27 @@ option.zhimi.airp.mb5-miot.reboot_cause-2 = REASON-UPDATE option.zhimi.airp.mb5-miot.reboot_cause-3 = REASON-WDT option.zhimi.airp.mb5-miot.temperature_display_unit-1 = Celsius option.zhimi.airp.mb5-miot.temperature_display_unit-2 = Fahrenheit +option.zhimi.airp.rmb1-miot.actions-air-purifier-toggle = Air Purifier Toggle +option.zhimi.airp.rmb1-miot.actions-custom-service-toggle-mode = Custom Service Toggle Mode +option.zhimi.airp.rmb1-miot.actions-filter-reset-filter-life = Filter Reset Filter Life +option.zhimi.airp.rmb1-miot.brightness-0 = Close +option.zhimi.airp.rmb1-miot.brightness-1 = Bright +option.zhimi.airp.rmb1-miot.brightness-2 = Brightest +option.zhimi.airp.rmb1-miot.country_code-1 = US +option.zhimi.airp.rmb1-miot.country_code-2 = EU +option.zhimi.airp.rmb1-miot.country_code-44 = UK +option.zhimi.airp.rmb1-miot.country_code-66 = TH +option.zhimi.airp.rmb1-miot.country_code-82 = KR +option.zhimi.airp.rmb1-miot.country_code-886 = TW +option.zhimi.airp.rmb1-miot.country_code-91 = IN +option.zhimi.airp.rmb1-miot.fault-0 = No Faults +option.zhimi.airp.rmb1-miot.fault-2 = Motor Stop +option.zhimi.airp.rmb1-miot.fault-3 = Sensor Lost +option.zhimi.airp.rmb1-miot.mode-0 = Auto +option.zhimi.airp.rmb1-miot.mode-1 = Sleep +option.zhimi.airp.rmb1-miot.mode-2 = Favorite +option.zhimi.airp.rmb1-miot.temperature_display_unit-1 = Celsius +option.zhimi.airp.rmb1-miot.temperature_display_unit-2 = Fahrenheit option.zhimi.airp.vb4-miot.actions-air-purifier-toggle = Air Purifier Toggle option.zhimi.airp.vb4-miot.actions-custom-service-toggle-fan-level = Custom Service Toggle Fan Level option.zhimi.airp.vb4-miot.actions-custom-service-toggle-mode = Custom Service Toggle Mode diff --git a/bundles/org.openhab.binding.miio/src/main/resources/database/zhimi.airp.rmb1-miot.json b/bundles/org.openhab.binding.miio/src/main/resources/database/zhimi.airp.rmb1-miot.json new file mode 100644 index 0000000000000..ad3da3d39478b --- /dev/null +++ b/bundles/org.openhab.binding.miio/src/main/resources/database/zhimi.airp.rmb1-miot.json @@ -0,0 +1,467 @@ +{ + "deviceMapping": { + "id": [ + "zhimi.airp.rmb1" + ], + "propertyMethod": "get_properties", + "maxProperties": 1, + "channels": [ + { + "property": "", + "friendlyName": "Actions", + "channel": "actions", + "type": "String", + "stateDescription": { + "options": [ + { + "value": "air-purifier-toggle", + "label": "Air Purifier Toggle" + }, + { + "value": "filter-reset-filter-life", + "label": "Filter Reset Filter Life" + }, + { + "value": "custom-service-toggle-mode", + "label": "Custom Service Toggle Mode" + } + ] + }, + "refresh": false, + "actions": [ + { + "command": "action", + "parameterType": "EMPTY", + "siid": 2, + "aiid": 1, + "condition": { + "name": "matchValue", + "parameters": [ + { + "matchValue": "air-purifier-toggle" + } + ] + } + }, + { + "command": "action", + "parameterType": "UNKNOWN", + "parameters": [ + 3.0 + ], + "siid": 4, + "aiid": 1, + "condition": { + "name": "matchValue", + "parameters": [ + { + "matchValue": "filter-reset-filter-life" + } + ] + } + }, + { + "command": "action", + "parameterType": "EMPTY", + "siid": 9, + "aiid": 1, + "condition": { + "name": "matchValue", + "parameters": [ + { + "matchValue": "custom-service-toggle-mode" + } + ] + } + } + ], + "readmeComment": "Value mapping `[\"air-purifier-toggle\"\u003d\"Air Purifier Toggle\",\"filter-reset-filter-life\"\u003d\"Filter Reset Filter Life\",\"custom-service-toggle-mode\"\u003d\"Custom Service Toggle Mode\"]`" + }, + { + "property": "on", + "siid": 2, + "piid": 1, + "friendlyName": "Air Purifier - Switch Status", + "channel": "on", + "type": "Switch", + "refresh": true, + "actions": [ + { + "command": "set_properties", + "parameterType": "ONOFFBOOL" + } + ], + "category": "switch", + "tags": [ + "Switch" + ] + }, + { + "property": "fault", + "siid": 2, + "piid": 2, + "friendlyName": "Air Purifier - Device Fault", + "channel": "fault", + "type": "Number", + "stateDescription": { + "readOnly": true, + "options": [ + { + "value": "0", + "label": "No Faults" + }, + { + "value": "2", + "label": "Motor Stop" + }, + { + "value": "3", + "label": "Sensor Lost" + } + ] + }, + "refresh": true, + "actions": [], + "readmeComment": "Value mapping `[\"0\"\u003d\"No Faults\",\"2\"\u003d\"Motor Stop\",\"3\"\u003d\"Sensor Lost\"]`" + }, + { + "property": "mode", + "siid": 2, + "piid": 4, + "friendlyName": "Mode", + "channel": "mode", + "type": "Number", + "stateDescription": { + "options": [ + { + "value": "0", + "label": "Auto" + }, + { + "value": "1", + "label": "Sleep" + }, + { + "value": "2", + "label": "Favorite" + } + ] + }, + "refresh": true, + "actions": [ + { + "command": "set_properties", + "parameterType": "NUMBER" + } + ], + "readmeComment": "Value mapping `[\"0\"\u003d\"Auto\",\"1\"\u003d\"Sleep\",\"2\"\u003d\"Favorite\"]`" + }, + { + "property": "relative-humidity", + "siid": 3, + "piid": 1, + "friendlyName": "Environment - Relative Humidity", + "channel": "relative_humidity", + "type": "Number:Dimensionless", + "unit": "percentage", + "stateDescription": { + "minimum": 0, + "maximum": 100, + "step": 1, + "pattern": "%.0f %unit%", + "readOnly": true + }, + "refresh": true, + "actions": [] + }, + { + "property": "pm2.5-density", + "siid": 3, + "piid": 4, + "friendlyName": "Environment - PM2 5 Density", + "channel": "pm2_5_density", + "type": "Number", + "unit": "μg/m3", + "stateDescription": { + "minimum": 0, + "maximum": 600, + "step": 1, + "pattern": "%.0f", + "readOnly": true + }, + "refresh": true, + "actions": [] + }, + { + "property": "temperature", + "siid": 3, + "piid": 7, + "friendlyName": "Temperature", + "channel": "temperature", + "type": "Number:Temperature", + "unit": "celsius", + "stateDescription": { + "minimum": -30, + "maximum": 100, + "pattern": "%.1f %unit%", + "readOnly": true + }, + "refresh": true, + "actions": [] + }, + { + "property": "filter-life-level", + "siid": 4, + "piid": 1, + "friendlyName": "Filter - Filter Life Level", + "channel": "filter_life_level", + "type": "Number:Dimensionless", + "unit": "percentage", + "stateDescription": { + "minimum": 0, + "maximum": 100, + "step": 1, + "pattern": "%.0f %unit%", + "readOnly": true + }, + "refresh": true, + "actions": [] + }, + { + "property": "filter-used-time", + "siid": 4, + "piid": 3, + "friendlyName": "Filter - Filter Used Time", + "channel": "filter_used_time", + "type": "Number:Time", + "unit": "days", + "stateDescription": { + "minimum": 0, + "maximum": 200, + "step": 1, + "pattern": "%.0f %unit%", + "readOnly": true + }, + "refresh": true, + "actions": [] + }, + { + "property": "filter-left-time", + "siid": 4, + "piid": 4, + "friendlyName": "Filter - Filter Left Time", + "channel": "filter_left_time", + "type": "Number:Time", + "unit": "days", + "stateDescription": { + "minimum": 0, + "maximum": 1000, + "step": 1, + "pattern": "%.0f %unit%", + "readOnly": true + }, + "refresh": true, + "actions": [] + }, + { + "property": "alarm", + "siid": 6, + "piid": 1, + "friendlyName": "Alarm - Alarm", + "channel": "alarm", + "type": "Switch", + "refresh": true, + "actions": [ + { + "command": "set_properties", + "parameterType": "ONOFFBOOL" + } + ] + }, + { + "property": "physical-controls-locked", + "siid": 8, + "piid": 1, + "friendlyName": "Physical Control Locked - Physical Control Locked", + "channel": "physical_controls_locked", + "type": "Switch", + "refresh": true, + "actions": [ + { + "command": "set_properties", + "parameterType": "ONOFFBOOL" + } + ] + }, + { + "property": "brightness", + "siid": 13, + "piid": 2, + "friendlyName": "Screen - Brightness", + "channel": "brightness", + "type": "Number", + "stateDescription": { + "options": [ + { + "value": "0", + "label": "Close" + }, + { + "value": "1", + "label": "Bright" + }, + { + "value": "2", + "label": "Brightest" + } + ] + }, + "refresh": true, + "actions": [ + { + "command": "set_properties", + "parameterType": "NUMBER" + } + ], + "readmeComment": "Value mapping `[\"0\"\u003d\"Close\",\"1\"\u003d\"Bright\",\"2\"\u003d\"Brightest\"]`" + }, + { + "property": "temperature-display-unit", + "siid": 14, + "piid": 1, + "friendlyName": "Device Display Unit - Temperature Display Unit", + "channel": "temperature_display_unit", + "type": "Number", + "stateDescription": { + "options": [ + { + "value": "1", + "label": "Celsius" + }, + { + "value": "2", + "label": "Fahrenheit" + } + ] + }, + "refresh": true, + "actions": [ + { + "command": "set_properties", + "parameterType": "NUMBER" + } + ], + "readmeComment": "Value mapping `[\"1\"\u003d\"Celsius\",\"2\"\u003d\"Fahrenheit\"]`" + }, + { + "property": "moto-speed-rpm", + "siid": 9, + "piid": 1, + "friendlyName": "Custom Service - Moto Speed Rpm", + "channel": "moto_speed_rpm", + "type": "Number", + "stateDescription": { + "minimum": 0, + "maximum": 2500, + "step": 1, + "pattern": "%.0f", + "readOnly": true + }, + "refresh": true, + "actions": [] + }, + { + "property": "country-code", + "siid": 9, + "piid": 10, + "friendlyName": "Custom Service - Country Code", + "channel": "country_code", + "type": "Number", + "stateDescription": { + "options": [ + { + "value": "2", + "label": "EU" + }, + { + "value": "1", + "label": "US" + }, + { + "value": "82", + "label": "KR" + }, + { + "value": "886", + "label": "TW" + }, + { + "value": "66", + "label": "TH" + }, + { + "value": "44", + "label": "UK" + }, + { + "value": "91", + "label": "IN" + } + ] + }, + "refresh": true, + "actions": [ + { + "command": "set_properties", + "parameterType": "NUMBER" + } + ], + "readmeComment": "Value mapping `[\"2\"\u003d\"EU\",\"1\"\u003d\"US\",\"82\"\u003d\"KR\",\"886\"\u003d\"TW\",\"66\"\u003d\"TH\",\"44\"\u003d\"UK\",\"91\"\u003d\"IN\"]`" + }, + { + "property": "favorite-level", + "siid": 9, + "piid": 11, + "friendlyName": "Custom Service - Favorite Level", + "channel": "favorite_level", + "type": "Number", + "stateDescription": { + "minimum": 0, + "maximum": 14, + "step": 1, + "pattern": "%.0f" + }, + "refresh": true, + "actions": [ + { + "command": "set_properties", + "parameterType": "NUMBER" + } + ] + }, + { + "property": "aqi-updata-heartbeat", + "siid": 11, + "piid": 4, + "friendlyName": "Aqi - Aqi Updata Heartbeat", + "channel": "aqi_updata_heartbeat", + "type": "Number", + "stateDescription": { + "minimum": 0, + "maximum": 65535, + "step": 1, + "pattern": "%.0f" + }, + "refresh": true, + "actions": [ + { + "command": "set_properties", + "parameterType": "STRING" + } + ] + } + ], + "readmeComment": "This device may not work with direct connection hence require cloud connection", + "experimental": true + } +} diff --git a/bundles/org.openhab.binding.miio/src/main/resources/misc/device_names.json b/bundles/org.openhab.binding.miio/src/main/resources/misc/device_names.json index 426f6e4014588..b5c18469d9794 100644 --- a/bundles/org.openhab.binding.miio/src/main/resources/misc/device_names.json +++ b/bundles/org.openhab.binding.miio/src/main/resources/misc/device_names.json @@ -11,6 +11,7 @@ "090615.curtain.byg247": "LS Life Smart Curtain Motor", "090615.curtain.crli82": "Intelligent lithium battery motor (Mesh)", "090615.curtain.crus6": "PTX Silent Curtain Motor(MESH)", + "090615.curtain.curm6": "X1 Invisible Curtain Motor (PTX)", "090615.curtain.dj001": "HWJ DJ-001 Smart Curtain Motor", "090615.curtain.gr82m1": "GR Smart Curtain", "090615.curtain.h6pro": "JC Smart Curtain Motor H6 Pro", @@ -33,7 +34,10 @@ "090615.curtain.ptxml1": "PTX Intelligent Dream Curtain Motor", "090615.curtain.q6": "QL Q6 Smart Curtain Motor", "090615.curtain.s2mesh": "Smart curtain motor(Bluetooth mesh)", + "090615.curtain.s3": "Three thousand gold S3 smart curtain motor", "090615.curtain.s6": "ZX S6 Smart Curtain Motor", + "090615.curtain.s6k1": "K1 Intelligent Curtain Motor (PTX)", + "090615.curtain.s6pro": "Haoyi Intelligent Speed Silent Motor pro", "090615.curtain.sidt82": "WiFi intelligent curtain motor", "090615.curtain.sm82b": "SUMI Smart Curtain Motor (MESH)", "090615.curtain.sumi82": "SUMI intelligent curtain motor", @@ -46,6 +50,7 @@ "090615.curtain.zs82b": "ZS Intelligent Curtain Motor (MESH)", "090615.curtain.zsdj35": "ZS roller shutter motor", "090615.curtain.zsdj82": "ZS intelligent curtain motor", + "090615.gateway.ac10": "VRF Central Air-Con Gateway", "090615.gateway.ktvrf": "PTXZN air conditioning gateway (VRF)", "090615.gateway.vrfgw": "SOCHUANG VRF Central Air-Con Controller", "090615.light.ailig1": "AI Color Temperature Light (MESH)", @@ -54,8 +59,11 @@ "090615.light.grlg2": "GR Smart Light Strip", "090615.light.grlg3": "GR Smart Magnetic Lamp", "090615.light.grlig1": "GR intelligent ceiling lamp", + "090615.light.hycxv2": "Haoyi Professional dimmer magnetic suction lamp (pro)", + "090615.light.hyddv2": "Haoyi Professional dimmer lamp strip (pro)", "090615.light.hylg01": "Haoyi intelligent dimming lamp (mesh)", "090615.light.hylg03": "Haoyi intelligent magnetic suction lamp (mesh)", + "090615.light.hypro7": "Haoyi Professional Dimmer Down Lamp (pro)", "090615.light.hyrgb1": "Haoyi RGB Music Rhythm Controller(mesh)", "090615.light.kylg02": "Haoyi intelligent two color light belt (mesh)", "090615.light.mdd02": "PTX intelligent two tone light strip (mesh)", @@ -67,6 +75,7 @@ "090615.light.pipadd": "Crackle smart light band (mesh)", "090615.light.pipatd": "Crackle smart anti glare lamp (mesh)", "090615.light.rgblg": "PTX Full Color Music Rhythm Controller", + "090615.light.sdcx1": "PTX Deep dimming magnetic suction lamp (V2pro)", "090615.light.xdlig": "PTX Cold And Warm Ceiling Lamp(Mesh)", "090615.light.xrlig1": "Cactus intelligent spotlight (mesh)", "090615.plug.cmp86": "PTX 86 power version socket (WiFi)", @@ -82,6 +91,8 @@ "090615.remote.x6s4q": "X6 intelligent four scene switch(PTX)", "090615.remote.x6xnsw": "PTX wireless situation knob switch", "090615.remote.yk6sw": "PTX six key wireless switch", + "090615.sensor_occupy.mw": "PTX Human Body Presence Sensor", + "090615.sensor_occupy.xw": "PTX Human Body Presence Sensor (Top Mounted)", "090615.switch.09dh1": "Intelligent single fire switch on (MESH)", "090615.switch.09dh2": "Intelligent single fire switch two on (MESH)", "090615.switch.09dh3": "Intelligent single fire switch three on (MESH)", @@ -94,8 +105,15 @@ "090615.switch.aikw4": "AE Intelligent Switch Four Key (mesh)", "090615.switch.akkw1": "AK intelligent switch (PTX) one key", "090615.switch.akkw2": "AK intelligent switch (PTX) two key", + "090615.switch.akpro1": "PTX ultra-thin aesthetic switch single button", + "090615.switch.akpro2": "PTX ultra-thin aesthetic switch two buttons", + "090615.switch.akpro3": "PTX ultra-thin aesthetic switch three buttons", + "090615.switch.akpro4": "PTX ultra-thin aesthetic switch four buttons", "090615.switch.aksk3": "AK intelligent switch (PTX) three key", "090615.switch.akstft": "AK Smart Screen Switch", + "090615.switch.akult1": "PTX ultrathin display screen switch single open", + "090615.switch.akult2": "PTX ultrathin display screen switch double open", + "090615.switch.akult3": "PTX ultrathin display screen switch three open", "090615.switch.azsw01": "Azena mesh intelligent zero fire one switch", "090615.switch.azsw02": "Azena mesh intelligent zero fire two switch", "090615.switch.azsw03": "Azena mesh intelligent zero fire three switch", @@ -114,9 +132,9 @@ "090615.switch.mesh01": "PTX single fire touch switch one button (mesh)", "090615.switch.mesh02": "PTX single fire touch switch two keys (mesh)", "090615.switch.mesh03": "PTX single fire touch switch three keys (mesh) ", - "090615.switch.meshk1": "PTX single fire key switch one keys (mesh)", - "090615.switch.meshk2": "PTX single fire key switch two keys (mesh)", - "090615.switch.meshk3": "PTX single fire key switch three keys (mesh) ", + "090615.switch.meshk1": "PTX single fire key switch one key (MESH)", + "090615.switch.meshk2": "PTX single fire key switch two keys (MESH)", + "090615.switch.meshk3": "PTX single fire key switch three keys (MESH)", "090615.switch.mesw1": "PTX Mesh intelligent one switch", "090615.switch.mesw2": "PTX Mesh intelligent two switch", "090615.switch.mesw3": "PTX Mesh intelligent three switch", @@ -132,6 +150,9 @@ "090615.switch.ptxtc1": "PTX intelligent touch switch one on (mesh)", "090615.switch.ptxtc2": "PTX intelligent touch switch two on (mesh)", "090615.switch.ptxtc3": "PTX intelligent touch switch three on (mesh)", + "090615.switch.q3pro1": "Haoyi Switch one open Q3pro (screen display)", + "090615.switch.q3pro2": "Haoyi Switch tow open Q3pro (screen display)", + "090615.switch.q3pro3": "Haoyi Switch three open Q3pro (screen display)", "090615.switch.qksw01": "PTX smart card power on switch (mesh)", "090615.switch.qksw32": "PTX card access switch (WiFi)", "090615.switch.sk4k": "PTX intelligent four key switch", @@ -146,6 +167,7 @@ "090615.switch.switch02": "Two Intelligent Switch (WIFI)", "090615.switch.switch03": "Three Intelligent switch(WIFI)", "090615.switch.tftcmb": "Knob intelligent switch", + "090615.switch.x1tp": "Smart Screen Switch (PTX)", "090615.switch.x6gr1": "GR smart one-button switch", "090615.switch.x6gr2": "GR smart two-button switch", "090615.switch.x6gr3": "GR smart three-button switch", @@ -164,10 +186,15 @@ "090615.switch.x6se1": "MAXBORN intelligent single key switch", "090615.switch.x6se2": "MAXBORN intelligent double key switch", "090615.switch.x6se3": "MAXBORN intelligent three key switch", + "090615.switch.x6tppr": "K1 HD Cent-Contr Screen Switch (PTX)", "090615.switch.x6wtft": "X6 Cent-Contr Screen Switch (WIFI)", + "090615.switch.x7sw2": "X7 Two Buttons Smart Switch (PTX)", + "090615.switch.x7sw3": "X7 Three Buttons Smart Switch (PTX)", + "090615.switch.x7sw4": "X7 Four Buttons Smart Switch (PTX)", "090615.switch.xswitch01": "PTX OneKey Switch (WIFI)", "090615.switch.xswitch02": "PTX Twokey switch(wifi)", "090615.switch.xswitch03": "PTX ThreeKey Switch (WIFI)", + "090615.wafa.f11026": "MinJie Whale Smart Washbasin Faucet", "090615.wifispeaker.x6bj": "X6 background music(PTX)", "1245.airfresh.mini2": "Potato Mini", "1245.airfresh.super2": "TUDOU PRO", @@ -193,7 +220,9 @@ "666.curtain.gt01": "Smart Curtain Motor", "666.curtain.gt01m": "Genwits Smart Curtain", "666.curtain.id92": "WIFI Smart Curtain", + "913101.carseat.d1pro": "qborn baby Dolphin child safety seat", "913101.tracker.d1": "qborn Child safety seat for small dolphins", + "abcmk.bed.abcmok": "ABCMOKOO Intelligent Folding Baby Crib", "aden.airc.a6": "VINO Inverter Air Conditioner 3P(New Energy Label Level 2)", "aden.aircondition.a1": "VINO Inverter Air Conditioner(Energy Label Level 3)", "aden.aircondition.a2": "VINO Inverter Air Conditioner(Energy Label Level 1)", @@ -202,27 +231,45 @@ "aden.aircondition.ad2p1": "Inverter Ducted Air conditioner", "aden.aircondition.vf1p5": "VINO Inverter air conditioner 1.5 pieces (Primary energy efficiency)", "aden.aircondition.xfkt1": "VINO Fresh Air Inverter Air Conditioner(New Energy Label Level 1)", + "aden.derh.derh16": "VINO Smart Dehumidifier 16L", + "aden.derh.fight": "VINO Smart Dehumidifier 16L Pro", "aden.derh.vsd30": "VINO Smart dehumidifier 30L", "aden.derh.vsid30": "VINO Smart inverter dehumidifier 30L", "aden.waterheater.ash200": "VINO Air energy water heater 200L", + "adl001.plug.itcs": "Odoran intelligent track conversion socket", + "adp.curtain.test02": "ADAPROX Curtain Robot", + "adp.fitting.adgw": "Adaprox Smart Controller", + "adp.robot.ad": "ADAPROX Fingerbot", "afour.s_lamp.001": "ZIWOOO Intelligent germicidal lamp", "ai123.magic_touch.xjb1a": "TefeshiAPP intelligent cervical massage instrument", "aice.motor.kzmu3": "KZM intelligent shutter door controller", + "ailol.remote.ts4": "ZXFANS F2 smart knob remote control", + "ailol.switch.sw1a01": "ZXFANS 2 key smart switch", + "ailol.switch.sw2a01": "ZXFANS 4 key smart switch", + "ailol.switch.sw3a01": "ZXFANS 6 key smart switch", + "ailol.switch.sw4a01": "ZXFANS 8 key smart switch", + "aimore.light.230915": "Smart Dimmable Light A2", + "aimore.light.240407": "aimore Intelligent cooling and heating ceiling light MESH", "aimore.light.cw3201": "smart dimmable light", "ainice.motion.bt": "AInice Motion Sensor", + "ainice.sensor_occupy.3b": "AInice Three Target Scene Sensor", "ainice.sensor_occupy.rd": "AInice Dual Presence Sensor", "air.fan.ca23ad9": "Airmate air circulation fan", "air.heater.wda14": "Airmate mobile floor heating", + "airdog.airp.x5sm": "Airdog air purifier X5S", "airdog.airpurifier.mn": "Airdog A5/MINI air purifier", "airdog.airpurifier.x5": "Airdog X3(M) air purifier", "airdog.airpurifier.x7": "Airdog X7(M) air purifier", "airdog.airpurifier.x7sm": "Airdog X7S(M) air purifier", "akt.derh.2008": "FLE-2008EW", + "alight.light.wy0a01": "AZ Intelligent scene light", "aok98.curtain.am50pw": "AOK AM50 intelligence curtain", "aok98.curtain.aok100": "AOK LM100 intelligence curtain", + "aok98.curtain.aok57": "AOK Folding Curtain AM57", "aok98.curtain.aok68": "AOK AM68 Smart Curtain", "aok98.curtain.lm50bw": "KeChuangZhe Curtain Motor", "aok98.curtain.qlam50": "qinglinkQ302 Smart Curtain", + "aonier.bed.001": "Ausneal Smart Bed", "app.light.wynd1": "Nnuodu Intelligent Living Room Lamp", "asdds.light.wyfpj1": "Feipujia Intelligent lamps and lanterns", "asp.treadmill.a9": "Lijiujia treadmill", @@ -234,21 +281,42 @@ "aupu.aircondition.kc26a": "AUPU Kitchen Air Conditioner KC-26/A", "aupu.bhf_light.360ap": "AUPU Q360A-Pro", "aupu.bhf_light.360pro": "AUPU Q360C-Pro", + "aupu.bhf_light.360t3s": "AUPU Q360T3S", + "aupu.bhf_light.360x3": "AUPU Q360X3", "aupu.bhf_light.360xp": "AUPU Q360X-Pro", + "aupu.bhf_light.a3spro": "AUPU Q360A3S-Pro", + "aupu.bhf_light.e371": "AUPU E371M", + "aupu.bhf_light.e371my": "AUPU E371M-Y", + "aupu.bhf_light.e372": "AUPU E372M", + "aupu.bhf_light.e372my": "AUPU E372M-Y", "aupu.bhf_light.f1pro1": "AUPU F1-Pro", "aupu.bhf_light.fxpro": "AUPU FX-Pro", + "aupu.bhf_light.ha01md": "AUPU HA01MD", + "aupu.bhf_light.l1b": "AUPU L1B", + "aupu.bhf_light.l1bs": "AUPU L1BS", "aupu.bhf_light.n80": "AUPU air housekeeper bath heater-N80Pro", "aupu.bhf_light.n80ss": "AUPU N80S", + "aupu.bhf_light.na01dp": "AUPU NA01-Pro", "aupu.bhf_light.p3328e": "AUPU-AOXIN", + "aupu.bhf_light.q360a3": "AUPU Q360A3", "aupu.bhf_light.q360c": "AUPU Q360C", + "aupu.bhf_light.q360g3": "AUPU Q360G3", "aupu.bhf_light.q360sp": "AUPU Q360S-PRO", + "aupu.bhf_light.qa3evo": "AUPU Q360A3-Evo", + "aupu.bhf_light.qa3pro": "AUPU Q360A3-Pro", + "aupu.bhf_light.qa3s": "AUPU Q360A3S", + "aupu.bhf_light.s01m": "AUPU S01M", + "aupu.bhf_light.s01md": "AUPU S01MD", "aupu.bhf_light.s10m": "AUPU S10M", "aupu.bhf_light.s118m1": "AUPU S118M", "aupu.bhf_light.s11m": "AUPU S11M", "aupu.bhf_light.s368m": "AUPU S368M", "aupu.bhf_light.s368m2": "AUPU S368M", + "aupu.bhf_light.s608m": "AUPU S608M", "aupu.bhf_light.s618m1": "AUPU S618M", "aupu.bhf_light.s628m": "AUPU S628M", + "aupu.bhf_light.t3spro": "AUPU Q360T3S-Pro", + "aupu.bhf_light.x3pro": "AUPU Q360X3-Pro", "aux.aircondition.hc1": "AUX Smart Air Conditioner", "aux.aircondition.v1": "AUX Smart Air Conditioner", "axent.tow_w.a804": "AXENT COZY heated towel rack", @@ -271,6 +339,7 @@ "babai.curtain.kyx850": "KYX Smart Curtain", "babai.curtain.lb100a": "LANBOO Smart Curtain", "babai.curtain.lm860": "LanMi Smart curtain", + "babai.curtain.lsxf83": "M3 Smart Curtain (WIFI)", "babai.curtain.m515e": "Zemismart smart curtain motor", "babai.curtain.mtx850": "MTX Smart Curtain", "babai.curtain.nh5810": "NanHoo Smart Curtain", @@ -311,13 +380,19 @@ "babai.switch.bb102s": "WiFi Wall Switch A2", "babai.switch.bb103s": "WiFi Wall Switch A3", "babai.switch.th01a": "ThoughtHome Switch module", + "babai.switch.th01m": "Ai Intelligent On-Off Device(MESH)", "babai.ven_fan.tycold": "Tianyu intelligent Ventilation Fan", "babai.wopener.82": "ChenYang window opener", "babai.wopener.83": "AIDEDAO", + "badian.humidifier.p1000": "bdair Pure humidifier", + "bairen.scales.hd01": "Hui Ding intelligent body fat scale HD01", "bangbo.airer.c3xhqm": "Color charm C", "bangbo.airer.x3xhqm": "Benoson", "bangbo.airer.x5xhqm": "Heichuang intelligent clothes drying machine", "bangbo.airer.y6": "Mans Cooper", + "baobo.scales.001": "Bobo intelligent body fat scale 001", + "baobo.scales.003": "Bobo intelligent body fat scale 003", + "baoju.scales.c026": "BENBO household body fat scale C026", "baomi.airpurifier.450a": "Baomi Air Purifier 2S", "bc1869.lock.t002": "Yi-Lock", "bcase.heater.s2220": "SOTHING Humidification Heater-Star", @@ -326,12 +401,19 @@ "bdx.i_stove.c1x": "BIGDIPPER Internet Integrated Cooker Appliance (C1 disinfection cabinet)", "bdx.i_stove.c2x": "BIGDIPPER Internet Integrated Cooker Appliance (C2 disinfection cabinet)", "bdx.i_stove.c5zk": "BIGDIPPER Internet Integrated Cooker Appliance ( C2/C3 steam box)", + "bean.aircondition.tc01": "Air Con Assist RCS-Mesh", + "bean.airrtc.nt01": "3 To 1 Thermostat SR-Mesh", "bean.curtain.bct01": "Smart curtain motor V1-WiFi", "bean.curtain.ct01": "Smart curtain V1-Mesh", + "bean.curtain.ct03": "SenRui Smart curtain - BLE Mesh", + "bean.curtain.ct05": "Smart curtain S1-Mesh", + "bean.curtain.ct23": "SR Day \u0026 Night Blinds", "bean.curtain.ctm1": "Ai home curtain light motor", "bean.curtain.ctw1": "Wistar Dream Curtain Motor-WiFi", "bean.curtain.ctw2": "Kosdom Smart Curtain Motor C5", "bean.curtain.ctw3": "Smart curtain motor V2-WiFi", + "bean.curtain.ctw6": "Dream Curtain Motor A3-WiFi", + "bean.light.lt07": "Smart 2-Colors Light P7 Mesh", "bean.switch.bl01": "Single button Fire Mesh switch", "bean.switch.bl02": "Two buttons fire Mesh switch", "bean.switch.bl03": "Three buttons fire Mesh switch", @@ -340,6 +422,15 @@ "bean.switch.bln02": "Two buttons Mesh switch", "bean.switch.bln03": "Three buttons Mesh switch", "bean.switch.bln04": "Four buttons Mesh switch", + "bean.switch.bln31": "Smart 1 Keys S2-Mesh", + "bean.switch.bln32": "Smart 2 Keys S2-Mesh", + "bean.switch.bln33": "Smart 3 Keys S2-Mesh", + "bean.switch.bln34": "Smart 4 Keys S2-Mesh", + "bean.switch.bln36": "Smart 6 Keys S2-Mesh", + "bean.switch.blns1": "Smart 1 Key S1-Mesh", + "bean.switch.blns2": "Smart 2 Keys S1-Mesh", + "bean.switch.blns3": "Smart 3 Keys S1-Mesh", + "beig.light.s660v": "Eiperfic smart lights iSulight", "beihao.airer.airer3": "xiangyang clothes-horse", "beihao.airer.bd": "Lanyou clothes-horse", "beihao.airer.l9": "Lisheng clothes-horse", @@ -373,6 +464,9 @@ "bofu.curtain.q301": "QinLinkQ301", "bofu.curtain.sp10xm": "SHIDIAN Dream Curtain", "bofu.curtain.zl82xa": "BLE-Mesh Curtain", + "booer.feeder.001": "Maotele pet smart feeder", + "box.light.w00a01": "BOXLAMP Star light", + "brains.sensor_occupy.r4": "Brains Human Presence Sensor", "brrx.switch.qst1c1": "Submarine Smart One-keys Wall Switch", "brrx.switch.qst1c2": "Submarine Smart Two-keys Wall Switch", "brrx.switch.qst1c3": "Submarine Smart Three-keys Wall Switch", @@ -397,19 +491,26 @@ "bull.switch.s112y": "Bull smart one-key switch(No Neutral)", "bull.switch.s212y": "Bull smart two-keys switch(No Neutral)", "bull.switch.s312y": "Bull smart three-keys switch(No Neutral)", + "bwlife.cup.01": "Black and white life smart thermos cup", "bymiot.aircondition.ir2": "未来居空调控制器(红外版)", "bymiot.aircondition.v1": "未来居中央空调控制器", "bymiot.aircondition.wl2": "未来居无线中央空调控制器", + "bymiot.airp.v3": "Future Home Smart Aldehyde Removing Air Purifier", + "bymiot.airrtc.wlv2": "Future Home Juqing Temperature Controller", "bymiot.controller.ctlv1": "未来居调光旋钮(冷暖)", "bymiot.controller.lumv1": "未来居调光旋钮(亮度)", "bymiot.controller.v1": "未来居背景音乐控制器", "bymiot.cs.sensor": "未来居有线弱电插卡取电", "bymiot.cs.switch": "未来居有线强电插卡取电", "bymiot.cs.wlv1": "未来居无线强电插卡取电", + "bymiot.cs.wlv2": "Future Home Juqing insert-card-for-power switch", "bymiot.curtain.m2w": "Bymiot curtain m2w", "bymiot.curtain.v2": "未来居电动窗帘", "bymiot.curtain.virv1": "未来居通用窗帘电机", + "bymiot.curtain.wlv1": "Future Juqing curtain motor", "bymiot.curtain.wlv2": "未来居无线窗帘电机(M1开合帘)", + "bymiot.curtain.wlv4": "wei lai ju Intelligent curtain motor", + "bymiot.curtain.wlv6": "Future Home Smart curtain (Mesh)", "bymiot.gateway.rcuv1": "未来居一体式RCU网关", "bymiot.gateway.v1": "企业有线智能网关", "bymiot.gateway.v2": "企业有线智能网关2.0版", @@ -427,6 +528,7 @@ "bymiot.light.dmwlv2": "未来居无线彩光灯带驱动器", "bymiot.light.lumv1": "未来居调光灯(亮度)", "bymiot.light.rgbv1": "未来居调光灯(彩色)", + "bymiot.light.wlv2": "Future Home Smart Colors Light (Mesh)", "bymiot.magnet.wlv2": "未来居无线门窗传感器(粘贴版)", "bymiot.magnet.wlv3": "未来居无线门窗传感器(嵌入版)", "bymiot.motion.v1": "未来居人体移动传感器", @@ -441,14 +543,27 @@ "bymiot.sensor_occupy.gl": "未来居通用存在传感器", "bymiot.sensor_occupy.v3": "未来居强电插卡取电", "bymiot.switch.1keyv1": "未来居单键强电开关", + "bymiot.switch.1kwls2": "Wei lai ju Single (zero) fire compatible intelligent switch (single key)", + "bymiot.switch.1kwls3": "wei lai ju Zero fire intelligent switch (single button)", + "bymiot.switch.1kwlv1": "Future Juqing single key strong current switch", "bymiot.switch.1kwlv2": "未来居单键强电无线开关", "bymiot.switch.2keyv1": "未来居双键强电开关", + "bymiot.switch.2kwls2": "Wei lai ju Single (zero) fire compatible intelligent switch (double key)", + "bymiot.switch.2kwls3": "wei lai ju Zero fire intelligent switch (double key)", + "bymiot.switch.2kwlv1": "Future Juqing double key strong current switch", "bymiot.switch.2kwlv2": "未来居双键强电无线开关", "bymiot.switch.3keyv1": "未来居三键强电开关", + "bymiot.switch.3kwls2": "Wei lai ju Single (zero) fire compatible intelligent switch (three key)", + "bymiot.switch.3kwls3": "wei lai ju Zero fire intelligent switch (three key)", + "bymiot.switch.3kwlv1": "Future Juqing three key strong current switch", "bymiot.switch.3kwlv2": "未来居三键强电无线开关", "bymiot.switch.4keyv1": "未来居四键强电开关", + "bymiot.switch.4kwls2": "Wei lai ju Single (zero) fire compatible intelligent switch (four key)", + "bymiot.switch.4kwls3": "wei lai ju Zero fire intelligent switch (four key)", + "bymiot.switch.4kwlv1": "Future Juqing four key strong current switch", "bymiot.switch.4kwlv2": "未来居四键强电无线开关", "bymiot.switch.6keyv1": "未来居六键强电开关", + "bymiot.switch.6kwlv1": "Future Juqing six key strong current switch", "bymiot.switch.6kwlv2": "未来居六键强电无线开关", "bymiot.switch.nad1bs": "Nano SubDevice -1 Button Switch", "bymiot.switch.nad2bs": "Nano SubDevice -2 Button Switch", @@ -463,8 +578,10 @@ "careli.fryer.maf04": "Mijia Smart Air Fryer Pro 4L", "careli.fryer.maf05a": "Xiaomi Smart Air Fryer Pro 4L", "careli.fryer.maf06a": "Mijia Smart Air Fryer 4.5L", + "careli.fryer.maf06b": "Mijia Smart Air Fryer 4.5L", "careli.fryer.maf07": "Mi Smart Air Fryer (3.5L)", "careli.fryer.maf07c": "Mijia Smart Air Fryer 5.5L (Transparent Window)", + "careli.fryer.maf09a": "Mijia Smart Air Fryer 6.5L(Tender Roast)", "careli.fryer.maf10a": "Xiaomi Smart Air Fryer 6.5L", "careli.fryer.ybaf01": "Upany Air Fryer YB-2208DTW", "careli.fryer.ybaf03": "KitchenMi Smart Air Fryer 6007WA", @@ -481,26 +598,45 @@ "cddz.plug.pc01m": "Jiuhao computer boot card (MESH)", "cddz.plug.pc01w": "Jiuhao computer boot card", "cdn.bhf_light.zjd606": "CDN intelligent heater", + "cdn.curtain.kh01": "PLC Intelligent Curtain for CDN.SJ (Opening and closing)", "cdn.gateway.wgdg1": "PLC gateway for CDN.SJ", - "cdn.light.12w2o": "Constant current PLC color temperature driver 12W for CDN.SJ", - "cdn.light.150w1o": "Constant voltage PLC dimming driver 150W for CDN.SJ", - "cdn.light.150w2o": "Constant voltage PLC color temperature driver 150W for CDN.SJ", + "cdn.light.12w1o": "Constant current PLC dimming driver for CDN.SJ", + "cdn.light.12w2o": "Constant current PLC color temperature driver for CDN.SJ", + "cdn.light.150w1o": "Constant voltage PLC dimming driver for CDN.SJ", + "cdn.light.150w2o": "Constant voltage PLC color temperature driver for CDN.SJ", + "cdn.light.150w5o": "Constant voltage PLC RGBCW driver for CDN.SJ", "cdn.light.75w1o": "Constant voltage PLC dimming driver 75W for CDN.SJ", "cdn.light.75w2o": "Constant voltage PLC color temperature driver 75W for CDN.SJ", + "cdn.light.75w5o": "Constant voltage PLC RGBCW driver 75W for CDN.SJ", + "cdn.light.cx01": "PLC magnetic suction light for CDN.SJ (dimming)", + "cdn.light.cx02": "PLC magnetic suction light for CDN.SJ (color temperature)", + "cdn.light.k200": "PLC switch controller for CDN.SJ", + "cdn.light.td001": "PLC to 0-10V controller for CDN.SJ (dimming )", + "cdn.light.td002": "PLC to 0-10V controller for CDN.SJ (color temperature)", "cdn.light.w00a02": "Seton monochrome light strip", + "cdn.light.w00a03": "Xidun Shejian LED sterilization kitchen and bathroom light", "cdn.light.wy0a01": "Xidun 26 Series Smart Spotlight", "cdn.light.wy0a03": "Xidun 36 Series Smart Spotlight", "cdn.light.wy0a04": "Xidun Constant Current Smart Drive", "cdn.light.wy0a05": "Seton two-color light strip", + "cdn.light.wy0a06": "Xidun Lighting Smart light D", + "cdn.light.wy0a07": "Xidun Lighting Smart light HL", + "cdn.light.wy0a08": "Xidun Lighting Smart light X", + "cdn.light.wy0a09": "Xidun Lighting Smart light XL", + "cdn.light.wy0a10": "Xidun Lighting Smart light DL", "cdn.remote.c4m3": "PLC scene panel (Four key) for CDN.SJ", "cdn.remote.c6m3": "PLC scene panel (Six key) for CDN.SJ", "cdn.remote.x1md2": "SJ 2-button scene switch", "cdn.remote.x1md3": "SJ 3-button scene switch", + "cdn.switch.fh002": "PLC composite panel (Four key) for CDN.SJ", + "cdn.switch.fh003": "PLC composite panel (Six key) for CDN.SJ", "cdn.switch.x1msl2": "SJ Smart Switch(2 keys)", "cdn.switch.x1msl3": "SJ Smart Switch(3 keys)", - "cetus.derh.1021": "Epin dehumidifier STSD20-1021/1022", + "cdn.switch.x6": "Six key composite dimming panel", + "cetus.derh.1021": "CETUS Dehumidifier STSD20-1021/1022", "cgllc.airm.cgd1st": "Qingping Air Monitor Lite", "cgllc.airm.cgdn1": "Qingping Air Monitor Lite", + "cgllc.airm.cgs2": "Qingping Air Monitor 2", "cgllc.airmonitor.b1": "Mi Multifunction Air Monitor", "cgllc.airmonitor.s1": "Qingping Air Monitor", "cgllc.clock.cgc1": "Qingping Bluetooth Clock", @@ -523,23 +659,33 @@ "chuangmi.camera.026c02": "Mi 360° Camera (1080p)", "chuangmi.camera.029a02": "Mi 360° Home Security Camera 2K", "chuangmi.camera.036a02": "IMILAB Home Security Camera Y2", - "chuangmi.camera.038a02": "IMILAB C21", + "chuangmi.camera.038a02": "IMILAB Home Security Camera C21", "chuangmi.camera.039a01": "Xiaomi Smart Camera C400", "chuangmi.camera.039a04": "Xiaomi Smart Camera C400", "chuangmi.camera.039c01": "Xiaomi Smart Camera C400", - "chuangmi.camera.040a02": "IMILAB EC6 Outdoor Camera", + "chuangmi.camera.039c04": "Xiaomi Smart Camera C400", + "chuangmi.camera.040a02": "IMILAB EC3 Lite Outdoor Security Camera", "chuangmi.camera.042a02": "IMILAB Security Camera EC3 Pro", "chuangmi.camera.046a01": "Mi 360° Camera (1080p)", "chuangmi.camera.046b02": "IMILAB Home Security Camera Y2", "chuangmi.camera.046c04": "Xiaomi Smart Camera C200", "chuangmi.camera.046d02": "IMILAB Home Security Camera Y2", - "chuangmi.camera.049a01": "Xiaomi 360° Home Security Camera 2", + "chuangmi.camera.049a01": "Xiaomi Smart Camera C400", "chuangmi.camera.051a01": "Xiaomi Smart Camera 2 AI Enhanced", "chuangmi.camera.055a02": "IMILAB EC5 Floodlight Camera", "chuangmi.camera.055c02": "IMILAB EC5 Floodlight Camera", "chuangmi.camera.060a02": "IMILAB C22", + "chuangmi.camera.061a01": "Xiaomi Smart Camera C500 Pro", + "chuangmi.camera.061a03": "Xiaomi Smart Camera C500 Pro", + "chuangmi.camera.065ac1": "IMILAB EC6 Outdoor Security Camera", + "chuangmi.camera.066a01": "Xiaomi Smart Baby Monitor Camera", + "chuangmi.camera.068ac1": "IMILAB EC6 Dual", "chuangmi.camera.069a01": "Xiaomi Smart Camera 3", + "chuangmi.camera.070a02": "IMILAB C22", "chuangmi.camera.27a02": "IMILAB C10", + "chuangmi.camera.46e01": "IMILAB C21", + "chuangmi.camera.72ac1": "Xiaomi Smart Camera C300 Dual", + "chuangmi.camera.81ac1": "Xiaomi Smart Camera C700", "chuangmi.camera.ip026c": "Mi 360° Home Security Camera 1080p Essential", "chuangmi.camera.ip029a": "Mi 360° Home Security Camera 2K", "chuangmi.camera.ipc004b": "IMI Home Security Camera 720P Youth", @@ -616,7 +762,9 @@ "chuangmi.vacuum.hmi707": "IMILAB V1 Vacuuming Robot", "chuangmi.wifi.v1": "小米随身WIFI", "chunmi.cooker.c301": "Mijia Smart Rice Cooker Mini 2", - "chunmi.cooker.eh1": "Mi Smart MultiCooker 1.6L", + "chunmi.cooker.cmwy3": "Xiaomi Smart IH Rice Cooker 3L", + "chunmi.cooker.cmwy4": "Xiaomi Smart IH Rice Cooker 4L", + "chunmi.cooker.eh1": "Mijia Rice cooker", "chunmi.cooker.eh3": "Mijia Smart Rice Cooker Mini 2", "chunmi.cooker.eh402": "Mi Smart Multicooker 4L", "chunmi.cooker.js5": "Mijia Smart Fast Rice Cooker 5L", @@ -640,13 +788,16 @@ "chunmi.cooker.wy3": "Xiaomi Smart Rice Cooker 3L", "chunmi.cooker.wy4": "Xiaomi Smart Rice Cooker 4L", "chunmi.cooker.ztw02": "zhiwuzhu Rice Cooker 1.6L", - "chunmi.cooker.zwz01": "ZHIWUZHU Cooking Intelligent Rice Cooker 4L", + "chunmi.cooker.zwz01": "zhiwuzhu Smart Rice Cooker L1", "chunmi.cooker.zwz02": "ZHIWUZHU Rice Cooker 1.6L", "chunmi.cooker.zwz04": "ZHIWUZHU Smart Rice Cooker 1.6L", + "chunmi.fan.lft03": "Lifeite Air Circulator Fan", "chunmi.health_pot.a1": "Mi Smart Multi-functional Kettle", + "chunmi.health_pot.cmpa1": "Mi Smart Multi-functional Kettle", "chunmi.health_pot.zwza1": "ZHIWUZHU Smart Multi-functional Kettle", "chunmi.hood.tkx1": "TOKIT Ultra-thin Cover Range Hood X1 Air Curtain", "chunmi.hood.tkx102": "TOKIT Ultra-thin Cover Range Hood X1 Air Curtain (White)", + "chunmi.i_stove.p1": "Mijia Multifunction Kitchen Range P1", "chunmi.i_stove.s1": "Mijia Multifunction Kitchen Range S1", "chunmi.i_stove.s1y": "Mijia Multifunction Kitchen Range S1", "chunmi.i_stove.x1": "TOKIT smart gas stove X1", @@ -658,6 +809,7 @@ "chunmi.ihcooker.exp1": "Mi Induction Cooker", "chunmi.ihcooker.hk1": "Mi Induction Cooker", "chunmi.ihcooker.korea1": "Mi Induction Cooker", + "chunmi.ihcooker.lft01": "Lifeite Smart Induction Cooker", "chunmi.ihcooker.slim": "Mi Induction Cooker Ultra Slim", "chunmi.ihcooker.tkcbeu": "TOKIT Razor Cooktop Pro", "chunmi.ihcooker.tkcbjp": "TOKIT Razor Cooktop Pro (JPN)", @@ -679,6 +831,8 @@ "chunmi.juicer.uka1": "Xiaomi Smart Blender", "chunmi.mfcp.c3": "Mijia Smart Cooking Robot", "chunmi.mfcp.c3os": "Xiaomi Smart Cooking Robot", + "chunmi.microwave.cmwb3": "Mijia Smart Microwave 20L", + "chunmi.microwave.cmwk2": "Mi Smart Microwave Oven with Grill", "chunmi.microwave.n20l01": "Mi Smart Microwave Oven", "chunmi.microwave.n20l02": "Mi Smart Microwave Oven", "chunmi.microwave.n23l01": "Mi Smart Microwave Oven with Grill", @@ -690,6 +844,7 @@ "chunmi.oven.tsx8": "Mijia Smart Combi Microwave Steam Oven", "chunmi.oven.x02": "Mi Smart Steam Oven (12L)", "chunmi.oven.x13": "Mijia Smart Oven 40L", + "chunmi.oven.x14": "Mijia Smart Steam Oven 20L", "chunmi.pre_cooker.dylg5": "Mi Smart Pressure Cooker 5L", "chunmi.pre_cooker.eh1": "Mi Smart Pressure Cooker", "chunmi.pre_cooker.mini1": "Mi Smart Pressure Cooker 2.5L", @@ -718,10 +873,15 @@ "codoon.bleshoes.s10k": "CODOOON RUNNER 10K", "codoon.watch.s1": "CODOON GPS SPORT WATCH S1", "coli.waterpuri.nf4645": "COLI Nanofiltration Intelligent Water Purifier", - "comely.light.wy0a01": "Comely Smart Light", + "comely.light.wy0a01": "Comely Intelligent lighting", + "comely.light.wy0a02": "Xinteli intelligent lamps", "cozy.toilet.jittgo": "JITTGO smart toilet", "cozy.toilet.noeo": "NOEO smart toilet", "cozy.toilet.s1": "Raywing X1 smart toilet", + "cqzx.switch.sw1a01": "Zhixin Intelligent M1 Pro switch", + "cqzx.switch.sw1a02": "Michi M1 Pro switch", + "creat6.curtain.ct05": "Create multi-use curtain(mesh)", + "creat6.light.lt07": "Create Smart 2-Colors Light 07P Mesh", "crzm.light.w00a01": "NW resistant simple point eye protection no stroboscopic single color intelligent light belt", "crzm.light.wy0a01": "NW resistant simple point eye protection no stroboscopic tricolor intelligent light belt", "crzm.light.wy0a02": "Anti-glare high-display spotlight pro 1", @@ -735,6 +895,7 @@ "cubee.airrtc.th123w": "Heatcold UFH Thermostat", "cubee.airrtc.th125a": "Heatcold FCU thermostat", "cubee.airrtc.th125t": "Heatcold Heat Pump Thermostat", + "cuco.acpartner.ap2a": "Diaoxiaoku AC Partner AP2", "cuco.acpartner.cp6": "Gosund AC Partner CP6", "cuco.light.sl4": "Smart Light SL4", "cuco.light.sl4a": "Smart Light Strip SL4", @@ -780,10 +941,43 @@ "cuco.switch.s6amtd": "Dianxiaoku Smart Switch S6AM", "cuco.switch.s6amts": "Gosund Smart Switch S6AM", "cxds.light.wymz01": "Muzi Intelligent Light", + "cxw.light.wyfv01": "Mesh Fan Light Series V1", + "cxw.light.wyv02": "Mesh color temperature lamp series V2", "cxw.plug.v1": "Mesh Smart Socket Series V1", + "cxw.remote.ble006": "Eight-scene Dimmable and Color-Temperature Smart Knob", + "cxw.remote.panv01": "Eight-Key Scene Panel V1", + "cxw.switch.swv01": "Mesh intelligent disconnector series V1", + "cycle.waterheater.d1": "CYCLE Smart Hot-water Circulator D1", "cykj.hood.jyj22": "Mijia Smart Purifying Range Hood P1", "cykj.hood.jyjs1": "Mi Smart Air Purification Range Hood S1", "cykj.hood.yjc901": "cleadeep hood", + "cym.magic_touch.a12": "Muselove Massage belt A12", + "daghat.fan.v1ifm": "Duohao Intelligent Fan", + "daikin.airc.k32": "大容量厨房(标准版/黑奢版)", + "daikin.aircondition.k1": "智能3D气流风管式温湿平衡型/3D气流风管式温湿平衡型", + "daikin.aircondition.k10": "单向气流嵌入式", + "daikin.aircondition.k11": "智能感知环绕气流嵌入式", + "daikin.aircondition.k12": "环绕气流嵌入式(全效型/低矮型)", + "daikin.aircondition.k13": "中静压风管机(全效型/低矮型)", + "daikin.aircondition.k14": "自由静压风管式", + "daikin.aircondition.k15": "内藏落地式(全效型/低矮型)", + "daikin.aircondition.k16": "明装落地式(全效型/低矮型)", + "daikin.aircondition.k17": "挂壁式", + "daikin.aircondition.k18": "智能3D气流风管式 新风净化型/3D气流风管式 新风净化型", + "daikin.aircondition.k19": "超薄风管式新风净化型", + "daikin.aircondition.k2": "超薄风管式温湿平衡型", + "daikin.aircondition.k20": "灯槽专用室内机标准型", + "daikin.aircondition.k21": "灯槽专用室内机Air Mirror黑奢型", + "daikin.aircondition.k3": "衣帽间防潮嵌入式标准式", + "daikin.aircondition.k4": "智能3D气流风管式PM2.5净化型/3D气流风管式PM2.5净化型", + "daikin.aircondition.k5": "超薄风管式PM2.5净化型/超薄风管式标准型", + "daikin.aircondition.k6": "智能3D气流风管式标准型/3D气流风管式标准型", + "daikin.aircondition.k7": "超薄风管式大容量型", + "daikin.aircondition.k8": "卫浴用嵌入式标准型", + "daikin.aircondition.k9": "高耐久厨房用嵌入式标准型/大容量型", + "daikin.airfresh.k22": "全热交", + "daikin.airfresh.k30": "明装新风净化系统(转角卫士)", + "daikin.airfresh.k33": "双直流马达新风奢悦系列/双直流马达小型新风系列", "daolai.light.dlb001": "LED Scene Lamp", "daolai.light.dls002": "Smart Mesh Color Temperature Lamp Pro", "daolai.light.dls006": "Smart WiFi Color Temperature Lamp Pro", @@ -796,15 +990,18 @@ "davell.airrtc.dv323x": "Heating thermostat", "dawn.toilet.02": "ZBZ Smart toilet", "dawn.toilet.808": "KeEnDa All-in-one smart toilet 808", + "dawn.toilet.max808": "Smart toilet MAX", "dayang.mosq.dyt16s": "Mosquito lamp", "dayang.mosq.qqtm6": "QQT Smart Mosquito Trap PRO QQT-M6", - "dayang.mosq.qqtq4": "QQT Smart Electric Mosquito Liquid Vaporizer QQT-Q4", + "dayang.mosq.qqtq4": "COKIT mosquito repellent vaporizer CO-Q4", "ddjzm.light.wy0a01": "Smart ceiling lamp of Shuai Lighthouse", "ddk.light.wy0a01": "NIOYE Intelligent lamp", "ddk.light.wyra01": "NIOYE full color LED lamp", "ddk.light.wyra02": "NIOYE Music rhythm color light", "ddk.light.wyra03": "NIOYE intelligent color light", "ddy.switch.sw4a02": "SZGL intelligent induction switch four key Mesh version", + "deerma.humidifier.300dw": "Deerma Humidifier SJS300W", + "deerma.humidifier.990dw": "Deerma Humidifier", "deerma.humidifier.ct500": "Evaporative Humidifier", "deerma.humidifier.cz300": "DEERMA Thermal Distillation Humidifier", "deerma.humidifier.jsq": "Mi Smart Antibacterial Humidifier", @@ -825,6 +1022,7 @@ "degree.lunar.smh013": "37 Degree Sleep Tracking Strap SMH013", "deruci.bed.mcw1": "Derucci Intelligent Ventilation Mattress Air-pro", "desay.bleshoes.s311": "90 urevo", + "deshi8.scales.t600": "Deshi Smart body fat scale T600", "devcea.light.ls2302": "IKEA MYRKISEL E27 600lm Smart bulb", "devcea.light.ls2303": "IKEA MYRKISEL E27 1055lm Smart bulb", "devcea.light.ls2304": "IKEA MYRKISEL E14 470lm Smart bulb", @@ -835,6 +1033,8 @@ "deye.derh.z12a3": "Deye dehumidifier", "deye.derh.z20": "Deye dehumidifier DYD-Z20B3", "dfl888.toilet.toilet": "Smart Toilet", + "dgqh.magic_touch.myj02": "MONYOE Inflatable massage neck pillow MYJ02", + "dhdzkj.airc.air01": "DiHang Air conditioning intelligent control gateway G/Z 770", "dhzm.light.wy0a01": "Compact bedroom lamp", "dhzn.switch.sw0a01": "Lezhigou WiFi light switch", "di8hao.heater.m3": "Smart Thermostat DKM3", @@ -884,24 +1084,58 @@ "dmaker.humidifier.p2": "Mijia Smart Evaporative Humidifier 2", "dmaker.waterpuri.600g": "Dimi RO water purifier 650G", "dmq.light.wy0a01": "DMS Smart downlight", + "dnake.curtain.ct05": "Dnake Smart curtain S1-Mesh", + "dnake.switch.bln04": "Dnake color screen switch panel G2-Mesh", + "dnake.switch.sw1b01": "Dnake Intelligent One Button Switch Panel", + "dnake.switch.sw2b01": "Dnake Intelligent Two Key Switch Panel", + "dnake.switch.sw3b01": "Dnake Intelligent Three Key Switch Panel", + "dnake.switch.sw4b01": "Dnake intelligent four key switch panel", "doco.fcb.docov001": "DOCO", "dong.light.wy0a01": "Dongdong simple smart living room lamp", "doorma.curtain.cura01": "Ai home smart curtain Mesh", "dooya.airer.mjlyj": "PanPan Smart Clothes Rack", "dooya.curtain.230x5": "Dooya Curtain X5", + "dooya.curtain.270q5": "Dooya smart curtain Q5", + "dooya.curtain.99tn": "Dooya smart curtain D12", "dooya.curtain.c1": "DooyaCurtainController", + "dooya.curtain.d10x": "Dooya Smart Curtain D10", + "dooya.curtain.d11x": "Dooya Smart Curtain D11", + "dooya.curtain.d15x": "Dooya Smart Curtain D15", + "dooya.curtain.d1li": "Dooya Curtain M7Li", "dooya.curtain.d1xc": "Dooya Curtain D1-XC", + "dooya.curtain.d3": "dooya Curtain Treasure D3", + "dooya.curtain.d8xc2": "Dooya Curtain D8-XC", "dooya.curtain.d8xwb": "Dooya Curtain d8xwb", + "dooya.curtain.d9pro": "Dooya Curtain D9", + "dooya.curtain.dk66": "DOOYA Dream Curtain MH8", + "dooya.curtain.dk71": "Dooya Curtain DK70", + "dooya.curtain.dt230": "Dooya Smart Curtain DT230", + "dooya.curtain.dt82n": "Dooya Smart Curtain DT82", + "dooya.curtain.dt860": "Dooya Kirin smart curtain 860", + "dooya.curtain.dt92": "Dooya Smart Curtain DT92", "dooya.curtain.k60": "DOOYA Dream Curtain DK60", + "dooya.curtain.km2": "Sunflower smart curtains KM2-C", "dooya.curtain.m03": "DOOYA Smart Curtain M3", "dooya.curtain.m1": "DooyaSmartCurtain", + "dooya.curtain.m11": "Dooya Curtain M11", + "dooya.curtain.m1p": "Dooya Smart Curtain M1", "dooya.curtain.m2": "Dooya Curtain", + "dooya.curtain.m2p": "Dooya Curtain M2", "dooya.curtain.m5": "Dooya Curtain", "dooya.curtain.m7": "DOOYA Smart Curtain M7", "dooya.curtain.m7li": "Dooya Curtain M6Li", + "dooya.curtain.mc5": "dooya Smart curtains MC5", + "dooya.curtain.mc5pro": "Duya Smart Curtains MC5PLUS", + "dooya.curtain.mh9": "DOOYA Intelligent Dream Curtain MH9", + "dooya.curtain.r8762e": "SFCurtainKM2", "dooya.curtain.w1578": "DT82TN/S", "dooya.curtain.x7": "Dooya Smart Curtain x7", "dooya.curtain.x7pro": "Dooya X7 Pro", + "dooya.curtain.x9": "Dooya Smart Curtain X9", + "dooya.curtain.ys7": "Dooya smart curtain YS7", + "dooya.curtain.z82": "Curtain Bang Impression Smart Curtain Z8WIFI", + "dooya.curtain.z8mesh": "Curtain Bang Impression Smart Curtain Z8", + "dooya.motor.riye": "DOOYA Intelligent Day And Night Honeycomb Controller FC2", "dotdot.light.dian24": "Diandian24w", "dotdot.light.dian45": "Diandian45w", "dotdot.light.dian90": "Diandian90w", @@ -953,6 +1187,7 @@ "dreame.vacuum.r2216o": "DreameBot L10s Pro", "dreame.vacuum.r2228": "DreameBot S10", "dreame.vacuum.r2228o": "DreameBot L10s Ultra", + "dreame.vacuum.r2228z": "DreameBot L10s Ultra", "dreame.vacuum.r2232a": "DreameBot W10s Pro", "dreame.vacuum.r2232c": "DreameBot L10s Prime", "dreame.vacuum.r2233": "DreameBot S10 Pro", @@ -966,6 +1201,7 @@ "dsm.lock.q3": "Q3", "dsm.lock.q3p": "DESSMANN Q3P", "dsm.lock.r5": "DESSMANN Facial recognition smart lock-Di R5", + "dsmile.bhf_light.001": "Top good beauty Smart Bath Heater C7L", "dtr.magic_touch.211mgr": "PGG Neck Massager P5B", "dtr.magic_touch.p6b": "PGG Neck Massager P6", "dtr.magic_touch.p6c": "PGG intelligent neck massage P6", @@ -975,6 +1211,7 @@ "duoqin.safe.pbfv01": "Privacy box for finger vein identification", "dwdz.switch.sw0a01": "Scenario mesh breaker DBS version", "dwjxf.airfresh.bdair": "Fifth season new fan", + "dwjxf.airfresh.bdair3": "Season 5 Fresh Air Fan M", "dz888.toilet.m": "XiaoHong Smart Toilet", "e11035.airer.1208a": "Heichuang HRLCHURE intelligent clothes hanger", "e11035.airer.1208b": "LFK intelligent clothes hanger", @@ -995,18 +1232,24 @@ "eda.switch.switch": "Earda Mesh Switch 1", "edon.humidifier.s108e1": "EDON 39° Humidifier", "eizi.toothbrush.sy01": "EIZI UltraClean AI Electric Toothbrush MAGIC 01", + "emelit.switch.xmrp00": "MixDALI Smart Switch Panel", "enchen.razor.bs8": "enchen smart shaver BS8", + "enchen.razor.d8": "Yingqu Intelligent shaver D8", "enjia1.bed.ej001": "恩嘉智能床", "enjia1.sofa.ej002": "恩嘉智能沙发", "era.airp.cwb03": "EraClean Intelligent deodorizer", "era.diffuser.ws01": "Smart Odor Eliminator", "era.steriliser.gc01": "UVC sterilizing ultrasonic cleaner", + "era.ysj.b65": "BluePro Cold Boiled Water Dispenser", "etern.airfresh.nh550": "QUICK IN", "evecca.wopener.bwp03": "EVECCA Smart Sliding Window Opener 1C", + "evecca.wopener.na03ma": "EVECCA Internet Assistant 3", "ezhome.light.l0001": "Ezhome Colorful Music Light Dimmer", "ezhome.switch.z4001": "One touch switch panel", "ezhome.switch.z4002": "Two touch switch panel", "ezhome.switch.z4003": "Three-position touch switch panel", + "fangdi.light.fgc001": "MixDALI dimming and TC control lamp", + "fantq0.light.wy0a02": "Fontahi Essence two color warm light companion", "fawad.aircondition.3010": "FOWAD air conditioning temperature controller 2", "fawad.airrtc.30011": "FOWAD VRF Thermostat", "fawad.airrtc.30012": "FOWAD VRF Thermostat - Enjoy", @@ -1016,19 +1259,27 @@ "fbs.airmonitor.pth02": "AIR QUALITY TESTER", "feebo.jmprope.fj6151": "FEEBO Smart Jump Rope", "feiyu.hair.am02": "KiCA Wireless High Speed Hair Dryer", + "fengmi.engrave.demo01": "Mijia Laser Engraver", "fengmi.projector.015fc2": "Xming Q2 Smart Projector", "fengmi.projector.015fc3": "Xming Q3 Smart Projector", + "fengmi.projector.015fco": "Xming 0101M Smart Projector", + "fengmi.projector.015fo2": "Xming Q5 Smart Projector", "fengmi.projector.025fc2": "Xming Q2 Pro Smart Projector", "fengmi.projector.025fc3": "Xming Q3 Pro Smart Projector", "fengmi.projector.045fc": "Formovie S5 Laser Projector", + "fengmi.projector.045mc2": "Mi Smart Projector 2S", "fengmi.projector.055fc": "Formovie R1 Nano UST Laser Projector", "fengmi.projector.085mc2": "Xiaomi Projector 2S", "fengmi.projector.146fc": "Formovie V10 4K Projector", "fengmi.projector.166fc2": "Formovie Laser TV Cinema 3", "fengmi.projector.196fc": "Formovie X5 4K Laser Projector", + "fengmi.projector.206ac3": "Appotronics Laser Home Projector B300T", + "fengmi.projector.206fc3": "Formovie T2 Laser TV", "fengmi.projector.c015": "Xming Q1 mini projector", "fengmi.projector.c025": "Xming Q1 Pro Smart Projector", "fengmi.projector.c045fc": "Xming Q3 Max Smart Projector", + "fengmi.projector.c065f": "Xming 0601 Smart Projector", + "fengmi.projector.c066f": "Xming 0611 Projector", "fengmi.projector.fm05": "Fengmi Young", "fengmi.projector.fm15": "Mijia Laser TV", "fengmi.projector.fm154k": "Mijia Laser Projection TV 4K", @@ -1070,6 +1321,7 @@ "fjrh.massage.rh7600": "RH multifunctional massage chair", "fnirsi.etool.40mpro": "IR40 Smart Rangefinder", "fnirsi.etool.fn40m": "FNIRSI 40m Intelligent Rangefinder", + "fojee.toilet.fjzn01": "Fulian Smart Toilet", "fotile.hood.emd1tmi": "CXW-200-EMD1T.MI", "frfox.switch.bl01": "Single button fire Mesh switch", "frfox.switch.bl02": "Two buttons fire Mesh switch", @@ -1077,14 +1329,42 @@ "fssd.tow_w.kb01": "Cabe electric towel rack", "fssd.tow_w.lc20a9": "Smart electric towel rack", "ftd.bhf_light.testmd": "Intelligent Bath Heater(WIFI)", + "ftd.light.cwrgb1": "FTD Intelligent Color Light (MESH)", "ftd.light.dsplmp": "Intelligent cw lamp v3(mesh)", + "ftd.light.dupont": "Dupont lighting", "ftd.light.ftdlmp": "Intelligent cw lamp v2(mesh)", + "ftd.light.hglmp": "HIGOLD Intelligent Cabinet Light (MESH)", + "ftd.light.lmpami": "AMI Smart Bulb", + "ftd.light.lmpfan": "Intelligent Fan Light V1 (WIFI)", + "ftd.light.lmpyul": "RF Smart Lighting V1 (MESH)", + "ftd.light.lpv2sl": "FTD Intelligent cw lamp v2sl(mesh)", + "ftd.light.lpv3sl": "Intelligent cw lamp v3sl(mesh)", + "ftd.light.nomain": "Intelligent Rhythm Light", + "ftd.light.wfibrm": "Intelligent Rhythm CW Light V1", + "ftd.light.wfibv2": "Intelligent Rhythm CW Light V2", "ftd.light.wfilmp": "Intelligent cw lamp(WIFI)", + "ftd.light.wfilv2": "Intelligent cw lamp v2(WIFI)", + "ftd.switch.swttdq": "FTD Intelligent Switch Pro(MESH)", + "ftd.ven_fan.wfifbh": "Mkmikoo Smart Fan", "ftds.light.wyft1": "Fantong Intelligent Lamp", + "ftzm.light.wy0a01": "Smart downlights Bluetooth Mesh edition", + "ftzm.light.wy0a02": "Smart strip light with Bluetooth Mesh version", "fyw.switch.sw0a01": "Xiaowei Scene MESH Switch", + "fzypyx.derh.snyp13": "Suning Yipin dehumidifier", "galime.curtain.gm46": "Dinton Smart Curtain", "galime.curtain.gp72": "Dinton Smart Sliding Window Opener", "galime.curtain.gz45": "Ding Dong intelligent rolling curtain motor", + "gaodi.sofa.001s": "CAASACI Smart electric sofa SFY004", + "gaodi.sofa.002t": "CAASACI Smart electric sofa Z003", + "gaosd.curtain.cmotor": "Gsd PLC curtain motor MICMK-01", + "gaosd.light.cctled": "Gsd PLC dimming control device", + "gaosd.light.cxled": "Gsd PLC magnetic track light", + "gaosd.switch.gsp1k": "Gsd PLC intelligent one-position compound switch (N,L)", + "gaosd.switch.gsp2k": "Gsd PLC intelligent two-position compound switch (N,L)", + "gaosd.switch.gsp3k": "Gsd PLC intelligent three-position compound switch (N,L)", + "gaosd.switch.gsp4k": "Gsd PLC intelligent four-position compound switch (N,L)", + "gaosd.switch.gsp6k": "Gsd PLC intelligent six-position compound switch (N,L)", + "gaosd.switch.gsp8k": "Gsd PLC intelligent eight-position compound switch (N,L)", "gdds.light.wy0a01": "High Light Master Smart Light", "gdxdkj.blanket.01": "XD-SNT01", "gdxdkj.blanket.smxdr1": "Xiaoda Graphene smart electric blanket", @@ -1093,33 +1373,64 @@ "gdyimu.vacuum.r1": "Lydsto Lydsto R1 A Intelligent Sweep\u0026Mop Integrated Robot", "gdyimu.vacuum.r1da": "Lydsto Sweeping And Mopping Robot R1DA", "ge.light.mono1": "X-Bulb智能灯泡", + "gerwin.curtain.25xm": "GM Intelligent Electric Curtain xm", + "gerwin.curtain.gm24tf": "GM day and night curtain motor", "gerwin.curtain.gm25l": "GM Intelligent Electric Curtain", "gerwin.curtain.gm25xm": "GM Smart Curtain", "gerwin.curtain.gm35xm": "GM Smart Curtain Motor", + "giot.airer.v1icdw": "V1 Intelligent Clothes Dryer (WIFI)", + "giot.airer.v2icdw": "V2 Intelligent Clothes Dryer (WIFI)", "giot.bhf_light.jpbm": "ARROW Bathroom warmer", "giot.bhf_light.sjbm": "MICOE bath heater", + "giot.bhf_light.v1ibhw": "V1 Intelligent Bath Heater(WiFi)", + "giot.curtain.v1icm": "V1 Intelligent Curtain (Mesh)", "giot.curtain.v5icm": "V1 Lithium battery smart curtain Mesh", "giot.light.aise01": "intelligence Ai scene WIFI two-color light", + "giot.light.dblgt1": "DuPont Ceiling", "giot.light.h60301": "XIERDUN Smart LED Ceiling Light", "giot.light.h86161": "XIERDUN Smart LED Pendant Light", "giot.light.hhyd1": "Moon Shadow Intelligent Eye Protection Lamp", + "giot.light.hwzd1": "Moonshadow Naturul-light Eye-protection no-main light", "giot.light.v3": "V3 Intelligent YW Light(Mesh)", "giot.light.v5ssm": "V5 Intelligent YW Light(Mesh)", "giot.light.v5ssw": "V5 Intelligent YW Light(WiFi)", + "giot.light.v8icm": "V8 Intelligent Color Light (Mesh)", "giot.light.v8ssm": "V8 Intelligent YW Light (Mesh)", + "giot.light.v8ssw": "V8 Intelligent YW Light (WiFi)", + "giot.light.v9ssw": "V9Gra Intelligent Color Temperature Light (WiFi)", + "giot.light.wy0a01": "NUOMI BLE Mesh smart tape lights", "giot.light.xhyd1": "XIERDUN Intelligent Eye Protection Lamp", + "giot.light.xwzd1": "Moonshadow natural light magnetic lamp", "giot.light.y60301": "Yueying Smart LED Ceiling Light", "giot.light.y86161": "Yueying Smart LED Pendant Light", + "giot.motor.v1imm": "V1 Motor Controller(WiFi)", "giot.plug.v3shsm": "V3 Intelligent Single Hole Socket(Mesh)", + "giot.plug.v6shsm": "V6 Intelligent Single Hole Socket(Mesh)", + "giot.remote.v51kwm": "V5 Wireless One Key Switch (BLE)", + "giot.remote.v52kwm": "V5 Wireless Two Key Switch (BLE)", + "giot.remote.v53kwm": "V5 Wireless Three Key Switch (BLE)", + "giot.remote.v54kwm": "V5 Wireless Four Key Switch (BLE)", + "giot.remote.v56kwm": "V5 Wireless Six Key Switch (BLE)", + "giot.remote.v58kwm": "V5 Wireless Eight Key Switch (BLE)", "giot.switch.v3oodm": "V3 Intelligent Switch", "giot.switch.v51ksm": "V5 Intelligent One-Button Switch (Mesh)", "giot.switch.v52ksm": "V5 Intelligent Two-Button Switch (Mesh)", "giot.switch.v53ksm": "V5 Intelligent Three-Button Switch (Mesh)", "giot.switch.v54ksm": "V5 Intelligent Four-Button Switch (Mesh)", + "giot.switch.v61ksm": "V6 Intelligent One Output Switch (Mesh)", + "giot.switch.v62ksm": "V6 Intelligent Two Output Switch (Mesh)", + "giot.switch.v63ksm": "V6 Intelligent Three Output Switch (Mesh)", + "giot.switch.v64ksm": "V6 Intelligent Four Output Switch (Mesh)", "giot.switch.v6oodm": "V6 Intelligent On-off Device(Mesh)", + "giot.switch.v81ksm": "V8Gra Intelligent One way Switch (Mesh2.0)", + "giot.switch.v82ksm": "V8Gra intelligent two-way switch (Mesh2.0)", + "giot.switch.v83ksm": "V8Gra intelligent three-way switch (Mesh2.0)", + "giot.switch.v84ksm": "V8Gra intelligent four-way switch (Mesh2.0)", + "giot.tow_w.v1itrw": "V1 Intelligent towel rack (WiFi)", + "giot.valve.valve1": "Gosvn High Mountain Navigation Intelligent Valve Controller Bluetooth MESH Edition", "gmm.light.wy0a01": "Dual Erotic Scene Wisdom Lamp", "gmm.light.wy0a02": "LED smart light mesh", - "gmn.bhf_light.yb1": "Gomani bath heater", + "gmn.bhf_light.yb1": "Situational smart bath heater", "gmn.light.wy0a01": "Gomanni G1 series ceiling lamp", "gmn.light.wy0a02": "Gomanni Scene two color downlight", "gmn.light.wy0a04": "Gorman Scene Lamp (Mesh version)", @@ -1145,6 +1456,7 @@ "gszn.airer.gs1685": "Mrs. Jin Gui drying rack", "gszn.airer.gs1686": "GS Smart Drying Rack", "gszn.motor.gs168": "Guoshun universal controller", + "gtop.bhf_light.b1": "Intelligent Scenario Bath Heater", "gtop.light.c02": "ZY Intelligent Light Lamp", "gtop.light.c04": "ZY Smart Universal Ceiling Lamp", "gtop.light.c05": "ZY Smart Ceiling Lamp pro", @@ -1153,6 +1465,7 @@ "gtop.light.eps120": "ZhiYue Smart Lighting", "gtop.light.fan03": "Scenario intelligent fan light", "gtop.light.gtop02": "ZhiYue Smart Spotlight", + "gtop.light.koey1": "KOEY Air Circulation Fan Light", "gtop.light.xl01": "ZhiYue Smart Light", "gtop.light.yl01": "Side Smart Ceiling lamp", "gtop.light.yl03": "Defender Smart Ceiling Lamp", @@ -1167,23 +1480,32 @@ "gxhl.switch.7zsw12": "7z Two-key Smart Switch", "gxhl.switch.7zsw13": "7z Three-key Smart Switch", "haibao.pet_waterer.mm2": "Smart water dispenser for pets", + "haier.curtain.cura01": "Haier intelligent curtain motor", "haikuo.cleaner.m7": "Cordless Vacuum Cleaner", "hannto.printer.anise": "Mi Wireless Inkjet Printer", "hannto.printer.basil": "Mi Portable Photo Printer", "hannto.printer.honey": "Mi Wireless Photo Printer", "hannto.printer.honey1s": "Xiaomi Instant Photo Printer 1S", "hannto.printer.lager": "Mi All-in-One Laser Printer K200", + "hannto.printer.mint": "Xiaomi Portable Photo Printer 1S", "hannto.printer.rmy": "Mi Wireless All-in-One Inkjet Printer", "hanyi.airpurifier.kj550": "MiWhole Air Purifier Mix", "hanyi.vacuum.m7pro": "MI WHOLE M7 PRO", "hanyi.vacuum.m8pro": "MIWHOLE M8", + "haoyi.light.hypro1": "Haoyi spotlight (Max)", + "haoyi.light.hypro2": "Haoyi magnetic suction lamp (Max)", + "haoyi.light.wy0a01": "Haoyi 24V constant voltage two colors light controller", + "haoyi.light.wy0a03": "Haoyi full spectrum ceiling light (Max)", + "haoyi.switch.sw0a01": "Haoyi Single Circuit Breaker (Max)", "hbc.light.wy0a01": "Huangde Smart Lamp", "hcs.light.yssl01": "Intelligent scene dimming lamp", "hcznjj.light.wyll01": "Langli intelligent LED ceiling lamp", + "hd699.scales.bf1224": "BMBL Smart body fat Scale BF1224", "hddz.blanket.zndrt": "Smart electric blanket", "hddz.s_lamp.uvl38w": "XiaoDa sterilizing lamp", "hdm.light.wy08a": "Hadaman intelligent LED ceiling lamp", "heko.light.wy0a01": "KEEY-BUS dimming and color control equipment", + "hey.plug.n100": "WDYK Smart Circuit Breaker N1", "hey.relay.h100": "WDYK Smart Controller", "hey.switch.x100": "IOT-BASED MICRO CIRCUIT BREAKER", "hfjh.fishbowl.600": "Desgeo intelligent modular eco-fish tank", @@ -1191,11 +1513,15 @@ "hfjh.fishbowl.m100": "Mijia Smart Fish Tank", "hfjh.fishbowl.v1": "Desgeo smart fishbowl", "hfjh.fishbowl.v2": "Desgeo C series smart fish tank", + "hfzn.desk.hf01": "H\u0026F intelligent lift table", + "hgzjjs.avamp.51m": "Huage MINI5.1 Intelligent Shadow K Audio and Video Amplifier", + "hgzjjs.avamp.mini51": "Huage MINI5.1 Intelligent Cinema Audio and Video Amplifier", "hhcc.bleflowerpot.v2": "Ropot", "hhcc.plantmonitor.v1": "Flower Care", "hith.foot_bath.m1z1": "Xiaomi Smart Collapsible Foot Spa Massager", "hith.foot_bath.mjz1": "Xiaomi Smart Collapsible Foot Spa Massager", "hith.foot_bath.q2": "HITH wireless foot bath Q2", + "hjhr.blanket.hrs51": "Royal Huiren Intelligent Water Heating Blanket SH2-SN04", "hjhr.fan.hcz11a": "DR.HURM 10-inch Portable Folding Fan HCZ11A", "hjk666.toilet.h1": "XiaoKang Smart Toilet", "hlznkj.dental.cs60a": "nyrel smart electric oral irrigator", @@ -1205,7 +1531,11 @@ "hmpace.scales.mibfs": "Mi Body Composition Scale 2", "hmpace.scales.miscale2": "Mi Smart Scale 2", "hmpace.watch.v1": "Amazfit Watch", + "hnjc.scales.tzc01": "Dorray intelligent body fat scale", "homray.sofa.zhsm1": "Cheers Smart Sofa M1", + "hongli.scales.gn007": "Honglin Light Energy body fat scale GN007", + "hooson.lock.tf22": "Cninco Yunzhi lock a grip T1", + "hope.switch.g7": "Smart screen switch M4", "hope.switch.w1": "Smart screen switch", "hope.switch.x3": "X3 Intelligent Switch", "hope.wifispeaker.4plus": "Single source BM", @@ -1243,8 +1573,10 @@ "hti.gateway.123": "123", "htwl.dryer.v1": "Shoes dryer", "huachu.dryer.xqd100": "Smart clothing", + "huadn.blanket.001": "HUADN smart display electric blanket", "huadn.blanket.123456": "Huanding water heating blanket", "huadn.blanket.abcdef": "GIPIN Water heating blanket", + "huadn.blanket.hd": "Ring Ding intelligent water heating blanket HD", "huayi.bhf_light.libra": "HUIZUO LIBRA BATH HEATER Pro", "huayi.light.aqu114": "HUIZUO AQUARIUS Bulb", "huayi.light.ari013": "HUIZUO ARIES For Bedroom", @@ -1294,6 +1626,7 @@ "hvac.airrtc.11m0": "Moehlenhoff Indoor Temperature Controller", "hwzn.light.wy0a01": "Xihui smart ceiling lamp", "hyd.airer.1s": "Mijia Smart Clothes Drying Rack 1S", + "hyd.airer.1s1": "Mijia Smart Clothes Drying Rack 1S", "hyd.airer.cs": "Hooeasy Smart Clothes Dryer-GEN", "hyd.airer.gen": "MrBond Smart Clothes Dryer-GEN", "hyd.airer.gen2": "MrBond Smart Clothes Dryer-GEN", @@ -1322,7 +1655,11 @@ "hyzngc.switch.zm0602": "Smart 2-key Wall Switch", "hyzngc.switch.zm0603": "Smart 3-key Wall Switch", "hyzngc.switch.zm0604": "Smart 4-key Wall Switch", + "hzsj.light.wy0a01": "Shanjing special control scene night light Mesh R1 version", + "hzsj.light.wyra01": "Shanjing special control atmosphere night light Mesh Q1 edition", "hzyx01.beauty.m180": "YUAIMEI Intelligent full effect RF beauty instrument M180", + "iccssi.lock.02": "ICCSSI MX Smart Lock", + "iccssi.lock.y3": "Oakes smart lock Y3", "idelan.aircondition.g1": "Jinxing Smart Air Conditioner", "idelan.aircondition.g2": "Jinxing Smart Air Conditioner", "idelan.aircondition.v1": "Jinxing Smart Air Conditioner", @@ -1360,23 +1697,39 @@ "inovel.projector.me2": "inovel projector", "inshow.watch.w1": "Mi Quartz Watch", "insistek.tracker.wa620": "米哇定位豆", - "iot.diffuser.h2": "HUITAI Diffuser Machine", + "iot.bed.upone": "BLUEBOX electric bed", + "iot.diffuser.h2": "Smart Diffuser Machine", "iot.light.fl02": "Scene Fan Light", + "iot.light.fl03": "Scene Intelligent Lamp pro", "iot.light.fl04": "Intelligent Scene Fan Light", "iot.light.socd01": "dream colour lamp", "iot.light.socd03": "spaceship atmosphere lighting", "iot.light.socw01": "CW cold and warm lamp", "iot.magic_touch.m101": "Intelligent warm palace belt M101", + "iot.plug.cm2": "DYM CM2 metering plug", + "iot.plug.jdls1": "Smart Power Meter Plug M1", + "iot.plug.pw6u1": "LW smart 6 way power strip", "iot.plug.socn1": "Smart Plug P1", + "iot.switch.jdltdq": "Power Meter Mesh intelligent controller", + "iot.switch.kg21m": "Puanda Neutral-Live Smart Switch (Single Control)", + "iot.switch.kg22m": "Puanda Neutral-Live Smart Switch (Double Control)", + "iot.switch.kg23m": "Puanda Neutral-Live Smart Switch (Triple Control)", + "iot.switch.padw2p": "Puanda single-phase intelligent protection switch", + "iot.switch.padwb1": "Puanda three-phase intelligent protection switch", + "iot.switch.tdq3": "Mesh intelligent controller", "iot.tow_w.jd015": "Intelligent electric towel rack", "iracc.aircondition.d19": "hosjoy+", + "isa.camera.cw500": "Xiaomi Outdoor Camera CW500", "isa.camera.df3": "Da Fang SMART CAMERA", "isa.camera.hl5": "XiaoYuan Smart Camera", "isa.camera.hlc6": "Mi Home Security Camera 1080p (Magnetic Mount)", "isa.camera.hlc7": "Mi Camera 2K (Magnetic Mount)", "isa.camera.hlc8": "Xiaomi 360° Outdoor Security Camera CW400", + "isa.camera.hlc8a": "Xiaomi Outdoor Camera CW400", "isa.camera.hlc9a": "Xiaomi Outdoor Camera AW200", + "isa.camera.hlmax": "Xiaomi Outdoor Camera CW500 Dual", "isa.camera.hlv3c": "Hualai small square outdoor camera 2K version", + "isa.camera.hlzoom": "Xiaomi Outdoor Camera CW700S", "isa.camera.isc5": "Xiao Fang SMART CAMERA", "isa.camera.isc5c1": "Xiao Fang SMART CAMERA", "isa.camera.panjd1": "Xiao Fang Smart Camera Pan", @@ -1396,10 +1749,13 @@ "isleep.blanket.hs2201": "LETSLEEP water heated blanket‘HS2201’", "isleep.blanket.hs2205": "LETSLEEP water heated blanket‘HS2205’", "izq.sensor_occupy.24": "ZQ Presence Sensor Lite", + "izq.sensor_occupy.24n": "ZQ Occupy Sensor Ceiling", + "izq.sensor_occupy.ble": "ZQ Occupy Sensor Loong", "izq.sensor_occupy.solo": "ZQ Occupy Sensor Solo", "izq.sensor_occupy.trio": "ZQ Occupy Sensor Trio", "janshi.magic_touch.g2": "G2 Spinal comfort neck massager", "janshi.magic_touch.g20": "G20 Jeeback Neck massager", + "jare.magic_touch.jr688": "Jiaren Massage Shawl JR-688", "jare.massage.jre6": "Jiaren Massage Chair JR-E6", "jare.massage.jrq81u": "Kangjia Massage Chair KZ-RH8800", "jare.massage.rh6687": "Konka Massage Chair KZ-RH6687", @@ -1410,13 +1766,19 @@ "jback.magic_touch.g9": "Waist Massager", "jback.magic_touch.k1pr": "Jeeback Intelligent Neck Massager", "jddm.bhf_light.yb0a01": "Jindundingmei smart bath heater", + "jdjz.light.jdjz01": "JDJZ Ceiling Light V1", + "jdjz.light.jdjzu1": "JDJZ U1 ceiling light", + "jdyw.vacuum.u300p": "U300", "jiawen.light.wy0a02": "Jia Diao guang tiaose intelligent Deng", + "jiayu.scales.bc235": "AI Intelligent Fat Scale PRO", + "jiayu.scales.le5020": "BC Intelligent LED heart rate and body fat scale", "jieman.magic_touch.fbv1": "GAX Bianstone waist and abdomen massager", "jieman.magic_touch.g771": "Yubaina Multifunctional Neck Massager", "jieman.magic_touch.g791": "GAX 8D Cervical vertebra massage apparatus", "jieman.magic_touch.g792": "Kangdoli 8D Cervical vertebra massage apparatus", "jieman.magic_touch.gax1": "GAX Smart Cervical Massage Apparatus", "jieman.magic_touch.gax2": "GAX Multifunctional Neck Massager", + "jieman.magic_touch.j001": "GAX Smart Neck massager J-001", "jieman.magic_touch.j10": "GAX 4D Intelligent Cervical Massage Instrument X", "jieman.magic_touch.js01": "Jishu Intelligent cervical spine massage instrument", "jieman.magic_touch.js03": "Jishu Smart Massager V1", @@ -1424,6 +1786,7 @@ "jieman.magic_touch.kdl0": "Kangduoli Smart Massager", "jieman.magic_touch.kdl2": "Condoli Multifunctional Neck Massager", "jieman.magic_touch.ms9": "Intelligent cervical massage instrument", + "jieman.magic_touch.n88": "GAX Intelligent Warm Palace Belt", "jieman.magic_touch.newf": "New for Smart Massager", "jieman.magic_touch.t100": "GAX Intelligent Head Massager", "jieman.magic_touch.tfs2": "Tefeishi Smart Massager", @@ -1437,9 +1800,15 @@ "jieman.magic_touch.ys01": "Yashen Intelligent cervical massage instrument", "jieman.magic_touch.ys02": "Yashen Smart Massager", "jihisi.light.wy0a01": "JIHISI Intelligent lamp", + "jinpin.derh.ct16": "Ginpine household dehumidifier CT16", "jipin.blanket.tt7xxa": "jipin intelligent mite control electric blanket", "jipin.fan.f001": "jipin intelligent floor fan", + "jipin.fan.f003": "Jipin Smart Internet Air Circulation Fan", + "jipin.fan.f004": "Jipin vertical air circulation fan", + "jipin.fan.f005": "Jipin Air Circulation Fan", + "jipin.fan.f006": "Jipin Smart Internet Flat Floor Fan", "jipin.fryer.my982w": "jipin intelligent cloud visual air fryer", + "jipin.heater.2207": "jipin humidify flame purify heater", "jipin.heater.my204": "JiPin Smart Heater", "jiqid.mistory.ipen1": "iPen", "jiqid.mistory.pro": "Mi Bunny Storyteller", @@ -1455,6 +1824,7 @@ "jmls.light.ls001": "colourful ceiling lamp", "jns.airer.1": "Intelligent clothes hanger", "joybos.airer.jbslyj": "Joybos intelligent electric clothes hanger", + "joypal.massage.jp880": "joypal AI Office massage chair", "jrj.toothbrush.j3m800": "imoya Smart Toothbrush", "jsc.light.wydfn1": "Danfino Intelligent Roof Suction Lamp", "jsc.light.wyls02": "Scene Ble mesh light", @@ -1464,11 +1834,15 @@ "jstar.curtain.jcv24": "JC Smart Blinds", "jstar.curtain.stew": "JC Smart Curtain Motor", "jstar.desk.jcb36": "AIDESK", + "juhl.aircondition.a11": "aircondition", + "juhl.aircondition.hvac": "Hisense Smart Central Air-conditioning", "julun.light.jl0002": "julun smart light", "julun.light.jlcw": "julun smart light(CW)", "julun.light.wyra01": "Great Wheel Yicai Ceiling Light", "julun.light.wyrf01": "JL Colorful Fan Light", "julun.switch.jlsw01": " julun smart switch", + "jxdh.bhf_light.dh001": "No.1 Pro of Zhixin bath heater", + "jxdh.ven_fan.dh004": "No.1 Pro of Zhixin ceiling fan", "jxgc.light.wyxy1": "Xiangyu intelligent LED ceiling lamp", "jxsoft.light.bump1": "JX Smart bulb", "jya.heater.sha1": "Jya Convection Heater", @@ -1484,6 +1858,7 @@ "k0918.toothbrush.t700": "mijia E-toothbrush t700", "k0918.toothbrush.t700i": "Xiaomi Electric Toothbrush T700", "kaadas.airer.km01": "kaadas basal hanger", + "kaadas.lock.m91": "Kaadas Smart Lock K9-S (M)", "kadeer.derh.2202": "AUX KDY-DP22A1 intelligent dehumidifier", "kadeer.derh.x1701": "AUX KDY10-01WS intelligent dehumidifier", "kadeer.fan.22xhr": "Philips L22XHR fan", @@ -1499,14 +1874,22 @@ "kadeer.heater.12b5rw": "JO FOND Indoor heater (electric oil)", "kadeer.heater.15b6rw": "JO FOND Wall mounted electric oiling", "kadeer.heater.200fgr": "Philips Tower Heater Series 3000 A1", + "kadeer.heater.200hrw": "Philips Multifunctional Heater Series 4000 A1", "kadeer.heater.200krw": "AUX tower heater A1", "kadeer.heater.20yrw": "JO FOND Indoor heater (wall mounted heater)", + "kadeer.heater.300arw": "Philips Multifunctional Heater Series 6000 A1", + "kadeer.heater.b73bg1": "Philips Central Electric Heating Series 4000 C1", "kadeer.heater.b73brg": "JO FOND Indoor heater (convection electric heater)", "kadeer.heater.b81rw": "AUX convection heater A1", "kadeer.heater.l200ir": "Philips baseboard heater Series 4000 R1", + "kadeer.heater.l200is": "Philips baseboard heater AHR4126CKD", "kadeer.heater.l200mr": "JO FOND heater", + "kadeer.heater.l200qr": "Philips baseboard heater Series 3000 A1", "kadeer.heater.l220ir": "JO FOND Indoor heater (skirting heater)", + "kadeer.heater.l220pr": "Philips baseboard heater Series 5000 A1", + "kadeer.heater.l250sr": "Philips baseboard heater Series 4000 X1", "kadeer.heater.wys15c": "Philips Vaneless Cooling and Heating Fan Series 5000 A1", + "kaifen.scales.kfmj01": "Kaifeng intelligent body fat scale KF-M01", "kanway.switch.sw4a01": "Kanway Flick Switch Zero Fire D-4K", "kejia.airer.jjs": "GARJOSS Smart Airer", "kejia.airer.krq": "COURAGE Smart Airer", @@ -1523,9 +1906,36 @@ "kk2022.switch.sw4a01": "Four key light control panel zero fire mesh version", "kk2022.switch.sw8a01": "RX Eight key composite panel zero fire mesh version", "klaled.light.wy0a01": "Qilang ALED natural spectrum lamp", + "klaled.light.wy0a02": "Qilang SunnyTop ceiling light", + "klf888.curtain.cura01": "Kelaifu Intelligent Opening and Closing Curtain Electric Curtain", + "klf888.light.wy0a01": "Kelaifu intelligent downlights", + "klf888.light.wy0a02": "Kelaifu smart light belt", + "klf888.light.wy0a03": "Kelaifu Intelligent Magnetic Light", + "klf888.switch.8a01": "Ke Laifu Intelligent Switch Eight Key", + "klf888.switch.sw1a01": "Kelaifu Intelligent Switch A Series One On", + "klf888.switch.sw1b01": "Kelaifu Intelligent Switch B Series One On", + "klf888.switch.sw2a01": "Kelaifu Intelligent Switch A Series Two Open", + "klf888.switch.sw2b01": "Kelaifu intelligent switch B series two open", + "klf888.switch.sw3a01": "Kelaifu Intelligent Switch A Series Three Open", + "klf888.switch.sw3b01": "Kelaifu Intelligent Switch B Series Three Open", + "klf888.switch.sw3c01": "Kelaifu smart Home Panel M4", + "klf888.switch.sw4a01": "Kelaifu Intelligent Switch A Series Four Open", + "klf888.switch.sw4b01": "Kelaifu Intelligent Switch B Series Four Open", "kmhb.fan.kmf1": "KM Smart Cycle Fan", + "koey.airer.wy0a04": "KOEY smart drying rack", + "koey.bhf_light.yb0a01": "KOEY Smart eye care bath heat", "koey.light.wy0a01": "KOEY territory series intelligent tube spotlights", + "koey.light.wy0a02": "KOEY World series ceiling light", + "koey.light.wy0a03": "KOEY Yao series magnetic lamp", + "koey.switch.sw1a01": "KOEY instant series intelligent switch one key", + "koey.switch.sw2a01": "KOEY instant series intelligent open two keys", + "koey.switch.sw3a01": "KOEY instant series intelligent switch three keys", + "koey.switch.sw4a01": "KOEY instant series intelligent open four keys", "kola.milk.v1": "Kola Mother Smart Milking Machine", + "ksks.light.wy0a01": "Kinsuny smart downlights", + "ksks.light.wy0a02": "Kinsuny smart linear light", + "ksks.light.wy0a04": "Kinsuny smart magnetic lamp", + "ksks.switch.sw3a01": "Kinsuny smart switch S2", "ksmb.treadmill.k12": "KingSmith K12 Treadmill", "ksmb.treadmill.m1v1": "Mi Treadmill", "ksmb.treadmill.m2": "Mijia Smart Treadmill", @@ -1538,6 +1948,7 @@ "kunton.plug.skwsg1": "CHLOROP Smart Wall Socket", "kxf321.mop.mo001": "sawadika robot", "kxf321.mop.mo002": "ZDG300s", + "lang.magic_touch.n7": "Intelligent neck and shoulder massager N7", "lbest.airer.lm01": "Clothes Drying Rack", "lbhd.razor.hs150": "Shaver", "lcrmcr.lock.cb2207": "CRMCR intelligent glass door lock", @@ -1546,11 +1957,13 @@ "lcrmcr.safe.25z": "CRMCR Anno Fingerprint Safe Deposit Box 25Z", "lcrmcr.safe.30j": "CRMCR Retro Mechanical Smart Safe Deposit Box", "lcrmcr.safe.30mk": "CRMCR Miike fingerprint safe deposit box", + "lcrmcr.safe.46mn": "CRMCR Mino Intelligent Single Pull Storage Cabinet", "lcrmcr.safe.46yn": "CRMCR Yarno smart safe deposit box", "lcrmcr.safe.an35sidz": "CRMCR iRon electronic safe", "lcrmcr.safe.an35sizw": "CRMCR iRon fingerprint safe", "lcrmcr.safe.d60ht": "CRMCR Hundred-Treasuresmart safe box", "lcrmcr.safe.kmzb53": "CRMCR Smart Safe", + "lcrmcr.safe.mp": "CRMCR Annuo Smart Safe PRO", "lcrmcr.safe.ms30b": "kamai safe box", "lcrmcr.safe.ms30mp": "CRMCR Annuo Smart Safe PRO", "lcrmcr.safe.ms55kn": "CRMCR Kanuo Smart Safe", @@ -1567,6 +1980,8 @@ "leishi.bhf_light.lsyb03": "NVC Smart Yuba N3", "leishi.bhf_light.lsyb04": "NVC Smart Bath-Heater N4", "leishi.bhf_light.pro1": "NVC Smart Bath Heater pro", + "leishi.bhf_light.tyyb": "NVC Smart Bath Heater V3", + "leishi.bhf_light.ybjck": "NVC Smart Bath Heater V", "leishi.bhf_light.yuba02": "NVC Smart Bath-Heater", "leishi.light.cw0a01": "NVC Smart Downlight", "leishi.light.cwtsd": "NVC Smart Downlight Pro", @@ -1582,7 +1997,7 @@ "leishi.light.eps122": "NVC Smart No Main Light", "leishi.light.eps123": "NVC Smart RGB light strip", "leishi.light.eps124": "NVC Smart Lighting Max", - "leishi.light.eps125": "NVC Fresh Fan Light pro", + "leishi.light.eps125": "NVC Fan Light pro", "leishi.light.eps126": "NVC Intelligent Lighting pro", "leishi.light.eps127": "NVC Smart led Ceiling Lamp pro", "leishi.light.eps128": "NVC Smart Light strip V", @@ -1616,21 +2031,32 @@ "leishi.light.wy0c02": "NVC Smart Ceiling Lamp(ZhiZhen)", "leishi.light.wyfa02": "NVC Smart fan lamp(ZhiYi)", "leishi.light.wyfa03": "NVC Smart Fan Light", + "leishi.light.wyfa05": "Leishi air clean breeze light", "leishi.light.wyfao1": "NVC Smart fan lamp(ZhiYa)", + "leishi.light.wzdc3": "NVC Smart No Main Light pro", "leishi.light.yying": "NVC YueYing LED ceiling lamp", "lejia.light.33301": "Scene Ble mesh light A", "lejia.light.wy02": "Scene mesh color temperature lamp C", + "lemesh.airc.air01": "Scene Mesh AC Indoor Unit Controller", "lemesh.aircondition.a01": "HT Smart Air Conditioner Controller (Mesh Version)", + "lemesh.airrtc.t16": "Scenario Mesh Thermostat (3-in-1 version)", "lemesh.cs.swk01": "HT card access switch", "lemesh.curtain.cura01": "Scene mesh curtain motor", "lemesh.curtain.cura02": "Scene Curtain WIFI S2", + "lemesh.curtain.curb02": "Scene Mesh curtain V2", "lemesh.curtain.curh01": "HT Smart curtain motor Mesh", + "lemesh.light.rgba04": "Scene TV atmosphere Lamp Pro", "lemesh.light.w00a01": "Scene Mesh monochrome light", + "lemesh.light.w00a02": "Scene Mesh monochrome light V2S series", + "lemesh.light.w00a03": "Smart scene eye protection floor lamp", + "lemesh.light.w00a04": "Scene intelligent floor learning light Pro", "lemesh.light.w00d01": "Scene mesh lamp K", "lemesh.light.wy": "Scene Color Light WIFI X", "lemesh.light.wy02": "Scene WiFi color temperature lamp C", "lemesh.light.wy0a19": "JS intelligent two-color light", "lemesh.light.wy0a20": "Scene Mesh color temperature light V2X series", + "lemesh.light.wy0a21": "Scene WiFi color temperature light TP series", + "lemesh.light.wy0a22": "Scene WiFi color Temperature Light Pro", "lemesh.light.wy0c02": "Scene mesh color temperature lamp", "lemesh.light.wy0c03": "Scene mesh color temperature lamp D", "lemesh.light.wy0c04": "Scene mesh color-temperature lamp K", @@ -1643,26 +2069,52 @@ "lemesh.light.wy0c15": "Scene Mesh Color Temperature Lamp V2S Series", "lemesh.light.wy0c17": "HT Smart Light", "lemesh.light.wy0c21": "Scene Mesh color temperature lamp ZS series", + "lemesh.light.wy0c22": "Scene Mesh downlights KY series", + "lemesh.light.wy0c23": "Huang Chuang color temperature downlights DT1", + "lemesh.light.wy0c24": "Scene Mesh color Temperature Light V2S Pro", + "lemesh.light.wy0c26": "Scene Mesh color temperature light V2G", "lemesh.light.wyfa01": "Scenario Smart Fan Light Universal Model C3", "lemesh.light.wyra01": "Scene Lights Mesh X1", + "lemesh.light.wyra02": "Scene Mesh color light V2S", "lemesh.light.wyrb01": "Scenario mesh atmosphere color temperature lamp", + "lemesh.light.wyrb02": "Scene Mesh atmosphere light V2S", + "lemesh.remote.ts0": "Scenario wireless switch", + "lemesh.remote.ts00": "Scenario wireless switch S", "lemesh.remote.ts1": "Eight-button wireless scene switch", + "lemesh.remote.ts10": "Scenario knob remote control Alpha", + "lemesh.remote.ts4": "Scenario wireless knob switch K4", + "lemesh.remote.ts5": "Scenario wireless switch K6", + "lemesh.remote.ts6": "Scenario wireless switch K4", + "lemesh.remote.ts7": "Scenario wireless switch K3", + "lemesh.remote.ts8": "Scenario wireless switch K2", + "lemesh.remote.ts9": "Scenario wireless switch K1", + "lemesh.sensor_occupy.s3": "Scenario presence sensor", "lemesh.switch.sw0a01": "Scene mesh breaker", "lemesh.switch.sw0a02": "Scene mesh breaker TM", "lemesh.switch.sw0a04": "Scenario Mesh Disconnect V2S Series", "lemesh.switch.sw0c01": "Switch Breaker C3", "lemesh.switch.sw1a02": "One-click Smart Switch Mesh version", "lemesh.switch.sw1f01": "Scene Mesh one button switch Pro", + "lemesh.switch.sw1f11": "Scene Mesh one-key switch Ultra", "lemesh.switch.sw1h01": "HT One key intelligent switch mesh edition", "lemesh.switch.sw2a02": "Two-button Smart Switch(Mesh)", + "lemesh.switch.sw2d02": "Scenario Smart Screen Switch", "lemesh.switch.sw2f01": "Scenario Meshe two-button Switch Pro", + "lemesh.switch.sw2f12": "Scene Mesh two-key switch Ultra", "lemesh.switch.sw2h01": "HT two key intelligent switch mesh edition", "lemesh.switch.sw3a02": "Three-button Smart Switch(Mesh)", "lemesh.switch.sw3b01": "Three-button smart single fire switch mesh version", "lemesh.switch.sw3f01": "Scene Mesh three-key Switch Pro", + "lemesh.switch.sw3f13": "Scene Mesh Three-key switch Ultra", + "lemesh.switch.sw3g01": "Scene Mesh V2S version one key switch", + "lemesh.switch.sw3g02": "Scene Mesh V2S version two key switch", + "lemesh.switch.sw3g03": "Scene Mesh V2S version three key switch", "lemesh.switch.sw3h01": "HT three key smart switch mesh edition", "lemesh.switch.sw4a02": "Four-button smart switch mesh version", + "lemesh.switch.sw4a03": "HT six key smart switch mesh version", "lemesh.switch.sw4f01": "Scene Mesh four key Switch Pro", + "lemesh.switch.sw4f14": "Scene Mesh Four-key switch Ultra", + "lemesh.switch.sw4f24": "Scene Lemesh four key screen switch Pro", "lemesh.switch.sw4h01": "HT four-button intelligent switch Mesh edition", "lemesh.switch.sw8a01": "8 key smart switch mesh version", "lesdn.light.wy0a01": "Leishitun intelligent lights", @@ -1693,9 +2145,17 @@ "leshow.humidifier.jsq1": "Mi Smart Evaporative Humidifer Pro", "leshow.humidifier.jsq2": "Mijia Smart Evaporative Humidifier 2 Lite", "leshow.humidifier.jsq3": "Mijia Smart Evaporative Humidifier Pro+", + "lhang.magic_touch.t3": "Slow passenger shoulder and neck massage massager T3", "lhang.magic_touch.y5": "Slow Air Massage Belt Y5", + "lhz.curtain.motor1": "Legrand Intelligent Curtain Motor MESH Edition", + "lhz.remote.2g": "Legrand two key scene switch MESH version", + "lhz.remote.4g": "Legrand four key scene switch MESH version", + "lhz.remote.6g": "Legrand Six Key Scene Switch MESH version", + "lhz.switch.1g": "Legrand one position zero line intelligent switch MESH version", "lhz.switch.1gang": "1 Gang Switch With Neutral", + "lhz.switch.2g": "Legrand two position zero line intelligent switch MESH version", "lhz.switch.2gang": "2 Gang Switch With Neutral", + "lhz.switch.3g": "Legrand three position zero line intelligent switch MESH version", "lhz.switch.3gang": "3 Gang Switch With Neutral", "line.curtain.8m1": "Line curtain 8m1", "line.curtain.azm01": "Line curtain azm01", @@ -1714,11 +2174,17 @@ "line.lock.bmsc1": "LineHope Smart Glass Lock C1", "line.lock.bmsc1s": "LineHope Smart Glass Lock C1S", "line.lock.fms2": "Ark Fish Smart Door Lock S2", + "line.lock.fms5": "Smart Door Lock S5", + "line.lock.fms6": "Ark Fish Smart Door Lock S6", "line.lock.ms2": "LineHope Smart Door Lock S2", + "line.lock.mst2": "NICK Smart Door Lock NJJ-101", "line.magnet.ftm1": "Ark Fish Door Window Sensor TM1", "line.magnet.tm1": "LineHope Door and Window Sensor TM1", "line.motion.ftr1": "Ark Fish Human Motion Sensor TR1", "line.motion.tr1": "LineHope Human Motion Sensor TR1", + "line.plug.afsb1": "Ark Fish Intelligent circuit breaker D1", + "line.plug.lhbl7": "Ark Fish Intelligent circuit breaker D2", + "line.remote.wkgf1": "Wireless Switch E1", "line.sensor_ht.fth1": "Ark Fish Temperature and Humidity Sensor TH1", "line.sensor_ht.fth1s": "Ark Fish Temperature and Humidity Sensor TH1S", "line.sensor_ht.th1": "LineHope Temperature and Humidity Sensor TH1", @@ -1737,15 +2203,22 @@ "line.switch.kgk1": "LineHope Smart Switch K1(Single Rocker)", "line.switch.kgk12": "LineHope Smart Switch K1(Double Rocker)", "line.switch.kgk13": "LineHope Smart Switch K1(Triple Rocker)", + "linju.light.wy0a01": "Lingju Bluetooth Mesh two-color light", + "linju.plug.znkzq": "Lingju intelligent controller", "linju.switch.sw0a01": "Lingju Bluetooth Mesh Switch", + "linp.aircondition.vrf02": "Linptech VRF Air Conditioner", + "linp.airrtc.s1tdw": "Linptech Thermostat S1T", "linp.airrtc.th113": "Linptech Thermostat TH1(Heat Pump)", "linp.curtain.c2": "Linptech curtain motor Mesh", "linp.curtain.c3": "Smart Curtain Motor C3 (PLC Version)", + "linp.curtain.c4b": "Linptech Intelligent Curtain Motor C4", "linp.curtain.lpc1": "Linptech Smart Curtain ", "linp.doorbell.g03": "Self-Powered Wirelss Doorbell", "linp.doorbell.g04": "Self-powered WiFi doorbell 2", + "linp.flood.rs1bb": "Linptect Flood and Rain Sensor", "linp.gateway.n2": "Linptech RF Gateway", "linp.gateway.pn1": "PLC Gateway", + "linp.gateway.vrf1": "Linptech VRF Central Air Conditioner Controller", "linp.light.d1pcw": "Smart Spot Lamp (PLC Version)", "linp.light.ldcw01": "Linptech Smart Spot Lamp", "linp.light.lm1pcw": "Smart Magnetic Lamp (PLC Version)", @@ -1754,8 +2227,11 @@ "linp.light.lm1pg": "Smart Magnetic Suction Grille Light (PLC Version)", "linp.light.lm1ps": "Smart Magnetic Suction Spotlight (PLC Version)", "linp.light.lmcw01": "Linptech Smart Magnet Lamp", + "linp.light.lp1bc": "Human presence panel light", "linp.light.ls1pcw": "Smart Light Strip (PLC Version)", + "linp.light.ls1rgb": "Intelligent Color Light (MESH Version)", "linp.light.lscw01": "Linptech Smart Strip Lamp", + "linp.light.wy0a01": "Smart Spot Lamp (MESH Version)", "linp.magnet.m1": "Linptech Door and Window Sensor", "linp.motion.h1": "Linptech Motion Sensor", "linp.motion.hs1bb1": "Linptech Motion Sensor 2", @@ -1767,8 +2243,15 @@ "linp.remote.kh1bb2": "Linptech Wireless Switch KH1(2 keys)", "linp.remote.kh1bb3": "Linptech Wireless Switch KH1(3 keys)", "linp.remote.kh1bb4": "Linptech Wireless Switch KH1(4 keys)", + "linp.remote.ks1": "Linptech Wireless Switch KS1", + "linp.senpres.ps1bb": "Linptech Pressure Present or Not Sensor", + "linp.sensor_ht.ks1bp": "Linptech Wireless Switch KS1Pro", + "linp.sensor_occupy.es2b": "Linptech Human Presence Sensor ES2", "linp.sensor_occupy.hb01": "Linptech human body presence sensor", "linp.sensor_occupy.hb04": "Human Body Presence Sensor(Top Mounted PLC Version)", + "linp.switch.e2db1": "Linptech Wall Switch (With Neutral Mesh 1 Key)", + "linp.switch.e2db2": "Linptech Wall Switch E2(With Neutral Mesh 2 Key)", + "linp.switch.e2db3": "Linptech Wall Switch E2(With Neutral Mesh 3 Key)", "linp.switch.q31": "Linptech Smart Wall Switch(1 Key)", "linp.switch.q31s": "Linptech Q3 Smart Wall Switch(1 Key)", "linp.switch.q32": "Linptech Smart Wall Switch(2 Keys)", @@ -1789,7 +2272,14 @@ "linp.switch.qh1dp2": "Smart Wall Switch QH1 (2 Keys PLC Version)", "linp.switch.qh1dp3": "Smart Wall Switch QH1 (3 Keys PLC Version)", "linp.switch.qh1dp4": "Smart Wall Switch QH1 (4 Keys PLC Version)", + "linp.switch.qh2db4": "Linptech Wall Switch H2(With Neutral Mesh 4 Key)", + "linp.switch.qh2db8": "Linptech Wall Switch H2(With Neutral Mesh 8 Key)", + "linp.switch.qt1db1": "Linptech Wall Switch QT1(With Neutral Mesh 1 Key)", + "linp.switch.qt1db2": "Linptech Wall Switch QT1(With Neutral Mesh 2 Key)", + "linp.switch.qt1db3": "Linptech Wall Switch QT1(With Neutral Mesh 3 Key)", + "linp.switch.qt1db4": "Linptech Wall Switch QT1(With Neutral Mesh 4 Key)", "linp.switch.s1": "Linptech full screen switch", + "linp.switch.s2dw3": "Linptech Touch Screen Switch S2", "linp.switch.wq4db1": "Zero Fire Smart Wall Switch(MESH 1 Key)", "linp.switch.wq4db2": "Zero Fire Smart Wall Switch (MESH 2 Keys)", "linp.switch.wq4db3": "Zero Fire Smart Wall Switch (MESH 3 Keys)", @@ -1798,11 +2288,28 @@ "linp.switch.wq4sb3": "Single Fire Smart Wall Switch(MESH 3 Keys)", "linp.switch.xh1dp": "Smart Knob Switch XH1 (PLC Version)", "linp.wopener.wd1lb": "Linptech Intelligent Sliding Window Driver WD1", + "linp.wopener.wd2lb": "Linptech Intelligent casement Window Driver WD2", "linqi.projector.td01lq": "Mi Cinema Headset", + "lipro.bhf_light.e3u1": "Lipro Intelligent Heater", + "lipro.light.23f4": "Lipro Smart Fan", + "lipro.light.23x1": "Lipro Ceiling Light", + "lipro.light.23x2": "Lipro Living Room Ceiling Light", + "lipro.light.23x3": "Lipro Ceiling Light Monochromatic", + "lipro.light.24a2": "Lipro Eye Protection Restaurant Pendant Light", + "lipro.light.r3g2": "Lipro Magnetic Rail Light", + "lipro.light.r3g3": "Lipro Magnetic Rail Light Monochrome", + "lipro.light.r3p3": "Lipro Downlight", + "lipro.light.r3p5": "Lipro Light Strip Monochrome", + "live.light.fs901": "Yeelight Yiyang DC Variable Frequency Fan Hanging Light C900SE", + "live.light.fsl001": "FSL Smart Fan Light Series", + "ljzp.curtain.khldj": "LJ Alien Visitor Curtain", + "ljzp.curtain.ljxhg": "LJ Black Tube Curtain", "lmdq.airp.dtha02": "LOMEDIQI DTH-A02 Air disinfector", "lmds.light.wy0a01": "Lemeng lighting living room ceiling lamp", "lmds.light.wy0a02": "Lemeng lighting bedroom ceiling lamp", "lndq.light.wy0a01": "LUNO Lvneng Mijia intelligent lamp", + "longs.light.lsts01": "Longsheng intelligent downlights", + "longwa.clock.air1": "Air clock X1", "lonink.switch.ln064": "LONINK Intelligent one key switch WIFI", "lonink.switch.ln065": "LONINK Intelligent two key switch WIFI", "lonink.switch.ln066": "LONINK Intelligent three key switch WIFI", @@ -1810,6 +2317,8 @@ "lonink.switch.ln085": "LONINK Two key switch (WiFi)", "lonink.switch.ln086": "LONINK Three key switch(WiFi)", "lonsam.curtain.001": "LS Smart Curtain Motor", + "lonsam.curtain.ct05": "LS-M3 CURTAIN-Mesh", + "lonsam.curtain.ct05a": "LS SMART CURTAIN", "lonsam.curtain.lscl": "LS intelligent curtain motor", "loock.camera.c1k": "Lockin Smart AI Camera", "loock.cateye.v01": "Loock CatY", @@ -1834,9 +2343,11 @@ "loock.lock.t1v2": "Xiaomi Automatic Smart Door Lock", "loock.lock.t2pv1": "Xiaomi Smart Door Lock M20 (Peephole Camera with Display)", "loock.lock.t2v1": "Xiaomi Smart Door Lock M20", + "loock.lock.t3pmax": "Xiaomi Smart Door Lock 2 (Face Unlock)", + "loock.lock.t3pul": "Xiaomi Smart Door Lock 2 Pro", "loock.lock.v1": "Loock Classic", "loock.lock.v14": "Loock Spider-Man Series Limited Edition", - "loock.lock.v15": "Lockin Smart Lock X1", + "loock.lock.v15": "Lockin Smart Lock X1/X3", "loock.lock.v16": "Lockin Smart Lock SV40", "loock.lock.v2203": "Lockin Smart Lock V5 Max INT", "loock.lock.v3": "Loock Q2", @@ -1848,6 +2359,8 @@ "loock.lock.v9": "Loock Smart", "loock.lock.xfvl10": "Lockin Finger Vein Automatic Smart Door Lock S50", "loock.safe.v1": "Mi Smart Safe Box", + "lrn.light.wya01": "LRN two-tone optical drive", + "lrn.switch.sw2a01": "LRN Thought Department high and low voltage dual switch", "lsds.light.wy0a01": "Shengxin Intelligent lamp", "ltdzsw.light.wylg1": "Lige lighting", "lumi.86plug.v1": "绿米86暗插", @@ -1887,6 +2400,7 @@ "lumi.flood.acn001": "Aqara Water Leak Sensor E1", "lumi.flood.bmcn01": "Mi Flood Detector", "lumi.gateway.acn004": "Aqara Hub M1S 2022", + "lumi.gateway.acn008": "Aqara Hub M1S series 2", "lumi.gateway.acn01": "Aqara Hub M1S", "lumi.gateway.aeu01": "Aqara Hub M1S", "lumi.gateway.aqcn02": "Aqara Hub E1", @@ -1905,6 +2419,7 @@ "lumi.gateway.v3": "Mi Control Hub", "lumi.light.acn003": "Aqara Ceiling Light L1-350", "lumi.light.acn014": "Aqara LED Light Bulb T1(Turnable White)", + "lumi.light.acn033": "Aqara Ceiling Light", "lumi.light.aqcn02": "Aqara LED Light Bulb (Tunable White)", "lumi.light.cwopcn01": "Ceiling Light MX960 (Adjustable Color Temperature)", "lumi.light.cwopcn02": "Ceiling Light MX650 (Adjustable Color Temperature)", @@ -1921,6 +2436,8 @@ "lumi.lock.bzacn2": "Aqara smart door lock N100", "lumi.lock.eicn02": "Smart Door Lock J1", "lumi.lock.mcn002": "Xiaomi Smart Door Lock with Face Unlock", + "lumi.lock.mcn008": "Xiaomi Smart Door Lock E20 (WiFi Version)", + "lumi.lock.mcn009": "Xiaomi Smart Door Lock E20 (Video Monitor)", "lumi.lock.mcn01": "Mi Smart Door Lock", "lumi.lock.v1": "Door lock", "lumi.lock.wbmcn1": "Mi Smart Door Lock Pro", @@ -2013,6 +2530,7 @@ "lxun.remote.wxkg08": "lxun smart wireless switch", "lxun.sensor_occupy.cz01": "LX occupy sensor", "lxun.switch.lxkgm1": "Smart Switch Three-key Mesh", + "lxun.switch.lxnsw3": "LX Smart switch - three-button BLE-Mesh edition", "lxun.switch.lxswm1": "Smart Switch One-key Mesh", "lxun.switch.lxswm2": "Smart Switch Two-key Mesh", "lxun.switch.lxswm4": "Smart Switch Four-key Mesh", @@ -2021,6 +2539,7 @@ "lxzn.switch.01": "Touch 1-key zero fire switch (Bluetooth mesh)", "lxzn.switch.02": "Touch 2-button Zero Fire switch (Bluetooth mesh)", "lxzn.switch.03": "Tap 3-button Zero Fire switch (Bluetooth mesh)", + "lxzn.switch.cbcsmj": "Wi-Fi smart guide Circuit breaker L1", "madv.alarm.winlock1": "Dling window security alarm smart model.", "madv.cateye.dlc5jz": "Dling Smart Video Doorbell C5", "madv.cateye.dle3jz": "Dling Smart Video Doorbell E3", @@ -2032,6 +2551,7 @@ "madv.cateye.dlowlse2": "Dling Smart Video Doorbell C5", "madv.cateye.mi2gt": "Mi Smart Video Doorbell 2", "madv.cateye.mi3iot": "Xiaomi Smart Doorbell 3", + "madv.cateye.mi3sg": "Xiaomi Smart Doorbell 3S", "madv.cateye.mic2jz": "Mi Smart VIdeo Doorbell 2", "madv.cateye.miowl": "Mi Smart Video Doorbell", "madv.cateye.miowl3": "Xiaomi Smart Doorbell 3", @@ -2046,8 +2566,17 @@ "maiyue.magic_touch.m018": "MA018 multifunctional cervical massage instrument", "mate.airfresh.a1": "MATE Air Fresh A1", "mate.humidifier.cs01": "MATE air cube", + "matter.light.mlight": "Matter Light", + "matter.plug.mplug": "Matter Plug", + "maxi.airc.air04": "Maisi VRF central air conditioning controller", + "maxi.aircondition.air02": "Maisi air duct controller A06B", "maxi.aircondition.m07": "Central air-conditioning", "maxi.gateway.m07": "Central air conditioner intelligent gateway", + "mbo.airc.mac35": "meipont inverter air conditioner", + "mbo.aircondition.mah35": "meipont heat pump air conditioner", + "mcl.switch.1k": "Xiaoyan Light Switch-1 Gang", + "mcl.switch.2k": "Xiaoyan Light Switch-2 Gang", + "mcl.switch.3k": "Xiaoyan Light Switch-3 Gang", "mcosu.bhf_light.pipam1": "Pipa smart Yuba M1", "mcosu.curtain.pipae1": "F1 MESH Motor", "mcosu.switch.pipaf1": "F1 MESH one position switch", @@ -2057,6 +2586,8 @@ "mcosu.switch.pipam1": "PIPA intelligent switch one keys MESH", "mcosu.switch.pipam2": "PIPA intelligent switch two keys MESH", "mcosu.switch.pipam3": "PIPA intelligent switch three keys MESH", + "meilen.scales.mtz601": "Meilen Intelligent body fat scale MTZ601", + "merryt.sensor_occupy.m1": "Merrytek human presence sensor M1", "mgzn.light.mgdd02": "MG Smart LED Strip", "mgzn.light.mggs01": "MG Smart Grille Lights", "mgzn.light.mgmz01": "MG smart surface mounted downlight", @@ -2068,6 +2599,7 @@ "miaomiaoce.blanket.d02": "Smart Low Voltage Blanket Double", "miaomiaoce.blanket.s02": "Smart Low Voltage Blanket Single", "miaomiaoce.clock.ht02": "ZenMeasure Smart Temperature Clock", + "miaomiaoce.sensor_ht.a1": "Meawow Smart Voice Control Clock", "miaomiaoce.sensor_ht.h1": "Bluetooth Hygrothermograph", "miaomiaoce.sensor_ht.o2": "Xiaomi Temperature and Humidity Monitor Clock", "miaomiaoce.sensor_ht.t1": "Mi Temperature and Humidity Monitor Digital Clock", @@ -2083,10 +2615,12 @@ "mibx2.fridge.v1": "Mi Internet Refrigerator 450L", "mibx2.washer.v1": "Mi Internet Direct Drive Washer Dryer 10kg", "mibx2.washer.v10": "Mijia Dual-Drum Washer Dryer 15kg", + "mibx2.washer.v10d": "Mijia Dual-drum Washer Dryer 15kg(white)", "mibx2.washer.v11": "Mijia DD Combination Washer Dryer 10kg", "mibx2.washer.v11rm": "Mijia DD Combination Washer Dryer 10kg", "mibx2.washer.v13": "Mijia Mini Washing Machine 1kg", "mibx2.washer.v15": "Mijia DD Combination Washer Dryer 12kg/11.8kg (Grey)", + "mibx2.washer.v15rm": "Mijia DD Combination Washer Dryer 12kg/11.8kg (Grey)", "mibx2.washer.v17": "Mijia DD Combination Washer Dryer Pro10kg", "mibx2.washer.v2": "Mi Direct Drive Washer Dryer 10kg", "mibx2.washer.v3": "Mi Wave Washer 10kg", @@ -2094,8 +2628,15 @@ "mibx2.washer.v6": "Mi Wave Washer 10kg m2", "mibx2.washer.v6rm": "Mi Wave Washer 10kg", "mibx2.washer.v7": "Mijia DD Combination Washer Dryer Pro10kg", + "mibx2.washer.x11": "Mijia Dual-drum Washer Dryer 15kg", "mibx5.dry.v2": "Mi Smart Heat Pump Dryer 10kg", "mibx5.dry.v3": "Mi Smart Dryer 10kg", + "mibx5.dry.v6": "Mi Smart Dryer 10kg", + "mibx5.washer.32": "Mijia Efficient Washing Machine 10kg", + "mibx5.washer.35": "Mijia Efficient Washer Dryer 10kg", + "mibx5.washer.37": "Mijia Intelligent Washing Machine 10kg", + "mibx5.washer.38": "Mijia Intelligent Washer Dryer 10kg", + "mibx5.washer.s06": "Mijia Mini Washing Machine 3kg Pro", "mibx5.washer.v1": "MI wave washer Premium 10kg", "mibx5.washer.v10": "Mijia DD Combination Washer Dryer 10kg (Touchscreen)", "mibx5.washer.v11": "Mijia Mini Combination Washer Dryer", @@ -2104,6 +2645,7 @@ "mibx5.washer.v4": "MI Direct Drive Washer Premium 10Kg", "mibx5.washer.v6": "Mijia Direct Drive Washer 10Kg", "mibx5.washer.v7": "Mijia DD Combination Washer Dryer 10kg", + "micar.car.ms11": "Xiaomi SU7", "micoe.airer.hz001h": "Mocie Mies 10 Pro- Drying Style", "micoe.airer.hz001z": "Mocie Mies 10S lighting", "micoe.airer.hz002h": "Rise10 Mix- Ring pole retainer (drying flagship)", @@ -2113,35 +2655,65 @@ "midea.aircondition.v1": "Midea AC-i Youth", "midea.aircondition.xa1": "Midea AC-Cool Golden", "midea.aircondition.xa2": "美的空调 - 酷金", + "midjd.fridge.256b": "Mijia Compact Refrigerator 256L(Glass Door)", + "midjd.fridge.439b": "Mijia Built-in Refrigerator 4-Door 439L/436L", + "midjd.fridge.501b": "Mijia Side Mounted Refrigerator 501L", "midjd.fridge.516": "Mijia 4-Door Refrigerator 520L", "midjd.fridge.5161": "Mijia 4-Door Refrigerator 520L", - "midjd.fridge.520b": "Mijia 4-Door Refrigerator 520L", + "midjd.fridge.520b": "Mijia 4-Door Refrigerator 520L/501L", "midjd.fridge.603": "Mijia 4-Door Refrigerator 603L (Glass Door)", "midjd.fridge.603a": "Mijia 4-Door Refrigerator 603L(Glass Door)", + "midjd.fridge.bd38s": "Mijia Side Mounted Refrigerator 501L", + "midjd.fridge.bs13s": "Mijia Built-in Refrigerator 4-Door 439L/436L", + "midjd.fridge.bs28s1": "Mijia 4-Door Refrigerator 520L/501L", + "midjd.fridge.bs36s": "Mijia Multi-zone Refrigerator 4 Glass Door 439L", + "midjd.fridge.bs37s": "Mijia Multi-zone Refrigerator 4 Glass Door 508L", + "midjd.fridge.bx09s": "Mijia Compact Refrigerator 256L(Glass Door)", + "midjd.fridge.f01": "Mijia Built-in Refrigerator Q7 French Door 439L", + "midjd.fridge.s24": "Mijia Built-in Refrigerator Q8 (4-Door 508L/485L)", "midjd6.fridge.430": "Mijia 4-Door Refrigerator 430L", - "midjd6.fridge.4301": "Mijia 4-Door Refrigerator 430L", + "midjd6.fridge.4301": "Mijia 4-Door Refrigerator 430L/410L", "midjd6.fridge.430b": "Mijia 4-Door Refrigerator 430L", "midjd6.fridge.430rm": "Mijia 4-Door Refrigerator 430L", + "midjd6.fridge.516b": "Mijia Built-in Refrigerator 4-Door 518L", "midjd6.fridge.536": "Mijia Side Mounted Refrigerator 536L/530L", - "midjd6.fridge.536b": "Mijia Side Mounted Refrigerator 536L/530L", + "midjd6.fridge.536b": "Mijia Side Mounted Refrigerator 536L/530L/516L", "midjd6.fridge.540": "Mijia Side Mounted Refrigerator 540L(Glass Door)", "midjd6.fridge.540b": "Mijia Side Mounted Refrigerator 540L(Glass Door)", "midjd6.fridge.540pro": "Mijia Double Door Refrigerator 540L Pro", "midjd6.fridge.5501": "Mijia Refrigerator Premium 550L cross four doors", + "midjd6.fridge.5501b": "Mijia Refrigerator Premium 550L cross four doors", "midjd6.fridge.606b": "Mijia 4-Door Refrigerator 606L", "midjd6.fridge.610": "Mijia Side Mounted Refrigerator 610L/606L", + "midjd6.fridge.6101": "Mijia Side Mounted Refrigerator 610L/606L", "midjd6.fridge.6103": "Mijia Side Mounted Refrigerator 610L (Glass Door)", "midjd6.fridge.6103b": "Mijia Side Mounted Refrigerator 610L(Glass Door)", - "midjd6.fridge.610b": "Mijia Side Mounted Refrigerator 610L/606L", + "midjd6.fridge.610b": "Mijia Side Mounted Refrigerator 610L/606L/616L", "midjd6.fridge.700": "Mijia Refrigerator MAX 700L", + "midjd6.fridge.s16": "Mijia Built-in Refrigerator 4-Door 518L", "midjd6.fridge.v1": "Mijia Internet Refrigerator 540L", "midjd7.fridge.4851": "Mijia Double Door Refrigerator 485L", "midjd7.fridge.4852": "Mijia Double Door Refrigerator 485L", "midjd7.fridge.5021": "Mijia Side Mounted Refrigerator 502L (Glass Door)", "midjd7.fridge.5022": "Mijia Side Mounted Refrigerator 502L (Carbon Black)", + "midjd7.fridge.520b": "Mijia Built-in Refrigerator 4-Door 521L/523L", "midjd8.fridge.400b": "Mijia Multi-door Refrigerator 400L(Glass Door)", "midjd8.fridge.630": "Mijia Refrigerator Double Door 630L", + "midjd8.washer.41": "Mijia Efficient Washing Machine 12kg pro", + "midjd8.washer.42": "Mijia Efficient Washer Dryer 12kg Pro", + "midjd8.washer.42a": "Mijia Efficient Washer Dryer 12kg Pro", + "midjd8.washer.43": "Mijia Intelligent Washing Machine 10kg Pro", + "midjd8.washer.44": "Mijia Efficient Washer Dryer 10kg pro", + "midjd8.washer.45": "Mijia Intelligent Washer Dryer 12kg Pro", + "midjd9.fridge.303b": "Mijia Compact Refrigerator pro 303L", + "midjd9.fridge.x14": "Mijia Compact Refrigerator pro 303L", "midr.bike.x1": "70mai Smart E- A1 Pro", + "midr.camera.bw300": "Xiaomi Outdoor Camera BW300", + "midr.camera.bw300c": "Xiaomi Outdoor Camera Base Station", + "midr.camera.bw400": "Xiaomi Outdoor Camera BW500", + "midr.camera.bw400b": "Xiaomi Outdoor Base Station", + "midr.camera.bw400g": "Xiaomi Outdoor Camera BW500", + "midr.camera.bw400p": "Xiaomi Solar Outdoor Camera BW400 Pro", "midr.cardvr.m1": "Mi rear-view mirror recorder", "midr.cardvr.mv2": "Mi Dash Cam 2 2K", "midr.cardvr.mv2h": "Mi Dash Cam 2", @@ -2150,6 +2722,7 @@ "midr.cardvr.v2": "Mi Dash Cam 1S", "midr.cardvr.wv2": "Mi Dash Cam 1S", "midr.cardvr.x200s": "70mai Dash Cam Omni", + "midr.cateye.ph300": "Smart Video Doorbell with Monitor 2", "midr.rv_mirror.m2": "70mai Smart Rearview Mirror lite", "midr.rv_mirror.m5": "70mai Smart Driving Mate", "midr.rv_mirror.v1": "Mi Smart Rear-view Mirror", @@ -2184,7 +2757,10 @@ "mijia.vacuum.v1": "Mi Robot Vacuum-Mop Essential", "mijia.vacuum.v2": "Mi Robot Vacuum-Mop Essential", "mijia.vacuum.v3": "Mi Robot Vacuum-Mop Essential", + "mike.bhf_light.2": "Smart Bath Pro (AI version) YB-007", "milizn.curtain.mili2": "XM electric curtains", + "milizn.curtain.ml002": "Intelligent electric rolling curtain", + "milizn.wopener.ml03": "V1intelligent window pusher", "mingpu.sensor_gas.det1": "Gas alarm", "minij.fridge.448w": "MINIJ 448L Smart French Refrigerator", "minij.washer.v1": "Miniji Washing Machine", @@ -2204,13 +2780,14 @@ "miot.camera.spec": "happening", "miot.clock.mijia": "米家App自动化RN的model", "miot.doorbell.spec": "标准插件HOOK设备(删除会影响线上所有插件运行,千万勿删,非常重要)", + "miot.light.lg1": "test_light", "miot.lock.cctest": "dsfs", "miot.lock.qqaly": "01", "miot.lock.test06": "mijia lock", "miot.lock.v000": "lock 2", "miot.lock.x2": "jianeng111", "miot.lock.x3": "佳能蓝牙智能门锁(海外)", - "miot.pettoy.bbb": "test-llj", + "miot.pettoy.bbb": "test", "miot.plug.021": "a/ apple", "miot.plug.v1640": "test update name", "miot.switch.mswl1": "Mesh无线开关测试(单键)", @@ -2218,27 +2795,35 @@ "miot.switch.mswl3": "Mesh无线开关测试(三键)", "miot.switch.spec": "标准插件HOOK设备(删除会影响线上所有插件运行,千万勿删,非常重要)", "miot.switch.y0715": "2", - "mipin.motion.mc1": "MIANCHU sensor", + "mipin.motion.mc1": "MIANCHU sensor standard", + "mipin.sensor_occupy.mc2": "MIANCHU sensor mesh", "mirsz.flood.wa500": "LOVYA Water leakage sensor", "mirsz.magnet.mc500": "LOVYA Door sensor", "mirsz.motion.ir500": "LOVYA PIR motion sensor", - "mirsz.sensor_gas.ga500": "LOVYA gas sensors", + "mirsz.sensor_gas.ga500": "Gas sensors", "mirsz.sensor_ht.te110": "LOVYA temperature and humidity sensor (without screen)", "mirsz.sensor_ht.te500": "LOVYA temperature and humidity sensor", - "mirsz.sensor_smoke.s500": "Rovia gas sensor", + "mirsz.sensor_occupy.h01": "LOVYA Human Presence Sensor MIR-HE1-BT", + "mirsz.sensor_smoke.s500": "Smoke sensor", "miwear.headphone.l76c": "L76_CN", "miwear.headphone.l76g": "L76_Global", "mjkj.light.wy0a01": "Instant rice intelligent lamp", "mjkj.light.wy0a02": "Instant intelligent magnetic lamp", "mjkj.light.wy0a03": "Instant intelligent linear lamp", + "mjzm.light.ceilin": "Moon Shadow Natural Eye Protection LAMP", + "mjzm.light.magnet": "Moon Shadow Eye Protection MGL", + "mjzm.light.v1": "Moon Shadow Eye Protector Spot Light", "mjzm.light.wy0a01": "YueYing Smart Ceiling Lamp", "mjzm.light.wy0a02": "YueYing Smart Droplight", "mjzm.light.wy0a03": "Xierdun Smart Ceiling Lamp", "mjzm.light.wy0a04": "Xierdun Smart Droplight", + "mjzm.light.wyfa01": "Yueying smart fan light", "mkit.light.wyra01": "Rhythmic lantern band", + "mlily.bed.001": "MLILY 0 pressure smart bed", "mls.light.mls001": "MLS LED Smart Ceiling Lamp1", "mls.light.mls002": "MLS LED Smart Ceiling Lamp2", "mls.light.mls003": "MLS LED Smart Ceiling Lamp3", + "mlszm.switch.sw3a01": "MuLinSen Z01 intelligent control screen switch", "mly.curtain.cura01": "Magic cloud smart curtain motor", "mly.light.wy0a01": "Magic Cloud Smart Lamp", "mly.switch.sw0a01": "Magic cloud intelligent lighting controller", @@ -2259,6 +2844,8 @@ "morfun.kettle.mf809": "MORFUN Smart Instant Heating Water Dispenser", "morfun.ysj.mf208": "MORFUN Smart Instant Heating Water Dispenser MF208", "morfun.ysj.mf213": "MORFUN Tea Machine", + "moyu.washer.dg02": "Moyu underwear washing machine dg02", + "moyu.washer.dg08": "moyu underwear washing machine dg08", "moyu.washer.s1hm": "Moyu Smart Baby Washing Machine", "mpe.mattress.xmgjb": "MPE Smart Mattress", "mpmiot.pettoy.v1": "Merrypet Smart Ball for Pets", @@ -2285,6 +2872,7 @@ "mrbond.airp.h1pro": "MrBond intelligent deodorizer", "mrbond.curtain.rac03": "MR.BOND Smart Curtain", "msj.dishwasher.s02": "MENSARJOR integrated sink nebula model", + "msj.dishwasher.s110u": "MENSARJOR home integrated sink", "msj.dishwasher.v1": "Mijia Smart Compact Dishwasher S1", "msj.f_washer.m1": "Sink cleaning machine", "msj.f_washer.m1pro": "Food cleaning machine", @@ -2296,26 +2884,42 @@ "msj.i_stove.m6x": "MENSARJOR integrated stove Rubik\u0027s cube style cleaning", "mskub.airer.k6": "Manskubo K model smart clothes dryer", "mson.light.ms000": "Scenario MESH dual tone light S1", + "mson.light.ms005": "Scenario WIFI dual tone light S1", + "mson.light.ms006": "Scenario MESH dual tone light S2", "msuen.switch.czc20": "Shuixiang intelligent valve", "msuen.switch.czc20s": "Shuixiang manual auxiliary intelligent valve", + "murong.light.mrk004": "Murong Ke smart light", "murong.switch.mrk002": "Murong Ko Invisible Switch Smart Edition", + "mvs.light.wy0a01": "Smart downlight Mesh version", + "mvs.light.wy0a02": "Smart strip light Mesh version", + "mvs.light.wy0a03": "Smart magnetic lamp Mesh version", + "mxc.toilet.toilet": "Smart toilet controller", + "mxiang.camera.c301": "Xiaomi Smart Camera C301", + "mxiang.camera.c500ch": "Xiaomi Smart Camera C500 Dual", + "mxiang.camera.moc001": "Xiaomi Outdoor Camera CW300", + "mxiang.camera.moc006": "Xiaomi Outdoor Camera CW300", "mxiang.camera.mod11": "Xiaomi Outdoor Camera AW300", "mxiang.camera.mod13": "Xiaomi Outdoor Camera AW300", "mxiang.camera.mwc10": "Mi Wireless Outdoor Security Camera 1080p Indoor Receiver", "mxiang.camera.mwc11": "Mi Wireless Outdoor Security Camera 1080p", "mxiang.cateye.mdb10": "Xiaomo Smart Video Doorbell", "mxiang.cateye.xmcatt1": "Xiaomo Smart Peep Hole", + "mxl.tow_w.mjj001": "DaMuGe Smart electric towel rack A9", + "mxl.tow_w.mjj002": "DaMuGe Smart electric towel rack A6", "myoung.massage.m900": "Mijia Smart Massage Chair", + "mypile.switch.sw5a01": "MyPile smart wall mount charging stand", "nancii.toothbrush.t600": "Nancii Smart Electric Toothbrush T600", + "naner.controller.86m": "Naner Intelligent Music Central Control Host", "nanfu.remote.nl2v4": "NanFu Smart 4-key Scene Panel", "nanmg.toilet.601": "Smart Toilet IoT Edition 601", + "narwa.vacuum.j4mi": "Narwal J4", "navee1.scooter.t2208": "NAVEE Electric Scooter V40", "navee1.scooter.t2209": "Xiaomi Electric Scooter 4", "navee1.scooter.t2209g": "Xiaomi Electric Scooter 4", "navee1.scooter.t2210": "Xiaomi Electric Scooter 4 Lite", "navee1.scooter.t2210g": "Xiaomi Electric Scooter 4 Lite", "navee1.scooter.t2211": "NAVEE Electric Scooter V50", - "navee1.scooter.t2214": "NAVEE Electric Scooter S65C", + "navee1.scooter.t2214": "NAVEE Electric Scooter S65C/D", "nbczwl.airer.airer": "Smart Airer", "nbczwl.airer.kfe01": "KFE", "nbczwl.airer.krqu40": "Courage Airer", @@ -2325,23 +2929,28 @@ "nbrs.airp.01": "Aldehyde Remover RS-JQ001", "nbsxh.blanket.dzsnt8": "Suning Yipin Intelligent Water Heating Blanket", "nbsxh.fan.alw5dw": "Suning Yipin cold air leafless fan (sterilization and humidification version)", + "nbsxh.heater.t21sw": "Suning Yipin Indoor Heater (Mobile Floor Heating)", "nbym.curtain.yznv1": "Cloud intelligent electric curtain", "nezha.cooker.x2pro": "X2pro-W Cooker", "nhy.airrtc.v1": "Golan Denmark Heating", "nhy.rtc.pexrtc730": "丹麦格澜空调", "nineam.desk.hoo01": "9am Standing Desk", "nineam.desk.hoo021": "9am Standing Desk Model L", + "nineam.desk.t06": "9am Dora Standing Desk", "ninebot.balscooter.v1": "Ninebot", "ninebot.scooter.15": "Xiaomi Electric Scooter 4 Pro", "ninebot.scooter.v1": "Electric Scooter", "ninebot.scooter.v13": "Xiaomi Electric Scooter 4 Go", + "ninebot.scooter.v16": "Xiaomi Electric Scooter 4 Pro Plus", + "ninebot.scooter.v17": "Xiaomi Electric Scooter 4 Pro Max", "ninebot.scooter.v2": "Mi Electric Scooter Pro", "ninebot.scooter.v3": "Mi Electric Scooter 1S", "ninebot.scooter.v4": "Mi Electric Scooter Pro 2 series", "ninebot.scooter.v5": "Mi Electric Scooter Essential", - "ninebot.scooter.v6": "Mi Electric Scooter 1S", + "ninebot.scooter.v6": "Xiaomi Electric Scooter 1S", "ninebot.scooter.v7": "Mi Electric Scooter 3", "ninebot.scooter.v8": "Xiaomi Electric Scooter 4 Pro", + "nmt.light.wy0a01": "Two-color smart light", "nnleaf.light.glbulp": "Nanoleaf Shapes (dual mode)", "nnleaf.light.nl59": "Nanoleaf Lines", "nnleaf.light.sqfx01": "FANTAQI EXPO Exhibit Display", @@ -2351,29 +2960,48 @@ "noc196.light.mdyctd": "MIDIAN NO BLUE LIGHT MUSIC LAMP", "novo.airer.g30": "NOVO smart luxury motorized clothes rack", "novo.airer.g31": "NOVO basic smart clothes rack", + "novo.curtain.e38": "Smart day and night honeycomb blinds", + "novo.curtain.k25": "High-end Ai smart roller blinds", + "novo.curtain.m21": "N21 Smart Curtain Motor(MESH)", + "novo.curtain.n20": "N23 Switching Motor", "novo.curtain.n21": "NOVO Smart Curtain Motor", + "novo.curtain.n31": "N31 Ambient Light Curtain", "npu.light.npu001": "NPU Smart Ceiling Lamp", "nuwa.robot.minikiwi": "Nuwa Robotics Danny Robot", "nuwa.robot.nb1": "KebbiAir", "nvcsmt.light.bas201": "NVC Smart Downlight (Pro version)", "nvcsmt.light.bas202": "NVC smart down light dual color", "nvcsmt.light.bas203": "NVC Intelligent Downlight(plus)", + "nvcsmt.light.bcs201": "NVC intelligent track light", + "nvcsmt.light.bds101": "NVC intelligent light strip (single dimming)", "nvcsmt.light.bds201": "NVC smart strip light dual color", + "nvcsmt.light.bts101": "NVC Smart Downlights", "nvcsmt.light.wxj301": "NVC home smart ceiling light", "nvcsmt.light.wzj201": "pendant light", + "nwt.airc.wap31a": "NWT Internet Mobile Air Conditioner Pro", "nwt.aircondition.26eaw1": "NWT Internet Portable Air Conditioner", "nwt.aircondition.26ebw1": "NWT intelligent mobile air conditioning", + "nwt.airp.kq01": "NWT Internet air purifier", "nwt.derh.24wu1": "NWT Internet Air Clean Dehumidification all-in-one 24L", "nwt.derh.312en": "NEW WIDETECH Internet Dehumidifier 12L", "nwt.derh.330ef": "NWT Internet Dehumidifier 30L", + "nwt.derh.35l": "NWT Internet frequency conversion dehumidifier 35L", "nwt.derh.60l": "NWT Internet Dehumidifier 60L", + "nwt.derh.las20l": "Lumias 20L Dehumidifier", + "nwt.derh.lua12l": "Lumias 12L Dehumidifier", + "nwt.derh.lua30l": "Lumias 30L Dehumidifier", "nwt.derh.nwt10l": "NWT Internet Dehumidifier 10L", "nwt.derh.wdh318efw1": "NWT Internet Dehumidifier 18L", "nwt.fan.16l": "NWT Internet DC inverter electric fan", "odds.light.wy0a01": "Zhanxiu Crystal Love intelligent lamp", + "oeco.light.a2803": "RippMesh-CW Smart Light", + "oit.plug.cb2": "Orient smart socket CB2", + "oit.plug.cb3": "Orient smart socket CB3", "ola.lock.i3": "Ola Mars", "olohas.bed.ogawa8": "Smart Bed", "oms.lock.dl01": "Smart Door Lock E10", + "oms.lock.g10": "Xiaomi Smart Door Lock G10", + "onej.vacuum.clean": "Xinshe True Wet Cleaning Intelligent Window Cleaning Machine YW703", "onemore.soundbox.sm001": "Mi Music Alarm Clock", "onemore.wifispeaker.sm4": "xiaomiaibox", "opple.airer.3022wi": "OPPLE Smart Clothes Dryer Mode A", @@ -2385,6 +3013,7 @@ "opple.bhf_light.fhbath": "Opple Bath Heater BPF12i", "opple.bhf_light.fx88a": "Opple Bath Heater Mode D", "opple.bhf_light.mkc3": "OPPLE.Bath-heater.Mode E", + "opple.bhf_light.mkcj": "OPPLE.Bath-heater.Mode J", "opple.bhf_light.wlyb": "OPPLE.Bath-heater.Mode G", "opple.light.barelp": "Opple Smart Lamp Board Mode A", "opple.light.bydceiling": "Opple BEYOND Ceiling", @@ -2392,11 +3021,13 @@ "opple.light.bytd": "OPPLE Downlight", "opple.light.dcfan": "OPPLE DC variable frequency Fan Light", "opple.light.dcfan2": "OPPLE Fan Light", + "opple.light.dcfan4": "OPPLE Fan Light Pro", "opple.light.fanlight": "OPPLE FANLIGHT", "opple.light.gy": "OPPLE Smart Light PRO", "opple.light.lgtstr": "OPPLE Light Strip Mode A", "opple.light.mgtd": "OPPLE MG Desk lamp", "opple.light.moat": "OPPLE Smart Light S", + "opple.light.qling": "OPPLE Kitchen \u0026 Bathroom Light", "opple.light.tabcol": "OPPLE Smartlamp Mode B", "opple.light.tabcw": "OPPLE Smartlamp Mode C", "opple.light.tablgt": "OPPLE Smartlamp Mode A", @@ -2410,9 +3041,11 @@ "opple.switch.lbs02a": "OPPLE Q4 Mesh Wall Switch(2 Keys)", "opple.switch.lbs03a": "OPPLE Q4 Mesh Wall Switch(3 Keys)", "opple.ven_fan.liba01": "OPPLE Intelligent cool bully", + "opple.ven_fan.liba02": "OPPLE Intelligent cool bully", "orion.wifispeaker.cm1": "小豹AI音箱", "orlant.airer.b": "Orlant Intelligent Clothes Hanger B Series", "orlant.airer.c": "Orlant Intelligent drying machine C series", + "orrgi.light.w00a03": "Qiyuan eye protection lamp", "orrgi.light.wy0a01": "Qiyuan two-color lamp", "ouchen.airer.m01": "Smart clothes hangers MOMO", "ougn.light.wy0a01": "Ougenuo Intelligent lamp", @@ -2428,8 +3061,10 @@ "ows.tow_w.mjj20a": "OWS NEX Towel rail", "ows.tow_w.mjjs1": "OWS-S1 towel-rack", "ows.tow_w.mjjxs": "OWS-XS Electric Heating Towel Rack", + "ows.tow_w.nexpro": "OWS NEXpro Towel Rack", "ows.towel_w.mj1x0": "Intelligent electric heating towel rack", "pak.bhf_light.pak11": "Pak bath heater", + "pak.bhf_light.pak16": "Pak Smart Bath Heater", "pak.light.fan01": "Pak Smart Fan Light", "pak.light.fan03": "Pak Invisible Fan Light", "pak.light.pak002": "pak ceiling lamp", @@ -2455,6 +3090,7 @@ "philips.light.bceiling1": "Philips Zhirui Ceiling Lamp Bedroom 40W", "philips.light.bceiling2": "Philips Zhirui Ceiling Lamp Bedroom 28W", "philips.light.blue": "Philips BlueSky Lamp", + "philips.light.blue1": "Philips Blue Sky G2", "philips.light.boc1": "Philips ZhiYi Ceiling lamp FL2 80W", "philips.light.boc2": "Philips ZhiYi Ceiling lamp FL2 40W", "philips.light.boc3": "Philips ZhiYi Ceiling lamp FL2 28W", @@ -2471,6 +3107,7 @@ "philips.light.ceilz3": "Philips Zhirui Ceiling Lamp Jianyue G2 Living Room L", "philips.light.dlight": "ZhiRui dimmable downlight", "philips.light.downlight": "Philips ZhiRui downlight", + "philips.light.fl": "Philips F9 Lite Floor Light", "philips.light.flat": "Philips Zeeray Fall Detection Panel Light", "philips.light.hbulb": "Philips Wi-Fi bulb E27 White", "philips.light.lite": "Mi Smart Desk Lamp Lite", @@ -2508,6 +3145,7 @@ "philips.light.sread6": "Philips Zhirui Desk Lamp 2S", "philips.light.sread8": "Philips Zhixiu Desk Lamp", "philips.light.sread9": "Mijia Smart LED Desk Lamp Pro (Reading Version)", + "philips.light.street": "Philips F9 Floor Light", "philips.light.strip2": "ZhiRui RGB strip", "philips.light.strip3": "Xiaomi Smart Lightstrip Pro", "philips.light.strip5": "Xiaomi Smart Lightstrip Pro", @@ -2523,23 +3161,27 @@ "philips.light.zysread": "Philips ZhiYi desk lamp", "philips.light.zystrip": "Philips ZhiYi strip", "phnix.waterheater.sf": "PHNIX Heat Pump Water Heater", + "pinlo.humidifier.sh01": "plabson humidifer SH01", "pinlo.juicer.pbj": "Mijia Smart Blender Mini", "pinlo.juicer.pbjs1": "Mijia Smart Blender Lite", + "pio.flowerpot.ivy01": "PlantsIO Smart Pet Planter Ivy", "pma.magic_touch.jb01": "KULAX Neck Support", "pma.magic_touch.kulaxp": "Graphene heated back massager", + "pma.magic_touch.l30pro": "Kulax graphene Neck fixator", "pma.magic_touch.pmav12": "Kulax Graphene Gurging Hot Compress Belt V12", "pmfbj.light.7s203s": "Panasonic downlight and spotlight", "pmfbj.light.ls5000": "Panasonic dining chandelier", + "pmfbj.light.lt0668": "Panasonic desk lamp pro+", "pmfbj.light.lz8321": "Panasonic fan light", "pmfbj.light.tl0666": "Panasonic desk lamp", "pmfbj.light.ts2001": "Panasonic floor lamp", "pmfbj.light.wy0b01": "Panasonic desk lamp pro", "pmfbj.light.xsx330": "Panasonic Mingpan Ceiling Light", "pmfbj.light.xsx332": "Panasonic Songtian Ceiling Light", - "pmfbj.light.xsx340": "Panasonic ceiling light", + "pmfbj.light.xsx340": "Panasonic smart ceiling light", "pmfbj.light.xsx341": "Panasonic ceiling light", "pmfbj.light.xsx344": "Panasonic chandelier", - "pmfbj.light.xsx345": "Panasonic chandelier", + "pmfbj.light.xsx345": "Panasonic smart chandelier", "pmfbj.light.xsx505": "Panasonic Yinglun Ceiling Light", "povit.jmprope.p231": "Puweite Smart Bluetooth Skipping Rope", "pwzn.light.apple": "LED Strip controller", @@ -2549,11 +3191,15 @@ "pxiang.fan.2310": "Suning Yipin Intelligent Circulation Fan", "pze.light.wy0a01": "Puzhuoer Smart Light", "qcy.camera.c1pro": "QCY IPC CC1S", + "qdhkl.airc.b19m": "Zhonghong VRF Central Air Conditioner Controller(MESH)", + "qdhkl.airc.ln0589": "LONINK VRF Air Conditioner Controller PRO(Mesh)", "qdhkl.aircondition.ac": "VRF Air Conditioner", - "qdhkl.aircondition.b23": "AC Indoor Unit Controller", + "qdhkl.aircondition.b23": "AC Indoor Unit Controller(WIFI)", "qdhkl.aircondition.b25": "AC Indoor Unit Controller(MESH)", "qdhkl.aircondition.loac": "VRF AC Indoor Unit", "qdhkl.aircondition.md01": "Sumi central air conditioning controller", + "qdhkl.airfresh.fb27": "Fresh Air Universal Controller", + "qdhkl.airrtc.t15": "Three-in-one Thermostat", "qdhkl.gateway.b18p": "VRF Air Conditioner Manager", "qdhkl.gateway.b19": "VRF Central Air Conditioner Controller", "qdhkl.gateway.ln0586": "LONINK VRF Central Air Conditioner Controller PRO", @@ -2564,9 +3210,55 @@ "qhzm.light.wy0a01": "Qinghe Smart Light", "qicyc.bike.tdp02z": "qicybike", "qicyc.bike.xmdzlzxc01qj": "Mi Smart Electric Folding Bike", + "qihang.magic_touch.4pro": "Tu Wei Le High Back and Waist Massager", + "qihang.magic_touch.nk01": "Tunvole U-shaped massage pillow U2", + "qihang.magic_touch.nk08": "Tunvole Shoulder and Neck Massager", + "qihang.magic_touch.nk8p": "Tunvole Shoulder and Neck Massager pro", "qihang.magic_touch.ty4": "Tunvole Waist massager", "qike.bhf_light.qk201801": "Smart Bath(Basic)", + "qimi.curtain.cura01": "Youke communication intelligent opening and closing curtain", + "qimi.light.wy0a01": "Youke communication intelligent dimming light", "qindao.blanket.1905": "Qindao Smart Electric Blanket", + "qiqi.bhf_light.qbot23": "Yubang intelligent bath master switch", + "qjiang.acpartner.ac02": "ICX Intelligent Air Conditioning Remote Control", + "qjiang.acpartner.wb20": "ICX Intelligent Air Conditioning Remote Control", + "qjiang.curtain.wsd001": "Weishida Bluetooth mesh intelligent opening and closing curtain", + "qjiang.light.mesh": "QM Intelligent Mesh Color Temperature Light", + "qjiang.light.wb6sv1": "QM Intelligent WiFi Color Temperature Light", + "qjiang.sensor_occupy.qj": "QUMI Qumi Human Presence Sensor", + "qjiang.switch.11ssw1": "QM Intelligent Mesh Switch U Series (Single Key)", + "qjiang.switch.11ssw2": "QM Intelligent Mesh Switch U Series (Double Key)", + "qjiang.switch.11ssw3": "QM Intelligent Mesh Switch U Series (Three Key)", + "qjiang.switch.12gsw1": "QM Intelligent Mesh Switch G Series (Single Key)", + "qjiang.switch.12gsw2": "QM Intelligent Mesh Switch G Series (Double Key)", + "qjiang.switch.12gsw3": "QM Intelligent Mesh Switch G Series (Three Key)", + "qjiang.switch.12gsw4": "QM Intelligent Mesh Switch G Series (Four Key)", + "qjiang.switch.12qj01": "QM Intelligent Mesh Scenario Switch Q Series (One Position Composite Switch)", + "qjiang.switch.12qj02": "QM Intelligent Mesh Scene Switch Q Series (Two Position Composite Switch)", + "qjiang.switch.12qj03": "QM Intelligent Mesh Scene Switch Q Series (Three Position Composite Switch)", + "qjiang.switch.12qj04": "QM Intelligent Mesh Scene Switch Q Series (Four Position Composite Switch)", + "qjiang.switch.12ssw1": "QM Intelligent Mesh Switch S Series (Single Key)", + "qjiang.switch.12ssw2": "QM Intelligent Mesh Switch S Series (Double Key)", + "qjiang.switch.12ssw3": "QM Intelligent Mesh Switch S Series (Three Key)", + "qjiang.switch.12ssw4": "QM Intelligent Mesh Switch S Series (Four Key)", + "qjiang.switch.b12sw1": "QM Intelligent Mesh Switch P Series (Single Key)", + "qjiang.switch.b12sw2": "QM Intelligent Mesh Switch P Series (Double Key)", + "qjiang.switch.b12sw3": "QM Intelligent Mesh Switch P Series (Three Key)", + "qjiang.switch.b12sw4": "QM Intelligent Mesh Switch P Series (Four Key)", + "qjiang.switch.fire1": "QM single fire switch (single key)", + "qjiang.switch.fire11": "QM intelligent switch (single key)", + "qjiang.switch.fire2": "QM Single fire switch (double keys)", + "qjiang.switch.fire3": "QM single fire switch (three key)", + "qjiang.switch.fire33": "QM intelligent switch (three key)", + "qjiang.switch.firey2": "QM intelligent switch (double key)", + "qjiang.switch.firey4": "QM intelligent switch (four key)", + "qjiang.switch.zero11": "QM Smart Switch (Single Key)", + "qjiang.switch.zero22": "QM Smart Switch (Double Key)", + "qjiang.switch.zero33": "QM Smart Switch (Three Key)", + "qjiang.switch.zero44": "QM Smart Switch (Four Key)", + "qjkj.cup.qjz001": "Qujia pure titanium smart cup FJ-TA015", + "ql0782.bed.001": "KLST floating cloud smart bed", + "ql0782.sofa.001": "KLST floating cloud smart sofa", "qmdq88.dishwasher.n116": "Mijia Smart FS\u0026BI Dishwasher N1", "qmdq88.dishwasher.p116": "Mijia Smart FS\u0026BI Dishwasher P1", "qmdq88.dishwasher.s1": "Mijia Smart Tabletop Dishwasher S1", @@ -2586,14 +3278,22 @@ "qushui.bed.010s": "8H Feel Eco leather smart electric bed F series", "qushui.bed.8hai1": "8H AI Smart mattress", "qushui.bed.de1": "8H Find smart electric bed", + "qushui.bed.de2": "8H Find Intelligent Cloud Sensing Suspended Electric Bed", + "qushui.bed.demax": "8H Find Intelligent electric Bed Pro", + "qushui.bed.dt31": "8H Milan Smart Electric Bed Ultra", "qushui.bed.dt4": "8H Milan Smart leather electric bed S", - "qushui.bed.dt7": "8H Feel leather Smart Suspension bed X+", + "qushui.bed.dt7": "8H Feel Smart leather Suspension bed X+", + "qushui.bed.hjdt8": "8H Twins Double partition electric bed", + "qushui.bed.ma006": "8H AI LumbarCare Sleep Mattress Zero A2", + "qushui.blanket.8h": "8H Smart Water Heated Mattress Pad", "qushui.blanket.g2": "bed warm pad", "qushui.blanket.g22": "8H graphene intelligent temperature control 3D thin mattress", "qushui.blanket.g3": "8h graphene intelligent temperature control mattress", "qushui.blanket.mj1": "Mijia Smart Water Circulation Heating Blanket", "qushui.dryer.8gxg1": "8h free Intelligent nursing, sterilization and deodorization shoe cabinet", + "qushui.massage.my01": "8H AI Intelligent 4D Massage Chair (Almighty Prince)", "qushui.mattress.mt": "8H 5D Sleep Aid Massage Mattress or S", + "qushui.mattress.zeroa1": "8H AI Smart Pillar Care Mattress PRO", "qushui.pillow.mj02": "Xiaomi Smart Pillow", "qushui.pillow.p2": "8h intelligent sleeping natural latex pillow x", "qushui.sofa.001": "8H Master Smart Electric Modular Sofa", @@ -2603,7 +3303,14 @@ "qushui.sofa.b7": "8H Le relaxed intelligent electric slow rocking sofa", "qwliot.fishbowl.38000": "Black Engine", "qyds.light.wy0a01": "Qianzhongyi intelligent lamp", + "qzgd.light.wy0a01": "Qingzhou photoelectric intelligent lamps", + "qzgd.switch.sw1a02": "Qingzhou one key intelligent switch", + "qzgd.switch.sw2a02": "Qingzhou two key intelligent switch", + "qzgd.switch.sw3a02": "Qingzhou three key intelligent switch", + "qzgd.switch.sw4a01": "Qingzhou four key intelligent switch", + "qzgd.switch.sw4a02": "Qingzhou eight key intelligent switch", "raex.curtain.le1xa": "Mr. Bang intelligent curtain", + "raile.bhf_light.sdjyby": "Smart linear bath master", "raile.light.zhzm1": "Intelligent lighting", "rbe.light.wy0a01": "RBE wisdow living room lamp", "rbe.light.wy0b01": "Ruiboer Intelligent Lamp", @@ -2611,9 +3318,15 @@ "renx.airer.dilai": "Laidi smart clothes dryer", "renx.airer.pinsh": "PISN smart clothes dryer", "repor.magic_touch.r1": "Repro intelligent neck pillow", + "rfd.airfresh.rdf01": "RIFINDE Air Full house customization", "rhj.robot.l81": "LeTianPai Desktop Robot", + "rhj.sensor_occupy.l730": "LeTianPai Presence Sensor Box", + "rhj.sensor_occupy.l730a": "LeTianPai Presence Sensor POP", "riot.plug.003": "Xiaorui WiFi Intelligent Socket-Basic Edition", + "riot.plug.006": "XiXiaoZhi socket wizard", "riot.switch.001": "RXW-Intelligent Double Key Switch", + "riot.switch.11": "CNYIOT Smart Meter", + "rixin.health_pot.bmgm01": "BEMEGA Intelligent Braised Tea Pot", "rjkj.switch.b103": "Intelligent Circuit Breaker", "rjkj.switch.mj152": "Rejuvee smart MCB2 with RCBO", "rjxn20.light.gxzm01": "Thank You Smart Dual Color Temperature Lamp", @@ -2629,6 +3342,9 @@ "rjxn20.switch.rixmsk": "RJ Intelligent three-button switch Mesh edition", "rjxn20.switch.rixmyk": "RJ Intelligent one-button switch Mesh edition", "rjxn20.switch.rjtdm": "RJ smart Bluetooth breaker", + "rmt.bed.asbed": "Asnug Smart Bed", + "rmt.bed.zhsbd2": "CHEERS waist support smart bed", + "rmt.bed.zhsbd3": "CHEERS Massaging Smart Bed", "rmt.bed.zhsbed": "CHEERS Smart Bed", "roborock.vacuum.a01": "Roborock E Series", "roborock.vacuum.a08": "Roborock S6 Pure", @@ -2659,7 +3375,7 @@ "roborock.vacuum.a72": "Roborock Q5 Pro", "roborock.vacuum.a73": "Roborock Q8 Max", "roborock.vacuum.a74": "Roborock P10", - "roborock.vacuum.a75": "Roborock Q Revo", + "roborock.vacuum.a75": "Roborock Qrevo", "roborock.vacuum.a76": "Roborock G10S Auto", "roborock.vacuum.c1": "Xiaowa C1", "roborock.vacuum.e2": "Xiaowa E Series", @@ -2684,8 +3400,11 @@ "roidmi.mop.xdj01": "ROIDMI Wet Dry Vacuum Cleaner NEO", "roidmi.mop.xdj03": "ROIDMI Smart Cordless Wet Dry Vacuum Cleaner R100", "roidmi.vacuum.r1b": "ROIDMI EVE", + "roidmi.vacuum.sdj60": "ROIDMI EVE MAX", "roidmi.vacuum.v1": "ROIDMI Cordless Vacuum Cleaner", "roidmi.vacuum.v60": "ROIDMI EVE", + "roidmi.vacuum.v62": "ROIDMI EVE CC", + "roidmi.vacuum.v63": "ROIDMI VACUUM EVE ROOK", "roidmi.vacuum.v66": "ROIDMI EVA", "rokid.robot.alien": "Rokid Alien", "rokid.robot.alien2": "Rokid Alien", @@ -2714,8 +3433,11 @@ "rttrp.sensor_gas.jy500": "Dory Gas Alarm", "runmi.suitcase.v1": "90 Marks Smart Metal Suitcase", "runmi.walkingpad.walk01": "Mijia Walking Pad (Foldable Handrail)", + "rutang.light.wy0a01": "Rutang full spectrum color temperature lamp Mesh", "ryeex.bracelet.sake": "Hey+ Band", + "saec.airc.rac": "SAEC", "saila.curtain.sle": "Smart Curtain Machine", + "san.airrtc.8909h": "Sancory Hot Thermostat", "san.airrtc.s89h": "Sancory Thermostat", "sayso.curtain.cura01": "SAYSO smart curtain motor", "sayso.light.wy0a01": "SAYSO intelligent spotlight", @@ -2723,6 +3445,20 @@ "sayso.switch.sw2a01": "SAYSO Smart Switch Two Keys", "sayso.switch.sw3a01": "SAYSO Smart Switch Three keys", "sayso.switch.sw4a01": "SAYSO Smart Switch Four Keys", + "scc.light.w00a1": "Simon Smart Track Light LT20", + "scc.light.wy0a01": "Simon smart downlights", + "scc.light.wy0a02": "Simon Yue series living room lights", + "scc.light.wy0a03": "Simon smart light with controller", + "scc.light.wy0a04": "Simon Yue series ceiling light", + "scc.light.wy0a05": "Simon Yue series bedroom lamp", + "scc.remote.ru02": "Simon Two Spot Switch (battery version)", + "scc.remote.ru06": "Simon Four Spot Switch (battery version)", + "scc.switch.bl01": "Simon Smart Switch(1 Gang LN/L adaptable)", + "scc.switch.bl02": "Simon Smart Switch(2 Gang LN/L adaptable)", + "scc.switch.bl03": "Simon Smart Switch(3 Gang LN/L adaptable)", + "scc.switch.bln01": "Simon smart switch (1 gang No neutral line switch)", + "scc.switch.bln02": "Simon smart switch (2 gang No neutral line switch)", + "scc.switch.bln03": "Simon smart switch (3 gang No neutral line switch)", "scds.light.wy0a01": "Dengbushangshu Picturesque lamp", "scds.light.wy0a03": "Deng bu Shang Shu intelligent Deng", "scdvb.aircondition.acm": "Bluetooth VRF Central air conditioning controller", @@ -2736,7 +3472,10 @@ "sfl.light.fsl003": "FSL smart lighting series", "sfl.light.lp001": "FSL Beauty Series Bulb", "sfl.light.lp002": "FSL series high pressure light strip", + "sfl.light.lp003": "FSL Foshan Lighting Intelligent Ceiling Light", + "shadow.switch.sw0a01": "Xuntou Light sensitive skylight control switch", "sharge.plug.sj01": "SHARGE 100W GaN Mini Charger ( Bluetooth Version)", + "shcs.analyzer.20md": "BaiJie Blood Glucose Uric Acid Cholesterol Analyzer", "shhf.light.mhcw01": "zhimei Smart Ceiling Light", "shhf.light.sfla10": "Smart Fan Light", "shhf.light.sfla12": "Intelligent dimming fan light", @@ -2744,6 +3483,7 @@ "shhf.light.slcwb3": "Intelligent lamp ble version", "shhf.light.slcwb8": "Intelligent lamp ble version V2", "shhf.light.slwfc3": "Smart light", + "shhf.plug.c001": "Smart metering socket WIFI version", "shhf.plug.spwc02": "Smart Socket WiFi edition", "shhf.switch.splgs1": "Intelligent breaker BLE Mesh version", "shibei.light.wy0a01": "Seebest Smart Living Room Ceiling Light", @@ -2753,6 +3493,18 @@ "shjszn.lock.kx": "Justree Smart Lock Kx", "shuii.humidifier.jsq001": "The fog free of humidifier", "shuii.humidifier.jsq002": "Zero-fog low-temperature evaporative humidifier (upgrade)", + "shus.bed.a01": "Sleepone AI mattress", + "shus.bed.bed01": "Shushi Intelligent electric bed", + "shuse.magnet.ss03": "Shuse Door Sensor (BLE)", + "shuse.plug.ifrc1": "Shuse Fingerbot Controller (Mesh)", + "shuse.valve.svc05": "Shuse Valve Controller", + "sic.scales.1300ar": "SENSSUN Domestic Smart Body Fat Scale", + "sic.scales.atz001": "Mumei Smart Body Fat Scale ATZ001", + "siemen.remote.arinap": "Siemens smart free location switch-1", + "siemen.remote.asw002": "Siemens smart free location switch-2", + "siemen.switch.arina1": "Siemens smart switch-1", + "siemen.switch.arina2": "Siemens smart switch-2", + "siemen.switch.arina3": "Siemens smart switch-3", "silen.fryer.sck501": "Silencare AirFryer 1.8L", "silen.fryer.sck505": "Silencare AirFryer", "silen.fryer.sck5o8": "Silencare AirFryer SC-K508W", @@ -2806,11 +3558,18 @@ "slf.switch.sw3b01": "Smart Zero Fire Three Button Switch HR7C07", "slf.switch.sw4a01": "Zhi Lafei two open four-four street light control", "slf.switch.sw4b01": "Smart Zero Fire Four Button Switch HR7C07", + "smartj.curtain.sjcmnp": "SmartJoy Curtain Motor (Bluetooth Mesh version)", "smartj.curtain.sjcmns": "SmartJoy Zhizhen Curtain Motor(WiFi)", "smartj.curtain.sjd82p": "SmartJoy Intelligent curtain motor (WiFi Pro)", "smartj.curtain.sjdt82": "SmartJoy intelligent curtain motor", "smartj.curtain.sjscmm": "SmartJoy Zhizhen curtain motor (Bluetooth Mesh version)", "smartj.light.sjdlds": "SmartJoy Zhizhen Dimmer (Bluetooth Mesh version)", + "smartj.light.sjpdls": "SmartJoy Smart Belt Controller (Bluetooth Mesh version)", + "smartj.light.sjpdsl": "SmartJoy Ultra Dimming Downlights (Bluetooth Mesh version)", + "smartj.light.sjpmdc": "SmartJoy Ultra-Smart Magnetic Dining Chandelier (Bluetooth Mesh version)", + "smartj.light.sjpmdf": "SmartJoy Ultra-Smart Magnetic Floodlight (Bluetooth Mesh version)", + "smartj.light.sjpmdg": "SmartJoy Ultra-Smart Magnetic Grid Light (Bluetooth Mesh version)", + "smartj.light.sjpmds": "SmartJoy Ultra-Intelligent Magnetic Spotlight (Bluetooth Mesh version)", "smartj.light.sjsdcb": "SmartJoy智臻色温灯(蓝牙Mesh版)", "smartj.light.sjsdls": "SmartJoy Zhizhen Dimmer Strip (Bluetooth Mesh version)", "smartj.light.sjsdmb": "SmartJoy smart Lantern (Bluetooth Mesh version)", @@ -2823,12 +3582,17 @@ "smartj.switch.sjlh02": "SmartJoy zhijian wall switch (two key WiFi)", "smartj.switch.sjlh03": "SmartJoy zhijian wall switch (three key WiFi )", "smartj.switch.sjlh1e": "SmartJoy wisdom at wall switch (one key WiFi) ", + "smartj.switch.sjlh1p": "SmartJoy jizhi Wall Switch (Zero fire one key Bluetooth Mesh version)", "smartj.switch.sjlh1s": "SmartJoy Zhizhen wall switch(one key Mesh)", "smartj.switch.sjlh2e": "SmartJoy wisdom at wall switch (two key WiFi)", + "smartj.switch.sjlh2p": "SmartJoy jizhi Wall Switch (Zero fire two key Bluetooth Mesh version)", "smartj.switch.sjlh2s": "SmartJoy Zhizhen wall switch (two key Mesh)", "smartj.switch.sjlh3e": "SmartJoy wisdom at wall switch (Three key WiFi)", + "smartj.switch.sjlh3p": "SmartJoy jizhi Wall Switch (Zero fire three key Bluetooth Mesh version)", "smartj.switch.sjlh3s": "SmartJoy Zhizhen wall switch (three key Mesh)", + "smartj.switch.sjlh4p": "SmartJoy jizhi Wall Switch (Zero fire four key Bluetooth Mesh version)", "smartj.switch.sjlh4s": "SmartJoy Zhizhen Wall Switch (Zero Fire Four-Button Bluetooth Mesh Version)", + "smg.scales.bt973": "Early fish intelligent body fat scale BT973", "smith.blanket.cxma1": "Chanitex Water-heated mattress CXM-A1", "smith.w_soften.cxs05ta1": "CHANITEX WATER SOFTENER", "smith.waterheater.cxea1": "Chanitex Electric Water Heater CXE-A1", @@ -2842,6 +3606,8 @@ "smooky.magic_touch.ma01": "SMOOKY Fascial gun", "solove.fan.f5new": "Plain desktop fan F5i", "soocare.magic_touch.m14": "Mijia Smart Neck Massager", + "soocare.toothbrush.1501": "Mi Smart Electric Toothbrush T501", + "soocare.toothbrush.2501": "Xiaomi Smart Electric Toothbrush T501", "soocare.toothbrush.m1": "Mi Electric Toothbrush", "soocare.toothbrush.m1s": "Mi Smart Electric Toothbrush T500", "soocare.toothbrush.mc1": "Mi Kids Electric Toothbrush", @@ -2852,26 +3618,40 @@ "sperll.light.sglw": "BanlanX Monochrome Light", "stds.light.wyst01": "Shengteng Lighting Ceiling Light", "stds.light.wyst02": "Shengteng Ceiling Light", + "stesh.blanket.rug02": "YNXT thermostatic floor heating pad", "suis.controller.pad01": "FMS Control Panel", + "suittc.airrtc.m301": "Smart thermostat touch version M", "suittc.airrtc.wk168": "Smart thermostat", + "suzi.scales.a33": "Suzi Smart body fat Scale A33", "sxds.blanket.jssn01": "JESIF Smart Plumbing Mattress(double)", "sxds.blanket.jssncd": "JESIF Smart Plumbing Mattress(single)", "sxds.pillow.pillow02": "Natural latex sleep pillow", + "sxs.lock.001": "Lock first sen smart door lock", "syi.airer.d08": "dengdi electric clothes hangers", "syi.airer.d16": "KaBei electric clothes rack", "syi.airer.hkg001": "Haohaka electric clothes hangers", "syi.airer.hsy01": "Hongshengyuan intelligent drying rack", "syi.airer.sy1": "KaRuiQi electric drying rack", "syi.airer.zjl": "ZhiJuLe electric drying rack", + "symi.airrtc.nt01": "Simi 3T1 Thermostat Mesh", "symi.curtain.cura01": "Kaomi smart curtain mesh version", + "symi.curtain.cura02": "Xiaoyi smart curtain mesh version", "symi.light.wy0a01": "Kaomi downlight mesh version", "symi.light.wy0a02": "Kaomi magnetic suction lamp mesh version", + "symi.light.wy0a03": "Xiao Yi smart light mesh version", + "symi.light.wy0a04": "Simi Smart light band mesh version", "symi.remote.ts1": "Simi six-key wireless switch", "symi.switch.apple": "16-way Switch Controller", + "symi.switch.s01": "simi Smart Switch Mesh", "symi.switch.sw1a01": "Kaomi one-key switch mesh version", + "symi.switch.sw1c01": "Xiaoyi One key switch mesh version", "symi.switch.sw2a01": "Kaomi two-button switch mesh version", + "symi.switch.sw2c01": "Xiaoyi two key switch mesh version", + "symi.switch.sw2d01": "Simi smart screen switch", "symi.switch.sw3a01": "Kaomi three-button mesh switch", + "symi.switch.sw3c01": "Xiaoyi three key switch mesh version", "symi.switch.sw4a01": "Kaomi four-button mesh switch", + "symi.switch.sw4c01": "Xiaoyi four key switch mesh version", "symi.switch.sw6a01": "Simi six-key switch mesh version", "symi.switch.sw8a01": "Kaomi eight key switch mesh version", "syniot.airer.l2": "smart airer", @@ -2883,23 +3663,42 @@ "syniot.switch.t1": "synIOT switch 1 Key", "syniot.switch.t2": "synIOT switch 2 key", "syniot.switch.t3": "synIOT switch 3 key", + "syzn01.tow_w.sy119": "Intelligent drying towel rack", "szdy.airfresh.n80": "Bijia Fresh Air Ventilator", + "szhhkj.diffuser.jd01": "Smart Connected Aromatherapy Diffuser JD01", "szkj.mop.mjhvc1": "Mijia Hi-temperature 3-in-1 Cordless Floor Washing Vacuum Cleaner", "szkj.mop.x1": "Shunzao HotClean Wet Dry Vacuum Cleaner", "szkj.vacuum.fc01eu": "Xiaomi Robot Vacuum S10T", "szkj.vacuum.mjfc01": "Mijia Robot Vacuum-Mop Tangle-free Brush", + "szks.etool.101": "Mr. Moores Window Cleaning Robot", + "szxzh.diffuser.v03": "Intelligent Aroma Diffuser V Series", + "t3ft.safe.001": "Triple ax password drawer T3", "tata.milkheat.bl1108": "BABY BOTTLE WARMER", "tcll.bhf_light.yb01": "TCL HZ Bath Heater", "tcll.bhf_light.yb02": "TCL Smart Bath Heater Fenghua 5Pro", + "tcll.bhf_light.yb03": "TCL Smart Bath Heater S2Pro", "tcll.light.wy0a01": "TCL Zhirui ceiling lamp", "tcll.light.xl6601": "TCL LED Ceiling Lamp", "tcll.light.xl6602": "TCL Modern room lamp", + "tenle.light.wya01": "TENLE Smart lighting", "teruns.humidifier.zyjs": "Terun central intelligent humidifier system", "thinks.lunar.xm1": "Smart Sleeping Sensor -- Lunar", + "thm11.blanket.2308": "THM smart water heating blanket", + "thm11.blanket.ln2401": "THM hot and cold mattress youth version", "tinymu.toilet.ailid": "TINYMU Smart Toilet AI Version", "tinymu.toilet.wmt15": "TINYMU Smart Toilet Ultimate V Shape", "tinymu.toiletlid.v1": "TINYMU Smart Toilet", "tnkq.airfresh.tnkq01": "TNKQ Multifunction Air Fresh", + "tnv.switch.sw1b01": "GAMDER V90 color screen one key switch", + "tnv.switch.sw1c01": "ZT intelligent switch one key", + "tnv.switch.sw2b01": "GAMDER V90 color screen two key switch", + "tnv.switch.sw2c01": "ZT intelligent switch two key", + "tnv.switch.sw3b01": "GAMDER V90 color screen three key switch", + "tnv.switch.sw3c01": "ZT intelligent switch three key", + "tnv.switch.sw4b01": "GAMDER V90 color screen four key switch", + "tnv.switch.sw4c01": "ZT intelligent switch four key", + "tofan.light.lt07": "YOOMI Smart 2-Colors Light Z7 Mesh", + "tofan.switch.s01": "YOOMI Smart Switch Z1-Mesh", "tokit.cooker.press1": "TOKIT Pressure IH Smart Rice Cooker", "tokit.cooker.tk20l01": "TOKIT Mini Rice Cooker", "tokit.cooker.tk4001": "TOKIT Smart IH Rice Cooker", @@ -2911,6 +3710,8 @@ "tokit.waterpuri.tkj1": "TOKIT Smart Water Purifier 600G", "topwit.bhf_light.htw02": "Smart bathroom master", "topwit.bhf_light.rz01": "Smart Bath Heater Switch", + "topwit.cs.rzw47": "UZ Card insertion device", + "topwit.curtain.rzct01": "UZ Curtain motor", "topwit.light.cw02": "Intelligent magnetic suction lamp", "topwit.light.cw03": "Dimmable magnetic lamp", "topwit.light.dw01": "Intelligent dimming lamp", @@ -2918,6 +3719,7 @@ "topwit.light.tsl01": "Intelligent no main light", "topwit.light.tsl02": "Intelligent line lamp", "topwit.light.tsl03": "Intelligent dimming drive", + "topwit.light.tsl07": "UZ Intelligent dimming drive", "topwit.remote.ru03": "Three Button Wireless Scene Panel", "topwit.switch.bln01": "Single way BLE Mesh zero fire switch", "topwit.switch.bln02": "Two way BLE Mesh zero fire switch", @@ -2938,11 +3740,21 @@ "topwit.switch.rzw32": "Intelligent switch zero fire two position (Mesh)", "topwit.switch.rzw33": "Intelligent switch zero fire three position (Mesh)", "topwit.switch.rzw34": "Intelligent switch zero fire four position (Mesh)", + "topwit.switch.rzw43": "UZ one position zero fire switch", + "topwit.switch.rzw44": "UZ two position zero fire switch", + "topwit.switch.rzw45": "UZ three position zero fire switch", + "topwit.switch.rzw46": "UZ four position zero fire switch", + "topwit.switch.rzw49": "UZ One key zero fire switch", + "topwit.switch.rzw50": "UZ two position zero fire switch", + "topwit.switch.rzw51": "UZ Three key zero fire switch", "tospo1.light.bpzc01": "Tospo LED full color bulb 7W", "tospo1.light.bpzc02": "Tospo LED full color bulb 12W", "tospo1.light.bpzp01": "Tospo A60 Bulb ", "tospo1.light.bpzp02": "Tospo A70 Bulb ", "tospo1.light.rpc01": "TOSPO LED Module", + "traxon.light.x1": "OSRAM Ultra-Thin Smart X1 Series", + "traxon.light.x2": "OSRAM Ultra-Thin Smart X2 Series", + "traxon.light.x3": "OSRAM Intelligent Barrel Spotlight ODS Series", "trios.bleshoes.v1": "米家智能跑鞋", "trios1.bleshoes.rftcdl": "L-ChiYi Temperature Control Shoes", "trios1.bleshoes.rftcdr": "R-ChiYi Temperature Control Shoes", @@ -2956,8 +3768,12 @@ "tsd.light.tp1": "DanceLight I Series Ceiling Lamp", "tsd.light.tsl001": "Dancelight I Series Downlight", "tsd.plug.hmi001": "Topstar Smart Socket", + "tsec.scales.bf669": "Intelligent Body Fat Scale", "tsoft.light.lite1": "ThunderSoft Little Table Lamp", + "tstar.magic_touch.6d": "Konka Smart Fascia Gun V19-6D", + "tstar.magic_touch.8x": "Konka Smart Fascia Gun V19-8X", "tstar.magic_touch.a8": "KONKA fascial gun", + "tstar.magic_touch.r8": "VTT Shoulder and neck massager", "tstar.razor.ra2": "VTT high end shaver", "twzm.light.wy0a01": "Taiwo Magnetic attraction lamp", "txdd.wifispeaker.x1": "Tencent Smart Display", @@ -2970,9 +3786,11 @@ "uvfive.steriliser.maine": "FIVE sterilization rack(Wall Mounted)", "uvfive.steriliser.tiger": "FIVE sterilization rack", "uvfive.tow_w.berry": "FIVE Smart Hot Towel Machine", + "uxkeji.airer.zbs02": "ZBS Airer(WIFI+BLE)", "uxkeji.bhf_light.ux47": "YanKon Smart Bath master", "uxkeji.curtain.40tt": "ZBS Curtain", "uxkeji.curtain.50tt": "ZBS Roller Blinds", + "uxkeji.curtain.63att": "ZBS intelligent curtain (BLE MESH)", "uxkeji.curtain.gmkhl": "GM curtain", "uze.hud.jl101": "JiuLu HUD GX", "vanco.toilet.max1": "Vancoco STARRY MAX intelligent toilet", @@ -2985,6 +3803,9 @@ "viomi.airc.m2": "meekee 1.5P", "viomi.airc.m3": "meekee 2P", "viomi.airc.m4": "meekee 3P", + "viomi.airc.sd26": "Viomi AI airc Smart 2S 1.5P (Level 1)", + "viomi.airc.sd28": "Viomi AI airc Spuer 3 3P (Level 1)", + "viomi.airc.y119": "Smart AC A2 Pro-18K", "viomi.aircondition.sd01": "Space E 1.5P(new)", "viomi.aircondition.sd02": "Space X 1.5P(new)", "viomi.aircondition.sd03": "Smart 2S new", @@ -3000,6 +3821,9 @@ "viomi.aircondition.sd17": "Super 2 Pro (UV) 1.5P", "viomi.aircondition.sd18": "Smart 2 (UV) 2P", "viomi.aircondition.sd19": "Smart 2 (UV) 3P", + "viomi.aircondition.sd22": "Super 3 1.5P", + "viomi.aircondition.sd23": "Super 3 2P", + "viomi.aircondition.sd24": "Viomi AI airc Super 3 Pro 1.5P (Level 1)", "viomi.aircondition.v10": "Royal Pro", "viomi.aircondition.v21": "Crown-22A", "viomi.aircondition.v22": "Crown-28A", @@ -3113,6 +3937,8 @@ "viomi.airer.vch106": "Viomi AI e-drying rack Super T", "viomi.airer.vch109": "Viomi AI e-drying rack Super 2S", "viomi.airer.vch110": "Viomi AI e-drying rack Super 2Y", + "viomi.airer.vchy12": "Viomi AI e-drying rack Smart S(Voice Version)", + "viomi.airer.vchy13": "Viomi AI e-drying rack Smart Pro(Voice Version)", "viomi.airer.vcy102": "Viomi Internet e-drying rack Sunny 2A", "viomi.airer.vcy104": "Viomi Internet e-drying rack Sunny 2A", "viomi.airer.vcy105": "Viomi AI e-drying rack Super", @@ -3128,6 +3954,7 @@ "viomi.bhf_light.v6": "Viomi Smart Bath Heater(Dinuclear version)", "viomi.bhf_light.v8": "VIOMI Bath Heater S1", "viomi.bhf_light.v9": "Viomi Smart Bath Heater (Swing version)", + "viomi.controller.pads": "Viomi AI intelligent controller HomePad", "viomi.cooker.v1": "Viomi Smart IH Rice Cooker", "viomi.cooker.v2": "Viomi Rice Cooker (4L Premium Edition)", "viomi.cooker.v4": "Viomi Smart IH Rice Cooker 3L", @@ -3136,6 +3963,7 @@ "viomi.curtain.v2": "Viomi Internet smart curtain Auto 1A", "viomi.curtain.v3": "Viomi AI smart curtain Auto 1S", "viomi.curtain.v4": "Viomi AI smart curtain Smart", + "viomi.curtain.v5": "Viomi AI smart curtain Master", "viomi.dishwasher.m01": "Mi Smart Built-in Dishwasher (8 Dining Sets)", "viomi.dishwasher.m02": "Mi Smart Dishwasher (4 Dining Sets)", "viomi.dishwasher.m03": "Mijia Smart FS\u0026BI Dishwasher S1", @@ -3153,6 +3981,7 @@ "viomi.dishwasher.v15": "Viomi AI Dishwasher Milano 15sets", "viomi.dishwasher.v17": "Viomi AI Dishwasher Super", "viomi.dishwasher.v23": "Viomi Smart Dishwasher (110V)", + "viomi.dishwasher.v26": "VIOMI Smart Built-in Dishwasher", "viomi.dry.v2": "Viomi Dryer Super 2E(10KG)", "viomi.fan.v13": "Viomi Smart Circulation Fan", "viomi.fan.v5": "Viomi ButterflyFan DC", @@ -3210,7 +4039,11 @@ "viomi.fridge.u60": "VIOMI AI Refrigerator Master 3Y(Quad 536)", "viomi.fridge.u62": "VIOMI AI Refrigerator Super 2S(SBS 550)", "viomi.fridge.u64": "VIOMI AI Refrigerator Smart E(SBS 456)", + "viomi.fridge.u68": "VIOMI AI Refrigerator Master 3(Fr 400)", + "viomi.fridge.u69": "VIOMI AI Refrigerator Super 2Pro(Quad 502)", "viomi.fridge.u7": "Viomi Internet refrigerator iLive (side by side 545L)", + "viomi.fridge.u70": "VIOMI AI Refrigerator Super 2S(Fr 509)", + "viomi.fridge.u71": "VIOMI AI Refrigerator Super 2S(Quad 508)", "viomi.fridge.u8": "Viomi Smart Refrigerator iLive(SBS 603L)", "viomi.fridge.v3": "Viomi Internet refrigerator iLive(French style 462L)", "viomi.fridge.w1": "Viomi Smart Refrigerator iLive2 (Three Door 301L)", @@ -3240,6 +4073,7 @@ "viomi.fridge.x49": "VIOMI AI Refrigerator 21Face2 (Quad 502)", "viomi.fridge.x50": "VIOMI AI Refrigerator 21Face 2PRO(T 515)", "viomi.fridge.x7": "Viomi Smart refrigerator 21 face (428L)", + "viomi.fryer.v2": "VIOMI Smart Air Fryer Pro 5L", "viomi.fryer.v3": "VIOMI Smart Air Fryer Pro 6L", "viomi.health_pot.c2": "Viomi Smart Health Pot Honey Pro", "viomi.health_pot.v1": "Mi Smart Multipurpose Kettle", @@ -3269,11 +4103,20 @@ "viomi.hood.c24": "Viomi AI Range Hood Super 2 Max", "viomi.hood.c25": "Viomi Smart Range hood Smart", "viomi.hood.c26": "Viomi AI range hood Super", + "viomi.hood.c28": "Viomi Al range hood Cross3 A1", "viomi.hood.c29": "Viomi AI range hood Super Pro", "viomi.hood.c3": "Viomi Smart Hood (VK501)", "viomi.hood.c30": "Viomi AI Range Hood Flash", + "viomi.hood.c33": "Viomi AI Range Hood Master 3 Pro", "viomi.hood.c35": "Viomi AI Range Hood Super 2 Pro", + "viomi.hood.c36": "Viomi AI Range Hood Super 2", + "viomi.hood.c37": "Viomi Al Range Hood Super 2 Pro", + "viomi.hood.c39": "Viomi AI Range Hood Smart 2", "viomi.hood.c4": "Viomi Internet Hood Flash Pro", + "viomi.hood.c41": "Viomi AI Range Hood Super 3 (BLACK)", + "viomi.hood.c42": "Viomi AI Range Hood Smart 2 Pro", + "viomi.hood.c43": "Viomi AI Range Hood Super 3 (White)", + "viomi.hood.c44": "Viomi AI Range Hood Cross 3E", "viomi.hood.c5": "Viomi Smart Hood Cross 3", "viomi.hood.c7": "Viomi Smart Hood", "viomi.hood.c8": "Viomi Internet Hood VK 707", @@ -3282,6 +4125,7 @@ "viomi.hood.h4": "Viomi Smart Hood Wing", "viomi.hood.h5": "Viomi Internet Hood Flash", "viomi.hood.v1": "Exhaust Hood \u0026 Stovetop", + "viomi.hood.v11": "Mijia Smart Ultra-slim Deep Suction Range Hood S1", "viomi.hood.v12": "Mi Smart Side Suction Range Hood S1", "viomi.hood.v2": "Mi Smart Side-Draft Range Hood", "viomi.hood.v5": "Mi Crossover Range Hood S1 ", @@ -3296,16 +4140,24 @@ "viomi.i_stove.v6": "Viomi AI Integrated Stove", "viomi.i_stove.v7": "Viomi AI Integrated Stove-VJ502", "viomi.i_stove.v8": "Viomi AI Integrated Stove-VJ503", + "viomi.ihcooker.v1": "VIOMI Smart Built-in Hob", "viomi.juicer.v1": "Mi High-speed Smart Blender", "viomi.juicer.v2": "Viomi High Speed Blender(Quiet Version)", "viomi.light.ewf11a": "Viomi Smart LED Strip Master (White)", "viomi.light.ewf11b": "Viomi Smart LED Strip Master (Color)", "viomi.lock.lbt14a": "Viomi Internet smart lock eLink 2A", + "viomi.lock.lbt16a": "Viomi AI Smart doorlock Super 2Y", "viomi.lock.lbt41e": "Viomi AI Smart lock eyeLink 2F Pro", "viomi.lock.lbt46a": "Yunmi AI intelligent door lock Master 3E", + "viomi.lock.lbt46b": "VIOMI Smart Door Lock Guard 3 Pro", + "viomi.lock.lbt46c": "VIOMI Smart Door Lock Guard 3A Pro", "viomi.lock.lbt48a": "Viomi AI Smart lock eyeLink 2S", "viomi.lock.lbt51a": "Viomi AI intelligent door lock Smart 2", + "viomi.lock.lbt51b": "VIOMI Smart Door Lock Guard 2", + "viomi.lock.lbt51c": "VIOMI Smart Door Lock Guard 2A", "viomi.lock.lbt61a": "Yunmi AI Intelligent Door Lock Super 2E (Bluetooth version)", + "viomi.lock.lbt61c": "VIOMI Smart Door Lock Guard 2 Pro", + "viomi.lock.lbt64a": "Viomi AI Smart doorlock Super 3Y", "viomi.lock.link1": "VIOMI door lock Link (Bluetooth)", "viomi.lock.link2": "Viomi Door Lock Link (Long endurance version)", "viomi.lock.link2p": "Viomi Internet smart lock eLink 2Pro", @@ -3322,6 +4174,9 @@ "viomi.oven.so8": "Viomi Smart Steam oven Face A1(Build-in)", "viomi.oven.so9": "Viomi Smart Steam and Baking Oven-Face (Taiwan)", "viomi.steriliser.v1": "Viomi Disinfection Cabinet (Build-in)", + "viomi.switch.nm1": "VIOMI Smart Switch Master(With Neutral,One Key)", + "viomi.switch.nm2": "VIOMI Smart Switch Master(With Neutral,Two Key)", + "viomi.switch.nm3": "VIOMI Smart Switch Master(With Neutral,Three Key)", "viomi.toilet.m05": "Viomi intelligent toilet Nano2 Max", "viomi.toilet.m06": "Viomi AI health check toilet Air", "viomi.vacuum.v11": "Viomi V-SLAM Robot Vacuum", @@ -3349,11 +4204,16 @@ "viomi.vacuum.v45": "VIOMI Auto Cleaning Alpha 3", "viomi.vacuum.v49": "Viomi Alpha 3 Pro", "viomi.vacuum.v53": "Viomi Alpha 2 Lite", + "viomi.vacuum.v56": "Viomi V3 Absolut", "viomi.vacuum.v6": "Viomi Cleaning Robot", "viomi.vacuum.v7": "Mi Robot Vacuum-Mop P", "viomi.vacuum.v8": "Mi Robot Vacuum-Mop P", "viomi.vacuum.v9": "Mi Robot Vacuum-Mop P", "viomi.washer.s1": "Viomi Smart Top Loading Washing Machine(9KG)", + "viomi.washer.sd10": "Viomi Washer and Dryer Super 2 Max 12KG", + "viomi.washer.sd11": "Viomi Washing Machine Super 2E(10kg DD)", + "viomi.washer.sd13": "Viomi Washer\u0026Dryer Super 2Pro Fresh 10KG", + "viomi.washer.sd14": "Viomi Washer and Dryer Super 2S 10KG", "viomi.washer.u1": "Viomi Voice Controlled Washing Machine", "viomi.washer.u2": "Viomi Smart Washer\u0026Dryer", "viomi.washer.u3": "Viomi Smart Washing Machine(8kg)", @@ -3418,6 +4278,7 @@ "viomi.waterheater.e45": "VIOMI AI Electric Waterheater Super", "viomi.waterheater.e47": "Viomi AI Electric Waterheater Smart 2", "viomi.waterheater.e48": "Viomi AI Electric Waterheater Super 2 Pro", + "viomi.waterheater.e49": "Viomi AI Electric Waterheater Smart E", "viomi.waterheater.e7": "Viomi Smart Electric Water Heater Air (60L Dual-Tank Excellent)", "viomi.waterheater.e8": "Viomi Smart Electric Water Heater Air (60L Dual-Tank Wisdom)", "viomi.waterheater.m1": "Mijia Smart Tankless Gas Heater S1 (18L)", @@ -3470,9 +4331,14 @@ "viomi.waterheater.u69": "Viomi Smart Gas Water Heater Smart Pro", "viomi.waterheater.u7": "Viomi Smart Gas Water Heater Zero 16L", "viomi.waterheater.u70": "Viomi Smart Gas Water Heater Super Pro", + "viomi.waterheater.u72": "Viomi AI Gas Water Heater Super 2", + "viomi.waterheater.u73": "Viomi AI Gas Water Heater Super 2 Pro", "viomi.waterheater.u8": "Viomi Smart Gas Water Heater Zero(18L)", "voc777.lock.757": "XKS Smartlock", + "voc777.lock.k5ss": "VOC Fully automatic palm vein door lock", + "voc777.lock.k6": "VOC Fully Automatic Door Lock", "voc777.lock.t8": "VOC Large Screen Cat Eye Face Lock T10 Plus", + "wainft.light.1123": "XinGuang dynamic light strips(Dual color temperature)", "wainft.light.wy0a01": "Xinguang intelligent bulb", "wainft.light.wy0a02": "XG magnet lamp", "wainft.light.wy0a03": "Xinguang intelligent bicolor temperature lamp", @@ -3485,9 +4351,14 @@ "wanhe.waterheater.s5": "VANWARD Water Heater S5", "wanrui.blanket.psn2a": "Zhiling Intelligent Water Warm Mat", "wdc.light.wy0a01": "AI Meiju intelligent lamp", + "weik.scales.t2816": "Visnn smart health body fat scale T2816", + "weik.scales.ws2901": "Weishang intelligent health body fat scale WS2901", "wfxx.fishbowl.ysb2": "Molian Feeder", + "wfxx.light.12": "TF light control box", "wfxx.motor.lsmk": "Qishi Controller", + "wfxx.motor.mxrf": "MX RF controller PLUS", "wfxx.motor.ycmkq": "MX RF controller", + "wfxx.plug.pdczwf": "PD smart socket (WiFi)", "wfxx.relay.asdasd": "PD Switch(WiFi)", "whx.magic_touch.11": "DAI QU Warm Uterus Treasure", "whx.magic_touch.nuanwe": "DAI QU Warm stomach", @@ -3495,14 +4366,22 @@ "wintom.curtain.230xm": "WinTom Curtain", "wise.switch.sw2a01": "WISE Situational smart screen switch", "wise.wifispeaker.x7": "WISE SMART CONTROL PAD", + "wiseda.scales.m01": "Bluetooth intelligent body fat scale M01", + "wiseda.scales.m02": "Bluetooth smart body fat scale M02", + "wiseda.scales.pro": "Bluetooth Smart body fat Scale M03", "wjh.magic_touch.p1": "Weijiahua smart thumping shawl", "wjh.magic_touch.yb01": "Weijiahua Smart Eye Massager", "wlg.light.wy0a01": "WLG intelligent dimming light", + "wlg.light.wy0a02": "WLG intelligent magnetic lamp", + "wlg.light.wy0a03": "WLG smart light belt", + "wliot.scales.fg2009": "Welland Scales FG2009B", "wxjzkj.kettle.lxj001": "LIxiangjia Intelligent electric tea stove", "wxjzkj.kettle.lxj002": "T1 intelligent voice electric tea stove", "wzt.desk.h100": "AOKE intelligent lifting table", "wzt.desk.h101": "AIMIZO Intelligent Elevating Table", "wzt.desk.h102": "ULOVEHOME intelligent lifting table", + "wzxj.lock.t5": "T5 intelligent door lock", + "xar.heater.wal1": "Wu Ai Ling smart carpet", "xbzhm.light.w00a01": "Jinbaili Smart Monochrome Light", "xbzhm.light.wy0a01": "Jinbaili Smart Two-color Light", "xckj.dishwasher.idw01": "Ocooker The Dishwasher", @@ -3525,6 +4404,7 @@ "xhuan.curtain.cura03": "Sumi Smart Curtain Motor T1 Pro", "xhuan.curtain.cura04": "Sumi Open-close Curtain Motor (Mesh)", "xhuan.curtain.cura05": "Sumi dream curtain", + "xhuan.curtain.plcg01": "Sumi intelligent curtain motor PLC version", "xhuan.light.wy0a01": "Sumi Ruying Light Strip", "xhuan.light.wy0a02": "Sumi Downlight Lite", "xhuan.light.wy0a03": "Sumi Magnetic Floodlight", @@ -3538,8 +4418,11 @@ "xhuan.light.wy0a12": "SuMi linear lamp", "xhuan.light.wy0a13": "SuMi tube spotlight Pro", "xhuan.light.wy0a14": "SuMi intelligent Deng Pro", + "xhuan.light.wy0a16": "Sumi rhythm lamp", "xhuan.light.wyrz04": "Sumi intelligent downlights H", + "xhuan.light.wyrz05": "Sumi Intelligent magnetic suction lamp H", "xhuan.light.wyrz06": "Sumi Intelligent linear light H", + "xhuan.light.wyrz4s": "Sumi intelligent downlights Hs", "xhuan.sensor_occupy.s01": "Sumi Presence Sensor", "xhuan.switch.1lrz02": "Sumi Intelligent Switch H(Single fire one key)", "xhuan.switch.1nrz02": "Sumi Intelligent Switch H(Zero fire one key)", @@ -3549,6 +4432,10 @@ "xhuan.switch.3nrz02": "Sumi Intelligent Switch H(Zero fire triple three key)", "xhuan.switch.4lrz02": "Sumi Intelligent Switch H(Single fire four key)", "xhuan.switch.4nrz02": "Sumi Intelligent Switch H(Zero fire four key)", + "xhuan.switch.plcg02": "Sumi Intelligent Switch PLC Version (One Position)", + "xhuan.switch.plcg03": "Sumi Intelligent Switch PLC Version (Two Position)", + "xhuan.switch.plcg04": "Sumi Intelligent Switch PLC Version (Three Position)", + "xhuan.switch.plcg05": "Sumi Intelligent Switch PLC Version (Four Position)", "xhuan.switch.sw1a01": "Sumi t 1 intelligent switch (zero fire single key)", "xhuan.switch.sw1b01": "Sumi smart switch (zero fire one key)", "xhuan.switch.sw2a01": "Sumi t 1 intelligent switch (Zero Fire Two keys)", @@ -3559,6 +4446,21 @@ "xhuan.switch.sw4b01": "Sumi smart switch-zero fire four keys", "xhuan.switch.sw8a01": "Sumi colorful panel", "xhzm.light.wy0a01": "Xinhong ceiling lamp", + "xiaomi.airc.h09h00": "Air Conditioner(1.5 HP/New China Energy Label 1)", + "xiaomi.airc.h09r00": "Air Conditioner(1.5 HP/New China Energy Label 1)", + "xiaomi.airc.r09h00": "Air Conditioner(1.5 HP/New China Energy Label 1)", + "xiaomi.airc.r24r00": "Power Saving Pro Air Conditioner 1.5HP Level 1+ Energy Efficiency", + "xiaomi.airc.r27r00": "Mi Nature Air Conditioner (2 HP/New China Energy Label 1)", + "xiaomi.airc.r33r00": "Mi Smart Electricity Saving Air Conditioner 3 HP/New China Energy Label 1", + "xiaomi.airc.r34r00": "Mijia Natural Wind Pro Air Conditioner 1.5HP Level 1+ Energy Efficiency", + "xiaomi.airc.r36r00": "Cooling Silence Air Conditioner 1.5HP Level 1 Energy Efficiency", + "xiaomi.airc.rr0r00": "Fresh Wind Air Conditioner Pro Dual-Outlet Vertical 3HP Level 1+ Energy Efficiency", + "xiaomi.airc.rr1r00": "Natural Wind Air Conditioner Pro Dual-Outlet Vertical 3HP Level 1+ Energy Efficiency", + "xiaomi.airc.rr2r00": "Natural Wind Air Conditioner Dual-Outlet Vertical 3HP Level 1 Energy Efficiency", + "xiaomi.airc.rr3r00": "Natural Wind Air Conditioner Dual-Outlet Vertical 3HP Level 1 Energy Efficiency (Silver)", + "xiaomi.airc.rr4r00": "Fresh Wind Air Conditioner Pro Dual-Outlet Vertical 3HP Level 1+ Energy Efficiency", + "xiaomi.airc.rr5r00": "Fresh Pro Air Conditioner Dual-Outlet Vertical 3HP Level 1+ Energy Efficiency (White)", + "xiaomi.airc.rr6r00": "Natural Wind Pro Air Conditioner Dual-Outlet Vertical 3HP Level 1+ Energy Efficiency (White)", "xiaomi.aircondition.c10": "Mi Smart Ultra Electricity Saving Vertical Air Conditioner (2HP/Inverter/New China Energy Label Level 1)", "xiaomi.aircondition.c11": "Mi Smart Ultra Electricity Saving Vertical Air Conditioner", "xiaomi.aircondition.c12": "Mi Smart Air Conditioner Natural Breeze (Gold Edition 1.5HP)", @@ -3590,7 +4492,11 @@ "xiaomi.aircondition.m11": "Air Conditioner Straight Cool (1 HP/New China Energy Label Level 5)", "xiaomi.aircondition.m15": "Mi Gentle Air Condition(1.5 HP/New China Energy Label 1)", "xiaomi.aircondition.m16": "Mi Nature Smart Electricity Saving Air Conditioner 2 HP/New China Energy Label 1", + "xiaomi.aircondition.m18": "Mi Central Air-conditioning Duct Machine", + "xiaomi.aircondition.m19": "Mi Smart AC with Ventilation (1.5HP New China Energy Label Level 1)", "xiaomi.aircondition.m22": "Mi Smart Electricity Saving Air Conditioner 2 HP/New China Energy Label 3", + "xiaomi.aircondition.m27": "Mi Nature Air Conditioner (1.5 HP/New China Energy Label 1)", + "xiaomi.aircondition.m28": "Mijia Fresh Air Pro Air Conditioner 1.5HP Level 1+ Energy Efficiency", "xiaomi.aircondition.m3": "Mi Nature Air Conditioner (1.5 HP/New China Energy Label 1)", "xiaomi.aircondition.m4": "Mi Smart Electricity Saving Air Conditioner (1HP/New China Energy Label 1)", "xiaomi.aircondition.m6": "Air Conditioner (1.5 HP/New China Energy Label Level 3)", @@ -3626,26 +4532,86 @@ "xiaomi.aircondition.mt8": "Mi Smart Ultra Electricity Saving Air Conditioner (1.5HP/Inverter/New China Energy Label Level 1)", "xiaomi.aircondition.t13": "Mi Smart Ultra Electricity Saving AC (1.5HP/Inverter/New China Energy Label L1)", "xiaomi.airer.1sfun": "Mijia Smart Multifunction Clothes Drying Rack 1S", + "xiaomi.airer.lyj3xs": "Mijia Smart Hidden Clothing Drying Rack", "xiaomi.airp.cpa4": "Xiaomi Smart Air Purifier 4 Compact", "xiaomi.airp.mp4": "Xiaomi Smart Air Purifier 4", + "xiaomi.airp.ua3": "Mijia Smart Air Purifier Ultra Enhanced Version", "xiaomi.airp.va2b": "Xiaomi Smart Air Purifier 4 Pro", + "xiaomi.airp.va3": "Mijia Smart Air Purifier 5S", "xiaomi.airp.va4": "Mijia Smart Air Purifier 4 Pro H", + "xiaomi.bhf_light.v2": "Mijia Smart Bathroom Heater", + "xiaomi.blanket.mj1": "Mijia Smart Electric Under Blanket", + "xiaomi.blanket.mj2": "Mijia Smart Water Heating Blanket", "xiaomi.camera.c01a01": "Xiaomi Smart Camera C300", "xiaomi.camera.c01a02": "Mi 360° Home Security Camera 2K", + "xiaomi.carlight.cars1": "Smart Underglow Lights", + "xiaomi.controller.86v1": "Xiaomi Smart Home Control", + "xiaomi.cooker.cmk7": "Xiaomi Smart Multifunctional Rice Cooker", + "xiaomi.curtain.acn009": "Mijia Smart Curtains Adjustable Rail", + "xiaomi.curtain.acn010": "Mijia Smart Motorized Curtain 2", "xiaomi.demo.v1": "Beta build", "xiaomi.demo.v2": "Beta build", + "xiaomi.derh.13l": "Mijia Smart Dehumidifier 13L", + "xiaomi.derh.lite": "Xiaomi Smart Dehumidifier Lite", + "xiaomi.diffuser.xwcztx": "Smart Scent Diffuser", + "xiaomi.diffuser.xwczxf": "Mijia Smart Scent Diffuser Cup Holder Edition", + "xiaomi.dishwasher.p116": "Mijia Smart BI Dishwasher P2", + "xiaomi.dishwasher.s2": "Mijia Smart Tabletop Dishwasher S2", + "xiaomi.dishwasher.v02": "Mijia Smart Compact Dishwasher S2 White", + "xiaomi.dishwasher.v03": "Mijia Smart Compact Dishwasher S2 Black", + "xiaomi.esteamer.mes01": "Mijia Smart Food Steamer 12L", + "xiaomi.fan.p43": "Mijia Smart Standing Fan Pro", + "xiaomi.fan.p45": "Xiaomi Smart Tower Fan 2", + "xiaomi.fan.p51": "Mijia Air Circulation Fan", + "xiaomi.feeder.iv2001": "Xiaomi Smart Pet Food Feeder 2", + "xiaomi.feeder.pi2001": "Mijia Smart Pet Food Feeder 2", + "xiaomi.foot_bath.mizs1": "Mijia Smart Sterilizing Foot Spa Massager", + "xiaomi.fryer.maf07d": "Xiaomi Smart Air Fryer 5.5L", + "xiaomi.fryer.maf14": "Xiaomi Smart Air Fryer 4.5L", + "xiaomi.fryer.maf16": "Mijia Smart Air Fryer P1 6.5L", "xiaomi.gateway.hub1": "Xiaomi Home Hub", + "xiaomi.health_pot.p1": "Mijia Smart Multifunctional Kettle P1", + "xiaomi.heater.ma4": "Xiaomi Smart Graphene Space Heater", "xiaomi.heater.ma7": "Mijia Graphene Baseboard Heater 2", "xiaomi.heater.ma8": "Mijia Graphene Fan Heater", + "xiaomi.hood.jyjp3": "Mijia Smart Purifying Range Hood T1", + "xiaomi.hood.jyjss2": "Mijia Smart Purifying Range Hood S2", + "xiaomi.hood.ympqs1": "Mijia Smart Built-in Side Suction Range Hood S1", + "xiaomi.hood.ymv5": "Mijia Smart Crossover Range Hood S2", + "xiaomi.humidifier.3lite": "Xiaomi Smart Evaporative Humidifier", "xiaomi.humidifier.airmx": "Mijia Mist-Free Humidifier 3 Pro", + "xiaomi.humidifier.p1200": "Mijia Mist-Free Humidifier 3 (1200)", "xiaomi.humidifier.p3": "Mijia Mist-Free Humidifier 3 (400)", "xiaomi.ihcooker.cmg28": "Mi Smart Induction Cooker Ultra Slim", + "xiaomi.intercom.mi2p": "Xiaomi Walkie-Talkie 3", + "xiaomi.juicer.cms1": "Mijia Smart Blender S1", + "xiaomi.kettle.mek01": "Mijia Smart Electric Hot Water Dispenser 5L", + "xiaomi.kettle.mek02": "Xiaomi Smart Electric Hot Water Dispenser 5L", + "xiaomi.kettle.v20": "Xiaomi Smart Kettle 2 Pro", + "xiaomi.kettle.v21": "Xiaomi Smart Kettle 2 Pro", + "xiaomi.light.cfan": "Mijia Fan Light 42"", + "xiaomi.light.lamp30": "Mijia Standing Study Lamp", + "xiaomi.light.lamp31": "Mijia LED Desk Lamp 2", + "xiaomi.light.lamp32": "Xiaomi LED Desk Lamp 2", + "xiaomi.lock.b03": "Xiaomi Smart Door Lock 2 (Finger Vein Unlock)", + "xiaomi.lock.dl02v1": "Xiaomi Smart Door Lock 2", + "xiaomi.magic_touch.my02": "Mijia Smart Eye Massager", + "xiaomi.magic_touch.yb01": "Mijia Smart Back Massager", + "xiaomi.mic.s33": "Xiaomi Karaoke Microphone", "xiaomi.motion.pir1": "Xiaomi Motion Sensor 2S", + "xiaomi.pet_waterer.002": "Mijia Wireless Smart Pet Fountain", "xiaomi.phone_ir.t1": "手机红外遥控器", "xiaomi.phone_ir.v1": "IR remote", "xiaomi.plc.v1": "Mi electricity WiFi extender", + "xiaomi.plug.mcn001": "Xiaomi Smart Wall Outlet Pro", + "xiaomi.plug.mcn003": "Xiaomi Smart Wall Outlet Pro", "xiaomi.plug.test1": "测试模拟插座", + "xiaomi.printer.label": "Mijia Label Printer", + "xiaomi.projector.a1s": "Redmi Smart Projector 2", + "xiaomi.projector.a2": "Redmi Smart Projector 2 Pro", + "xiaomi.projector.yslite": "Redmi Smart Projector Lite", "xiaomi.repeater.mc04": "Mi WiFi Range Extender AC1200", + "xiaomi.repeater.rd10m": "Xiaomi WiFi Range Extender N300", "xiaomi.repeater.v1": "Mi Wi-Fi Repeater", "xiaomi.repeater.v2": "Mi Wi-Fi Repeater 2", "xiaomi.repeater.v3": "Mi Wi-Fi Range Extender Pro", @@ -3655,6 +4621,8 @@ "xiaomi.router.cr8806": "小米路由器CR8806", "xiaomi.router.cr8808": "小米路由器CR8808", "xiaomi.router.cr8809": "小米路由器CR8809", + "xiaomi.router.cr8816": "Xiaomi Router CR8806", + "xiaomi.router.cr8819": "小米路由器CR8809", "xiaomi.router.d01": "Mi Router Mesh", "xiaomi.router.lv1": "Mi Wi-Fi Nano", "xiaomi.router.lv3": "小米路由器R3C", @@ -3685,6 +4653,7 @@ "xiaomi.router.ra72": "小米路由器AX6000", "xiaomi.router.ra74": "Redmi Router AX5400", "xiaomi.router.ra80": "小米路由器AX3000", + "xiaomi.router.ra80v2": "Xiaomi Router AX3000", "xiaomi.router.ra81": "Redmi路由器AX3000", "xiaomi.router.ra82": "Xiaomi Mesh System AX3000", "xiaomi.router.rb01": "Xiaomi Router AX3200", @@ -3695,19 +4664,40 @@ "xiaomi.router.rb08": "Xiaomi HomeWiFi三频Mesh路由器", "xiaomi.router.rc01": "Xiaomi万兆路由器", "xiaomi.router.rc02": "Xiaomi Router AX3000 NE", - "xiaomi.router.rc06": "Xiaomi Router 7000", + "xiaomi.router.rc06": "Xiaomi Router BE7000", + "xiaomi.router.rd01": "Xiaomi Whole-home Mesh System", + "xiaomi.router.rd02": "Xiaomi全屋路由 子路由", "xiaomi.router.rd03": "Xiaomi Router AX3000T", + "xiaomi.router.rd04": "Xiaomi路由器AX1500", + "xiaomi.router.rd08": "Xiaomi Router BE6500 Pro", + "xiaomi.router.rd12": "Xiaomi Router AX1500", + "xiaomi.router.rd13": "Xiaomi Mesh System AC1200", + "xiaomi.router.rd15": "Xiaomi路由器BE3600 2.5G版", + "xiaomi.router.rd16": "Xiaomi Router BE3600", + "xiaomi.router.rd18": "Xiaomi Router BE5000", + "xiaomi.router.rd23": "Xiaomi Router AX3000T", + "xiaomi.router.rd28": "Xiaomi Mesh System AX3000 NE", "xiaomi.router.rm1800": "小米路由器AX1800", "xiaomi.router.rm2100": "Redmi 路由器AC2100", - "xiaomi.router.rmo15": "小米路由器", + "xiaomi.router.rmo15": "Xiaomi Router", "xiaomi.router.tr606": "小米路由器TR606", "xiaomi.router.v1": "Mi Wi-Fi", "xiaomi.router.v2": "Mi Wi-Fi", "xiaomi.router.v3": "小米路由器3", "xiaomi.router.wr30u": "小米路由器WR30U", + "xiaomi.scales.ms112": "Mijia Smart Scale S200", + "xiaomi.scooter.lq4lp": "Xiaomi Electric Scooter 4 Lite (2nd Gen)", + "xiaomi.scooter.t2336": "Xiaomi Electric Scooter 4 Pro (2nd Gen)", + "xiaomi.sensor_occupy.03": "Xiaomi Human Presence Sensor", "xiaomi.split_tv.b1": "Mi TV Bar", "xiaomi.split_tv.v1": "Mi TV Bar", "xiaomi.switch.a2ota": "Universal Remote", + "xiaomi.switch.pro1": "Xiaomi Smart Wall Switch Pro (1 Gang)", + "xiaomi.switch.pro2": "Xiaomi Smart Wall Switch Pro (2 Gang)", + "xiaomi.switch.pro3": "Xiaomi Smart Wall Switch Pro (3 Gang)", + "xiaomi.switch.wpro1": "Xiaomi Smart Wall Switch Pro (1 Gang)", + "xiaomi.switch.wpro2": "Xiaomi Smart Wall Switch Pro (2 Gang)", + "xiaomi.switch.wpro3": "Xiaomi Smart Wall Switch Pro (3 Gang)", "xiaomi.tv.4kh1": "Mi 4K TV 82", "xiaomi.tv.8kh1": "Mi 8K TV 82", "xiaomi.tv.b1": "Xiaomi TV", @@ -3740,26 +4730,47 @@ "xiaomi.tvbox.b1": "Mi Box", "xiaomi.tvbox.i1": "Mi Box", "xiaomi.tvbox.v1": "Mi Box", + "xiaomi.vacuum.b106bk": "Xiaomi Robot Vacuum T12", "xiaomi.vacuum.b106eu": "Xiaomi Robot Vacuum S12", + "xiaomi.vacuum.b108gl": "Xiaomi Robot Vacuum S20+", "xiaomi.vacuum.b112": "Xiaomi Robot Vacuum E10", "xiaomi.vacuum.b112bk": "Xiaomi Robot Vacuum E10C", "xiaomi.vacuum.b112gl": "Xiaomi Robot Vacuum E12", "xiaomi.vacuum.c101": "Mijia Self-Cleaning Robot Vacuum-Mop 2", + "xiaomi.vacuum.c101eu": "Xiaomi Robot Vacuum X20", "xiaomi.vacuum.c102cn": "Mijia Infinite Robot Vacuum-Mop 2", + "xiaomi.vacuum.c102gl": "Xiaomi Robot Vacuum X20+", "xiaomi.vacuum.c103": "Mijia Robot Vacuum-Mop 3C (Enhanced Edition)", "xiaomi.vacuum.c104": "Mijia Robot Vacuum-Mop 3", + "xiaomi.vacuum.c107": "Mijia Robot Vacuum M30 Pro", + "xiaomi.vacuum.c108": "Xiaomi Robot Vacuum E5", + "xiaomi.vacuum.d102ev": "Mijia Robot Vacuum M30", + "xiaomi.vacuum.d103cn": "Mijia Robot Vacuum M30 S", + "xiaomi.vacuum.d106gl": "Xiaomi Robot Vacuum S20", "xiaomi.watch.band1": "Mi Band", "xiaomi.watch.band1A": "小米手环", "xiaomi.watch.band1S": "小米手环", "xiaomi.watch.band2": "小米手环", + "xiaomi.watch.sw769": "Mi Kids Smart Watch S1", "xiaomi.watch.sw772a": "Mi Kids Smartwatch U1 Pro", "xiaomi.watch.sw773": "Mi Kids Smartwatch C7A", + "xiaomi.watch.sw775": "Mi Kids Smart Watch 7", + "xiaomi.watch.sw776": "Mi Kids Smart Watch 7X", + "xiaomi.watch.sw777a": "Mi Kids Smart Watch U2", + "xiaomi.watch.sw778": "Mi Kids Smart Watch 7A", + "xiaomi.waterheater.m3": "Mijia Smart Tankless Gas Heater 16L N1", + "xiaomi.waterheater.ym02": "Mijia Smart Electric Water Heater N1 60L", + "xiaomi.waterheater.ym03": "Mijia Smart Double Tank Electric Water Heater P1 60L", "xiaomi.waterheater.ym05": "Mijia Smart Double Tank Electric Water Heater S1 60L", "xiaomi.waterheater.yms2": "Mijia Smart Tankless Gas Heater 18L S2", "xiaomi.waterpuri.400f4": "Mijia Water Purifier 400G", + "xiaomi.waterpuri.800f4": "Mijia Water Purifier 800G", + "xiaomi.waterpuri.lx20": "Mijia Dual-core Water Purifier 1200G Pro", "xiaomi.waterpuri.lx32": "Mijia Water Purifier 1000G Pro", + "xiaomi.waterpuri.lx33": "Mijia Water Purifier 1000G Plus", "xiaomi.waterpuri.q1000": "Mijia Instant Hot Water Purifier Q1000", "xiaomi.wifispeaker.07g": "Xiaomi Smart Speaker Lite", + "xiaomi.wifispeaker.16b": "Xiaomi Sound", "xiaomi.wifispeaker.l04m": "Mi Smart Clock 4inch", "xiaomi.wifispeaker.l05b": "Mi AI Speaker Play", "xiaomi.wifispeaker.l05c": "Mi AI Speaker Play Plus", @@ -3776,7 +4787,12 @@ "xiaomi.wifispeaker.lx05": "Mi AI Speaker Play 2019", "xiaomi.wifispeaker.lx06": "Mi AI Speaker Pro", "xiaomi.wifispeaker.lx5a": "Mi AI Speaker Remote", + "xiaomi.wifispeaker.m01a": "Xiaomi Bluetooth Speaker Mini", + "xiaomi.wifispeaker.m01g": "Xiaomi Bluetooth Speaker Mini", + "xiaomi.wifispeaker.m02a": "Xiaomi Bluetooth Speaker", + "xiaomi.wifispeaker.m02g": "Xiaomi Bluetooth Speaker", "xiaomi.wifispeaker.m03a": "Xiaomi Sound Move", + "xiaomi.wifispeaker.m06": "Xiaomi Bluetooth Speaker Camp", "xiaomi.wifispeaker.s12": "Mi AI Speaker", "xiaomi.wifispeaker.v1": "Mi Network Speaker", "xiaomi.wifispeaker.v3": "小米网络音箱", @@ -3787,10 +4803,19 @@ "xiaomi.wifispeaker.x6a": "Xiaomi Smart Display 6", "xiaomi.wifispeaker.x8f": "Xiaomi Smart Home Screen Pro 8", "xiaomi.wifispeaker.x8s": "Xiaomi Smart Display 8inch", + "xiaomi.ysj.a1en": "Xiaomi Smart Filtered Water Dispenser Pro", + "xiaomi.ysj.gxj": "Mijia Wall-mounted Pipeline Water Dispenser", + "xiaovv.camera.bp340": "xiaovv Outlook Dual Lens PTZ Camera", "xiaovv.camera.c1": "xiaovv Babymonitor", "xiaovv.camera.c12k": "xiaovv Babymonitor 2K", + "xiaovv.camera.fjcam2": "Smart Dual Lens Camera S1 PTZ Verison", + "xiaovv.camera.fjcam3": "Dlingsmart Outdoor Dual Lens Camera A1", + "xiaovv.camera.fjcam5": "Dlingsmart Outdoor PTZ Camera 4G", + "xiaovv.camera.fjcam6": "Dlingsmart Smart Camera N1", "xiaovv.camera.lamp": "Flood light camera", + "xiaovv.camera.ljcam1": "PTZ Dome Camera 2K", "xiaovv.camera.p1": "xiaovv Outdoor PTZ Camera 2K", + "xiaovv.camera.p124g": "xiaovv Outlook PTZ Camera 4G", "xiaovv.camera.p12l": "Outdoor PTZ Camera", "xiaovv.camera.p94mp": "xiaovv Outdoor PTZ Camera Pro 2.5K", "xiaovv.camera.ptz": "Outdoor 360 Webcam", @@ -3800,7 +4825,9 @@ "xiaovv.camera.q24mp": "xiaovv Kitten Camera Pro 2.5K", "xiaovv.camera.q2lite": "Kitten Camera Pro", "xiaovv.camera.q330": "xiaovv PTZ Dome Camera 2.5K", + "xiaovv.camera.q4": "Xb-1 Smart Camera 2K", "xiaovv.camera.q8": "xiaovv Smart Wifi PTZ Camera 2K", + "xiaovv.camera.q9": "xiaovv Smart PTZ Camera 2K", "xiaovv.camera.svp940": "safeV Outlook PTZ Camera Pro 2.5K", "xiaovv.camera.xva3": "xiaovv smart panoramic camera", "xiaovv.camera.xvb4": "xiaovv Outdoor Camera", @@ -3844,11 +4871,20 @@ "xijia1.curtain.ck3xwb": "Xijia Curtain C3", "xijia1.curtain.cr1": "Xijia Intelligent Curtain Module CR1", "xijia1.curtain.m8": "Xijia Curtain C8", + "xijia1.curtain.x3": "Xijia Curtain Treasure X3", "xingh.light.fsd1": "Fan light", "xingh.light.fsd2": "Dual-color fan light", + "xinji.airrtc.nt01": "New pole 3T1 Thermostat", + "xinji.curtain.cura01": "New pole intelligent curtain motor", "xinji.light.wy0a01": "New Pole Smart Light", + "xinji.light.wy0a02": "New pole intelligent no main light", + "xinji.switch.sw1a02": "New pole intelligent one-button switch Pro", + "xinji.switch.sw2a02": "New pole intelligent two-button switch Pro", + "xinji.switch.sw3a02": "New pole intelligent three-button switch Pro", + "xinji.switch.sw4a02": "New pole intelligent four-button switch Pro", "xinyue.blanket.n1918": "Letsleep one click smart aqua-heat mattress", "xinzhi.bhf_light.zhyb01": "intelligence bath heater", + "xizhen.airrtc.mi0002": "GERLSAIR Central Air Conditioning Controller", "xjx.toilet.pro": "Uclean Smart Toilet Seat", "xjx.toilet.pure": "Uclean smart toilet pure", "xjx.toilet.relax": "Uclean smart toilet relax", @@ -3859,6 +4895,9 @@ "xlang.desk.nlocv1": "NOC LOC Intelligent electric learning desk for children", "xlang.desk.vlocv2": "Adult lift table", "xm008.curtain.dy01": "Mohen Smart Curtain Motor", + "xmd.switch.sw2d03": "Xing Minghao smart screen switch S4", + "xmd.switch.sw3d03": "Xing Meida smart screen switch S4", + "xmibox.light.1047": "请勿操作本产品", "xmlong.toothbrush.r02": "XiMALONG Smart Sonic Electric Toothbrush R02", "xmlong.toothbrush.r05": "XiMALONG Smart Sonic Electric Toothbrush R06", "xox.toilet.ts": "YM Intelligent Control Smart Toilet Pro", @@ -3866,17 +4905,24 @@ "xqiao.treadmill.srpro1": "Xqiao Treadmill SR Pro", "xqwgt.light.zsh": "Friday tide play display box", "xry.light.xrycxd": "Xingruyu smart lights", + "xtl.vacuum.xm2216": "Jonr P20 Pro", "xumei.razor.str212": "SMATE PORTABLE ELECTRIC SHAVER", + "xunzhi.bhf_light.01": "Intelligent remote controller for Bathroom heater", "xwhzp.diffuser.xwxfj": "Mijia Smart Scent Diffuser", + "xxll.fridge.mtb40g": "xingxing wisdom freezer", "xzx.light.wyxzx1": "Xi Zhi Xi Intelligent Lamp", "yakino.curtain.e10": "YaKino smart curtain", "yankon.airer.l66": "Yankon Intelligent Clothes Rack", "yankon.light.xdd01": "Sunshine Smart Ceiling Light", + "yankon.light.ykmesh": "Yankon Intelligent Mesh Color Temperature Light", "ybb.magic_touch.jz": "YBB Neck Massager", "ybb.magic_touch.ms": "Eye Massager", + "ybb.magic_touch.znpj01": "Shoulder and neck massager N5", "ybb.massage.jxs": "AI Smart Massage Chair", "ybb.massage.ms": "Smart Massage Chair", "ybf.light.wy0a01": "One hundred points smart spotlight", + "ybsm.scales.fl649": "Bubble Hall Intelligent Body Fat Scale FL549", + "ybsm.scales.mpt992": "Maopaotang Smart body fat Scale MPT992", "ydhome.cateye.pr1": "Uodi Smart Doorbell R1", "ydhome.lock.c1p": "Uodi Smart Lock C1P", "ydhome.lock.m2lite": "优点智能锁M2Lite", @@ -3888,6 +4934,7 @@ "ydsemi.light.fan01": "ZY Smart Fan Light", "ydsemi.switch.cz03": "Zhiyue smart socket", "ydzl.waterpuri.t1": "Uodi Cuber", + "yeelink.airc.vrf1": "Yeelight VRF Air Conditioner Controller", "yeelink.aircondition.01": "Yeelight Pro Air Conditioner", "yeelink.airer.fold1": "Yeelight Smart Clothes Rack E2101", "yeelink.airer.fold2": "Yeelight Smart Clothes Rack E2102", @@ -3897,6 +4944,7 @@ "yeelink.bhf_light.v13": "Mi Smart Bathroom Heater Pro", "yeelink.bhf_light.v15": "Yeelight Warmer Bath Heater Pro", "yeelink.bhf_light.v17": "Yeelight Smart Bathroom Heater S20", + "yeelink.bhf_light.v18": "Yeelight Smart Bathroom Heater Z10", "yeelink.bhf_light.v2": "Yeelight Smart Bath Heater", "yeelink.bhf_light.v3": "Yeelight Smart Bath Heater Duo", "yeelink.bhf_light.v5": "Mi Smart Bathroom Heater Pro", @@ -3907,12 +4955,16 @@ "yeelink.curtain.crc1": "Yeelight intelligent open-close curtain motor", "yeelink.curtain.crc2": "Yeelight Smart Curtain C2 (WIFI)", "yeelink.curtain.crc3": "Yeelight intelligent open-close motor", + "yeelink.curtain.crc4": "Yeelight intelligent curtain motor", + "yeelink.curtain.crc5": "YEELIGHT moves smart curtain motor", + "yeelink.curtain.crc6": "Yeelight SU Intelligent Curtain Motor", "yeelink.curtain.ctmt1": "Yeelight Smart Curtain Controller", "yeelink.curtain.ctmt2": "Yeelight Automatic Curtain Opener", "yeelink.curtain.ywc01": "Yeelight Pro Curtain", "yeelink.gateway.pro01": "Yeelight Pro Gateway", "yeelink.gateway.v1": "Yeelight Mesh Hub", "yeelink.gateway.va": "Yeelight Mesh Hub", + "yeelink.gateway.vrf": "Yeelight VRF Air Conditioner Gateway", "yeelink.light.ble1": "Yeelight Bedside Lamp", "yeelink.light.bslamp1": "Mi Bedside Lamp", "yeelink.light.bslamp2": "Mi Bedside Lamp 2", @@ -3928,6 +4980,9 @@ "yeelink.light.ceil35": "Yeelight Intelligent Led Droplight", "yeelink.light.ceil36": "Yeelight Intelligent Led Droplight S", "yeelink.light.ceil38": "Yeelight Smart Ceiling Light", + "yeelink.light.ceil39": "Yeelight Smart Ceiling Light Pro", + "yeelink.light.ceil40": "Yeelight Smart LED Ceiling Light Upgrade", + "yeelink.light.ceil45": "Yeelight Ultra-thin Smart Ceiling Light", "yeelink.light.ceila": "Yeelight LED Ceiling Light Pro", "yeelink.light.ceilb": "Yeelight Arwen Ceiling Light", "yeelink.light.ceilc": "Yeelight Ambience Ceiling Light", @@ -3986,6 +5041,7 @@ "yeelink.light.lamp27": "Mijia LED Desk Lamp 1S (Enhanced Edition)", "yeelink.light.lamp28": "Mijia LED Desk Lamp 1S Enhanced Edition (Black)", "yeelink.light.lamp3": "Yeelight LED Lamp", + "yeelink.light.lamp30": "Yeelight Standing Study Lamp V8", "yeelink.light.lamp4": "Mi LED Desk Lamp 1S", "yeelink.light.lamp5": "Yeelight Smart Desk Lamp Prime", "yeelink.light.lamp7": "Yeelight LED Light Sensor Desk Lamp V1", @@ -3998,6 +5054,8 @@ "yeelink.light.meshbulb2": "Yeelight Mesh LED Bulb", "yeelink.light.ml1": "Yeelight downlight \u0026 spotlight", "yeelink.light.ml10": "Yeelight smart downlights", + "yeelink.light.ml11": "YEELIGHT moves smart downlights", + "yeelink.light.ml12": "YEELIGHT intelligent magnetic lamp", "yeelink.light.ml2": "Yeelight tunable white bulb M2", "yeelink.light.ml3": "Yeelight Surface mounted downlight M1", "yeelink.light.ml6": "Mijia Smart Magnetic Track System (Array Spotlight)", @@ -4010,6 +5068,7 @@ "yeelink.light.mono6": "Mi Smart LED Bulb", "yeelink.light.mono7": "Yeelight Skylight", "yeelink.light.mono8": "Yeelight Skylight G6", + "yeelink.light.mono9": "Yeelight Panel Rooflight A10", "yeelink.light.monoa": "Yeelight LED smart bulb W3(dimmable)", "yeelink.light.monob": "Yeelight GU10 Smart Bulb W1(dimmable)", "yeelink.light.nl1": "Mi Motion-Activated Night Light 2 (Bluetooth)", @@ -4028,10 +5087,12 @@ "yeelink.light.stripa": "Yeelight LED Lightstrip 1S", "yeelink.light.stripb": "Xiaomi Smart Lightstrip", "yeelink.light.stripf": "Yeelight C1 intelligent high pressure color temperature light strip", + "yeelink.light.stripj": "YEELIGHT light with controller", "yeelink.light.virtual": "Light Group (Mi \u0026 Yeelight)", "yeelink.light.vtl_ble1": "Yeelight Bedside Lamp(Virtual)", "yeelink.light.wy0a01": "Yeelight LED intelligent magnetic lamp belt", "yeelink.light.wy0a03": "Yeelight LED intelligent light belt", + "yeelink.light.wyra01": "Yeelight LED color light strip", "yeelink.light.yct01": "Yeelight Pro Tunable White Light", "yeelink.light.ydim01": "Yeelight Pro Dimmable Light", "yeelink.light.yrgb01": "Yeelight Pro Color Light", @@ -4043,15 +5104,25 @@ "yeelink.remote.remote": "Yeelight Wireless Switch S1", "yeelink.remote.sw1": "Yeelight Smart Wireless Switch (Single Key)", "yeelink.remote.sw2": "Yeelight Smart Wireless Switch (Double Keys)", + "yeelink.remote.swd5": "Yeelight Scene Switch (Wireless Four Buttons)", "yeelink.remote.yrm02": "Yeelight Pro Control Panel (8-keys)", "yeelink.remote.yrm03": "Yeelight Pro Control Panel (4-keys)", "yeelink.remote.yrm04": "Yeelight Pro Control Panel (6-keys)", "yeelink.remote.yrm05": "Yeelight Pro Remote Knob", "yeelink.remote.yrm06": "Yeelight Scene Switch Six Keys", + "yeelink.sensor_occupy.a": "Yeelight human body presence sensor", "yeelink.switch.sw1": "Yeelight Smart Dual Control Module", + "yeelink.switch.sw3": "YEELIGHT moves smart switch (one key)", + "yeelink.switch.sw4": "YEELIGHT moves smart switch (two keys)", + "yeelink.switch.sw5": "YEELIGHT moves smart switch (three keys)", + "yeelink.switch.sw6": "YEELIGHT moves smart switch (four keys)", + "yeelink.switch.swd1": "Yeelight Smart switch (zero fire one button)", + "yeelink.switch.swd2": "Yeelight Smart switch (zero fire two buttons)", + "yeelink.switch.swd3": "Yeelight Smart switch (zero fire three buttons)", "yeelink.switch.szsw1": "Yeelight smart switch C1 (single key)", "yeelink.switch.szsw2": "Yeelight smart switch C1 (double keys)", "yeelink.switch.szsw3": "Yeelight smart switch C1 (three keys)", + "yeelink.switch.v3": "YEELIGHT moves smart center panel switch", "yeelink.switch.ylsw4": "Yeelight Smart Switch (Single key)", "yeelink.switch.ylsw5": "Yeelight Smart Switch (Double key)", "yeelink.switch.ylsw6": "Yeelight Smart Switch (three keys)", @@ -4068,21 +5139,28 @@ "yeelink.ven_fan.vf3": "Yeelight Smart Panel Fan E1", "yeelink.ven_fan.vf5": "Yeelight Smart Ventilation Fan E1", "yeelink.wifispeaker.v1": "Yeelight Smart Speaker", + "yeeloc.etool.m09": "Yeelock Drawer Cabinet Switch Pro", "yesoul.exbike.jsc01y": "Mijia Indoor Spinning Bike (Self-generating)", "yh1209.airer.public": "yonghui intelligent clothes hanger", "yh1209.airer.yhxm": "Heichuang intelligent washing machine", "yhph.light.wy0a01": "Peihong ceiling lamp", "yht.light.wy0a01": "Silver Fit Light Bulb Bluetooth Mesh Version", "yhzm.light.wyfh01": "Feihong lighting", + "yifang.fan.yx02": "One-side intelligent fan", "yifang.mosq.yx01": "Intelligent mite removal and mosquito repellent", "yilai.light.ceiling1": "Yilai Ceiling Light Aiyue 480", "yilai.light.ceiling2": "Yilai Ceiling Lamp Hefeng 430", "yilai.light.ceiling3": "Yilai Ceiling Lamp Hefeng Pro", "yilock.curtain.yilc3": "Yi-LOCK Intelligent Curtain", + "yimilx.ysj.yc1w": "Yimi Ice Quick Hot Water dispenser YC-1W", + "yiree.bed.yibed1": "yiree smart bed", "yjy.wifispeaker.u9": "8inch music panel", "ykbn.curtain.k9": "YKBN Intelligent curtain motor", "ykcn.relay.rdcbl": "YKCN Intelligent Circuit Breaker", "ykcn.switch.cbcsmj": "Wi-Fi intelligent guide circuit breaker YKCN", + "ykcn.valve.cbcs": "Intelligent guide rail type breaker YKCN", + "yktime.scales.zshz1": "To Life intelligent body fat scale ZSH-Z1", + "yktime.scales.zshz2": "To Life intelligent body fat scale ZSH-Z2", "ylyd.blanket.sk1000": "Eluadi Water heating blanket", "ylzm.light.wyly01": "Leiyuan Intelligent Living Room Lamp", "ymj.light.wy0a02": "Yi Mei Home Smart Light", @@ -4093,12 +5171,20 @@ "ymwl.curtain.cura01": "YMWL smart curtain motor M1", "yoda.fan.m55": "Cyclone Circulating Fan", "yoda.k_scale.cy80": "Baijie Intelligent Baking Nutrition Scale BJ26", + "yoda.k_scale.e2": "Kaifeng Intelligent Baking Scale E2", + "yoda.k_scale.x3": "Kaifeng Smart Baking Scale X3", + "yoda.scales.hd0": "Huiding Body Fat Scale HD0", + "yoda.scales.m01": "Intelligent Fat Scale M01", "yoda.scales.mx80": "TUYI Body Fat Scale MX80", + "yoda.scales.mx81": "Heshi Body Fat Scale MX81", + "yoda.scales.rq01": "RuoQing body fat scale RQ01", + "yoda.scales.xgs001": "Little Monster Body Fat Scale XGS01", "yoda.sensor_ht.le508": "Deli Temperature Hygrometer LE508", - "yodq.humidifier.yo001": "YO-M2 Humidifier", + "yodq.humidifier.yo001": "YO Humidifier", "yooeca.tow_w.mj04": "Smart towel dryer", "yopins.tow_w.mimj01": "Youpin intelligent towel machine", "youha.breast.s1": "Youha S1 breast pump", + "youpon.bhf_light.x7": "YOUPON Smart bath heater X7", "youpon.bhf_light.yb0a01": "YOUPON Smart bath heater DZ", "yszh.wopener.bs817": "Intelligent window pusher", "yszn01.airer.krq01": "Carricci ProS1 Smart drying rack", @@ -4107,6 +5193,7 @@ "yszn01.airer.ys2102": "M1 Intelligent electric clothes dryer pro", "yszn01.airer.ys2103": "M1 intelligent electric clothes dryer", "ytl.airrtc.8921": "Intelligent temperature controller", + "yuemee.airm.mhfdv2": "Honeywell Smart Formaldehyde Monitor PRO", "yuemee.airmonitor.mhfd1": "Honeywell Smart Formaldehyde Monitor", "yuemee.mic.s32": "MIJIA K歌麦克风 大屏版", "yuemee.sensor_gas.0605": "Residential Flammable Gas Detector", @@ -4117,7 +5204,12 @@ "yunlu.door.sd2104": "Yunlu Security Smart Door Y", "yunlu.door.sd2106": "Yunlu Security Smart Door P50", "yunlu.door.sd2107": "Yunlu Security Smart Door K2", + "yunlu.door.sd2112": "Smart Door Classic", "yunmai.scales.m1690": "YUNMAI mini2", + "yunmai.scales.ms103": "Mijia Body Composition Scale S400", + "yunmai.scales.ms104": "Xiaomi Body Composition Scale S400", + "yunmai.scales.ms106": "Mijia Smart Scale S200", + "yunmai.scales.ms107": "Mijia Body Composition Scale S400", "yunmai.scales.ms3001": "Xiaomi 8-Electrode Body Composition Scale", "yunmi.kettle.r1": "VIOMI Smart Instant Heating Water Dispenser (MINI)", "yunmi.kettle.r2": "VIOMI Smart Instant Heating Water Dispenser (MINI)", @@ -4153,7 +5245,7 @@ "yunmi.waterpuri.lx14": "Mi Water Purifier H1000G", "yunmi.waterpuri.lx2": "Mi Water Purifier", "yunmi.waterpuri.lx20": "Mi Dual-core Water Purifier 1200G", - "yunmi.waterpuri.lx21": "Mi instant heating water purifier Q800", + "yunmi.waterpuri.lx21": "Mi Instant Heating Water Purifier Q800", "yunmi.waterpuri.lx24": "Mi Dual-core Water Purifier 1000G", "yunmi.waterpuri.lx27": "Mijia Water Purifier 1000G", "yunmi.waterpuri.lx28": "Mijia Water Purifier 1200G", @@ -4178,7 +5270,10 @@ "yunmi.waterpuri.s20": "VIOMI Blues Pro 1200G Water Purifier", "yunmi.waterpuri.s21": "Viomi AI heating water purifier Super Pro", "yunmi.waterpuri.s23": "Viomi AI water purifier Super Pro 1200G", + "yunmi.waterpuri.s25": "Viomi AI Water Purifier JD-Dragon", "yunmi.waterpuri.s26": "Viomi AI water purifier Blues", + "yunmi.waterpuri.s27": "Viomi AI water purifier Cross 3 1000G+", + "yunmi.waterpuri.s28": "Viomi AI water purifier Blue+", "yunmi.waterpuri.s29": "Viomi AI water purifier Super S", "yunmi.waterpuri.s3": "Viomi smart water purifier SE(400G)", "yunmi.waterpuri.s30": "Viomi AI water purifier Super Y", @@ -4190,8 +5285,17 @@ "yunmi.waterpuri.s36": "Viomi AI water purifier Super Y(Strontium-Rich)", "yunmi.waterpuri.s37": "Viomi AI water purifier Blues 2", "yunmi.waterpuri.s38": "Little Dolphin 2 AI Water Purifier", + "yunmi.waterpuri.s39": "Viomi AI water purifier Super 2", "yunmi.waterpuri.s4": "Viomi smart water purifier S2(500G)", + "yunmi.waterpuri.s41": "Viomi AI Water Purifier Super 2S", + "yunmi.waterpuri.s43": "Viomi AI Water Purifier Super 2+", + "yunmi.waterpuri.s49": "Viomi AI water purifier Dolphin+", "yunmi.waterpuri.s5": "Viomi smart water purifier S2(600G)", + "yunmi.waterpuri.s50": "Viomi AI Water Purifier Super 2Y", + "yunmi.waterpuri.s55": "Viomi AI Water Purifier Super 2Y Plus", + "yunmi.waterpuri.s56": "Viomi AI Water Purifier Super 2E", + "yunmi.waterpuri.s57": "Viomi AI Water Purifier White Dragon+", + "yunmi.waterpuri.s58": "Viomi AI Water Purifier Smart", "yunmi.waterpuri.s9": "Viomi water purifier super 1000G", "yunmi.waterpuri.x10": "Viomi ai protable heating water purifier X2", "yunmi.waterpuri.x11": "Viomi protable heating water purifier X2 mini", @@ -4207,14 +5311,16 @@ "yunmi.ysj.mg6": "Viomi instant heat pipeline water dispenser", "yunmi.ysj.mg7": "Viomi pipeline water dispenser Master 3", "yunmi.ysj.mg8": "Viomi pipeline water dispenser Super 2E", + "yunmi.ysj.mg9": "Viomi pipeline water dispenser Master 2S", "yunmi.ysj.v1": "Mijia Smart Hot and Cold Water Dispenser", "yunmi.ysj.x1": "Viomi AI protable heating water purifier X2 mini Mango", "yunmi.ysj.x2": "Viomi AI protable heating water purifier X2", "yunshi.lock.s2": "SherLock M1", "yunyi.camera.v1": "Yi Smart Webcam", + "yunzyo.feeder.t001": "Maotele pet feeder", "yuxuan.light.wy0a01": "Yuxuan Smart Ceiling Light", - "yyjj.diffuser.ldc": "Sunset Aromatherapy machine (IOT Lithium electric version)", - "yyjj.diffuser.rxjiot": "Sunset Aromatherapy Machine IOT Edition", + "yyjj.diffuser.ldc": "Shubus Smart Aromatherapy Machine (lithium battery version)", + "yyjj.diffuser.rxjiot": "Shubus intelligent aromatherapy machine", "yyunyi.wopener.yylt": "Yunyi chain window opener", "yyunyi.wopener.yypy24": "Yun yi translation window opener", "yywq.toilet.wqzn01": "YunQI Smart Control Smart Toilet AIR Edition", @@ -4222,10 +5328,13 @@ "yyzn.light.wy0a01": "Ai home intelligent light belt", "yyzn.light.wy0a02": "Ai home intelligent magnetic suction lamp", "yyzn.light.wy0a03": "Ai home smart tube spotlight", + "yyzn.light.wy0a04": "Ai home smart two-color temperature light", + "yyzn.switch.sw3a03": "Ai home smart screen switch", "yz66.wifispeaker.yz": "Youzhuan music host", "zair.light.zcw01w": "ZAIR Smart floor lamp (Enhance)", "zair.light.zcw02w": "ZAIR Smart floor lamp (Common)", "zair.switch.zsc02w": "Moxiaoqi smart lamp switch controller", + "zbmesh.light.wy0a01": "Huashi smart lamps", "zdeer.ajh.a8": "ZDEER Moxibustion Box", "zdeer.ajh.a9": "ZDEER Moxibustion Box 2th", "zdeer.ajh.ajb": "Warm Moxibustion Box", @@ -4240,8 +5349,19 @@ "zedong.light.cdnxd1": "CDN smart bedroom light", "zedong.light.cdnxd2": "CDN smart bedroom light plus", "zedong.light.cdnxd3": "CDN smart living room light", + "zedong.light.led2": "ZD Bluetooth bicolor downlight and spotlight series", + "zedong.light.led3": "ZD Bluetooth bicolor-ceiling light series", "zemi.curtain.zm25": "Zemismart Smart rolling curtain motor", + "zemi.curtain.zm85": "ZM Smart curtain", "zhaomu.safe.bgx45l": "BOFON W series", + "zhefa.switch.zero11": "ZF One Position Intelligent Switch (N7-ZK01-AXM)", + "zhefa.switch.zero22": "ZF two position intelligent switch (N7-ZK02-AXM)", + "zhefa.switch.zero33": "ZF Three Position Intelligent Switch (N7-ZK03-AXM)", + "zhefa.switch.zero44": "ZF four position intelligent switch (N7-ZK04-AXM)", + "zhhome.fan.m35": "Smart Ceiling Fan M35", + "zhhome.fan.m55": "Intelligent Circulating Fan M55", + "zhhome.fan.m65": "Intelligent Storm Outdoor Fan M65", + "zhhome.magic_touch.a9": "A9 Intelligent cupping instrument", "zhij.toothbrush.bv1": "Smart Sterilization Cup", "zhimi.aircondition.ma1": "MIJIA Smart Air Conditioner (Energy Efficiency Level 3)", "zhimi.aircondition.ma3": "MIJIA Smart Air Conditioner (Energy Efficiency Level 3)", @@ -4354,8 +5474,10 @@ "zhimi.vacuum.hd1": "Lydsto Inertial Navigation Sweeping and Mopping Robot G2", "zhimi.vacuum.l1": "Lydsto Sweeping and Mopping Robot L1", "zhimi.vacuum.r5": "Lydsto Sweeping and Mopping Robot R5", + "zhimi.vacuum.r5l": "Lydsto Sweeping and Mopping Robot R1Edge", "zhimi.vacuum.w2": "Lydsto Self Cleaning Sweeping Robot W2", "zhimi.vacuum.w2lite": "Lydsto Self Cleaning Sweeping Robot W2Lite", + "zhimi.vacuum.w2max": "Lydsto Self Cleaning Sweeping Robot W2Edge", "zhimi.vacuum.wa1": "Smartmi VortexWave Robot Vacuum Cleaner", "zhimi.vacuum.xa1": "Lydsto Sweeping and Mopping Robot R1", "zhimi.vacuum.xa2": "Lydsto Sweeping and Mopping Robot R1D", @@ -4367,8 +5489,15 @@ "zhiqin.switch.x101": "CHLOROP G1 Smart Wall Switch (No Neutral Single Rocher)", "zhiqin.switch.x102": "CHLOROP G1 Smart Wall Switch (No Neutral Double Rocher)", "zhiqin.switch.x103": "CHLOROP G1 Smart Wall Switch (No Neutral Triple Rocher)", + "zhj.curtain.zhj928": "Zhihejia linglong intelligent motor", + "zhj.light.wy0a01": "Zhihejia xing can Intelligent spot light", + "zhj.switch.sw1a01": "Zhihejia L intelligent switch one open", + "zhj.switch.sw2a01": "Zhihejia L intelligent switch two open", + "zhj.switch.sw3a01": "Zhihejia L intelligent switch three open", + "zhj.switch.sw4a01": "Zhihejia L intelligent switch four open", "zhtech.curtain.zm25s": "Smart emperor intelligent rolling curtain motor", "zhtech.curtain.zm83": "Smart emperor open and close curtain motor", + "zhtech.curtain.zm83s": "ZH Smart Curtain (Mesh)", "zhzt.switch.nia11": "NVC Mesh Wall Switch(1 key)", "zhzt.switch.nia21": "NVC Mesh Wall Switch(2 keys)", "zhzt.switch.nia31": "NVC Mesh Wall Switch(3 keys)", @@ -4391,6 +5520,7 @@ "zimmo.magic_touch.ffv1": "ZIMMO-FREEFOOT1.0", "zinguo.etool.sc01": "Smart Thermostat", "zinguo.etool.sc03": "zinguo multi thermostat", + "zinguo.etool.tk01": "Zinguo SWH meter", "zinguo.motor.mk01": "Smart Motor Controller", "zinguo.plug.c2m": "Smart Plug (Wi-Fi)", "zinguo.plug.sc02": "Smart Timer", @@ -4399,6 +5529,7 @@ "ziwooo.s_lamp.uvc": "ZIWOOO Intelligent germicidal lamp Pro", "zjaupu.airer.d557": "AUPU Airer-D557", "zjaupu.airer.d558": "AUPU Airer-D558", + "zjaupu.airer.l157s": "AUPU hot-drying airer", "zjaupu.airer.l557": "AUPU Airer-L557", "zjaupu.airer.l558": "AUPU Airer-L558", "zjaupu.airer.lxx6": "AUPU hot-drying airer", @@ -4406,13 +5537,34 @@ "zjaupu.airer.lxx64": "AUPU hot-drying airer", "zjaupu.airer.lxx7": "AUPU swing and hot-drying airer", "zjaupu.humidifier.a1": "ZAYGEE Air Wash Humidifier", + "zjaupu.humidifier.c1": "ZAYGEE Air Wash Humidifier C1", "zjcr.razor.rs158": "SuperHuman Smart Shaver HS158", "zjcr.razor.rs7368": "SuperHuman smart shaver", "zjcx.switch.s6": "6 Gangs Switch", "zjdh.curtain.xj001": "XM smart electric curtain", + "zjdh.curtain.xj002": "Smart Electric Curtain (Mesh)", + "zjie.scales.adl26m": "Zengjie household body fat scale ADL-26M", + "zjjsw.airer.sa006": "JSW smart drying rack", "zjyg.dishwasher.zzy01": " Smart washing dishwasher", + "zkxt.light.w00a01": "Zhongke eyes eye protection ceiling light Haoyue series", "znsn.cs.cp01m": "ZNSN BLE-Mesh Insert-card-for-power Switch", + "znsn.curtain.zsct01": "ZNSN Smart curtain", "znsn.light.v5ssw": "ThoughtHome smart lights S1", + "znsn.light.zslt07": "ZNSN Smart 2-Colors Light P7 Mesh", + "znsn.switch.oled1": "znsn half-screen Mesh single-key switch", + "znsn.switch.oled2": "znsn half-screen Mesh double key switch", + "znsn.switch.oled3": "znsn half-screen Mesh three-button switch", + "znsn.switch.oled4": "znsn half-screen Mesh four-button switch", + "znsn.switch.oled6": "znsn half-screen Mesh six-button switch", + "znsn.switch.tdq1a": "znsn mesh switch", + "znsn.switch.yjpd1": "ZNSN 1 Key Switch", + "znsn.switch.yjpd2": "ZNSN 2 Key Switch", + "znsn.switch.yjpd3": "ZNSN 3 Key Switch", + "znsn.switch.yjpd4": "ZNSN 4 Key Switch", + "znsn.switch.z1g3": "ZNSN BLE-Mesh Wall Switch G1P", + "znsn.switch.z2g3": "ZNSN BLE-Mesh Wall Switch G2P", + "znsn.switch.z3g3": "ZNSN BLE-Mesh Wall Switch G3P", + "znsn.switch.z4g3": "ZNSN BLE-Mesh Wall Switch G4P", "znsn.switch.zg1m": "ZNSN BLE-Mesh Wall Switch G1", "znsn.switch.zg1ml": "ZNSN BLE-Mesh Wall Switch G1M", "znsn.switch.zg2m": "ZNSN BLE-Mesh Wall Switch G2", @@ -4442,6 +5594,7 @@ "zxgs.light.wdcl01": "WiFi dual color light", "zxkj.aircondition.kt22": "Zhengxi outdoor portable air conditioner", "zxzm.light.j01": "J.zao ceiling light", + "zywjw.sensor_occupy.c01": "ZM Human Presence Sensor", "zyzy1.aircondition.0715": "空调", "zyzy1.aircondition.y712": "智能空调", "zyzy1.fan.y07011": "智能米家风扇", diff --git a/bundles/org.openhab.binding.mqtt.generic/README.md b/bundles/org.openhab.binding.mqtt.generic/README.md index 2bce4766285c2..4821abd1d24ff 100644 --- a/bundles/org.openhab.binding.mqtt.generic/README.md +++ b/bundles/org.openhab.binding.mqtt.generic/README.md @@ -329,7 +329,7 @@ Please prefer formatting as described in the next section whenever possible. This feature is quite powerful in transforming an item state before it is published to the MQTT broker. It has the syntax: `%[flags][width]conversion`. -Find the full documentation on the [Java](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Formatter.html) web page. +Find the full documentation on the [Java](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Formatter.html) web page. The default is "%s" which means: Output the item state as string. diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java index 80fbb958a7d35..1aef48287da3c 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java @@ -225,7 +225,7 @@ public void resolveConflict() { protected ComponentChannel.Builder buildChannel(String channelID, ComponentChannelType channelType, Value valueState, String label, ChannelStateUpdateListener channelStateUpdateListener) { - if (groupId == null) { + if (groupId == null && newStyleChannels) { channelID = componentId; } return new ComponentChannel.Builder(this, channelID, channelType.getChannelTypeUID(), valueState, label, @@ -304,12 +304,15 @@ public String getUniqueId() { */ public String getName() { String result = channelConfiguration.getName(); + if (result.isBlank()) { + result = null; + } Device device = channelConfiguration.getDevice(); if (result == null && device != null) { result = device.getName(); } - if (result == null) { + if (result == null || result.isBlank()) { result = haID.objectID; } return result; diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java index 44117740821b2..abed25174bcfb 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/ClimateTests.java @@ -38,6 +38,7 @@ @NonNullByDefault public class ClimateTests extends AbstractComponentTests { public static final String CONFIG_TOPIC = "climate/0x847127fffe11dd6a_climate_zigbee2mqtt"; + public static final String TION_CONFIG_TOPIC = "climate/living-room-tion-3s/living-room-tion-3s"; @SuppressWarnings("null") @Test @@ -397,8 +398,82 @@ public void testClimateHumidity() { assertState(component, Climate.TARGET_HUMIDITY_CH_ID, new QuantityType<>(50, Units.PERCENT)); } + @SuppressWarnings("null") + @Test + public void testClimateWithEmptyName() { + var component = discoverComponent(configTopicToMqtt(TION_CONFIG_TOPIC), """ + { + "curr_temp_t": "living-room-tion-3s/climate/living-room-tion-3s/current_temperature/state", + "mode_cmd_t": "living-room-tion-3s/climate/living-room-tion-3s/mode/command", + "mode_stat_t": "living-room-tion-3s/climate/living-room-tion-3s/mode/state", + "modes": [ + "off", + "heat", + "fan_only", + "heat_cool" + ], + "temp_cmd_t": "living-room-tion-3s/climate/living-room-tion-3s/target_temperature/command", + "temp_stat_t": "living-room-tion-3s/climate/living-room-tion-3s/target_temperature/state", + "min_temp": 1, + "max_temp": 25, + "temp_step": 1, + "precision": 1, + "temp_unit": "C", + "min_hum": 30, + "max_hum": 99, + "act_t": "living-room-tion-3s/climate/living-room-tion-3s/action/state", + "fan_mode_cmd_t": "living-room-tion-3s/climate/living-room-tion-3s/fan_mode/command", + "fan_mode_stat_t": "living-room-tion-3s/climate/living-room-tion-3s/fan_mode/state", + "fan_modes": [ + "1", + "2", + "3", + "4", + "5", + "6" + ], + "name": "", + "ic": "mdi:air-filter", + "avty_t": "living-room-tion-3s/status", + "uniq_id": "ESPclimateliving-room-tion-3s", + "dev": { + "ids": "f09e9e213ab0", + "name": "living-room-tion-3s", + "sw": "2024.8.0 (ESPHome 2024.11.3)", + "mdl": "tion", + "mf": "dentra", + "cns": [ + [ + "mac", + "f09e9e213ab0" + ] + ] + } + } + """); + + assertThat(component.channels.size(), is(5)); + assertThat(component.getName(), is("living-room-tion-3s")); + + assertChannel(component, Climate.ACTION_CH_ID, "living-room-tion-3s/climate/living-room-tion-3s/action/state", + "", "living-room-tion-3s", TextValue.class); + assertChannel(component, Climate.CURRENT_TEMPERATURE_CH_ID_DEPRECATED, + "living-room-tion-3s/climate/living-room-tion-3s/current_temperature/state", "", "living-room-tion-3s", + NumberValue.class); + assertChannel(component, Climate.FAN_MODE_CH_ID_DEPRECATED, + "living-room-tion-3s/climate/living-room-tion-3s/fan_mode/state", + "living-room-tion-3s/climate/living-room-tion-3s/fan_mode/command", "living-room-tion-3s", + TextValue.class); + assertChannel(component, Climate.MODE_CH_ID, "living-room-tion-3s/climate/living-room-tion-3s/mode/state", + "living-room-tion-3s/climate/living-room-tion-3s/mode/command", "living-room-tion-3s", TextValue.class); + assertChannel(component, Climate.TEMPERATURE_CH_ID, + "living-room-tion-3s/climate/living-room-tion-3s/target_temperature/state", + "living-room-tion-3s/climate/living-room-tion-3s/target_temperature/command", "living-room-tion-3s", + NumberValue.class); + } + @Override protected Set getConfigTopics() { - return Set.of(CONFIG_TOPIC); + return Set.of(CONFIG_TOPIC, TION_CONFIG_TOPIC); } } diff --git a/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/internal/ssl/PinTrustManager.java b/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/internal/ssl/PinTrustManager.java index 3e7823124b090..2fe0dddb78c34 100644 --- a/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/internal/ssl/PinTrustManager.java +++ b/bundles/org.openhab.binding.mqtt/src/main/java/org/openhab/binding/mqtt/internal/ssl/PinTrustManager.java @@ -71,7 +71,7 @@ protected byte[] getEncoded(PinType type, X509Certificate cert) throws Certifica /** * A signature name depends on the security provider but usually follows - * https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html#signature-algorithms. + * https://docs.oracle.com/en/java/javase/21/docs/specs/security/standard-names.html#signature-algorithms. * E.g.: "SHA256withRSA". We need "SHA" and "256" to initialize a {@link PinMessageDigest}. */ PinMessageDigest getMessageDigestForSigAlg(String sigAlg) throws CertificateException { diff --git a/bundles/org.openhab.binding.mqtt/xtend_examples.md b/bundles/org.openhab.binding.mqtt/xtend_examples.md index 64e44d3c1ba82..7d2c6db572ead 100644 --- a/bundles/org.openhab.binding.mqtt/xtend_examples.md +++ b/bundles/org.openhab.binding.mqtt/xtend_examples.md @@ -39,7 +39,7 @@ mqtt:broker:myAuthentificatedBroker [ host="192.168.0.43", secure=false, usernam In a fourth connection, the public key pinning is enabled again. This time, a public key hash is provided to pin the connection to a specific server. It follows the form "hashname:hashvalue". Valid _hashnames_ are SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 and all others listed -in [Java MessageDigest Algorithms](https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html#messagedigest-algorithms). +in [Java MessageDigest Algorithms](https://docs.oracle.com/en/java/javase/21/docs/specs/security/standard-names.html#messagedigest-algorithms). `mqttConnections.things`: diff --git a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo_it.properties b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo_it.properties index c72544cdb11d4..cb48377231083 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo_it.properties +++ b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo_it.properties @@ -16,7 +16,7 @@ channel-group-type.netatmo.battery-extended.label = Batteria channel-group-type.netatmo.battery.label = Batteria channel-group-type.netatmo.energy.label = Energia Domestica channel-group-type.netatmo.energy.channel.end.label = Modalità Fine -channel-group-type.netatmo.energy.channel.end.description = Ora di fine del setpoint attualmente applicato. +channel-group-type.netatmo.energy.channel.end.description = Ora di fine della modalità termostato attualmente applicata. channel-group-type.netatmo.humidity.label = Umidità channel-group-type.netatmo.last-event-alarm.label = Ultimo Evento channel-group-type.netatmo.last-event-alarm.channel.time.label = Data/Ora Evento @@ -459,12 +459,13 @@ config.refreshInterval.description = Intervallo di aggiornamento per interrogare conf-error-no-client-id = Impossibile connettersi al bridge Netatmo poiché non è configurato il Id cliente conf-error-no-client-secret = Impossibile connettersi al bridge Netatmo poiché non è configurata alcuna parola segreta -conf-error-grant-needed = Configurazione incompleta, si prega di dare accesso a questo binding a Netatmo Connect. +conf-error-grant-needed = Completa la configurazione autorizzando il binding a Netatmo Connect\: ''{0}''. status-bridge-offline = Bridge non è connesso alle API Netatmo device-not-connected = Thing non è raggiungibile data-over-limit = I dati sembrano piuttosto vecchi request-time-out = Richiesta scaduta - tenterà di riconnettersi più tardi deserialization-unknown = La deserializzazione genera un valore sconosciuto +maximum-usage-reached = Raggiunto Massimo utilizzo. Si ritenterà la connessione dopo 'reconnectInyerval' secondi. homestatus-unknown-error = Errore sconosciuto homestatus-internal-error = Errore interno diff --git a/bundles/org.openhab.binding.ntp/README.md b/bundles/org.openhab.binding.ntp/README.md index 8289d5278f6b9..7e6ed9cc7a8ce 100644 --- a/bundles/org.openhab.binding.ntp/README.md +++ b/bundles/org.openhab.binding.ntp/README.md @@ -33,7 +33,7 @@ The ntp binding has two channels: - `dateTime` which provides the data in a dateTime type - `string` which provides the data in a string type. The string channel can be configured with the formatting of the date & time. This also allows proper representation of timezones other than the java machine default one. -See the [Java documentation](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Formatter.html) for the detailed information on the formatting +See the [Java documentation](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Formatter.html) for the detailed information on the formatting ## Full Example diff --git a/bundles/org.openhab.binding.pihole/src/main/java/org/openhab/binding/pihole/internal/rest/JettyAdminService.java b/bundles/org.openhab.binding.pihole/src/main/java/org/openhab/binding/pihole/internal/rest/JettyAdminService.java index 5379999f3c2c1..4218c651864c4 100644 --- a/bundles/org.openhab.binding.pihole/src/main/java/org/openhab/binding/pihole/internal/rest/JettyAdminService.java +++ b/bundles/org.openhab.binding.pihole/src/main/java/org/openhab/binding/pihole/internal/rest/JettyAdminService.java @@ -81,7 +81,7 @@ public void disableBlocking(long seconds) throws PiHoleException { @Override public void enableBlocking() throws PiHoleException { logger.debug("Enabling blocking"); - var url = baseUrl.resolve("/admin/api.php?disable&auth=%s".formatted(token)); + var url = baseUrl.resolve("/admin/api.php?enable&auth=%s".formatted(token)); var request = client.newRequest(url).timeout(TIMEOUT_SECONDS, SECONDS); send(request); } diff --git a/bundles/org.openhab.binding.pulseaudio/README.md b/bundles/org.openhab.binding.pulseaudio/README.md index e2552cc7e2682..4be9a5769f46f 100644 --- a/bundles/org.openhab.binding.pulseaudio/README.md +++ b/bundles/org.openhab.binding.pulseaudio/README.md @@ -71,7 +71,7 @@ This requires the module **module-simple-protocol-tcp** to be present on the ser ### Thing Configuration | Config Name | Item Type | Description | -|-----------------------------|-----------------------------------------------------------------------------------------------------------------| +|-----------------------------|-------------|---------------------------------------------------------------------------------------------------| | name | text | The name of one specific device. You can also use the description | | activateSimpleProtocolSink | boolean | Activation of a corresponding sink in openHAB | | additionalFilters | text | Additional filters to select the proper device on the pulseaudio server, in case of ambiguity | @@ -90,7 +90,7 @@ This requires the module **module-simple-protocol-tcp** to be present on the tar ### Thing Configuration | Config ID | Item Type | Description | -|------------------------------|-----------------------------------------------------------------------------------------------------------------| +|------------------------------|-------------|---------------------------------------------------------------------------------------------------| | name | text | The name of one specific device. You can also use the description | | activateSimpleProtocolSource | boolean | Activation of a corresponding sink in openHAB | | additionalFilters | text | Additional filters to select the proper device on the pulseaudio server, in case of ambiguity | @@ -119,7 +119,9 @@ Bridge pulseaudio:bridge: "" @ "" [ host=" diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java index b80fc161cb5c9..279efffffa21f 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyLightHandler.java @@ -38,6 +38,7 @@ import org.openhab.core.library.types.IncreaseDecreaseType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; @@ -187,6 +188,12 @@ public boolean handleDeviceCommand(ChannelUID channelUID, Command command) throw } else if (command instanceof DecimalType decimalCommand) { temp = decimalCommand.intValue(); logger.debug("{}: Set color temp to {}K (Integer)", thingName, temp); + } else if (command instanceof QuantityType genericQuantity) { + QuantityType kelvinQuantity = genericQuantity.toInvertibleUnit(Units.KELVIN); + if (kelvinQuantity != null) { + temp = kelvinQuantity.intValue(); + logger.debug("{}: Set color temp to {}K (Integer)", thingName, temp); + } } validateRange(CHANNEL_COLOR_TEMP, temp, col.minTemp, col.maxTemp); col.setTemp(temp); diff --git a/bundles/org.openhab.binding.tado/README.md b/bundles/org.openhab.binding.tado/README.md index 90973abe8473e..4bd995224a160 100644 --- a/bundles/org.openhab.binding.tado/README.md +++ b/bundles/org.openhab.binding.tado/README.md @@ -5,6 +5,8 @@ The tado° binding integrates devices from [tado°](https://www.tado.com). It requires a fully functional tado° installation. You can then monitor and control all zone types (Heating, AC, Hot Water) as well as retrieve the HOME/AWAY status of mobile devices, and setting the HOME/AWAY status of your home. +**WARNING**: This binding doesn't work together with new tado X radiator thermostats, as they are using a different API (see [here](https://app.swaggerhub.com/apis/JPlenert/TadoX/0.8.0) ). + ## `home` Thing (the Bridge) The `home` thing serves as bridge to the tado° cloud services. diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/devices/wifi/bulb/TapoBulbHandler.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/devices/wifi/bulb/TapoBulbHandler.java index e09427319a288..2cc7ea0a9f54b 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/devices/wifi/bulb/TapoBulbHandler.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/devices/wifi/bulb/TapoBulbHandler.java @@ -25,6 +25,7 @@ import org.openhab.core.library.types.HSBType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelGroupUID; import org.openhab.core.thing.ChannelUID; @@ -147,8 +148,14 @@ private void handleColorCommand(Command command) { } private void handleColorTempCommand(Command command) { - if (command instanceof DecimalType decimalCommand) { - setColorTemp(decimalCommand.intValue()); + QuantityType kelvinQuantity = null; + if (command instanceof QuantityType genericQuantity) { + kelvinQuantity = genericQuantity.toInvertibleUnit(Units.KELVIN); + } else if (command instanceof DecimalType decimal) { + kelvinQuantity = QuantityType.valueOf(decimal.intValue(), Units.KELVIN); + } + if (kelvinQuantity != null) { + setColorTemp(kelvinQuantity.intValue()); } } diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/devices/wifi/lightstrip/TapoLightStripHandler.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/devices/wifi/lightstrip/TapoLightStripHandler.java index 4e9c721c2c5fa..87c9835d72600 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/devices/wifi/lightstrip/TapoLightStripHandler.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/devices/wifi/lightstrip/TapoLightStripHandler.java @@ -23,6 +23,7 @@ import org.openhab.core.library.types.HSBType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; +import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -43,7 +44,7 @@ public class TapoLightStripHandler extends TapoBaseDeviceHandler { /** * Constructor - * + * * @param thing Thing object representing device */ public TapoLightStripHandler(Thing thing) { @@ -53,7 +54,7 @@ public TapoLightStripHandler(Thing thing) { /** * Function called by {@link org.openhab.binding.tapocontrol.internal.api.TapoDeviceConnector} if new data were * received - * + * * @param queryCommand command where new data belong to */ @Override @@ -71,7 +72,7 @@ public void newDataResult(String queryCommand) { /** * handle command sent to device - * + * * @param channelUID channelUID command is sent to * @param command command to be sent */ @@ -128,8 +129,14 @@ private void handleColorCommand(Command command) { } private void handleColorTempCommand(Command command) { - if (command instanceof DecimalType decimalCommand) { - setColorTemp(decimalCommand.intValue()); + QuantityType kelvinQuantity = null; + if (command instanceof QuantityType genericQuantity) { + kelvinQuantity = genericQuantity.toInvertibleUnit(Units.KELVIN); + } else if (command instanceof DecimalType decimal) { + kelvinQuantity = QuantityType.valueOf(decimal.intValue(), Units.KELVIN); + } + if (kelvinQuantity != null) { + setColorTemp(kelvinQuantity.intValue()); } } @@ -164,7 +171,7 @@ private void handleLightFx(String channel, Command command) { /** * Switch device On or Off - * + * * @param on if true device will switch on. Otherwise switch off */ protected void switchOnOff(boolean on) { @@ -174,7 +181,7 @@ protected void switchOnOff(boolean on) { /** * Set Britghtness of device - * + * * @param newBrightness percentage 0-100 of new brightness */ protected void setBrightness(Integer newBrightness) { @@ -190,7 +197,7 @@ protected void setBrightness(Integer newBrightness) { /** * Set Color of Device - * + * * @param command HSBType */ protected void setColor(HSBType command) { @@ -203,7 +210,7 @@ protected void setColor(HSBType command) { /** * Set ColorTemp - * + * * @param colorTemp (Integer) in Kelvin */ protected void setColorTemp(Integer colorTemp) { @@ -214,7 +221,7 @@ protected void setColorTemp(Integer colorTemp) { /** * Set light effect - * + * * @param lightEffect TapoLightEffect */ protected void setLightEffect(TapoLightEffect lightEffect) { diff --git a/bundles/org.openhab.binding.telegram/README.md b/bundles/org.openhab.binding.telegram/README.md index fb0302b82767f..56f34aa7eea25 100644 --- a/bundles/org.openhab.binding.telegram/README.md +++ b/bundles/org.openhab.binding.telegram/README.md @@ -196,7 +196,7 @@ These actions will send a message to all chat ids configured for this bot. | Action | Description | |----------------------------|--------------| | sendTelegram(String message) | Sends a message. | -| sendTelegram(String format, Object... args) | Sends a formatted message (See for more information). +| sendTelegram(String format, Object... args) | Sends a formatted message (See for more information). | sendTelegramQuery(String message, String replyId, String... buttons) | Sends a question to the user that can be answered via the defined buttons. The replyId can be freely choosen and is sent back with the answer. Then, the id is required to identify what question has been answered (e.g. in case of multiple open questions). The final result looks like this: ![Telegram Inline Keyboard](doc/queryExample.png) | | sendTelegramAnswer(String replyId, String message) | Sends a message after the user has answered a question. You should _always_ call this method after you received an answer. It will remove buttons from the specific question and will also stop the progress bar displayed at the client side. If no message is necessary, just pass `null` here. | | deleteTelegramQuery(String replyId) | Deletes a question in the chat. The replyId must be the same as used for the corresponding sendTelegramQuery() action. | diff --git a/bundles/org.openhab.binding.tplinksmarthome/src/main/java/org/openhab/binding/tplinksmarthome/internal/device/BulbDevice.java b/bundles/org.openhab.binding.tplinksmarthome/src/main/java/org/openhab/binding/tplinksmarthome/internal/device/BulbDevice.java index 97643eef1b59b..8ccd76cfc86e3 100644 --- a/bundles/org.openhab.binding.tplinksmarthome/src/main/java/org/openhab/binding/tplinksmarthome/internal/device/BulbDevice.java +++ b/bundles/org.openhab.binding.tplinksmarthome/src/main/java/org/openhab/binding/tplinksmarthome/internal/device/BulbDevice.java @@ -68,6 +68,13 @@ public boolean handleCommand(final ChannelUID channelUid, final Command command) response = handleOnOffType(channelId, onOffCommand, transitionPeriod); } else if (command instanceof HSBType hsbCommand && CHANNEL_COLOR.equals(channelId)) { response = handleHSBType(channelId, hsbCommand, transitionPeriod); + } else if (command instanceof QuantityType genericQuantity + && CHANNEL_COLOR_TEMPERATURE_ABS.equals(channelId)) { + QuantityType kelvinQuantity = genericQuantity.toInvertibleUnit(Units.KELVIN); + if (kelvinQuantity == null) { + return false; + } + response = handleDecimalType(channelId, new DecimalType(kelvinQuantity.intValue()), transitionPeriod); } else if (command instanceof DecimalType decimalCommand) { response = handleDecimalType(channelId, decimalCommand, transitionPeriod); } else { diff --git a/bundles/org.openhab.io.metrics/README.md b/bundles/org.openhab.io.metrics/README.md index c01ccc4ee60bb..3857965d78793 100644 --- a/bundles/org.openhab.io.metrics/README.md +++ b/bundles/org.openhab.io.metrics/README.md @@ -82,7 +82,7 @@ The InfluxDB exporter service will start as soon as the _influxMetricsEnabled_ c The Java Management Extensions (JMX) exporter service will start as soon as the _jmxMetricsEnabled_ configuration parameter is set to true. -You can monitor the JMX metrics using a tool like [JConsole](https://docs.oracle.com/en/java/javase/17/management/using-jconsole.html) or [VisualVM](https://visualvm.github.io/) (after installing the VisualVM-MBeans plugin). +You can monitor the JMX metrics using a tool like [JConsole](https://docs.oracle.com/en/java/javase/21/management/using-jconsole.html) or [VisualVM](https://visualvm.github.io/) (after installing the VisualVM-MBeans plugin). When the JMX exporter is enabled, the metrics will be available under the "metrics" MBean. JConsole and VisualVM will only be able to connect using JMX when openHAB is started in debug mode (use `start_debug.sh` or `start_debug.bat`). diff --git a/bundles/org.openhab.transform.basicprofiles/README.md b/bundles/org.openhab.transform.basicprofiles/README.md index 65629f1ef232d..1442490732557 100644 --- a/bundles/org.openhab.transform.basicprofiles/README.md +++ b/bundles/org.openhab.transform.basicprofiles/README.md @@ -106,7 +106,7 @@ Switch invertedSwitch { channel="xxx" [profile="basic-profiles:invert"] } ## Round Profile The Round Profile scales the State to a specific number of decimal places based on the power of ten. -Optionally the [Rounding mode](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/RoundingMode.html) can be set. +Optionally the [Rounding mode](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/math/RoundingMode.html) can be set. Source Channels should accept Item Type `Number`. ### Round Profile Configuration diff --git a/bundles/org.openhab.transform.map/README.md b/bundles/org.openhab.transform.map/README.md index 715e7bfbebac2..4e6370f5fd0a8 100644 --- a/bundles/org.openhab.transform.map/README.md +++ b/bundles/org.openhab.transform.map/README.md @@ -7,7 +7,7 @@ Transforms the input by mapping it to another string. The mapping is performed based on "key=value" pairs. When the input matches a `key` in the mapping table, the corresponding `value` is given as the output of the transformation. -The format of the mapping table is documented [here](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Properties.html#load(java.io.Reader)). +The format of the mapping table is documented [here](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Properties.html#load(java.io.Reader)). A default value can be provided if no matching entry is found by using "=value" syntax. Defining this default value using `_source_` would then return the non transformed input string. diff --git a/bundles/org.openhab.transform.regex/README.md b/bundles/org.openhab.transform.regex/README.md index d423049478a65..5321a4f971b56 100644 --- a/bundles/org.openhab.transform.regex/README.md +++ b/bundles/org.openhab.transform.regex/README.md @@ -8,7 +8,7 @@ A full regex is in the form `s///g` whereat the delimiter ` The regular expression in the format `s//result/g`, replaces all occurrences of `` in the source string with `result`. The regular expression in the format `s//result/` (without `g`), replaces the first occurrence of `` in the source string with `result`. -If the regular expression contains a [capture group](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html#cg) defined by `()`, it returns the captured string. +If the regular expression contains a [capture group](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/regex/Pattern.html#cg) defined by `()`, it returns the captured string. Multiple capture groups can be used to retrieve multiple strings and can be combined as a result string defined in the `substitution`. The transformation can be set to be restricted to only match if the input string begins with a character by prepending `^` to the beginning of a pattern or to only match if the input string ends with a specified character by appending `$` at the end.