node-red-contrib-opcua icon indicating copy to clipboard operation
node-red-contrib-opcua copied to clipboard

OPC UA ExtensionObject Simatic S7-1500 (write value doesn´t work)

Open IbfUwe opened this issue 2 years ago • 21 comments

Hallo I have a problem and hope you can help me. I took the example of writing ExtensionObjects. After I deploy my flows I get following errors if I start the flow:

https://discourse.nodered.org/t/opc-ua-extensionobject-simatic-s7-1500/70375

[ { "id": "8fa81128505f4289", "type": "tab", "label": "Write UDT to PLC", "disabled": false, "info": "" }, { "id": "ca77f5b419768afd", "type": "comment", "z": "8fa81128505f4289", "name": "Test Struktur schreiben", "info": "Type is stored ns=3;i=3010", "x": 140, "y": 80, "wires": [] }, { "id": "0835e18cc1d7b5b2", "type": "OpcUa-Client", "z": "8fa81128505f4289", "endpoint": "a5bf82989af42abf", "action": "build", "deadbandtype": "a", "deadbandvalue": 1, "time": 10, "timeUnit": "s", "certificate": "n", "localfile": "", "localkeyfile": "", "securitymode": "None", "securitypolicy": "None", "folderName4PKI": "", "name": "BUILD EXTENSION OBJ.", "x": 410, "y": 260, "wires": [ [ "16ae60b8ae0a7ad9", "dfd55d99b72414a2" ] ] }, { "id": "3fc4976002f2623a", "type": "OpcUa-Item", "z": "8fa81128505f4289", "item": "ns=3;s=DT_\"udtMaterialIn\"", "datatype": "Extension Object", "value": "", "name": "ScanSettings type", "x": 170, "y": 260, "wires": [ [ "0835e18cc1d7b5b2" ] ] }, { "id": "ee4f1853063073d7", "type": "inject", "z": "8fa81128505f4289", "name": "Client Get ExtensionObject", "props": [], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "x": 150, "y": 160, "wires": [ [ "3fc4976002f2623a" ] ] }, { "id": "36e4395573ce3f98", "type": "function", "z": "8fa81128505f4289", "name": "Set values", "func": "var myvar = {\n \"szAuftragsnummer\": \"S7OpcUaTest\",\n \"szAuftragsnamen\" : \"S7OpcUaTest\",\n \"usiCnt\": \"1\",\n \"usiNo\": \"2\",\n \"rAbfuellgroeße\": \"3.1\",\n \"usiAbfuellmenge\": \"3\",\n \"rSpeedSwingArm\": \"3.3\",\n \"rSpeedMixingScrew\": \"3.4\",\n \"rMischzeit\": \"3.5\",\n \"szName\": \"3.56\",\n \"rMenge\": \"3.7\",\n \"rToleranzAbweichung\": \"3.9\",\n \"usiZufuehrung\": \"23\",\n \"rGrobdosierungSpeed\": \"4.3\",\n \"rUmschaltpunktInhaltsstoff\": \"4.4\",\n \"rFeindosierungSpeed\": \"4.5\",\n \"rRuettelzeitVibration\": \"4.6\",\n \"rRuettelzeitPauseVibration\": \"4.7\",\n \"rRuettelzeitStampfer\": \"4.8\",\n \"rRuettelzeitPauseStampfer\": \"4.9\",\n \"rSpeed22RV105\": \"5.5\",\n \"rSpeed23RV105S\": \"5.6\",\n \"rSpeed22M106\": \"5.7\",\n \"rSpeed22RV108\": \"5.8\",\n \"rSpeedBlower25M103\": \"5.85\",\n \"rSpeedBlower35M103\": \"8.9\"\n};\n\n\n//msg.dataType = \"ExtensionObject\";\n// Merge new values to payload\nObject.assign(msg.payload, myvar);\n\n// NOTE:\n// typeId need to constructExtensionObject\n//msg.topic = 'ns=3;s=DT_\"udtMaterialIn\"';\n//msg.datatype = \"ExtensionObject\";\n//return msg;\n\n//msg.topic = '\"ns=3;s=\"DB_TEST\".\"Inhaltstoff\";datatype=ExtensionObject;typeId=ns=3;s=DT_\"udtMaterialIn\"';\n\n\n// typeId need to constructExtensionObject\nmsg.topic = '\"ns=3;s=\"DB_TEST\".\"Inhaltstoff\";datatype=ExtensionObject;typeId=ns=3;s=DT_\"udtMaterialIn\"';\nreturn msg;\n\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 770, "y": 260, "wires": [ [ "9a244659fad10c15", "c53593d5da38a3ec" ] ] }, { "id": "bf52ca3cb1b2b83d", "type": "debug", "z": "8fa81128505f4289", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "x": 1190, "y": 360, "wires": [] }, { "id": "9a244659fad10c15", "type": "debug", "z": "8fa81128505f4289", "name": "debug 23", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 840, "y": 360, "wires": [] }, { "id": "16ae60b8ae0a7ad9", "type": "debug", "z": "8fa81128505f4289", "name": "debug 28", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 480, "y": 360, "wires": [] }, { "id": "707e5677540ffd13", "type": "debug", "z": "8fa81128505f4289", "name": "debug 29", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 660, "y": 360, "wires": [] }, { "id": "ae695aff9dd5d64a", "type": "catch", "z": "8fa81128505f4289", "name": "", "scope": null, "uncaught": true, "x": 240, "y": 420, "wires": [ [ "145a72ed96ba6f41" ] ] }, { "id": "47673455b4b5628d", "type": "OpcUa-Client", "z": "8fa81128505f4289", "endpoint": "a5bf82989af42abf", "action": "write", "deadbandtype": "a", "deadbandvalue": 1, "time": 10, "timeUnit": "s", "certificate": "n", "localfile": "", "localkeyfile": "", "securitymode": "None", "securitypolicy": "None", "folderName4PKI": "", "name": "", "x": 1160, "y": 260, "wires": [ [ "bf52ca3cb1b2b83d" ] ] }, { "id": "dfd55d99b72414a2", "type": "json", "z": "8fa81128505f4289", "name": "", "property": "payload", "action": "obj", "pretty": true, "x": 610, "y": 260, "wires": [ [ "707e5677540ffd13", "36e4395573ce3f98" ] ] }, { "id": "145a72ed96ba6f41", "type": "debug", "z": "8fa81128505f4289", "name": "debug 30", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 500, "y": 420, "wires": [] }, { "id": "c53593d5da38a3ec", "type": "OpcUa-Item", "z": "8fa81128505f4289", "item": "\"ns=3;s=\"DB_TEST\".\"Inhaltstoff\"", "datatype": "Extension Object", "value": "", "name": "", "x": 960, "y": 260, "wires": [ [ "47673455b4b5628d", "b4ebb219ef325aa3" ] ] }, { "id": "b4ebb219ef325aa3", "type": "debug", "z": "8fa81128505f4289", "name": "debug 33", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 1080, "y": 400, "wires": [] }, { "id": "a5bf82989af42abf", "type": "OpcUa-Endpoint", "endpoint": "opc.tcp://192.168.200.30:4840", "secpol": "None", "secmode": "None", "none": false, "login": false, "usercert": false, "usercertificate": "", "userprivatekey": "" } ]

