Read/Write and Clear from an Array Tag (integer array)

Based on this post,

This is how you would read values from an Integer Array Tag:

tagValues = system.tag.readBlocking(tagPath)
arrayTag = tagValues[0].value
for value in arrayTag:
	print value

But how would you write (append) values to the next available element in the Array?
How would you clear all the values from this Array tag (so that I can start adding values starting fromthe fist element)?

v = system.tag.readBlocking("[default]TestArray")[0].value
print v

# append
v_append = [i for i in v]
v_append.append(42)

system.tag.writeBlocking(["[default]TestArray"], [v_append])
print system.tag.readBlocking("[default]TestArray")[0].value

# clear
system.tag.writeBlocking(["[default]TestArray"], [[]])
print system.tag.readBlocking("[default]TestArray")[0].value

# set back to [1,2,3]
system.tag.writeBlocking(["[default]TestArray"], [[1, 2, 3]])
print system.tag.readBlocking("[default]TestArray")[0].value

result:

array(java.lang.Integer, [1, 2, 3])
[Good]
array(java.lang.Integer, [1, 2, 3, 42])
[Good]
array(java.lang.Integer)
[Good]
array(java.lang.Integer, [1, 2, 3])
>>> 
1 Like

Thank you SO MUCH!

Hi Kevin, I have another question.

This is what I am trying to do... In postgresql, is the query I am doing where the Col named Good_Parts takes an integer Array. So in PGAdmin, the following would be the correct sintax :

INSERT INTO oee_history ("Good_Parts")
       VALUES ( '{0,1,2,3,4,0,1,2,3,4,1,2,3,4,5,6}' );

Using the Ignition Script Console, this is also a correct sintax which works for me by reading the integer array type of tag:

v = system.tag.readBlocking("[default]TestArray")[0].value
Col1 = "\"Good_Parts\""
system.db.runPrepUpdate("INSERT INTO oee_history ("+Col1+") VALUES (?);", [v], "DatabaseConnection")

However, when I try to insert to the database an array of integers I created using a list, it does not work... how can I convert the list type to an integer array type?

The following code does not work, how can I make it work with a list in the Script Console?

# I already tried  using the following lists (list1, list2, list3, list4) but none of them work so far
list1 = [0,1,2,3,4,0,1,2,3,4,1,2,3,4,5,6] 
list2 = "\'{0,1,2,3,4,0,1,2,3,4,1,2,3,4,5,6}\'"
list3 = "{0,1,2,3,4,0,1,2,3,4,1,2,3,4,5,6}"
list4 = '{0,1,2,3,4,0,1,2,3,4,1,2,3,4,5,6}'
system.db.runPrepUpdate("INSERT INTO oee_history ("+Col1+") VALUES (?);", [list1], "Historian")

And these are some of the errors I am getting in the script console:

#Error for List1
Caused by: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: Unable to decode arguments

#Error for List2
Caused by: org.postgresql.util.PSQLException: ERROR: column "Good_Parts" is of type integer[] but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
Caused by: java.io.InvalidClassException: failed to read class descriptor

#Error for List3
Caused by: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: SQL error for "INSERT INTO oee_history ("Good_Parts") VALUES (?);": ERROR: column "Good_Parts" is of type integer[] but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.

#Error for List4
Caused by: org.postgresql.util.PSQLException: ERROR: column "Good_Parts" is of type integer[] but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.

Does it work if you convert the list into a jarray first?

v = [0,1,2,3]
import jarray
from java.lang import Integer
v_arr = jarray.array(v, Integer)

To be honest I'm not even sure if array columns are supported or not, but see if this gets you to an error somewhere further.

1 Like

It does work!! Thank you very much for your great help!!

2 Likes

Ooooo! Passing arrays to PostgreSQL didn't work in the past. I wonder when this changed. But this could be a game-changer for those needing to use the IN (....) clause with a variable list of elements.

1 Like

I was surprised to see it work, because this function isn't using the setArray API, but it seems to work anyway :man_shrugging:

I'm admittedly pretty unfamiliar with this stuff. Maybe it depends on the JDBC driver implementation in some way.

2 Likes

I have reading and writing a float array but system.tag.writeBlocking giving Good as a result and system.opc.writevalue giving Error_configuration , so values are not written here in OPC so is there any mistake in my code??

v = system.tag.readBlocking("[Sample_Tags]TO_LVF_CIT_N")[0].value
print v
print(v[1])

v[2] = 125.65
print("==============")
print(v[2])
print v


print("##############")
w = system.tag.writeBlocking("[Sample_Tags]TO_LVF_CIT_N", [v])
print w

print("$$$$$$$$$$$$$$$$")
o = system.opc.writeValue("[Sample_Tags]TO_LVF_CIT_N", [v])
print o

Same happens this code while I use print statement and time.sleep(0.5) where writing is not happens , so below is my input as well as output

Input:

import time

opcTagPath = "[Sample_Tags]TO_LVF_CIT_N"
elementIndex = 2  # Replace with the desired index
newValue = 125.65  # Replace with the desired value

# Read the current values from the OPC tag
currentValues = system.tag.readBlocking([opcTagPath])[0].value

# Ensure the currentValues is a list (convert from tuple if needed)
if not isinstance(currentValues, list):
    currentValues = list(currentValues)

# Print the current values before the update
print("Before Update - OPC tag: {}, Current Values: {}".format(opcTagPath, currentValues))

# Update the specific element in the list based on the provided elementIndex
currentValues[elementIndex] = float(newValue)

# Print the updated values before writing
print("Updated Values (Before Write) - OPC tag: {}, Updated Values: {}".format(opcTagPath, currentValues))

# Write the updated list back to the OPC tag
system.tag.writeBlocking([opcTagPath], [currentValues])

