[IALabs] Scripting Module

Scripting Module

Exposes scripting functions to dynamically add/edit/delete devices, database connections, and tags in Ignition.


Current version: 1.0.0
Download link: IA Labs Scripting-module.modl
Cost: This module will be free.
Dependencies: OPC-UA module.


To use:

Simply install the module and call any of the following functions:

Datasource Functions:

system.db.addDatasource(…) - Takes PyArgs, example:

system.db.addDatasource(jdbcDriver="MySQL ConnectorJ", name="MySQL", connectURL="jdbc:mysql://localhost:3306/test", username="root", password="password", props="zeroDateTimeBehavior=convertToNull;")Possible arguments:

jdbcDriver - String, the name of the JDBC driver in Ignition
name - String
description - String
connectUrl - String
username - String
password - String
props - String, extra connection props
validationQuery - String
maxConnections - Integer

system.db.removeDatasource(String dsName)
system.db.setDatasourceEnabled(String dsName, Boolean enabled)
system.db.setDatasourceMaxConnections(String dsName, Integer maxConnections)
system.db.setDatasourceConnectURL(String dsName, String connectURL)

Device Functions

system.device.addDevice(…) - Takes PyArgs, example:system.device.addDevice(driver="controllogix", deviceName="CLX", hostname="10.10.1.10", slotNumber=0)Possible arguments (look at properties and compare against driver, not all props work for every device):

driver - String, Possible drivers:"dairysim", "genericsim", "slcsim", "compactlogix", "controllogix", "micrologix", "plc5", "slc", "modbus", "modbusrtu", "s71200", "s7300", "s7400", "tcp", "udp"
deviceName - String
group - String
browseTimeout - Integer
readTimeout - Integer
writeTimeout - Integer
enabled - Boolean
hostname - String
communicationTimeout - Integer
browseCacheTimeout - Integer
connectionPath - String
disableProcessorBrowse - Boolean
slotNumber - Integer
concurrentRequests - Integer
showStringArrays - Boolean
port - Integer
maxHoldingRegisters - Integer
maxInputRegisters - Integer
maxCoils - Integer
maxDiscreteInputs - Integer
reverseWordOrder - Boolean
zeroBasedAddressing - Boolean
spanGaps - Boolean
allowWriteMultipleRegisters - Boolean
allowWriteMultipleCoils - Boolean
reconnectAfterTimeouts - Boolean
reverseStringByteOrder - Boolean
rightJustifyStrings - Boolean
pduSize - Integer
rackNumber - Integer
cpuSlot - Integer
ports - String
inactivityTimeout - Integer
messageDelimiterType - String
messageDelimiter - String
fieldCount - Integer
fieldDelimiter - String
writebackEnabled - Boolean
writebackMessageDelimiter - String
multicast - Boolean

system.device.listDevices()
system.device.removeDevice(String dsName)
system.device.setDeviceEnabled(String dsName, Boolean enabled)
system.device.setDeviceHostname(String dsName, String hostname)
system.device.refreshBrowse(String dsName) - Only for AB controllers

Tag Functions

system.tag.addTag(…) - Takes PyArgs, example:system.tag.addTag(parentPath="Folder", name="TagName", tagType="OPC", dataType="Int4", attributes={"OPCServer":"Ignition OPC-UA", "OPCItemPath":"[DeviceName]N7:0"})Possible arguments:

parentPath - String
*NOTE: you specify the SQLTag provider name in square brackets at the beginning of the parentPath string. Example: “[myTagProvider]MyTagsFolder”
If the SQLTag provider name is left off then the tag will be added to the default internal provider named “default”.

