mikakaraila / node-red-contrib-opcua

A Node-RED node to communicate OPC UA. Uses node-opcua library.
Other
208 stars 191 forks source link

Read/Write ExtensionObject (data type) between NX102 & PLCnext using OPC UA & REST api. #707

Open Maxime771 opened 2 weeks ago

Maxime771 commented 2 weeks ago

Hi, this is how I try to establish read/write communication for a structure variable between an NX102 & PLCnext.

I am using OPC UA protocol to read a data structure from the NX102 as shown below : My DataType that I want to read/write : MyDataType In UaExpert, we can see the following information : UaExpert_MyDataType In Node-Red, I can read '' staaMCtest '' and its members from the NX102. Node-Red Read MyDataType Using the fonction "Map to PLCnext", I can write each member of staaMCtest to the PLCnext structure : MapToPLCnext In the PLCnext, we can see that the value are correctly written in ''teststruc'' of type MyStruct : PLCnextDataTypeValue I set the variable teststruc as a HMI tag, so it can use the REST data interface. PLCnextRESTapi

Since the value of staaMCtest (NX102) and teststruc (PLCnext) can be change in both PLC, I want to send the value of teststruc back to staaMCtest (NX102) : NodeRedSendBackInfo We can see that the content in the msg payload of ''debug 6" is the same as the content in "debug 1" (showed in previous image)

My issue is writing via the function bloc "Omron NX102 Client Write". I got this error : image

Any ideas how can we solve this issue?

Maxime771 commented 2 weeks ago

