Blockly Script changing value over time - ReferenceError: xyz is not defined

Dear Community,

I am trying to implement a generic blockly script which increases or decreases the value of a number item over time. It should be possible to call this script for two or more items at the same time without interfering each other.

My current approach is not bulletproof if it comes to multiple calls for different items - I am aware of that - but it is already failing. I get following error messages in console.log:

2023-01-25 08:14:31.482 [WARN ] [ore.internal.scheduler.SchedulerImpl] - Scheduled job '<unknown>' failed and stopped
jdk.nashorn.internal.runtime.ECMAException: ReferenceError: "itemName" is not defined
        at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:319) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:291) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.objects.Global.__noSuchProperty__(Global.java:1616) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.scripts.Script$Recompilation$5087$1036$\^eval\_.L:26(<eval>:28) ~[?:?]
        at jdk.nashorn.javaadapters.org_eclipse_xtext_xbase_lib_Procedures$Procedure0.apply(Unknown Source) ~[?:?]
        at org.openhab.core.model.script.actions.ScriptExecution.lambda$0(ScriptExecution.java:97) ~[?:?]
        at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$12(SchedulerImpl.java:191) ~[?:?]
        at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$1(SchedulerImpl.java:88) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:829) [?:?]

It seems like all variables inside my timer body are dead even for the first execution. I fiddled around with the initial delay (using 10s) and the timer name (using “MyTimer”) but still getting the same error. And yes I did make sure that my context attributes were set by using logging messages. For testing purposes I am using startValue=0, endValue=100, intervallInS=60*5, itemName=“Spotify_Volume”

Here is the blockly “code”:

And here the generated code:

var startValue, endValue, intervalInS, itemName, updateIntervalInS, delta, stepCount, stepSize, counter, currentValue;

var scriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution');

var zdt = Java.type('java.time.ZonedDateTime');

if (typeof this.timers === 'undefined') {
  this.timers = [];
}


startValue = ctx['startValue'];
endValue = ctx['endValue'];
intervalInS = ctx['intervalInS'];
itemName = ctx['itemName'];
updateIntervalInS = 10;
delta = endValue - startValue;
stepCount = Math.floor(intervalInS / updateIntervalInS);
stepSize = delta / stepCount;
counter = 0;
currentValue = startValue;
if (typeof this.timers[itemName] === 'undefined' || this.timers[itemName].hasTerminated()) {
  this.timers[itemName] = scriptExecution.createTimer(zdt.now().plusSeconds(0), function () {
    if (counter < stepCount) {
      events.sendCommand(itemName, currentValue);
      counter = (typeof counter == 'number' ? counter : 0) + 1;
      currentValue = (typeof currentValue == 'number' ? currentValue : 0) + stepSize;
      if (typeof this.timers[itemName] !== 'undefined') { this.timers[itemName].reschedule(zdt.now().plusSeconds(updateIntervalInS)); }
    } else {
      events.sendCommand(itemName, endValue);
    }
    })
}

I would really appreciate your feedback and help. Thank you in advance

Cheers for now

Clemens

sendCommand function should expect an item object and not the item name as string. Use the getItem block first, to get the correct item object based on the name.

If that’s not fixing your issue:
maybe itemName is a reserved word and has a special function in the rule execution. Try to use a different variable name.

Also post your code on how to call the script.
Even you have mentioned this in the text briefly, maybe there is a typo, syntax issue, etc

I always used the name of an item with sendCommand and didn’t had any problems. Also the “send command” block does not accept an input of the block “get item”.
image
I could tweak it via variables or in code but it seems not like the problem.

I also tried that, I changed “itemName” to “itemToChange”. I would hope that there is no overlapping with such a generic name. Also I would except different errors.

Good point. I changed my code so the inputs are overriden. This should make my calling code irrelevant.

I updated my code a bit. Now it should actually go through the initial start value and really ends with end value. Still the issue with the variables is not gone. I also made sure that the program is not crashing outside of the timer body by adding lots of test logging calls outside and inside of the timer body.

Here is the blockly “code”:

And here the generated code:

var startValue, endValue, intervalInS, itemToChange, updateIntervalInS, delta, stepCount, stepSize, counter, currentValue;

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);

var scriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution');

var zdt = Java.type('java.time.ZonedDateTime');

if (typeof this.timers === 'undefined') {
  this.timers = [];
}