Please can you help to fix my issue in this flow?

best regards Uwe

IbfUwe avatar Nov 10 '22 06:11 IbfUwe

Sorry, link you provided don´t show anything. I don´t have S7 to test this so I will need debug log.

Which version you are using? Node-opcua contains extension object handling. Error log could tell more.

mikakaraila avatar Nov 10 '22 18:11 mikakaraila

This seems to be same / duplicate that have been reported as issue multiple times. Node-opcua cannot find specific nodeId for the extension object or some sub-variable. We have to wait until Etienne will have time to fix this or somebody will pay (support) him to fix code.

Reported already, look this one: https://github.com/node-opcua/node-opcua/issues/1199

mikakaraila avatar Nov 10 '22 18:11 mikakaraila

Hello, which log do you need and in which directory can I find it?

IbfUwe avatar Nov 10 '22 19:11 IbfUwe

Good morning, I think you meant this file... log.txt

IbfUwe avatar Nov 11 '22 05:11 IbfUwe

Yes, strange those session not activated messages, but this one is coming from the node-opcua: "Cannot find dataType Definition ! with nodeId =ns=2;i=6525"

Can you provide UaExpert screenshots from the dynamic extension object and also the corresponding type from the types?

mikakaraila avatar Nov 11 '22 05:11 mikakaraila

Add them as zip because now there is no screenshots visible above.

mikakaraila avatar Nov 11 '22 06:11 mikakaraila

Did you check yourself this ticket? I cannot see any screenshot or *piz as attachment

mikakaraila avatar Nov 11 '22 10:11 mikakaraila

Ah okay. I sent it by E-Mail. StructDt.zip

Here again...

IbfUwe avatar Nov 11 '22 10:11 IbfUwe

Now I perhaps know what is causing this on node-opcua.

I expect dynamic extension object will browse and read each variable one by one.

AccessLevelEx does not allow reading one by one if I understand it correctly. Have to ask from experts: @erossignon / @AndreasHeine how client can read variables. Nonatomicread and Nonatomicwrite will require to read/write whole structure.

image

mikakaraila avatar Nov 11 '22 10:11 mikakaraila

@mikakaraila to be honest i have never used the nonatimic stuff... i always read/write the whole structure, so its always consistent according to the timestamp! the issue with siemens udt's is that there mostly aren't used as consistent data-points like a robotic frame (x, y, z, A, B, C) which always need to be consistent to define a frame in 3D-Space

AndreasHeine avatar Nov 11 '22 11:11 AndreasHeine

If you (@AndreasHeine) look all issues, there are now 4 similar cases that node-opcua-dynamic-extension-object fails to handle. Could it be related to fact that code tries to read each field separated thus it will fail due Nonatomicread.

mikakaraila avatar Nov 11 '22 11:11 mikakaraila

@mikakaraila i am in homeoffice today... let me test on monday with the s7-1500 on my desk!

AndreasHeine avatar Nov 11 '22 13:11 AndreasHeine