name - String
tagType - String, Possible types:"OPC", "DB", "UDT_INST"
dataType - String, Possible types:"Int1", "Int2", "Int4", "Int8", "Float4", "Float8", "Boolean", "String", "DateTime", "DataSet"
accessRights - String, Possible types:"Read_Only", "Read_Write", "Custom"
enabled - Boolean
value - Object
attributes - PyDictionary (meta properties), Possible attributes:OPCServer(String.class, ""), OPCItemPath(String.class, ""), OPCWriteBackServer(String.class, ""), OPCWriteBackItemPath(String.class, ""), ScaleMode(Integer.class, 0), RawLow(Double.class, 0d), RawHigh(Double.class, 100d), ScaledLow(Double.class, 0d), ScaledHigh(Double.class, 10d), ClampMode(Integer.class, 0), Deadband(Double.class, .0001), FormatString(String.class, "#,##0.##"), EngUnit(String.class, ""), Tooltip(String.class, null), EngHigh(Double.class, new Double(100)), EngLow(Double.class, new Double(0)), Documentation(String.class, ""), Expression(String.class, ""), ExpressionType(Integer.class, 0), AlertMode(Integer.class, 0), AlertAckMode(Integer.class, 1), AlertSendClear(Integer.class, 1), AlertMessageMode(Integer.class, 0), AlertMessage(String.class, ""), AlertNotes(String.class, ""), AlertDisplayPath(String.class, ""), AlertDeadband(Double.class, 0.0d), LastChange(Date.class, null, false), DriverName(String.class, ""), ScanClass(String.class, "Default"), PollRate(PollingRate.class, new PollingRate()), SQLBindingDatasource(String.class, ""), PrimaryHistoryProvider(String.class, ""), HistoricalDeadband(Double.class, .01), HistoryEnabled(Boolean.class, false), HistoricalScanclass(String.class, "Default Historical"), InterpolationMode(Integer.class, 3), AlertExecEnabled(Boolean.class, true), AlertActive(Boolean.class, false, false), AlertCurrentState(String.class, "", false), AlertCurrentSeverity(Integer.class, -1, false), AlertAcknowledged(Boolean.class, false, false), AlertAcknowledgeUser(String.class, "", false), AlertActiveTime(Date.class, null, false), AlertAcknowledgedTime(Date.class, null, false), AlertClearedTime(Date.class, null, false), AlertTimestampSource(Integer.class, 0), AlertMessageSubject(String.class, ""), HistoryTimestampSource(Integer.class, 0), HistoryMaxAgeMode(Integer.class, 0), HistoryMaxAge(Integer.class, 1), UDTParentType(String.class, ""), ExtendedProperties(PropertySet.class, null), PropertyOverrides(OverrideMap.class, null), UDTMemberUID(String.class, null)
parameters - PyDictionary, used only for UDT instances, contains param for each UDT parameter

system.tag.browseTags(String parentFolder) returns array of BrowseTag, example:tags = system.tag.browseTags("Folder") for tag in tags: print tag.name, tag.path, tag.fullPath, tag.isFolder(), tag.isUDT(), tag.isOPC(), tag.isDB(), tag.typesystem.tag.removeTag(String tagPath)
system.tag.removeTags(String[] tagPath)
system.tag.editTag(…), PyArgs, Possible arguments:

tagPath - String
attributes - PyDictionary - Same as addTag
parameters - PyDictionary - Same as addTag

system.tag.editTags(…), PyArgs, Possible arguments:

tagPaths - String[]
attributes - PyDictionary - Same as addTag
parameters - PyDictionary - Same as addTag

Feedback is encouraged over on the Module Discussion forum.

Updated module to version 1.0.1

Added ability to configure alarm states when adding / editing tags.


Current version: 1.0.1
Download link: IA Labs Scripting-module_1.0.1.modl
Cost: This module will be free.
Dependencies: OPC-UA module.