startValue = ctx['startValue'];
endValue = ctx['endValue'];
intervalInS = ctx['intervalInS'];
itemToChange = ctx['itemName'];
startValue = 0;
endValue = 100;
intervalInS = 60 * 5;
itemToChange = itemRegistry.getItem('Spotify_Volume').getName();
updateIntervalInS = 10;
delta = endValue - startValue;
stepCount = Math.floor(intervalInS / updateIntervalInS);
stepSize = delta / stepCount;
counter = 1;
currentValue = startValue;
logger.info((['Start value over time for item ',itemToChange,' from ',startValue,' to ',endValue,' in ',intervalInS,' seconds'].join('')));
events.sendCommand(itemToChange, startValue);
if (typeof this.timers[itemToChange] === 'undefined' || this.timers[itemToChange].hasTerminated()) {
  this.timers[itemToChange] = scriptExecution.createTimer(zdt.now().plusSeconds(updateIntervalInS), function () {
    if (counter < stepCount) {
      currentValue = (typeof currentValue == 'number' ? currentValue : 0) + stepSize;
      logger.info((['Update value to ',currentValue,' over time for item ',itemToChange,' from ',startValue,' to ',endValue,' in ',intervalInS,' seconds'].join('')));
      events.sendCommand(itemToChange, currentValue);
      if (typeof this.timers[itemToChange] !== 'undefined') { this.timers[itemToChange].reschedule(zdt.now().plusSeconds(updateIntervalInS)); }
      counter = (typeof counter == 'number' ? counter : 0) + 1;
    } else {
      logger.info((['End value over time for item ',itemToChange,' from ',startValue,' to ',endValue,' in ',intervalInS,' seconds'].join('')));
      events.sendCommand(itemToChange, endValue);
    }
    })
}

And the current output

2023-01-26 07:43:25.204 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Start value over time for item Spotify_Volume from 0 to 100 in 300 seconds
2023-01-26 07:43:35.235 [WARN ] [ore.internal.scheduler.SchedulerImpl] - Scheduled job '<unknown>' failed and stopped
jdk.nashorn.internal.runtime.ECMAException: ReferenceError: "startValue" is not defined
        at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:319) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:291) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.objects.Global.__noSuchProperty__(Global.java:1616) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.scripts.Script$Recompilation$5587$1241$\^eval\_.L:31(<eval>:34) ~[?:?]
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunction
Data.java:655) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:527) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.javaadapters.org_eclipse_xtext_xbase_lib_Procedures$Procedure0.apply(Unknown Source) ~[?:?]
        at org.openhab.core.model.script.actions.ScriptExecution.lambda$0(ScriptExecution.java:97) ~[?:?]
        at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$12(SchedulerImpl.java:191) ~[?:?]
        at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$1(SchedulerImpl.java:88) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:829) [?:?]

ps. did I mention that I love that community… responses within 24h. I love it! Thank you!

Okay now something really weird happened. A semi successful run went through. I added the “send command” and “get item” block to my current script for the screenshot and forgot to remove them when running the script. This lead to an error when running the script with these dangling blocks but obviously the timer didn’t break.

My guess is that somehow the context of the thread was not dying then. But I might be wrong.

When I removed the “send command” and “get item” block it returned to not working again. I tried to provoke that semi successful run again and it works.

So if my non timer body code crashes after the timerBody invoke, the timerBody actually works. But if not my variables keep dying. This must be related to the lifetime of the thread(-context), right?

Here is the output in openhab.log