Were the Node-RedFlow : [ { "id": "b0d5c20d2c81e15a", "type": "tab", "label": "Flow 1", "disabled": false, "info": "", "env": [] }, { "id": "49cca7a35053b110", "type": "OpcUa-Client", "z": "b0d5c20d2c81e15a", "endpoint": "40fb7f127b35e0f0", "action": "read", "deadbandtype": "a", "deadbandvalue": 1, "time": 10, "timeUnit": "s", "certificate": "n", "localfile": "", "localkeyfile": "", "securitymode": "None", "securitypolicy": "None", "useTransport": false, "maxChunkCount": 1, "maxMessageSize": 8192, "receiveBufferSize": 8192, "sendBufferSize": 8192, "name": "Omron NX102 Client Read", "x": 200, "y": 180, "wires": [ [ "2e8343ce1a45409c", "f0a7e671e6104770" ], [] ] }, { "id": "2e8343ce1a45409c", "type": "debug", "z": "b0d5c20d2c81e15a", "name": "debug 1", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 460, "y": 160, "wires": [] }, { "id": "5c269e11d32f8ade", "type": "inject", "z": "b0d5c20d2c81e15a", "name": "", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "ns=4;s=aaMC_testStructure;datatype=staaMCtest", "payload": "", "payloadType": "date", "x": 100, "y": 100, "wires": [ [ "49cca7a35053b110" ] ] }, { "id": "b9c293015b1d7ff2", "type": "comment", "z": "b0d5c20d2c81e15a", "name": "READ STRUC - From NX102", "info": "\n", "x": 140, "y": 60, "wires": [] }, { "id": "ead8e219006a71bb", "type": "plc-write-variables", "z": "b0d5c20d2c81e15a", "plc_connector": "e6ec980a1af28a84", "vars": "", "var_list": "{\"items\":[]}", "searchbar": "", "x": 350, "y": 340, "wires": [ [ "f0701750cbc2f454", "85728191a581a00b" ] ] }, { "id": "f0a7e671e6104770", "type": "function", "z": "b0d5c20d2c81e15a", "name": "Map to PLCnext", "func": "// @ts-nocheck\n\nresult = msg.payload;\n\nTest= {\n variables: [\n { \"path\": \"Arp.Plc.Eclr/teststruct.testbool\", \"value\": result.testbool, \"valueType\": \"Constant\"},\n { \"path\": \"Arp.Plc.Eclr/teststruct.testreal\", \"value\": result.testreal, \"valueType\": \"Constant\"},\n { \"path\": \"Arp.Plc.Eclr/teststruct.testword\", \"value\": result.testword, \"valueType\": \"Constant\"}\n ]\n };\n \nfor (let i = 0; i <= result.testarrbool.length; i++){\n Test.variables.push({\n \"path\": Arp.Plc.Eclr/teststruct.testarrbool[${i}],\n \"value\": result.testarrbool[i],\n \"valueType\": \"Constant\"\n });\n}\nfor (let i = 0; i <= result.testarrreal.length; i++){\n Test.variables.push({\n \"path\": Arp.Plc.Eclr/teststruct.testarrreal[${i}],\n \"value\": result.testarrreal[i],\n \"valueType\": \"Constant\"\n });\n}\nfor (let i = 0; i <= result.testarrword.length; i++){\n Test.variables.push({\n \"path\": Arp.Plc.Eclr/teststruct.testarrword[${i}],\n \"value\": result.testarrword[i],\n \"valueType\": \"Constant\"\n });\n}\nmsg.payload= Test\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 260, "y": 260, "wires": [ [ "ead8e219006a71bb", "42a2e8fe8de293a0" ] ] }, { "id": "f0701750cbc2f454", "type": "debug", "z": "b0d5c20d2c81e15a", "name": "debug 2", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 540, "y": 320, "wires": [] }, { "id": "42a2e8fe8de293a0", "type": "debug", "z": "b0d5c20d2c81e15a", "name": "debug 3", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 440, "y": 240, "wires": [] }, { "id": "6dd09d901334807d", "type": "comment", "z": "b0d5c20d2c81e15a", "name": "WRITE STRUC - To NX102", "info": "\n", "x": 820, "y": 620, "wires": [] }, { "id": "85728191a581a00b", "type": "plc-read-variables", "z": "b0d5c20d2c81e15a", "plc_connector": "e6ec980a1af28a84", "variables": "Arp.Plc.Eclr/teststruct", "searchbar": "", "x": 430, "y": 420, "wires": [ [ "48ab1a9ec89e0475", "ce23644cf229cfc5" ] ] }, { "id": "48ab1a9ec89e0475", "type": "debug", "z": "b0d5c20d2c81e15a", "name": "debug 4", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 620, "y": 400, "wires": [] }, { "id": "928746d33deacd09", "type": "OpcUa-Client", "z": "b0d5c20d2c81e15a", "endpoint": "40fb7f127b35e0f0", "action": "write", "deadbandtype": "a", "deadbandvalue": 1, "time": 10, "timeUnit": "s", "certificate": "n", "localfile": "", "localkeyfile": "", "securitymode": "None", "securitypolicy": "None", "useTransport": false, "maxChunkCount": 1, "maxMessageSize": 8192, "receiveBufferSize": 8192, "sendBufferSize": 8192, "name": "Omron NX102 Client Write", "x": 780, "y": 560, "wires": [ [ "8a488d631e9bce63" ], [] ] }, { "id": "8a488d631e9bce63", "type": "debug", "z": "b0d5c20d2c81e15a", "name": "debug 5", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 1040, "y": 540, "wires": [] }, { "id": "ce23644cf229cfc5", "type": "function", "z": "b0d5c20d2c81e15a", "name": "Map to NX102", "func": "// @ts-nocheck\n \nresult = msg.payload;\nTest = \n {\n testbool: result.variables[0].value,\n testreal: result.variables[1].value,\n testword: result.variables[2].value,\n testarrbool : [result.variables[3].value,result.variables[4].value,result.variables[5].value,result.variables[6].value,\n result.variables[7].value,result.variables[8].value,result.variables[9].value,result.variables[10].value,result.variables[11].value,result.variables[12].value],\n testarrreal: [result.variables[13].value, result.variables[14].value, result.variables[15].value, result.variables[16].value,\n result.variables[17].value, result.variables[18].value, result.variables[19].value, result.variables[20].value, result.variables[21].value, result.variables[22].value],\n testarrword: [result.variables[23].value, result.variables[24].value, result.variables[25].value, result.variables[26].value,\n result.variables[27].value, result.variables[28].value, result.variables[29].value, result.variables[30].value, result.variables[31].value, result.variables[32].value]\n }\nmsg.payload= Test\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 520, "y": 500, "wires": [ [ "1e9f6f406ec0228b", "928746d33deacd09" ] ] }, { "id": "1e9f6f406ec0228b", "type": "debug", "z": "b0d5c20d2c81e15a", "name": "debug 6", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 780, "y": 480, "wires": [] }, { "id": "40fb7f127b35e0f0", "type": "OpcUa-Endpoint", "endpoint": "opc.tcp://192.168.78.170:4840", "secpol": "None", "secmode": "None", "none": true, "login": false, "usercert": false, "usercertificate": "", "userprivatekey": "" }, { "id": "e6ec980a1af28a84", "type": "plc-connector", "host": "192.168.78.169", "station_name": "axcf2152-pnc", "session_timeout": "20000", "api_version": "v1.4", "auth_required": "false" } ]

mikakaraila commented 2 weeks ago

Hmm, it could be that a value is checked on PLC and it will reject value with statuscode out of range. String too long or some value is smaller/bigger than it will accept...

Maxime771 commented 2 weeks ago

Could it be because Node-Red don't recognize the type of variable aaMC_testStructure? image Strange... because UaExpert see aaMC_testStructure as a ExtensionObject... (like shown in previous images)

Maxime771 commented 2 weeks ago

Nvm I tried an other OPC UA browser and aaMC_testStructure data type is ExtensionObject : image

Maxime771 commented 2 weeks ago

Im even just trying to write some values in aaMC_testStructure and I get BadNodeIdUnknow error.. image image If I change datatype to ''ExtensionObject'' in the fonction staaMCtest I get the same BadOutOfRange error.