Until now I made a function writing every opc variable seperated. Maybe in future I will make an update when it is working.

IbfUwe avatar Nov 13 '22 11:11 IbfUwe

@mikakaraila finaly ^^

image

so i just used the stuff which was on the test plc... the thing with Siemens's OPC UA Server (S7-1500 @ FW 02.08.03) is that they expose the inner Fields of the ExtensionObjects in the Addressspace as Childnodes (therefore the NonatomicRead)

so you can read the whole structure in one shot (Variable "VBH" from the screenshot above)

image

this should be the most natural way to do it (read/write) to interact with ExtensionObjects

the PLC DataBlock looks like:

(struct nesting) image

for UDT's:

image

image

image

works as well!

image

AndreasHeine avatar Nov 14 '22 13:11 AndreasHeine

Hi There Reading was not a problem Writing the values doesnt work

IbfUwe avatar Nov 14 '22 13:11 IbfUwe

ok i will test that ;)

AndreasHeine avatar Nov 14 '22 13:11 AndreasHeine

ok some insights:

14 Nov 15:49:59 - [error] TypeError: Cannot read properties of undefined (reading 'indexOf')
    at Object.module.exports.build_new_dataValue (C:\Users\andre\.node-red\node_modules\node-red-contrib-opcua\opcua\opcua-basics.js:952:22)
    at write_action_input (C:\Users\andre\.node-red\node_modules\node-red-contrib-opcua\opcua\102-opcuaclient.js:1337:23)
    at OpcUaClientNode.processInputMsg [as _inputCallback] (C:\Users\andre\.node-red\node_modules\node-red-contrib-opcua\opcua\102-opcuaclient.js:581:11)
    at C:\Users\andre\AppData\Roaming\npm\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\Node.js:210:26
    at Object.trigger (C:\Users\andre\AppData\Roaming\npm\node_modules\node-red\node_modules\@node-red\util\lib\hooks.js:166:13)
    at OpcUaClientNode.Node._emitInput (C:\Users\andre\AppData\Roaming\npm\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\Node.js:202:11)
    at OpcUaClientNode.Node.emit (C:\Users\andre\AppData\Roaming\npm\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\Node.js:186:25)
    at OpcUaClientNode.Node.receive (C:\Users\andre\AppData\Roaming\npm\node_modules\node-red\node_modules\@node-red\runtime\lib\nodes\Node.js:485:10)
    at Immediate.<anonymous> (C:\Users\andre\AppData\Roaming\npm\node_modules\node-red\node_modules\@node-red\runtime\lib\flows\Flow.js:831:52)
    at processImmediate (node:internal/timers:464:21)

from what is see in code: https://github.com/mikakaraila/node-red-contrib-opcua/blob/5b38a848f86c1e2913f33eb1075b97ebc05139e3/opcua/opcua-basics.js#L810 switch/case does not contain "ExtensionObject" not sure if it is intentional @mikakaraila

AndreasHeine avatar Nov 14 '22 15:11 AndreasHeine

@mikakaraila maybe its wise to make a different action for writing an ExtensionObject!

  1. : Build the ExtensionObject (session.constructExtensionObject())
  2. : Make the actual write request

AndreasHeine avatar Nov 14 '22 15:11 AndreasHeine

@AndreasHeine do you some test flow that I could use?

BTW: I don´t have S7, so I need to simulate it somehow...

Here is my test flow how extension object can be build and then write: CUSTOM_OBJECT.txt

image

mikakaraila avatar Nov 14 '22 17:11 mikakaraila

sorry for the late reply... unplaned things happen ^^

i am actually able to write!

image

image

flows.zip

the only thing i am not sure about is that we need two client instances/sessions for that!?... would be a huge improvement if its just one instance/session

action: write-extension-object / autodetect if datatype and typeid is present 1: Build the ExtensionObject (session.constructExtensionObject()) 2: Make the actual write request

@IbfUwe

image

i am currently not sure what causes this... can you check if the OPC UA Server is consistent to the DataBlock / UDT Definition in some FW versions you need to compile and load the HW-Config in order to force the OPC UA Server to reload all the changes from the PLC Program!?

AndreasHeine avatar Nov 21 '22 14:11 AndreasHeine

You can always use just one client node. Sorry I was on vacation thus no time to comment.

You just have to use msg.payload.action, here is code snippet that have been in the code:

      // With new node-red easier to set action into payload
      if (msg.payload && msg.payload.action && msg.payload.action.length > 0) {
        verbose_log("Override node action by msg.payload.action:" + msg.payload.action);
        node.action = msg.payload.action;
      }

mikakaraila avatar Nov 28 '22 18:11 mikakaraila

Hello, sorry for the late reply. At the moment, everyone is in the Christmas rush and I won't be able to try them again until next year.

IbfUwe avatar Dec 21 '22 10:12 IbfUwe

Please test with new v0.2.295 as it uses now node-opcua v2.89 that contains fixes to extension objects.

mikakaraila avatar Jan 24 '23 18:01 mikakaraila

Closed due no feedback.

mikakaraila avatar Feb 28 '23 16:02 mikakaraila