New optional argument for addTag and editTag called alarmList that is a string. Here is an example of adding a tag with a digital alarm:system.tag.addTag(parentPath="", name="N7_0", tagType="OPC", dataType="Int4", attributes={"OPCServer":"Ignition OPC-UA Server", "OPCItemPath":"[MLX]N7:0", "AlertMode":1, "AlertDisplayPath":"Machine A", "AlertNotes":"Notes for the alert", "AlertAckMode":2}, alarmList="Out of Range;Medium;1.0;1.0;0;;;0.0;SEC$")Example of adding a tag with analog alarm:system.tag.addTag(parentPath="", name="N7_0", tagType="OPC", dataType="Int4", attributes={"OPCServer":"Ignition OPC-UA Server", "OPCItemPath":"[MLX]N7:0", "AlertMode":2, "AlertDisplayPath":"Machine A", "AlertNotes":"Notes for the alert", "AlertAckMode":2}, alarmList="Lo Lo;High;0.0;5.0;0;;;0.0;SEC$Lo;Low;5.0;15.0;1;;;0.0;SEC$Hi;Medium;85.0;95.0;4;;;0.0;SEC$Hi Hi;High;95.0;100.0;0;;;0.0;SEC$")Example of editing a tag:system.tag.editTag(tagPath="N7_0", attributes={"AlertMode":1, "AlertDisplayPath":"Machine A", "AlertNotes":"Notes for the alert", "AlertAckMode":2}, alarmList="Out of Range;Medium;1.0;1.0;0;;;0.0;SEC$")The alarmList property is a string where each alarm state is separated by a $ character. Each individual alarm state has 9 values separated by a ;. Here are the values:

StateName,Severity,LoSP,HiSP,Flags,LoTagPath,HiTagPath,TimeDeadband,TimeDeadbandUnits

If you export a tag in the Ignition designer to a CSV file you will see an example in the “AlarmStates” column.

Hi,

Really nice done… You give me a banana smile with this.
Small add would be great at this time while waiting for the new Alarm system :wink: :

  • be able to have a free severity range [0-FFFF]

Regarding the alarmList properties, could you explain the following :

  • flag definition (I suppose it deals with tag driven alarm)
  • how to set -/+ infinite…

Thank you again for this :wink:

The flag definition has to do with how to deal with the low and high setpoints. It is an integer field where each bit represents a different flag. There are 7 possible flags right now:

bit 0 - low exclusive
bit 1 - low infinite
bit 2 - high exclusive
bit 3 - high infiinite
bit 4 - any change
bit 5 - low driven (by tag)
bit 6 - high driven (by tag)

So if you want the alert to be in alarm if the value is negative infinity and <= 10, the flag would be 2. If the 10 is replaced by a tag the flag would be 66. Hope this helps.

Updated module to version 1.1.0

Added getAlarmStates and getTagAttribute to tag functions
Fixed module to allow key=value argument for gateway side scripts
Fixed NPE system.device.listDevices()


Current version: 1.1.0
Download link: IA Labs Scripting-module_1.1.0.modl
Cost: This module will be free.
Dependencies: OPC-UA module.


Two new functions added to module:

system.tag.getAlarmStates(String tagPath)states = system.tag.getAlarmStates("Path/To/Tag") for state in states: print state.name, state.severity, state.timeDeadband, state.timeDeadbandUnits, state.flags, state.loLimit, state.hiLimit, state.loTagPath, state.hiTagPath
system.tag.getAttribute(String tagPath, String attribute)print system.tag.getAttribute("Path/To/Tag", "AlertMode")The same attributes used for editTag and addTag apply.

:thumb_left:

Exactly what i expected !

Addition of a paramter to recurse browsing inside the sub folder for browseTags function will be cool.

tags = system.tag.browseTags("Folder",1) => recurse

