I am creating a python OPC UA client based on opcua-asyncio github (https://github.com/FreeOpcUa/opcua-asyncio) to read values in an instrument that has a server already set up.
My problem lies in reading array values of data type byte or UInt16. What I expect is something similar to the values shown in UaExpert/DataFeed below.
However if I use python client, I get Value = 0 inside each variant object.
val: [Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.UInt16: 5>, Dimensions=None, is_array=False)]
val: [Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False)]
I have tried some other functions as well, with the results below.
import asyncio
import logging
import sys
import common
from asyncua import ua
sys.path.insert(0, "..")
async def main():
client = await common.connectViaUsername()
try:
async with client:
while True:
# Getting a variable nodes
pi_node = client.get_node("ns=1;i=57")
val = await pi_node.read_value()
print("val: ", val)
print("type of val: ", type(val))
att = await pi_node.read_attribute(ua.AttributeIds.DataType)
print("att: ", att)
print("type of att: ", type(att))
print("att value value: ", att.Value.Value)
dataval = await pi_node.read_data_value()
print("dataval: ", dataval)
print("variant type: ", dataval.Value.Value[0].VariantType)
rv = ua.ReadValueId()
rv.NodeId = pi_node.nodeid
rv.AttributeId = ua.AttributeIds.DataType
params = ua.ReadParameters()
params.NodesToRead.append(rv)
result = await pi_node.session.read(params)
print("result: ", result)
print(type(result[0]))
print(type(result[0].Value))
print(type(result[0].data_type))
print(type(result[0].Encoding))
print((result[0].Value))
print((result[0].data_type))
print((result[0].Encoding))
print("node_class: ", await pi_node.read_node_class())
print("att.value: ", await pi_node.read_attribute(ua.AttributeIds.Value))
print("data type: ", await pi_node.read_data_type())
print("array dim: ", await pi_node.read_array_dimensions())
print("data values: ", await pi_node.read_data_value())
print("variant type: ", await pi_node.read_data_type_as_variant_type())
print("_______")
await asyncio.sleep(100)
except ua.UaError as err:
_logger.error(err)
finally:
await client.disconnect()
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO) # configure at info level
_logger = logging.getLogger(__name__)
# filter out the logs from asynua logger
logging.getLogger('asyncua').setLevel(logging.CRITICAL + 1)
# formate log messages with the file path of the log, comment out if not needed
fh = common.configureLogs("logs/OPC Status - InstrumentSensor (Pulse Sensors).log")
_logger.addHandler(fh)
asyncio.run(main())
These are the results of the print statements.
val: [Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False)]
type of val: <class 'list'>
att: DataValue(Value=Variant(Value=NodeId(Identifier=3, NamespaceIndex=0, NodeIdType=<NodeIdType.TwoByte: 0>), VariantType=<VariantType.NodeId: 17>, Dimensions=None, is_array=False), StatusCode_=StatusCode(value=0), SourceTimestamp=None, ServerTimestamp=None, SourcePicoseconds=None, ServerPicoseconds=None)
type of att: <class 'asyncua.ua.uatypes.DataValue'>
att value value: NodeId(Identifier=3, NamespaceIndex=0, NodeIdType=<NodeIdType.TwoByte: 0>)
dataval: DataValue(Value=Variant(Value=[Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False)], VariantType=<VariantType.Variant: 24>, Dimensions=None, is_array=True), StatusCode_=StatusCode(value=0), SourceTimestamp=datetime.datetime(2023, 10, 27, 1, 48, 35, 270000), ServerTimestamp=None, SourcePicoseconds=None, ServerPicoseconds=None)
variant type: VariantType.Byte
result: [DataValue(Value=Variant(Value=NodeId(Identifier=3, NamespaceIndex=0, NodeIdType=<NodeIdType.TwoByte: 0>), VariantType=<VariantType.NodeId: 17>, Dimensions=None, is_array=False), StatusCode_=StatusCode(value=0), SourceTimestamp=None, ServerTimestamp=None, SourcePicoseconds=None, ServerPicoseconds=None)]
<class 'asyncua.ua.uatypes.DataValue'>
<class 'asyncua.ua.uatypes.Variant'>
<class 'asyncua.ua.uatypes.NodeId'>
<class 'int'>
Variant(Value=NodeId(Identifier=3, NamespaceIndex=0, NodeIdType=<NodeIdType.TwoByte: 0>), VariantType=<VariantType.NodeId: 17>, Dimensions=None, is_array=False)
NodeId(Identifier=25, NamespaceIndex=0, NodeIdType=<NodeIdType.TwoByte: 0>)
0
node_class: 2
att.value: DataValue(Value=Variant(Value=[Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False)], VariantType=<VariantType.Variant: 24>, Dimensions=None, is_array=True), StatusCode_=StatusCode(value=0), SourceTimestamp=datetime.datetime(2023, 10, 27, 1, 48, 35, 270000), ServerTimestamp=None, SourcePicoseconds=None, ServerPicoseconds=None)
data type: NodeId(Identifier=3, NamespaceIndex=0, NodeIdType=<NodeIdType.TwoByte: 0>)
array dim: [10]
data values: DataValue(Value=Variant(Value=[Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False), Variant(Value=0, VariantType=<VariantType.Byte: 3>, Dimensions=None, is_array=False)], VariantType=<VariantType.Variant: 24>, Dimensions=None, is_array=True), StatusCode_=StatusCode(value=0), SourceTimestamp=datetime.datetime(2023, 10, 27, 1, 48, 35, 270000), ServerTimestamp=None, SourcePicoseconds=None, ServerPicoseconds=None)
variant type: VariantType.Byte
My thoughts are that the python client is decoding the byte/UInt16 values into int of value 0 as it is unable to print such bytes/UInt16.
Note: I am able to read the arrays of strings/floats without any problems. Below is the example for array of float
[Variant(Value=1002.32, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False), Variant(Value=1002.01, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False), Variant(Value=1002.16, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False), Variant(Value=1002.4, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False), Variant(Value=0.0, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False), Variant(Value=0.0, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False), Variant(Value=0.0, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False), Variant(Value=0.0, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False), Variant(Value=0.0, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False), Variant(Value=0.0, VariantType=<VariantType.Double: 11>, Dimensions=None, is_array=False)]
Is there any way I am able to read the byte/UInt16 array values?
Best regards, opc Beginner