2023-01-26 08:12:01.740 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Start value over time for item Spotify_Volume from 0 to 100 in 300 seconds
2023-01-26 08:12:01.746 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 1
2023-01-26 08:12:01.784 [WARN ] [rnal.defaultscope.ScriptBusEventImpl] - Item 'MyItem' does not exist.
2023-01-26 08:12:01.786 [WARN ] [e.automation.internal.RuleEngineImpl] - Fail to execute action: script
java.lang.RuntimeException: org.openhab.core.items.ItemNotFoundException: Item 'MyItem' could not be found in the item registry
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:531) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:456) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:413) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:409) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:162) ~[jdk.scripting.nashorn:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) ~[java.scripting:?]
        at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:58) ~[?:?]
        at java.util.Optional.ifPresent(Optional.java:183) ~[?:?]
        at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:55) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1181) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1030) ~[?:?]
        at jdk.nashorn.internal.scripts.Script$Recompilation$4856$\^eval\_.:program(<eval>:25) ~[?:?]
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:655) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:527) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:456) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:413) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:409) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:162) ~[jdk.scripting.nashorn:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) ~[java.scripting:?]
        at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:58) ~[?:?]
        at java.util.Optional.ifPresent(Optional.java:183) ~[?:?]
        at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:55) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1181) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1030) ~[?:?]
        at jdk.nashorn.internal.scripts.Script$Recompilation$5643$\^eval\_.:program(<eval>:19) ~[?:?]
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:655) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:527) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:456) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:413) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:409) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:162) ~[jdk.scripting.nashorn:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) ~[java.scripting:?]
        at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:58) ~[?:?]
        at java.util.Optional.ifPresent(Optional.java:183) ~[?:?]
        at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:55) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1181) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1033) ~[?:?]
        at org.openhab.core.automation.internal.RuleEngineImpl.runNow(RuleEngineImpl.java:1049) ~[?:?]
        at org.openhab.core.automation.rest.internal.RuleResource.runNow(RuleResource.java:327) ~[?:?]
        at jdk.internal.reflect.GeneratedMethodAccessor333.invoke(Unknown Source) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) ~[bundleFile:3.4.5]
        at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[bundleFile:3.4.5]
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201) ~[bundleFile:3.4.5]
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104) ~[bundleFile:3.4.5]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) ~[bundleFile:3.4.5]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) ~[bundleFile:3.4.5]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:298) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:217) ~[bundleFile:3.4.5]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) ~[bundleFile:3.1.0]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:273) ~[bundleFile:3.4.5]
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) ~[bundleFile:9.4.46.v20220331]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:74) ~[bundleFile:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) ~[bundleFile:9.4.46.v20220331]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:294) ~[bundleFile:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.46.v20220331]
        at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:90) ~[bundleFile:?]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) ~[bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.46.v20220331]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.46.v20220331]
        at java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: org.openhab.core.items.ItemNotFoundException: Item 'MyItem' could not be found in the item registry
        at org.openhab.core.internal.items.ItemRegistryImpl.getItem(ItemRegistryImpl.java:86) ~[?:?]
        at jdk.nashorn.internal.scripts.Script$Recompilation$5754$\^eval\_$cu1$restOf.:program(<eval>:58) ~[?:?]
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:655) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513) ~[jdk.scripting.nashorn:?]
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:527) ~[jdk.scripting.nashorn:?]
        ... 95 more
2023-01-26 08:12:11.770 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 2
2023-01-26 08:12:11.771 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 3
2023-01-26 08:12:11.773 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 4
2023-01-26 08:12:11.794 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Update value to 3.3333333333333335 over time for item Spotify_Volume from 0 to 100 in 300 seconds
2023-01-26 08:12:11.795 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 5
2023-01-26 08:12:11.824 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 6
2023-01-26 08:12:11.844 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 7
2023-01-26 08:12:11.846 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 8
2023-01-26 08:12:11.847 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 11
2023-01-26 08:12:21.832 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 2
2023-01-26 08:12:21.836 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 3
2023-01-26 08:12:21.840 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 4
2023-01-26 08:12:21.843 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Update value to 6.666666666666667 over time for item Spotify_Volume from 0 to 100 in 300 seconds
2023-01-26 08:12:21.844 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 5
2023-01-26 08:12:21.849 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 6
2023-01-26 08:12:21.857 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 7
2023-01-26 08:12:21.859 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 8
2023-01-26 08:12:21.861 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 11
[...]
2023-01-26 08:16:42.105 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Update value to 93.33333333333331 over time for item Spotify_Volume from 0 to 100 in 300 seconds
2023-01-26 08:16:42.106 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 5
2023-01-26 08:16:42.107 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 6
2023-01-26 08:16:42.109 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 7
2023-01-26 08:16:42.110 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 8
2023-01-26 08:16:42.110 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 11
2023-01-26 08:16:52.109 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 2
2023-01-26 08:16:52.110 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 3
2023-01-26 08:16:52.111 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 4
2023-01-26 08:16:52.113 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Update value to 96.66666666666664 over time for item Spotify_Volume from 0 to 100 in 300 seconds
2023-01-26 08:16:52.114 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 5
2023-01-26 08:16:52.115 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 6
2023-01-26 08:16:52.130 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 7
2023-01-26 08:16:52.132 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 8
2023-01-26 08:16:52.133 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 11
2023-01-26 08:17:02.117 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 2
2023-01-26 08:17:02.140 [INFO ] [org.openhab.rule.Set_Value_over_Time] - End value over time for item Spotify_Volume from 0 to 100 in 300 seconds
2023-01-26 08:17:02.141 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 9
2023-01-26 08:17:02.146 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 10
2023-01-26 08:17:02.147 [INFO ] [org.openhab.rule.Set_Value_over_Time] - Breakpoint 11

