system.opc.writeValues() --> QualityCode[] : only first object returned

returnQuality = system.opc.writeValues(server, NodeID, newValue)

returnQuality[1].isGood():

throws AttributeError: 'NoneType' object has no attribute 'isGood'

returnQuality[0].isGood():

does not

returnQuality = system.opc.writeValue(server, NodeID[n], newValue[n])
returnQuality.isGood():

does not

https://docs.inductiveautomation.com/display/DOC80/system.opc.writeValues

All nodes are updated, but only one quality object is returned.

Can you share more code? What are the values of NodeID and newValue in this case? I'd have to guess they're just lists with one element each...

only static until I understand more:


NodeID = []
NodeID.append("ns=4;i=169")
NodeID.append("ns=4;i=170")
NodeID.append("ns=4;i=171")

oldQualifiedValue = [] 
oldQualifiedValue.append(system.opc.readValue(server, NodeID[0]))
oldQualifiedValue.append(system.opc.readValue(server, NodeID[1]))
oldQualifiedValue.append(system.opc.readValue(server, NodeID[2]))

newValue = [] 
newValue.append(oldQualifiedValue[0].getValue())
newValue.append(oldQualifiedValue[1].getValue())
newValue.append(oldQualifiedValue[2].getValue())

newValue[0][0] = long(myValue[0])
newValue[1][0] = long(myValue[1])
newValue[2][0] = myValue[2][0:12]

You must be leaving something out or there’s something weird going on with your final reassignment to newValue.

This works fine:

server = "Ignition OPC UA Server"

NodeID = []
NodeID.append("ns=1;s=[sim]_Meta:Writeable/WriteableInteger1")
NodeID.append("ns=1;s=[sim]_Meta:Writeable/WriteableInteger2")
NodeID.append("ns=1;s=[sim]_Meta:Writeable/WriteableInteger3")

oldQualifiedValue = [] 
oldQualifiedValue.append(system.opc.readValue(server, NodeID[0]))
oldQualifiedValue.append(system.opc.readValue(server, NodeID[1]))
oldQualifiedValue.append(system.opc.readValue(server, NodeID[2]))

newValue = [] 
newValue.append(oldQualifiedValue[0].getValue())
newValue.append(oldQualifiedValue[1].getValue())
newValue.append(oldQualifiedValue[2].getValue())

newValue[0] = newValue[0] + 1
newValue[1] = newValue[1] + 1
newValue[2] = newValue[2] + 1

returnQuality = system.opc.writeValues(server, NodeID, newValue)

print returnQuality[0].isGood()
print returnQuality[1].isGood()
print returnQuality[2].isGood()
newValue = [] 
newValue.append(oldQualifiedValue[0].getValue())
newValue.append(oldQualifiedValue[1].getValue())
newValue.append(oldQualifiedValue[2].getValue())

newValue[0][0] = long(myValue[0])
newValue[1][0] = long(myValue[1])
newValue[2][0] = myValue[2][0:12]

I struggle with type. This is the only way I can write without type errors
I am sure I am doing something wrong, but I found an example on a java site and it worked.

print newValue[0]
print newValue[1]
print newValue[2]

results :

array(java.lang.Long,[1L])
array(java.lang.Long,[9L])
array(java.lang.string,[u'SomeText']) 

Either way, the node values are written, I just don't get a quality code back for anything other than the first object of the returned list.

Still works if I write to array values like you are doing and then update just one element.

# ns=1;s=[sim]_Meta:Writeable/WriteableFloat2
# ns=2;s=CTT/Static/All Profiles/Array/Int16Array
server = "Eclipse Milo OPC UA Demo Server"

NodeID = []
NodeID.append("ns=2;s=CTT/Static/All Profiles/Array/Int16Array")
NodeID.append("ns=2;s=CTT/Static/All Profiles/Array/Int32Array")
NodeID.append("ns=2;s=CTT/Static/All Profiles/Array/Int64Array")

oldQualifiedValue = [] 
oldQualifiedValue.append(system.opc.readValue(server, NodeID[0]))
oldQualifiedValue.append(system.opc.readValue(server, NodeID[1]))
oldQualifiedValue.append(system.opc.readValue(server, NodeID[2]))

newValue = [] 
newValue.append(oldQualifiedValue[0].getValue())
newValue.append(oldQualifiedValue[1].getValue())
newValue.append(oldQualifiedValue[2].getValue())

print "newValue before: %s" % newValue

newValue[0][0] = newValue[0][0] + 1
newValue[1][0] = newValue[1][0] + 1
newValue[2][0] = newValue[2][0] + 1

print "newValue after: %s" % newValue

returnQuality = system.opc.writeValues(server, NodeID, newValue)

print "return quality: %s" % returnQuality
print returnQuality[0].isGood()
print returnQuality[1].isGood()
print returnQuality[2].isGood()

Results:

newValue before: [array(java.lang.Short, [2, 0, 0, 0, 0]), array(java.lang.Integer, [2, 0, 0, 0, 0]), array(java.lang.Long, [2L, 0L, 0L, 0L, 0L])]
newValue after: [array(java.lang.Short, [3, 0, 0, 0, 0]), array(java.lang.Integer, [3, 0, 0, 0, 0]), array(java.lang.Long, [3L, 0L, 0L, 0L, 0L])]
return quality: array(com.inductiveautomation.ignition.common.model.values.QualityCode, [Good, Good, Good])
True
True
True

array(com.inductiveautomation.ignition.common.model.values.QualityCode, [Good, None, None])

I get these codes but the writes are completed. Is this a failure of the device to report the write was completed?

I don’t know. This is very strange. Can you capture this write happening on Wireshark?

And/or find the logger for com.inductiveautomation.ignition.gateway.opcua.client.connection.OpcUaConnection and turn it to TRACE level before doing the write again? (and then get me the logs)

Yes, I will try the trace first. Thank you again for the quick response.

The trace doesn’t show much. I get an Index 1 out of bounds error, but it doesn’t say more. I will capture with wireshark when I have time. The values are written correctly, but now all three return values are bad. When I write one value at a time I get good quality. Maybe the device isn’t responding for each or any of the bulk updates.

You can close or hide this thread, as I don’t think it will help anyone else on here.

This means your server is broken in an interesting way I've never seen before. As you guessed earlier, this server is only returning 1 operation result instead of 3. Wireshark will probably confirm this.

1 Like