-
-
Couldn't load subscription status.
- Fork 458
Description
QuantityType Percent cast (as) to HSBType, UpDownType, OnOffType and OpenClosedType is broken. Caused by a wrong internal representation?
Only '1%' maps to the UpDownType.DOWN, OnOffType.ON or OpenClosedType.OPEN. For a cast to HSBType an exception is thrown for '100%' and '1%' results in a brightness value of 100!!
Expected behavior is that for UpDownType '100%' maps to DOWN only and for OnOffType or OpenClosedType any value greater ZERO maps to OnOffType.ON or OpenClosedType.OPEN.
For HSBType the value range should be 0-100% instead 0-1%.
Following groovy script can be used to reproduce the problem:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Logger log = LoggerFactory.getLogger('QuantityType Test');
log.warn('QuantityType(100 %).as(UpDownType.class) = {}', new QuantityType('100 %').as(UpDownType.class));
log.warn('QuantityType(1 %).as(UpDownType.class) = {}', new QuantityType('1 %').as(UpDownType.class));
log.warn('QuantityType(100 %).as(OnOffType.class) = {}', new QuantityType('100 %').as(OnOffType.class));
log.warn('QuantityType(1 %).as(OnOffType.class) = {}', new QuantityType('1 %').as(OnOffType.class));
log.warn('QuantityType(100 %).as(OpenClosedType.class) = {}', new QuantityType('100 %').as(OpenClosedType.class));
log.warn('QuantityType(1 %).as(OpenClosedType.class) = {}', new QuantityType('1 %').as(OpenClosedType.class));
log.warn('QuantityType(1 %).as(HSBType.class) = {}', new QuantityType('1 %').as(HSBType.class));
try {
log.warn('QuantityType(100 %).as(HSBType.class) = {}', new QuantityType('100 %').as(HSBType.class));
} catch(exp) {
log.error('QuantityType(100 %).as(HSBType.class) =', exp);
}
The script produces the following output:
2025-10-18 10:51:11.134 [WARN ] [QuantityType Test ] - QuantityType(100 %).as(UpDownType.class) = null
2025-10-18 10:51:11.136 [WARN ] [QuantityType Test ] - QuantityType(1 %).as(UpDownType.class) = DOWN
2025-10-18 10:51:11.137 [WARN ] [QuantityType Test ] - QuantityType(100 %).as(OnOffType.class) = ON
2025-10-18 10:51:11.138 [WARN ] [QuantityType Test ] - QuantityType(1 %).as(OnOffType.class) = ON
2025-10-18 10:51:11.139 [WARN ] [QuantityType Test ] - QuantityType(100 %).as(OpenClosedType.class) = null
2025-10-18 10:51:11.140 [WARN ] [QuantityType Test ] - QuantityType(1 %).as(OpenClosedType.class) = OPEN
2025-10-18 10:51:11.142 [WARN ] [QuantityType Test ] - QuantityType(1 %).as(HSBType.class) = 0,0,100
2025-10-18 10:51:11.143 [ERROR] [QuantityType Test ] - QuantityType(100 %).as(HSBType.class) =
java.lang.IllegalArgumentException: Value must be between 0 and 100
at org.openhab.core.library.types.PercentType.validateValue(PercentType.java:95) ~[?:?]
at org.openhab.core.library.types.PercentType.<init>(PercentType.java:90) ~[?:?]
at org.openhab.core.library.types.QuantityType.as(QuantityType.java:578) ~[?:?]
at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321) ~[?:?]
at test.run(test.groovy:15) ~[?:?]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:331) ~[?:?]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:161) ~[?:?]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:137) ~[?:?]
at javax.script.AbstractScriptEngine.eval(Unknown Source) ~[java.scripting:?]
at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.loadScript(ScriptEngineManagerImpl.java:165) ~[?:?]
at org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher.createAndLoad(AbstractScriptFileWatcher.java:335) ~[?:?]
at org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher.lambda$13(AbstractScriptFileWatcher.java:309) ~[?:?]
at java.util.concurrent.CompletableFuture$AsyncRun.run(Unknown Source) ~[?:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:?]
at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[?:?]
at java.lang.Thread.run(Unknown Source) [?:?]