I had often been disappointed that not all device connection properties for existing devices were easily available through supported scripting (system.device.listDevices()) . I recently had cause to develop a methodology to create/update/remove devices, UDTs (definitions/instances), tags and tag alarms based on an Excel workbook. Without scripted access to device connection properties it was difficult to determine whether a device required an update so I dug in and finally found a way to retrieve all device connection properties.
Disclaimers:
- This methodology is not officially supported in that it uses classes and functions that are not guaranteed to stay consistent between minor/major Ignition versions. However I expect it will continue to work for all future Ignition v8.1.x releases.
- This methodology was developed in Ignition 8.1.50, do not expect it to work in Ignition v8.3.x
- The code provided must run in the Gateway context (run from Gateway message handler, Gateway event script, or Perspective script)
- As far as scripted update of device properties, probably the most advisable option is to read the existing properties for the device, organize it in such a way that it can can be used to create a new device using
system.device.addDevice(), apply whatever modification is needed, then delete/remove the existing device and add a new one with the modified properties.
Credit
This methodology was developed through examination and extrapolation of hints left in other forum posts but none of those threads provided a functioning example. I’ll attempt to leave a list of referenced forum threads here.
- How do I interface with device properties setting?
- How to get all device driver types and driver name by script?
- Connecting to adhoc SQLite database from Jython? - #7 by Kevin.Herron
- Jython Script to read Internal Database using javadocs - #9 by CJ_Johnson
Example Code:
import traceback
def getDeviceConfigurations():
"""Returns a list of dictionaries, each dictionary containing device configuration.
This methodology is not officially supported in that it uses classes and functions
that are not guaranteed to stay consistent between minor/major Ignition versions.
However I expect it will continue to work for all future Ignition v8.1.x releases.
"""
logger = system.util.getLogger("getDeviceConfigurations")
session = IgnitionGateway.get().getPersistenceInterface().getSession()
try:
# Query the Ignition Internal Database for the names of tables containing device connection settings/properties
# It appears these tables end in either "DEVICESETTINGS" or "DRIVERSETTINGS"
# but it is possible some relevant tables have been overlooked.
logger.info("Table Names | performing query...")
sql = "SELECT name FROM sqlite_master WHERE type='table' AND ( name LIKE '%DEVICESETTINGS' OR name LIKE '%DRIVERSETTINGS' )"
flush=True
params=[]
result = session.rawQueryMaps(sql, flush, params)
tableNames = [item["name"] for item in result]
logger.infof("Table Names | Count: %d | Result: %s", len(result), tableNames)
# Query each table for device connection settings/properties
deviceConfigs = {}
for tableName in tableNames:
logger.infof("Table '%s' | performing query...", tableName)
sql = "SELECT * FROM %s" % tableName
flush=True
params=[]
result = session.rawQueryMaps(sql, flush, params)
logger.infof("Table '%s' | Count %d devices | Result: %s", tableName, len(result), str(result))
for deviceConfig in result:
# Determine the device setting ID
# This ID is used to associate the "DEVICESETTINGS" table with the relevant device driver table
# "DEVICESETTINGS_ID" is used in the "DEVICESETTINGS" table
# "DEVICESETTINGSID" is used in the relevant device driver tables
if "DEVICESETTINGS_ID" in deviceConfig:
deviceSettingsId = deviceConfig["DEVICESETTINGS_ID"]
else:
deviceSettingsId = deviceConfig["DEVICESETTINGSID"]
for propertyKey, propertyValue in deviceConfig.items():
logger.infof("Table: %s Key: %s Value: %s", tableName, propertyKey, propertyValue)
if propertyKey in ["DEVICESETTINGSID", "DEVICESETTINGS_ID"]:
continue
else:
# Table "DEVICESETTINGS" contains the standard/common device properties
# Other tobles contains the driver specific device properties
deviceConfigs.setdefault(deviceSettingsId, {})[propertyKey]=propertyValue
for deviceId, deviceConfig in deviceConfigs.items():
logger.infof("Device ID: %d | Name: %s | Config: %s", deviceId, deviceConfig["NAME"], deviceConfig)
return deviceConfigs.values()
except:
logger.error(traceback.format_exc())
raise
finally:
session.close()
Bonus:
Found out late in the game that the Ignition gateway provides a URL (http://localhost:8088/web/status/sys.internaldb) with interface that can be used to query the internal database.