# Print the confirmation message
print("Write Successful - OPC tag: {}, New Value: {}".format(opcTagPath, newValue))

time.sleep(0.5)
# Attempt to write the updated list using OPC writeValue
try:
    system.opc.writeValue(opcTagPath, currentValues)
    print("OPC Write Successful")
except Exception as e:
    print("OPC Write Error: {}".format(e))

Output:

Jython 2.7.2, executing locally in the Designer.
Press (Ctrl + Space) to activate autocompletion.
>>> 
Before Update - OPC tag: [Sample_Tags]TO_LVF_CIT_N, Current Values: [625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0]
Updated Values (Before Write) - OPC tag: [Sample_Tags]TO_LVF_CIT_N, Updated Values: [625.3499755859375, 625.3499755859375, 125.65, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0]
[Good]
Write Successful - OPC tag: [Sample_Tags]TO_LVF_CIT_N, New Value: 125.65
Error_Configuration
OPC Write Successful
>>>

So what is issue here I exactly dont know also when i see Log console then not any logs generated after execute this script via script console , but when run perspective project then sometime this log occured :
Uncaught Throwable during execution.

Your opcTagPath is actually a TagPath (for use with system.tag.read*/write* functions), not an OPC item address...
For the system.opc.read*/write* functions, you need ACTUAL opc item path, like the one in the Tag definition.

1 Like

Ok , Thanks for correct me for tag writing and opc ua writing , Please see this below image and correct me ,Here I have used readblocking and writeblocking for that specific tag path and then write updated variable(named as o) in opc via system.opc.writeValue and give opcItemPath but it is giving this error
Bad("Bad_EncodingError: Encoding halted because of invalid data in the objects being serialized.")


opcTagPath = "[Sample_Tags]TO_LVF_CIT_N"
# Read the current values from the OPC tag
currentValues = system.tag.readBlocking([opcTagPath])[0].value
print(currentValues)

c1 = currentValues[0]
print("c1",c1)
print(type(c1))

c1 = 631.67
print("updated c1 : ",c1)
print(type(c1))

currentValues[0] = c1
print("changed value : ", currentValues)

o = system.tag.writeBlocking([opcTagPath], [currentValues])
print system.tag.writeBlocking([opcTagPath], [currentValues])

opcServer = "UAS@VLC210203"
itempath = "nsu=https://www.com/S/;s=TO_LVF_CIT.CIT"
system.opc.writeValue(opcServer, itempath, o)

print system.opc.writeValue(opcServer, itempath, o)
print("End")

print("Again read updated values")
currentValues1 = system.tag.readBlocking([opcTagPath])[0].value
print(currentValues1)

Here when I connect my OPC then default values that is coming from OPC in TO_LVF_CIT tag that giving Eroor_TypeConversion , So that I have created new OPC tag named as TO_LVF_CIT_N and select Float Array datatype (while creating this tag) so then I show entries of this TO_LVF_CIT_N tag showing properly because it is no. of values in Float array.:point_down::point_down:

Why are you writing 'o' to opc?
Shouldn't you write 'currentValues'?

Ohh yes, I have to write currentValues


opcTagPath = "[Sample_Tags]TO_LVF_CIT_N"
# Read the current values from the OPC tag
currentValues = system.tag.readBlocking([opcTagPath])[0].value
print(currentValues)

c1 = currentValues[0]
print("c1",c1)
print(type(c1))

c1 = 631.67
print("updated c1 : ",c1)
print(type(c1))

currentValues[0] = c1
print("changed value : ", currentValues)

o = system.tag.writeBlocking([opcTagPath], [currentValues])
print system.tag.writeBlocking([opcTagPath], [currentValues])

opcServer = "UAS@VLC210203"
itempath = "nsu=https://wwwS/;s=TO_LVF_CIT.CIT"
system.opc.writeValue(opcServer, itempath, currentValues)

print system.opc.writeValue(opcServer, itempath, currentValues)
print("End")

print("Again read updated values")
currentValues1 = system.tag.readBlocking([opcTagPath])[0].value
print(currentValues1)

but when i again read that tag then values are not changed on opc server.

This is my output:

>>> 
array(java.lang.Float, [625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0])
('c1', 625.3499755859375)
<type 'float'>
('updated c1 : ', 631.67)
<type 'float'>
('changed value : ', array(java.lang.Float, [631.6699829101562, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0]))
[Good]
Good
Good
End
Again read updated values
array(java.lang.Float, [625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, 625.3499755859375, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0])
>>>

@Swathi_G, please have a look at Wiki - how to post code on this forum. You can fix your earlier posts by clicking on the pencil icon.

Of course not... you're reading back with system.tag.readBlocking([opcTagPath])[0].value...
It'll take time, which is defined in the TagGroup for this tag to show changed value...

1 Like

sorry not understand exactly..

System.tag.readBlocking and system.tag.writeBlocking reads and writes to the Ignition tag database. Write back to the actual OPC Device are per the setup for that tag group and particular device.

So even after you have directly written to the OPC device, you still have to give the Ignition tag database time to see that write and refresh the data in the tag database.

If you want to check if the value from a system.opc.writeValue is successful, and not use the status returned, then you have to use the system.opc.readValue to get the data directly from the PLC.

1 Like

Ok so when I read data from OPCUA via system.opc.readValue(opcServer, itempath)
then it will give this output
[[Ljava.lang.Double;@547d51dc, Good, Mon Dec 11 19:17:38 IST 2023 (1702302458529)]

But I have one question regarding this time that you told how much time it will take to write data back in OPC tag, because I refresh my tag browser but 1st element of that array that I have updated is not changed, I run this script via Script Console

The actual time is based on the tag group that this tag is in. Take a look there to see what the settings are.

Ok where can I see this? In tag editor?