Connect Python scripts to Ignition OPC server

Continuing the discussion from reading/Writing OPC tags from a python script outside Ignition:

Hey everyone, I found this old thread about connecting to Ignition's OPC sever and reading/writing tags with external Python scripts. After a bit of testing I thought I'd share my solution here in case it can save anyone some time. One of the reasons why you would use an external script is some Python libraries require C to work (looking at you SFTP), so this is a very basic example below that would allow you to read and write some types of OPC memory tags externally.

Issues:

  • I do not know how to read/write datetime tags. They seem to read the value back as None. A workarounds for this that I've used is to read/write to a string tag and then convert with an expression tag within Ignition.
  • Same as above for datasets. Workaround is creating individual data point tags.

Before you run your script, ,make sure you:

  1. Install the OPC-UA Python library (pip install opcua) first
  2. Expose the Ignition OPC-UA server to external connections (Ignition's OPC UA Server | Ignition User Manual): quickest way is set bind address to 0.0.0.0 and set expose tag providers to true.
  3. Create new credentials to connect to the OPC-UA server with.

Then you can use the below functions in an external script:

from opcua import Client

def read_opc_val(server_url,tag_path):
    client = Client(server_url)
    result = {}
    try:
        client.connect()
        tag = client.get_node(f"ns=2;s={tag_path}").get_data_value()
        result["quality"] = tag.StatusCode
        result["value"] = tag.Value.Value
        result["variant"] = tag.Value.VariantType
        result["dimensions"] = tag.Value.Dimensions
        result["timestamp"] = tag.SourceTimestamp
    finally:
        client.disconnect()
    return result

def write_opc_val(server_url,tag_path,write_val):
    client = Client(server_url)
    try:
        client.connect()    
        client.get_node(f"ns=2;s={tag_path}").set_value(write_val)
    finally:
        client.disconnect()

def write_opc_vals(server_url,tag_path_list,write_val_list):
    client = Client(server_url)
    try:
        client.connect()
        for i, tag_path in enumerate(tag_path_list):
            client.get_node(f"ns=2;s={tag_path}").set_value(write_val_list[i])
    finally:
        client.disconnect()

#####
opc_username = "your username here"
opc_password = "your password here"
server_ip = "ignition server ip here"
opc_port = "your opc port here"  # default = 62541
server_url = f"opc.tcp://{opc_username}:{opc_password}@{server_ip}:{opc_port}/discovery"


# read
tag_path = "[default]folder/tag_name"  # copy tag path here
example_value = read_opc_val(server_url,tag_path)

# write
tag_path = "[default]folder/tag_name"  # copy tag path here
write_val = "your new value"
write_opc_val(server_url,tag_path,write_val)

# write multiple at once
tag_path_list = [
    "[default]folder/tag_name1",  # copy tag path here
    "[default]folder/tag_name2"  # copy tag path here
]
write_val_list = [
    "value 1",
    "value 2"
]
write_opc_vals(server_url,tag_path_list,write_val_list)

If you've read this far, perhaps you can help me with reading/writing to datetime and dataset tags?

I think the timestamps value in a Tag/OPC do not have the same source and work different?
You can however write tags (value, timestamp, Quality etc..) directly using the WebDev module, maybe this is an option?

This is great! But Im having trouble making a connection with the OPC-UA server (getting timeout errors). Could you share some more detail on your Ignition settings?

  • Security - Are you using a security policy (i.e Basic256Sha256)? If so, how are you passing this certificate to Ignition though python?
  • Endpoint Address - opc.tcp://localhost:62541/discovery, is it OK if the port number is the same as other devices connecting to the server? In other words, can multiple devices connect to the OPCUA sever though the same port?