bkuner / opcUaUnifiedAutomation

EPICS opcUa device support with Unified Automation C++ based client sdk.
Other
0 stars 4 forks source link

How to specify access an S7-1500 OPC UA output bit variable? #42

Closed Kamforka closed 6 years ago

Kamforka commented 6 years ago

I'm using the Python package opcua to test OPC UA communication with an S7-1500 PLC.

I have an output bit called "Outputbit1" in my PLC, and I can successfully access it using the opcua.Client.get_node() method the following way:

import opcua
client = opcua.Client('<opc.tcp-url>')
client.connect()
bit = client.get_node('ns=3;s="Outputbit1"')

However I can't seem to achieve the same result using the opcUa package with EPICS.

I've set up a simple db file with the following contents:

record(bo, "Outputbit1"){
  field(TSE, "-2")
  field(DTYP, "OPCUA")
  field(OUT, "@3,\"Outputbit1\"")
}

and my st.cmd file looks like this:

#!../bin/linux-x86_64/OPCUAIOC

cd ..
epicsEnvSet IOC OPCUAIOC
dbLoadDatabase "dbd/OPCUAIOC.dbd",0,0
${IOC}_registerRecordDeviceDriver pdbbase

# S7-1500 OPC UA
drvOpcuaSetup("opc.tcp://192.168.179.137:4840","","",0)
dbLoadRecords("testIocApp/opcuas7.db")

opcuaDebug(1)
setIocLogDisable 1
iocInit
opcuaDebug(0)
opcuaStat(0)

Then from the directory testTop/testIocApp I execute the command below:

../bin/linux-x86_64/OPCUAIOC st.cmd.OPCUAIOC

After that the ioc shell starts without any errors:

Starting iocInit
############################################################################
## EPICS R3.16.1
## EPICS Base built Oct 19 2017
############################################################################
OpcUaSetupMonitors Browsepath ok len = 0
DevUaSubscription::createMonitoredItems

Add monitored items to subscription ...
iocRun: All initialization complete
opcuaDebug(0)
opcuaStat(0)
OpcUa driver: Connected items: 1
epics> 
***************************************************
 The OPC UA client SDK is running in demo mode.
 Communication will be stopped in 60 minutes.
***************************************************
dbl
Outputbit1

But then from another terminal using caget, caput or camonitor I cannot retrieve nor modify the value of Outputbit1, can you help me guide into the right way of doing this?

ralphlange commented 6 years ago

Minor thing: dbLoadRecords("db/opcuas7.db") to load from the database file install directory (not the source), but in your setup your line works, too.

Are you sure you are not missing a part of the name? On my 1500 (using TiA-Portal) the string id has a PLC part and a DB part before the variable name, e.g. field(INP, "@3,\\"PLC_1\\".\\"Data_block_1\\".\\"BoolOut1\\"")

Kamforka commented 6 years ago

According the minor thing you are right, but I leaved as it was, as I'm using the provided examples as a skeleton, so that should be fixed in the future.

Well I'm kinda sure the StringNodeId is fine, as if I change Outputbit1 for example to Outputbit100, then after restarting the IOC I get the following exception:

Add monitored items to subscription ...
   0 Outputbit1 DevUaSubscription::createMonitoredItems failed for node: ns=3;s="Outputbit100" - Status BadNodeIdUnknown

And with Outputbit1 it was not the case.

Any thoughts?

Update: When using the following syntax in Python: client.get_node('ns=3;s="PLC_1"."Outputs"."Outputbit1"') I can access the bit, but when I change the string in the EPICS db to: field(OUT, "@3,\"PLC_1\".\"Outputs\".\"Outputbit1\"") I get the Status BadNodeIdUnknown exception as again.

ralphlange commented 6 years ago

Are you sure your Channel Access connection is working? (Often firewalls are causing CA to fail.)

What does cainfo Outputbit1 say?

Kamforka commented 6 years ago

It returns with the following:

evpuser@ubuntu:~$ cainfo Outputbit1
Outputbit1
    State:            connected
    Host:             192.168.179.135:5064
    Access:           read, write
    Native data type: DBF_ENUM
    Request type:     DBR_ENUM
    Element count:    1
ralphlange commented 6 years ago

Good. So what do caput -n Outputbit1 1 and caget -n Outputbit1 do? (You should use -n = numeric since you did not specify strings for zero and one in your record.)

ralphlange commented 6 years ago

On the OPC-UA layer, you have to make sure you made the variable visible and writable on the 1500.

Kamforka commented 6 years ago

Okay, it looks fine with the -n flag. Thanks!

BTW how should I specify enums in my record to skip the -n flag?

ralphlange commented 6 years ago

In the bo record, that would be the ZNAM and ONAM fields. https://wiki-ext.aps.anl.gov/epics/index.php/RRM_3-14 is your friend. Yes, it applies to 3.14, but 90+% are still true.

Kamforka commented 6 years ago

Got it! Thanks once again for your help!