3

I can't find the correct syntax for assigning a value to a variable using its BrowseName. I am testing with the 'flag1' boolean variable because it is easier to debug. But my goal is be able to write in all variables, including the arrays.

If I try to use the index number it works fine.

import pyOPCClient as opc

client = opc.opcConnect('192.168.5.10')

opc.write_value_bool(client, 'ns=4;s="opcData"."flag1"', True)

client.disconnect()

Here is my function to write boolean

##### Function to WRITE a Boolean into Bool Object Variable - Requires Object Name #####
def write_value_bool(client, node_id, value):
    client_node = client.get_node(node_id)  # get node
    client_node_value = value
    client_node_dv = ua.DataValue(ua.Variant(client_node_value, ua.VariantType.Boolean))
    client_node.set_value(client_node_dv)
    print("Value of : " + str(client_node) + ' : ' + str(client_node_value))

I am getting this error:

PS C:\Users\ALEMAC\Documents\Python Scripts> & C:/ProgramData/Anaconda3/python.exe "c:/Users/ALEMAC/Documents/Python Scripts/opctest.py"
Requested session timeout to be 3600000ms, got 30000ms instead
Traceback (most recent call last):
  File "c:\Users\ALEMAC\Documents\Python Scripts\opctest.py", line 5, in <module>
    opc.write_value_bool(client, 'ns=4;s="opcData"."flag1"', True)
  File "c:\Users\ALEMAC\Documents\Python Scripts\pyOPCClient.py", line 49, in write_value_bool
    client_node.set_value(client_node_dv)
  File "c:\Users\ALEMAC\Documents\Python Scripts\opcua\common\node.py", line 217, in set_value
    self.set_attribute(ua.AttributeIds.Value, datavalue)
  File "c:\Users\ALEMAC\Documents\Python Scripts\opcua\common\node.py", line 263, in set_attribute
    result[0].check()
  File "c:\Users\ALEMAC\Documents\Python Scripts\opcua\ua\uatypes.py", line 218, in check
    raise UaStatusCodeError(self.value)
opcua.ua.uaerrors._auto.BadNodeIdUnknown: "The node id refers to a node that does not exist in the server address space."(BadNodeIdUnknown)

TIA Portal V17 OPC UA - S7-1212

UA Expert Client

AlexMacabu
  • 127
  • 9
  • Your write function has as input argument nodeid not browsename. Use ns=4;i=20 instead. – SFriedl Feb 15 '23 at 05:56
  • Thanks for your reply! But my goal here is to use the name instead of the index... something like "opcData"."flag1" instead of the index number – AlexMacabu Feb 15 '23 at 17:37

3 Answers3

3

I see you use the pyOPCClient package. I´m not sure if this is maintaned anymore (Last Update: 2014-01-09 see here).

You can switch to opcua-asyncio which can address nodes with the browse services like this:

myvar = await client.nodes.root.get_child(["0:Objects",..., "4:flag1"])

And here is the complete example

SFriedl
  • 195
  • 10
  • Thanks so much for the advice! I did know this module and I will try it as soon as I get SiOME to change the identifier from NUMERIC to STRING.! – AlexMacabu Feb 17 '23 at 16:55
  • Why do you want to change the identifier? With this way you use the browsenames / browsepath – SFriedl Feb 17 '23 at 17:30
  • Thanks once again! I tried the above example but I am getting weird readings: – AlexMacabu Feb 22 '23 at 20:32
  • Is there an other error message? – SFriedl Feb 23 '23 at 07:25
  • No error messages, it is working, reading information but apparently, the data needs to be converted somehow – AlexMacabu Feb 23 '23 at 18:12
  • maybe this is the same issues than this here: https://stackoverflow.com/questions/75239562/is-there-a-function-or-method-for-decoding-opc-ua-extension-objects-to-readable/75243577#75243577 – SFriedl Feb 23 '23 at 18:30
  • Thanks a lot for your effort! I was able to work around this by changing the NodeID Type from NUMERIC to STRING following this tutorial: https://support.industry.siemens.com/cs/document/109793221/how-do-you-change-the-node-id-identifier-type-of-the-nodes-in-the-s7-1200-opc-ua-server-from-numeric-to-string-?dti=0&dl=en&lc=nl-NL If you add the Server interface through SiOME and not in TIA Portal it works like a charm! Now I just need to figure it out how to write in user-created data types! – AlexMacabu Feb 23 '23 at 20:58
1

You are using a mix of NodeId and BrowseName. Just Keep the node NodeId

opc.write_value_bool(client, 'ns=4;i=20', True)

To write other datapoint "args" you will also have to find their NodeId.

You can use the OPC UA Service Browse for that.

Camille G.
  • 3,058
  • 1
  • 25
  • 41
  • Thanks for your reply Camille! But my goal is actually use the name instead of the index. I remember using this syntax before ( 'ns=#;s="xxxx"')and working with a different PLC. But I can't figure why... – AlexMacabu Feb 15 '23 at 17:03
0

Apparently the S7-1200 by default, when you create a tag in S7-1200 the NodeID is set to NUMERIC. Looks lik you can change it though, using another software called SiOME. https://support.industry.siemens.com/cs/document/109793221/how-do-you-change-the-node-id-identifier-type-of-the-nodes-in-the-s7-1200-opc-ua-server-from-numeric-to-string-?dti=0&dl=en&lc=nl-NL

AlexMacabu
  • 127
  • 9