dibs
@Samuel_Sueur, you definitely may trust @pturmel... and best of all, he is speaking french
see you at icc @pturmel
Bien sûr!
Automation Professionals is pleased to announce a new version of the Integration Toolkit:
For Ignition v8.1+, as usual: v2.0.19.242411414
Fixes a couple bugs, including the NPE found by @lrose, and adds some new scripting functions:
This new orderBy()
function is very similar to the same-named expression function, but doesn't require you to supply expressions that extract cell values. String arguments are interpreted as column names and turned into the necessary lambda for you (entirely with java code), similar to how IA's system.dataset.sort()
works, but not limited to a single column key.
system.dataset.naturalCasedOrder()
Note that the latter three are function-returning functions, intended to be used with system.dataset.orderBy()
. These function-returning functions similarly accept strings as column names, and can be nested. The following will order a dataset by ascending natural order on one column, then descending natural order on a second column:
newDS = system.dataset.orderBy(
sourceDS,
system.dataset.naturalOrder('col1'),
system.dataset.descending(system.dataset.naturalOrder('col2')))
I feel as though my post about sorting using arbitrary key functions may have inspired system.dataset.orderBy
...
Not really. I've had the expression function which sorts by arbitrary key expressions since last year. But I needed a scripted version that can efficiently handle some potentially very large datasets. So an actual jython lambda is suboptimal. (Though you can pass those to my new function if you must.)
Phil,
Perhaps I am missing something, but I don't see any where in the documentation where you show what values can be used to specify each type when providing columninfo to unionAll()
. Specifically, I am trying to provide a column with type Date.
I have tried "Date","date", and "java.util.Date". Non-of which work. I get an Unsupported inner columnInfo element error.
I use the same class as IA uses in their CSV tools to handle those strings. Documented here: system.dataset.fromCSV().
So, "date" should work.
Show your expression?
This test expression:
unionAll(
asMap('someDate', 'date'),
asList()
)
Produces this empty dataset:
"#NAMES"
"someDate"
"#TYPES"
"date"
"#ROWS","0"
Here is the Expression:
unionAll(
asList(
"BestByDate","date",
"CaseCode", "str",
"FGItem", "str",
"ShopOrder","I",
"RecordID", "str",
"ShopOrderQty","F",
"CaseUpcCode","str",
"SerialKey","I",
"TemplateName","str",
"GtinCode","str",
"CaseProductDesc","str",
"LogoCode","str",
"CaseCountUnitSize","str",
"BestBuyFormatCode","str",
"BB_YEAR4","I",
"BB_YEAR2","I",
"BB_MONTHNAME","str",
"BB_MONTHNUMBER","I",
"BB_DAY","I",
"MISC1","str",
"MISC2","str",
"MISC3","str",
"StockNumber","str",
"DATE_FMT","str"
),
forEach(
objectScript("system.util.sendRequest('<project name>','retrievePalletInfo',{'line':'1A'},'<remoteServer>')"),
it()[1]
)
)
The objectScript()
returns the following map:
{u'BB_MONTHNAME': u'December', u'ShopOrderQty': 19208.0, u'DATE_FMT': u' ', u'BestBuyFormatCode': u'XX', u'CaseCode': u'SFY59P1E424208 ', u'FGItem': u'HOUY59PNEL ', u'CaseProductDesc': u'Tomato Ketchup ', u'BB_YEAR4': u'2025', u'BB_DAY': 28, u'BB_MONTHNUMBER': 12, u'MISC3': u' ', u'MISC2': u' ', u'TemplateName': u'M00C2', u'MISC1': u' ', u'BestByDate': 2025-12-28 00:00:00.0, u'BB_YEAR2': 25, u'GtinCode': u'10734730058341', u'CaseUpcCode': u'34730-05834*/* ', u'SerialKey': 395740, u'ShopOrder': 1146113.0, u'LogoCode': u'HOU ', u'StockNumber': u' ', u'RecordID': u'PH', u'CaseCountUnitSize': u'6/114 OZ '}
Error
java.lang.Exception: Error executing expression binding on
AutoCasePrint.Root Container.Text Area.palletInfo
at com.inductiveautomation.factorypmi.application.binding.ExpressionPropertyAdapter.runExpression(ExpressionPropertyAdapter.java:92)
at com.inductiveautomation.factorypmi.application.binding.ExpressionPropertyAdapter.startup(ExpressionPropertyAdapter.java:113)
at com.inductiveautomation.factorypmi.application.binding.DefaultInteractionController.setPropertyAdapter(DefaultInteractionController.java:248)
at com.inductiveautomation.factorypmi.designer.property.configurators.ExpressionConfigurator.bind(ExpressionConfigurator.java:246)
at com.inductiveautomation.factorypmi.designer.property.configurators.ExpressionConfigurator.tryCommit(ExpressionConfigurator.java:192)
at com.inductiveautomation.factorypmi.designer.property.configurators.ConfiguratorMultiplexor$EditorParent.tryCommit(ConfiguratorMultiplexor.java:398)
at com.inductiveautomation.factorypmi.designer.property.configurators.ConfiguratorMultiplexor.tryCommit(ConfiguratorMultiplexor.java:546)
at com.inductiveautomation.factorypmi.designer.property.configurators.DynamicOptsDialog.doOK(DynamicOptsDialog.java:95)
at com.inductiveautomation.factorypmi.designer.property.configurators.DynamicOptsDialog$1.actionPerformed(DynamicOptsDialog.java:64)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.desktop/java.awt.Component.processEvent(Unknown Source)
at java.desktop/java.awt.Container.processEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.WaitDispatchSupport$2.run(Unknown Source)
at java.desktop/java.awt.WaitDispatchSupport$4.run(Unknown Source)
at java.desktop/java.awt.WaitDispatchSupport$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at java.desktop/java.awt.WaitDispatchSupport.enter(Unknown Source)
at java.desktop/java.awt.Dialog.show(Unknown Source)
at java.desktop/java.awt.Component.show(Unknown Source)
at java.desktop/java.awt.Component.setVisible(Unknown Source)
at java.desktop/java.awt.Window.setVisible(Unknown Source)
at java.desktop/java.awt.Dialog.setVisible(Unknown Source)
at com.inductiveautomation.factorypmi.designer.property.configurators.DynamicOptsDialog.showDialog(DynamicOptsDialog.java:163)
at com.inductiveautomation.factorypmi.designer.model.VisionDesignerImpl.openBindingDialog(VisionDesignerImpl.java:1236)
at com.inductiveautomation.factorypmi.designer.property.editors.bb.DynamicOptionsButton.actionPerformed(DynamicOptionsButton.java:37)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at com.jidesoft.plaf.basic.BasicJideButtonListener.mouseReleased(Unknown Source)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.desktop/java.awt.Component.processEvent(Unknown Source)
at java.desktop/java.awt.Container.processEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicTableUI$Handler.repostEvent(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicTableUI$Handler.mouseReleased(Unknown Source)
at com.jidesoft.swing.DelegateMouseInputListener.mouseReleased(Unknown Source)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.desktop/java.awt.Component.processEvent(Unknown Source)
at java.desktop/java.awt.Container.processEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Caused by: com.inductiveautomation.ignition.common.expressions.ExpressionException: Unsupported inner columnInfo element BestByDate
at com.automation_pros.simaids.expressions.UnionAll.builderFromColumnInfo(UnionAll.java:71)
at com.automation_pros.simaids.expressions.UnionAll.execute(UnionAll.java:112)
at com.inductiveautomation.ignition.client.expressions.ClientDynamicDispatchFunction.execute(ClientDynamicDispatchFunction.java:43)
at com.inductiveautomation.ignition.common.expressions.FunctionExpression.execute(FunctionExpression.java:69)
at com.inductiveautomation.factorypmi.application.binding.ExpressionPropertyAdapter.runExpression(ExpressionPropertyAdapter.java:83)
... 102 more
Ignition v8.1.35 (b2023120517)
Java: Azul Systems, Inc. 17.0.8
For context, I am using this in Vision. The reason I am turning a perfectly acceptable map back into a Dataset here is that I would like to store the result of this expression in a custom property. This way it can be accessed multiple times without the need to query across the GAN every time (The function is located on a remote server for other reasons). However, I do not know of any way to store a map in a custom property in Vision without also having all column values converted to strings.
Replace your first asList()
with an asMap()
. When using lists to supply column info, each pair must be a nested list.
FWIW, using objectScript()
completely breaks the justification for my expression functions. Consider just processing the return value locally in your script.
Is there any reason why
vvm = system.perspective.viewVarMap() | ||
---|---|---|
vvm.tagQueryResult = retv |
returns "AttributeError: 'com.automation_pros.simaids.persist.BindableVarMap' object has no attribute 'tagQueryResult' " for Ignition 8.1.43, but works fine in 8.1.42 ?
Are you sure you are using the latest version of my module in both versions of Ignition? And rebooted, actually. That bug was in a persistent jar that can only be replaced by restarting the service.
I tried to restart the ignition service, but same result. Same version of the modules, different versions of igntion 8.1.42 (running in docker) <--Working and 8.1.43 (running on windows) <---Not working
Solved, My bad, restarted the module, and now its working
Hey Phil, apologies if you've already answered this, but can I do the equivalent of ','.join(map(str, [10,20,30]))
with your toolkit expression functions? And just in case, what about "','".join(map(str, [10,20,30]))
?
As of v8.1.8:
groupConcat(
forEach(
asList(10, 20, 30),
stringFormat("%s", it())
),
","
)
Adjust to suit.
For posterity, I'm pretty sure bare groupConcat
should just work:
groupConcat(
asList(10, 20, 30),
","
)
Assuming asList
spits out a regular java.util.List
.
asList()
produces an ArrayList
, so yes. groupConcat()
stringifies the elements of the list? (I did not test.)
Yes, using Objects.toString
, using empty string for null inputs.
Automation Professionals is pleased to announce a BETA release of its Integration Toolkit, with many new functions.
For Ignition v8.1+: v2.0.20.242841644
New/Updated Expression functions:
New/Updated Scripting functions:
Only lightly tested.
Edit: Survived some weeks with a client under heavy use. I consider this production grade, now.