Is there a trick for using the [color=#BF0000]w[/color][color=#BF4000]o[/color][color=#FFBF00]n[/color][color=#40FF40]d[/color][color=#008080]e[/color][color=#0080BF]r[/color][color=#0040BF]f[/color][color=#8000FF]u[/color][color=#8000BF]l [/color]addTag() function to make Client tags too?
Thanks!

Found a workaround. I can create my tags (Expression and SQL) programatically as normal tags first, then export them and change the tagType from a ‘1’ to a ‘2’, and then re-import them as Client tags. I’m sure there is a much better way; by using the proper tagType enumeration perhaps?

We finally have upgraded the scripting module to work for Ignition 7.6. You can download the new version here:

marketplace.inductiveautomation. … oduleId=46

The new version is 1.6.0 and includes the following changes:


Added ability to override UDT instances in addTag and editTag.
Added recursion, filtering, and sorting to browseTags.
The function getAlarmStates now returns an array of TagAlarmDefinition.
Works with the new alarming configurations.
Fixed the bug where alarm states get removed when editing tag.
Added ability to get data type from the browseTags function.


Documentation is included in the module. Once you install the module you will see a “View Documentation” link to the right of the module.

Support will still be handled through this forum.

[quote=“Dustin.Schroll”]Found a workaround. I can create my tags (Expression and SQL) programatically as normal tags first, then export them and change the tagType from a ‘1’ to a ‘2’, and then re-import them as Client tags. I’m sure there is a much better way; by using the proper tagType enumeration perhaps?[/quote]You can’t make client tags with this module so that is best workaround.

the recursive option “stop” on UDT type, when an UDT contain other UDT.
tags = system.tag.browseTags(parentPath=“Batterie_01”, recursive=1)

Is it possible to improve the recursive option for the browseTags function in order browse inside all UDT contained into other UDT ?
:prayer:

I will add a request in for that.

for the browse tag function, we have ASC or DESC order, can we have an option for the native order displayed in the designer tag’s tree.

Will do.

Thanks travis :thumb_left:

Any Idea for the date of the next release of the Scripting Module ?

I am working on it right now. I will have an update today.

Ok there is now a new update for the IA labs scripting module. You can download it on the marketplace:

marketplace.inductiveautomation. … oduleId=46

Here is the changelog:

  • system.tag.browseTags function now recurses UDT tags

  • New native sort order on browseTags function

  • Fixed bug that didn’t allow multiple overrides on a single tag withing a UDT

  • Added new system.opc.browse function to browse the OPC servers

  • Added system.db.runSFPrepUpdate and system.db.runSFUpdateQuery to run inserts, updates, and deletes through the store and forward system in scripting.

  • Added new OPC browse function to the expression language. Simply bind a tree view component to an expression “browse()”

  • Added new tag browse function to the expression language. Simply bind a tree view component to an expression “browseTags()”

I’ve upgrade from IA Script module 1.6.1 to 1.6.3 (b13).

num = event.source.parent.parent.Num folder = event.source.parent.getComponent('DropdownFolder').selectedStringValue tags = system.tag.browseTags(parentPath="Simulink_" + str(num) + "\\" + folder, recursive=1)

browseTags function return an error :

[quote] Traceback (most recent call last):
File “event:actionPerformed”, line 6, in
com.inductiveautomation.ignition.client.gateway_interface.GatewayException: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: TagFunctionsImpl.browseTags does not have the @KeywordArgs annotation.
caused by GatewayException: TagFunctionsImpl.browseTags does not have the @KeywordArgs annotation.
caused by IllegalArgumentException: TagFunctionsImpl.browseTags does not have the @KeywordArgs annotation.

Ignition v7.6.2 (b2368)
Java: Oracle Corporation 1.7.0_21[/quote]

I’ve probably miss a new parameter but I don’t find in the module documentation ?

I would like to use the “native sort order”, could you give an example forthe synthax please ?

mazeyrat, are you still have this problem?

To sort native just put “,sort=NATIVE” as an argument.

I've tried with sort="NATIVE"
for example in my script :
system.tag.browseTags(parentPath="Param", recursive=1,sort="NATIVE")

I always have the same error :

the same error is produce with :
tags = system.tag.browseTags(parentPath="")

Any idea ?