Awesome, we’ll try binding things then, I have to admit we didn’t really try as there wasn’t the binding icon.
I would love to but unfortunately a flight from France to Sacramento might be too much to ask for to my employer ahah !
Thanks!
Awesome, we’ll try binding things then, I have to admit we didn’t really try as there wasn’t the binding icon.
I would love to but unfortunately a flight from France to Sacramento might be too much to ask for to my employer ahah !
Thanks!
There's a livestream option for ICC, too.
My presentation is done. The source code I mentioned is available here:
Automation Professionals is pleased to announce the production release of this module for Ignition v8.3: v2.1.1.252721938
As usual, refer to the Module Sales page linked in the OP to keep up with the latest production releases.
Hey @pturmel , with the Bulk Action, can we use relative tagpaths in the called script that are relative to the tagpath that triggered it?
e.g. if I’m calling this function:
def doThisLongThing(values):
# read udt param
deviceName = system.tag.readBlocking('[.]../Parameters.DeviceName')[0].value
No, but each item delivered includes the .source as a TagPath object, which can efficiently compute relative paths with the parentPath property and the .getChildPath(...) method.
Keep in mind that the function gets a list of items, that do not have to have the same source at all. Only if a function was set up to take just one item at a time could you apply relative paths automatically. And then, you just have the standard valueChange event. ![]()
Also be aware that each function called, while not blocking the tag subsystem, relies on the gateway context's Execution Manager to run each delivery asynchronously. If you expect to run many long processes, consider handing off to a custom thread pool execution manager with the desired level of parallelism. If each potential item has its own long process, you may want to parallelize them individually.
Ah, derr, that makes sense. Monday brain still kicking in… Good note about the TagPath object though, that is handy to know.
Hey Phil,
I'm trying to use @system.util.runInGateway and am encountering an error.
toolkitTestlogger = system.util.getLogger(system.util.getProjectName() + '.' + system.reflect.getModulePath())
@system.util.runInGateway
def gwLogInfof(*args):
logger.infof(*args)
toolkitTest.gwLogInfof('Test Message')
Java Traceback:
Traceback (most recent call last):
File "<input>", line 1, in <module>
java.util.NoSuchElementException: No value present
at java.util.Optional.orElseThrow(:0)
at com.automation_pros.simaids.gateway.ToolkitRPCImpl.runInGateway(ToolkitRPCImpl.java:77)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(:0)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(:0)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(:0)
at java.lang.reflect.Method.invoke(:0)
at com.inductiveautomation.ignition.gateway.rpc.RpcDelegate$DelegateRpcHandler.handle(RpcDelegate.java:275)
at com.inductiveautomation.ignition.gateway.rpc.RpcRoutes.lambda$handle$1(RpcRoutes.java:209)
at com.inductiveautomation.ignition.gateway.rpc.RpcRoutes.safelyHandle(RpcRoutes.java:225)
at com.inductiveautomation.ignition.gateway.rpc.RpcRoutes.handle(RpcRoutes.java:209)
at com.inductiveautomation.ignition.gateway.dataroutes.Route.service(Route.java:355)
at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupImpl.service(RouteGroupImpl.java:117)
at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupCollectionServlet.serviceInternal(RouteGroupCollectionServlet.java:152)
at com.inductiveautomation.ignition.gateway.dataroutes.AbstractRouteGroupServlet.service(AbstractRouteGroupServlet.java:40)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
at org.eclipse.jetty.ee10.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1385)
at org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:751)
at org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1622)
at com.inductiveautomation.catapult.filters.GatewayFilter.doFilter(GatewayFilter.java:119)
at jakarta.servlet.http.HttpFilter.doFilter(HttpFilter.java:97)
at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)
at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1594)
at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle(ServletHandler.java:1555)
at org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch(ServletChannel.java:823)
at org.eclipse.jetty.ee10.servlet.ServletChannel.handle(ServletChannel.java:440)
at org.eclipse.jetty.ee10.servlet.ServletHandler.handle(ServletHandler.java:470)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
at org.eclipse.jetty.ee10.servlet.SessionHandler.handle(SessionHandler.java:717)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1071)
at org.eclipse.jetty.rewrite.handler.RewriteHandler$LastRuleHandler.handle(RewriteHandler.java:159)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:143)
at org.eclipse.jetty.server.Handler$Sequence.handle(Handler.java:805)
at org.eclipse.jetty.server.Handler$Sequence.handle(Handler.java:805)
at org.eclipse.jetty.server.Server.handle(Server.java:182)
at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:677)
at org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:416)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:480)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:443)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:293)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:201)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:311)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:981)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1211)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1166)
at java.lang.Thread.run(:0)
java.util.NoSuchElementException: java.util.NoSuchElementException: No value present
at org.python.core.Py.JavaError(Py.java:545)
at org.python.core.PyTableCode.call(PyTableCode.java:182)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1703)
at org.python.core.Py.exec(Py.java:1747)
at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:277)
at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:130)
at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:639)
at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:627)
at java.desktop/javax.swing.SwingWorker$1.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.desktop/javax.swing.SwingWorker.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.util.NoSuchElementException: No value present
at java.util.Optional.orElseThrow(:0)
at com.automation_pros.simaids.gateway.ToolkitRPCImpl.runInGateway(ToolkitRPCImpl.java:77)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(:0)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(:0)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(:0)
at java.lang.reflect.Method.invoke(:0)
at com.inductiveautomation.ignition.gateway.rpc.RpcDelegate$DelegateRpcHandler.handle(RpcDelegate.java:275)
at com.inductiveautomation.ignition.gateway.rpc.RpcRoutes.lambda$handle$1(RpcRoutes.java:209)
at com.inductiveautomation.ignition.gateway.rpc.RpcRoutes.safelyHandle(RpcRoutes.java:225)
at com.inductiveautomation.ignition.gateway.rpc.RpcRoutes.handle(RpcRoutes.java:209)
at com.inductiveautomation.ignition.gateway.dataroutes.Route.service(Route.java:355)
at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupImpl.service(RouteGroupImpl.java:117)
at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupCollectionServlet.serviceInternal(RouteGroupCollectionServlet.java:152)
at com.inductiveautomation.ignition.gateway.dataroutes.AbstractRouteGroupServlet.service(AbstractRouteGroupServlet.java:40)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
at org.eclipse.jetty.ee10.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1385)
at org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:751)
at org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1622)
at com.inductiveautomation.catapult.filters.GatewayFilter.doFilter(GatewayFilter.java:119)
at jakarta.servlet.http.HttpFilter.doFilter(HttpFilter.java:97)
at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)
at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1594)
at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle(ServletHandler.java:1555)
at org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch(ServletChannel.java:823)
at org.eclipse.jetty.ee10.servlet.ServletChannel.handle(ServletChannel.java:440)
at org.eclipse.jetty.ee10.servlet.ServletHandler.handle(ServletHandler.java:470)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
at org.eclipse.jetty.ee10.servlet.SessionHandler.handle(SessionHandler.java:717)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1071)
at org.eclipse.jetty.rewrite.handler.RewriteHandler$LastRuleHandler.handle(RewriteHandler.java:159)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:143)
at org.eclipse.jetty.server.Handler$Sequence.handle(Handler.java:805)
at org.eclipse.jetty.server.Handler$Sequence.handle(Handler.java:805)
at org.eclipse.jetty.server.Server.handle(Server.java:182)
at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:677)
at org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:416)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:480)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:443)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:293)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:201)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:311)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:981)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1211)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1166)
at java.lang.Thread.run(:0)
Traceback (most recent call last):
File "<input>", line 1, in <module>
java.util.NoSuchElementException: No value present
at java.util.Optional.orElseThrow(:0)
at com.automation_pros.simaids.gateway.ToolkitRPCImpl.runInGateway(ToolkitRPCImpl.java:77)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(:0)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(:0)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(:0)
at java.lang.reflect.Method.invoke(:0)
at com.inductiveautomation.ignition.gateway.rpc.RpcDelegate$DelegateRpcHandler.handle(RpcDelegate.java:275)
at com.inductiveautomation.ignition.gateway.rpc.RpcRoutes.lambda$handle$1(RpcRoutes.java:209)
at com.inductiveautomation.ignition.gateway.rpc.RpcRoutes.safelyHandle(RpcRoutes.java:225)
at com.inductiveautomation.ignition.gateway.rpc.RpcRoutes.handle(RpcRoutes.java:209)
at com.inductiveautomation.ignition.gateway.dataroutes.Route.service(Route.java:355)
at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupImpl.service(RouteGroupImpl.java:117)
at com.inductiveautomation.ignition.gateway.dataroutes.RouteGroupCollectionServlet.serviceInternal(RouteGroupCollectionServlet.java:152)
at com.inductiveautomation.ignition.gateway.dataroutes.AbstractRouteGroupServlet.service(AbstractRouteGroupServlet.java:40)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
at org.eclipse.jetty.ee10.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1385)
at org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:751)
at org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1622)
at com.inductiveautomation.catapult.filters.GatewayFilter.doFilter(GatewayFilter.java:119)
at jakarta.servlet.http.HttpFilter.doFilter(HttpFilter.java:97)
at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)
at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1594)
at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle(ServletHandler.java:1555)
at org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch(ServletChannel.java:823)
at org.eclipse.jetty.ee10.servlet.ServletChannel.handle(ServletChannel.java:440)
at org.eclipse.jetty.ee10.servlet.ServletHandler.handle(ServletHandler.java:470)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
at org.eclipse.jetty.ee10.servlet.SessionHandler.handle(SessionHandler.java:717)
at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1071)
at org.eclipse.jetty.rewrite.handler.RewriteHandler$LastRuleHandler.handle(RewriteHandler.java:159)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.HeaderPatternRule$1.handle(HeaderPatternRule.java:89)
at org.eclipse.jetty.rewrite.handler.Rule$Handler.handle(Rule.java:108)
at org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:143)
at org.eclipse.jetty.server.Handler$Sequence.handle(Handler.java:805)
at org.eclipse.jetty.server.Handler$Sequence.handle(Handler.java:805)
at org.eclipse.jetty.server.Server.handle(Server.java:182)
at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:677)
at org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:416)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:480)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:443)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:293)
at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:201)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:311)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:981)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1211)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1166)
at java.lang.Thread.run(:0)
java.util.NoSuchElementException: java.util.NoSuchElementException: No value present
Thoughts
Gateway: 8.3.4-SNAPSHOT (b2026010816)
Toolkit: 2.1.1 (b252721938)
Did you remember to save the project? Gateway scope cannot run unsaved content from the designer.
Yup, the project is saved. I also tried restarting the designer without any change.
Hmmm. This is the relevant code:
if (ClientReqSession.exists()) {
project = (String) ClientReqSession.get().getAttribute(ClientReqSession.SESSION_PROJECT_NAME);
} else {
project = ScriptContext.getDefaultProject().orElseThrow();
}
This might be an unexpected dependency on Vision. I'll have to dig into this and figure out the corresponding Perspective-only project reference. If you would, add Vision and try again--I suspect that it will suddenly work.
Even weirder then, I already have Vision installed.
Hmm. Is this an inheritable project?
Nope, not inheritable.
This is on a development gateway, I can try anything you’d find useful.
Did you get a gateway log entry, too?
Nah, I don’t see any gateway log messages coming from the Toolkit module.
My dev gateway regularly throws ClockDriftDetector messages, but I doubt that’s relevant ![]()
Oops, debug level for ToolkitRPCImpl. Should provide a more specific line number--77 is the beginning of the try.
I think I may have to pass the project name as an actual argument, since I can't seem to rely on ClientReqSession or ScriptContext.
If you're using the standard machinery/happy path/RpcDelegate, you can use the static utility on RpcDelegate:
com.inductiveautomation.ignition.gateway.rpc.RpcDelegate.projectName()
But internally this is just reporting from the RpcContext, which is backed by the ClientReqSession:
String projectName = (String) session.getAttribute(ClientReqSession.SESSION_PROJECT_NAME);
So no idea why it wouldn't be working.