It creates

events.sendCommand(‘MyItem’, ‘value’);

(see actions - Documentation)

Either I misunderstand you or you are mistaken:

If you look at

Rules Blockly - Items & Things | openHAB you see this block

image

which is actually documented here:

and explained as

Technically this block returns the name of the item as a String.
As a result, this block can be used wherever the item name is required as a String.

To add to that: I even find confusing that in some block types an item is expected as a string item (like the one above) and sometimes an item object is expected. I am aware of that and I intend to make our blocks more resilient in 4.0 to allow to pass either the item name (to be backward compatible) or the item object block instead.

1 Like

I got a workaround working which I am not really happy with. I am using the “store value” and “stored value” blocks to store and retrieve my variables. It shows that my local variables all die when my script terminates with invoking the timer. I am unsure if that is the desired behavior.

Nevertheless I still want to make that script executable for multiple items, therefore I need some kind of a map, which uses the item name as key. Is that possible with blockly? I would appreciate feedback.

Here is the blockly “code” without logging:

Here is the code:

var startValue, endValue, intervalinS, itemName, updateIntervalinS, delta, stepCount, stepSize, counter, currentValue;

if (typeof this.storedValues === 'undefined') {
  this.storedValues = [];
}

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);

var scriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution');

var zdt = Java.type('java.time.ZonedDateTime');

if (typeof this.timers === 'undefined') {
  this.timers = [];
}


startValue = ctx['startValue'];
endValue = ctx['endValue'];
intervalinS = ctx['interval'];
itemName = ctx['itemName'];
updateIntervalinS = 10;
delta = endValue - startValue;
stepCount = Math.floor(intervalinS / updateIntervalinS);
stepSize = delta / stepCount;
counter = 1;
currentValue = startValue;
this.storedValues['startValue'] = startValue;
this.storedValues['endValue'] = endValue;
this.storedValues['intervalinS'] = intervalinS;
this.storedValues['itemName'] = itemName;
this.storedValues['updateIntervalinS'] = updateIntervalinS;
this.storedValues['delta'] = delta;
this.storedValues['stepCount'] = stepCount;
this.storedValues['stepSize'] = stepSize;
this.storedValues['counter'] = counter;
this.storedValues['currentValue'] = currentValue;
logger.info((['Start value over time for item ',itemName,' from ',startValue,' to ',endValue,' in ',intervalinS,' seconds'].join('')));
events.sendCommand(itemName, startValue);
if (typeof this.timers[itemName] === 'undefined' || this.timers[itemName].hasTerminated()) {
  this.timers[itemName] = scriptExecution.createTimer(zdt.now().plusSeconds(updateIntervalinS), function () {
    startValue = (this.storedValues['startValue']);
    endValue = (this.storedValues['endValue']);
    intervalinS = (this.storedValues['intervalinS']);
    itemName = (this.storedValues['itemName']);
    updateIntervalinS = (this.storedValues['updateIntervalinS']);
    delta = (this.storedValues['delta']);
    stepCount = (this.storedValues['stepCount']);
    stepSize = (this.storedValues['stepSize']);
    counter = (this.storedValues['counter']);
    currentValue = (this.storedValues['currentValue']);
    if (counter < stepCount) {
      currentValue = (typeof currentValue == 'number' ? currentValue : 0) + stepSize;
      logger.info((['Update value to ',currentValue,' over time for item ',itemName,' from ',startValue,' to ',endValue,' in ',intervalinS,' seconds'].join('')));
      events.sendCommand(itemName, currentValue);
      if (typeof this.timers[itemName] !== 'undefined') { this.timers[itemName].reschedule(zdt.now().plusSeconds(updateIntervalinS)); }
      counter = (typeof counter == 'number' ? counter : 0) + 1;
      this.storedValues['counter'] = counter;
      this.storedValues['currentValue'] = currentValue;
    } else {
      logger.info((['End value over time for item ',itemName,' from ',startValue,' to ',endValue,' in ',intervalinS,' seconds'].join('')));
      events.sendCommand(itemName, endValue);
    }
    })
}

Thank you Stefan for elaborating on sendCommand! I was looking for the documentation in my last post, but didn’t find the right parts. But when I couldn’t find it right away, I was too lazy to dig deeper.