From 9733f2405c19903f3eb844d9a07c7bde07dadb3e Mon Sep 17 00:00:00 2001 From: esmith1729 <131008854+esmith1729@users.noreply.github.com> Date: Tue, 6 May 2025 10:38:22 +0100 Subject: [PATCH 1/4] Create OPCUA.cmd Add file for general OPCUA knowledge --- doc/specific_iocs/plcs/OPCUA.cmd | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/specific_iocs/plcs/OPCUA.cmd diff --git a/doc/specific_iocs/plcs/OPCUA.cmd b/doc/specific_iocs/plcs/OPCUA.cmd new file mode 100644 index 000000000..8dbb2f9bc --- /dev/null +++ b/doc/specific_iocs/plcs/OPCUA.cmd @@ -0,0 +1 @@ +# Security From 17368a66dd08af4e31db645607750f276e2e356a Mon Sep 17 00:00:00 2001 From: esmith1729 <131008854+esmith1729@users.noreply.github.com> Date: Tue, 6 May 2025 10:48:34 +0100 Subject: [PATCH 2/4] Update OPCUA.cmd --- doc/specific_iocs/plcs/OPCUA.cmd | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/specific_iocs/plcs/OPCUA.cmd b/doc/specific_iocs/plcs/OPCUA.cmd index 8dbb2f9bc..8720dece8 100644 --- a/doc/specific_iocs/plcs/OPCUA.cmd +++ b/doc/specific_iocs/plcs/OPCUA.cmd @@ -1 +1,3 @@ -# Security +# OPCUA + + From 5fd8f86ce28f0aea63194c549ae9749f3d8bbe34 Mon Sep 17 00:00:00 2001 From: esmithExperimentControls Date: Thu, 8 May 2025 10:05:02 +0100 Subject: [PATCH 3/4] Add docs for OPC UA and MAPS System --- doc/specific_iocs/plcs/MAPS-Vacuum-System.md | 8 ++ doc/specific_iocs/plcs/OPCUA.cmd | 3 - doc/specific_iocs/plcs/OPCUA.md | 110 +++++++++++++++++++ doc/spelling_wordlist.txt | 5 + 4 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 doc/specific_iocs/plcs/MAPS-Vacuum-System.md delete mode 100644 doc/specific_iocs/plcs/OPCUA.cmd create mode 100644 doc/specific_iocs/plcs/OPCUA.md diff --git a/doc/specific_iocs/plcs/MAPS-Vacuum-System.md b/doc/specific_iocs/plcs/MAPS-Vacuum-System.md new file mode 100644 index 000000000..39e1a9424 --- /dev/null +++ b/doc/specific_iocs/plcs/MAPS-Vacuum-System.md @@ -0,0 +1,8 @@ +# MAPS Vacuum System +MAPS vacuum system is set up as two TPGs communicating via a single OMRON [OPC UA](OPCUA) PLC + +## OPI +As this system is two TPG300s, one to measure the pressure tank, and another for other miscellaneous readings, the OPI for this system is two linking containers to a modified TPG300 OPI. Sunil Patel, the vacuum specialist, made a requirement that TPG (and likely other pressure controllers) cannot have their pressure, nor any other setpoint, set by the OPI. This means that for this OPI, those changes have already been made, and all values are read-only, except for the units which can be set between mbar, Torr, and Pa. + +## Contacts +The main contact for information about this system is the Instrumentation and Control Systems Group, under Tim Carter \ No newline at end of file diff --git a/doc/specific_iocs/plcs/OPCUA.cmd b/doc/specific_iocs/plcs/OPCUA.cmd deleted file mode 100644 index 8720dece8..000000000 --- a/doc/specific_iocs/plcs/OPCUA.cmd +++ /dev/null @@ -1,3 +0,0 @@ -# OPCUA - - diff --git a/doc/specific_iocs/plcs/OPCUA.md b/doc/specific_iocs/plcs/OPCUA.md new file mode 100644 index 000000000..06e88de62 --- /dev/null +++ b/doc/specific_iocs/plcs/OPCUA.md @@ -0,0 +1,110 @@ +# OPC UA +## What is OPC UA +OPC UA is a cross-platform, open-source, IEC62541 standard for data exchange from sensors to cloud applications developed by the OPC Foundation. It is characterised by: + +* Standardized data models freely available for over 60 types of industrial equipment, published by the OPC Foundation via Companion Specifications +* Extensible security profiles, including authentication, authorization, encryption and checksums +* Extensible security key management, including X.509, token and password +* Support for both client-server and publish-subscribe communication patterns +* Communication protocol independent. Mappings to several communication protocols like TCP/IP, UDP/ +IP, WebSockets, AMQP and MQTT are specified +* Initially successful in standardized data exchange with industrial equipment (discrete manufacturing, process manufacturing, energy) and systems for data collection and control, but now also leveraged in building automation, weighing and kitchen equipment and cloud applications +* [Open](https://en.wikipedia.org/wiki/Open_standard) – open-source reference implementations freely available to OPC Foundation members, non members under GPL 2.0 license[2] +* [Cross-platform](https://en.wikipedia.org/wiki/Cross-platform) – not tied to one operating system or programming language +* [Service-oriented architecture](https://en.wikipedia.org/wiki/Service-oriented_architecture) (SOA) +* The specification is freely available on the OPC Foundation website and is split into several parts +to ease implementation, but only OPC UA stack vendors need to read them, end users simply leverage +existing commercial and/or open-source stacks available in all popular programming languages + +More info can be found [here on Wikipedia for a general overview](https://en.wikipedia.org/wiki/OPC_Unified_Architecture), or for a more detailed description from [OPC Foundation](https://opcfoundation.org/about/what-is-opc/). + +## How is authentication handled? +Currently, the IOC does not seem to be able to support encrypted message security policy. It does, however, support “None” security mode, and connecting with a username and password, which also appears to require sending the password encrypted with Basic256 (username and password connection works with None security mode, but does not work if there is no certificate and private key provided via the `opcuaCLientCertificate` option in the `st-common.cmd` or `st.cmd` file, which loads the IOC with some other options. + +Currently, authentication configurations in Windows only seem to work with username and password. This is likely due to functionality missing from the `open62541` library, the open source library that we use in conjunction with `opcua` EPICS module. A username and password is set on the PLC itself, and those values can be read at IOC startup to authenticate, and sent via Basic256 encryption to the PLC to sign in. When implementing/installing onto a new instrument, the `client_private_key.pem`, `cert.txt` (which will need to be edited to reflect current username and password for the target PLC/server), and `OPCUA_01.cmd` should be moved from the Experiment Controls non-public share `OPCUA` folder, to the instrument's configurations area, in a new folder that should be named `opcua`. If done properly, the `opcua` EPICS module should be able to pick up the user name and password, log in to the OPC server properly, and begin a connection. + +## Do any settings in the PLC side need to be adjusted to get communicating properly? +On occasion, a client certificate needs to be trusted manually, from the PLC technician side. However, things *_should_* be set up on our PLCs currently deployed; this step is done in deployment/implementation. A security policy might be set that is not what the IOC is trying to use, if everything else seems fine but you are unable to connect. Lastly, another person might be connected to the server (perhaps testing an IOC or something), and they would need to be kicked off in order for the IOC to communicate properly. Speak with Tim Carter or a member of his team to see if this is the case. + +## Where are instrument-specific configs loaded from +We load instrument specific configs from the $(INSTRUMENT)/configurations/opcua/ folder. This `opcua` folder is created at implementation time, on the `NDX` machine. It should contain a `OPCUA_01.cmd` file, which contains any `DbLoadRecords` calls, and where paths are specified to the `db` files for that `NDX`'s specific `OPCUA` IOC. If an `NDX` is missing an `opcua` folder, create one; if you cannot find it's `OPCUA_01.cmd` file, it _should_ be placed in the Experiment Controls non-public network share, in the `OPCUA` folder, in a folder specific to that `NDX`. For example, `NDXMAPS`'s `OPCUA_01.cmd` file is in `/OPCUA/MAPS_OPCUA/`. + +## Where are instrument-specific DBs defined +Instrument specific `db` files are currently defined in `ioc/master/OPCUA/OPCUA-IOC-01App/Db`. Hence, the `db` files should have somewhat specific names so as to avoid confusion. + + +## Any troubleshooting information (As a support/on call person, things to look out for) +As always, be sure to check the IOC log first, if something isn't working properly. If the IOC has connected properly to the server, the IOC log should print out something like the following: +``` +# namespace 4 urn:OMRON:SomeOpcUaServer:FactoryAutomation + +Structure TPG_Gauge { # binaryEncodingId: ns=4;i=5002 + Float Pressure # mandatory opc:Float + # memberSize=4 alignment=4 padding=0 memSize=4 + Float Lower_Threshold # mandatory opc:Float + # memberSize=4 alignment=4 padding=0 memSize=8 + Float Upper_Threshold # mandatory opc:Float + # memberSize=4 alignment=4 padding=0 memSize=12 + String Measured_Value_Status # mandatory opc:CharArray + # memberSize=16 alignment=8 padding=4 memSize=32 + String Measuring_Circuit_Status # mandatory opc:CharArray + # memberSize=16 alignment=8 padding=0 memSize=48 + String Switching_Function_Assignment # mandatory opc:CharArray + # memberSize=16 alignment=8 padding=0 memSize=64 + String Switching_Function_Status # mandatory opc:CharArray + # memberSize=16 alignment=8 padding=0 memSize=80 + String Filter_Time_Constant # mandatory opc:CharArray + # memberSize=16 alignment=8 padding=0 memSize=96 +}; # alignment=8 memSize=96 8 members +# adding type TPG_Gauge to known types +``` +Which means that the IOC has read data properly from the server and has a good connection. + +You will then see output like this, near the bottom of the IOC log: + +``` +** Session OPC1: (readComplete) getting data for item ns=4;s=Opc_TPG2_Sensor_B2.Measuring_Circuit_Status = "No measuring channel" (String) Good +** Session OPC1: (readComplete) getting data for item ns=4;s=Opc_TPG2_Sensor_B1.Switching_Function_Assignment = "No assignment" (String) Good +** Session OPC1: (readComplete) getting data for item ns=4;s=Opc_TPG2_Sensor_B1.Switching_Function_Status = "Off" (String) Good +** Session OPC1: (readComplete) getting data for item ns=4;s=Opc_TPG2_Sensor_B1.Filter_Time_Constant = "Slow" (String) Good +``` + +If you don't see this sort of read out at the end of the IOC log, you'll know that something has gone wrong, and likely there is a repeated output that signifies attempts to connect to the server. + +An example of BadInternalError IOC output, which can usually be caused by username and password not being read properly, or the paths not being set properly in the `OPCUA_01.cmd` file, looks like this: + +``` +OPC UA: Autoconnecting sessions +Session OPC1: (initClientSecurity) loading client certificate C:/Instrument/Settings/config//configurations/opcua/client_cert.der +Session OPC1: (initClientSecurity) loading client private key C:/Instrument/Settings/config//configurations/opcua/client_private_key.pem +[2025-05-06 08:48:55.699 (UTC+0100)] warn/userland AcceptAll Certificate Verification. Any remote certificate will be accepted. +[2025-05-06 08:48:55.705 (UTC+0100)] info/securitypolicy The Basic128Rsa15 security policy with openssl is added. +[2025-05-06 08:48:55.711 (UTC+0100)] info/securitypolicy The basic256 security policy with openssl is added. +[2025-05-06 08:48:55.716 (UTC+0100)] info/securitypolicy The basic256sha256 security policy with openssl is added. +[2025-05-06 08:48:55.723 (UTC+0100)] info/securitypolicy The Aes128Sha256RsaOaep security policy with openssl is added. +OPC UA session OPC1: cannot open credentials file C +OPC UA session OPC1: credentials file C does not contain settings for Username token (user + pass) or Certificate token (cert + key [+ pass]) +Session OPC1: (setupSecurity) no security configured +[2025-05-06 08:48:55.736 (UTC+0100)] warn/client The configured ApplicationURI does not match the URI specified in the certificate for the SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#None +[2025-05-06 08:48:55.743 (UTC+0100)] warn/client The configured ApplicationURI does not match the URI specified in the certificate for the SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15 +[2025-05-06 08:48:55.751 (UTC+0100)] warn/client The configured ApplicationURI does not match the URI specified in the certificate for the SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#Basic256 +[2025-05-06 08:48:55.759 (UTC+0100)] warn/client The configured ApplicationURI does not match the URI specified in the certificate for the SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256 +[2025-05-06 08:48:55.766 (UTC+0100)] warn/client The configured ApplicationURI does not match the URI specified in the certificate for the SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep +Session OPC1: secure channel state changed from Closed to HelSent +Session OPC1: secure channel state changed from HelSent to AckReceived +Session OPC1: secure channel state changed from AckReceived to OPNSent +[2025-05-06 08:48:55.785 (UTC+0100)] info/channel Connection 1704 | SecureChannel 140237378 | SecureChannel opened with SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#None and a revised lifetime of 600.00s +[2025-05-06 08:48:55.792 (UTC+0100)] info/client Client Status: ChannelState: Open, SessionState: Closed, ConnectStatus: Good +Session OPC1: secure channel state changed from OPNSent to Open +[2025-05-06 08:48:55.801 (UTC+0100)] info/client The initially defined EndpointURL opc.tcp://0.0.0.0:4080is valid for the server +[2025-05-06 08:48:55.810 (UTC+0100)] info/client Rejecting UserTokenPolicy 0 (username) in endpoint 0: configuration doesn't match +[2025-05-06 08:48:55.813 (UTC+0100)] info/client Rejecting endpoint 1: security mode doesn't match +[2025-05-06 08:48:55.818 (UTC+0100)] info/client Rejecting endpoint 2: security mode doesn't match +[2025-05-06 08:48:55.822 (UTC+0100)] error/client No suitable UserTokenPolicy found for the possible endpoints +[2025-05-06 08:48:55.825 (UTC+0100)] info/client Client Status: ChannelState: Closed, SessionState: Closed, ConnectStatus: BadInternalError +Session OPC1 irrecoverably failed: BadInternalError +OPC UA session OPC1: connect service failed with status BadInternalError +``` +This output will often repeat, as the client/IOC continually tries to connect to the server/PLC. + +You'll see that the IOC gets quite close to connecting, as it goes from `Closed` to `HelSent`, or "hello sent", then from `HelSent` to `AckReceived`, meaning it receives an acknowledgement, and then moves to `OPNSent`, sending a message to open the connection, which then fails on configuration mismatch. More information about the [OPC UA Connection protocol can be found here](https://reference.opcfoundation.org/Core/Part6/v105/docs/7.1). \ No newline at end of file diff --git a/doc/spelling_wordlist.txt b/doc/spelling_wordlist.txt index 2d307be69..fcd1bf72e 100644 --- a/doc/spelling_wordlist.txt +++ b/doc/spelling_wordlist.txt @@ -114,6 +114,7 @@ Chakraborty checkboxes checkRelease checkstyle +checksums Chell Chrono Chronus @@ -582,6 +583,8 @@ Omron onboarding Onenote onwards +opc +opcua openjfx openssl openwire @@ -800,6 +803,7 @@ subVI Sudeepta sudo Sumitomo +Sunil Superlogics supermirror supermirrors @@ -859,6 +863,7 @@ TTi Turbotronik TwinCAT txt +ua uA uamps UC From 42d478c224c9e2fff2c445259907c1962cf066a1 Mon Sep 17 00:00:00 2001 From: esmithExperimentControls Date: Tue, 3 Jun 2025 09:25:47 +0100 Subject: [PATCH 4/4] Added clarity, changed headers, --- doc/specific_iocs/plcs/OPCUA.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/doc/specific_iocs/plcs/OPCUA.md b/doc/specific_iocs/plcs/OPCUA.md index 06e88de62..f802285ef 100644 --- a/doc/specific_iocs/plcs/OPCUA.md +++ b/doc/specific_iocs/plcs/OPCUA.md @@ -1,5 +1,5 @@ # OPC UA -## What is OPC UA +## General / What is OPC UA OPC UA is a cross-platform, open-source, IEC62541 standard for data exchange from sensors to cloud applications developed by the OPC Foundation. It is characterised by: * Standardized data models freely available for over 60 types of industrial equipment, published by the OPC Foundation via Companion Specifications @@ -18,22 +18,24 @@ existing commercial and/or open-source stacks available in all popular programmi More info can be found [here on Wikipedia for a general overview](https://en.wikipedia.org/wiki/OPC_Unified_Architecture), or for a more detailed description from [OPC Foundation](https://opcfoundation.org/about/what-is-opc/). -## How is authentication handled? -Currently, the IOC does not seem to be able to support encrypted message security policy. It does, however, support “None” security mode, and connecting with a username and password, which also appears to require sending the password encrypted with Basic256 (username and password connection works with None security mode, but does not work if there is no certificate and private key provided via the `opcuaCLientCertificate` option in the `st-common.cmd` or `st.cmd` file, which loads the IOC with some other options. +## Authentication +### How is authentication handled? +Currently, the IOC does not seem to be able to support encrypted message security policy. It does, however, support “None” security mode, and connecting with a username and password, which also appears to require sending the password encrypted with Basic256 (username and password connection works with None security mode, but does not work if there is no certificate and private key provided via the `opcuaCLientCertificate` option in the `st-common.cmd` or `st.cmd` file, which loads the IOC with some other options, such as IP address, node configuration, namespace address, etc. More information on the EPICS OPC UA module can be found here: [EPICS OPC UA Documentation](https://github.com/epics-modules/opcua?tab=readme-ov-file#documentation). -Currently, authentication configurations in Windows only seem to work with username and password. This is likely due to functionality missing from the `open62541` library, the open source library that we use in conjunction with `opcua` EPICS module. A username and password is set on the PLC itself, and those values can be read at IOC startup to authenticate, and sent via Basic256 encryption to the PLC to sign in. When implementing/installing onto a new instrument, the `client_private_key.pem`, `cert.txt` (which will need to be edited to reflect current username and password for the target PLC/server), and `OPCUA_01.cmd` should be moved from the Experiment Controls non-public share `OPCUA` folder, to the instrument's configurations area, in a new folder that should be named `opcua`. If done properly, the `opcua` EPICS module should be able to pick up the user name and password, log in to the OPC server properly, and begin a connection. +Authentication configurations in Windows only seem to work with username and password. This is likely due to functionality missing from the `open62541` library, the open source library that we use in conjunction with `opcua` EPICS module. A username and password is set on the PLC itself, and those values can be read at IOC startup to authenticate, and sent via Basic256 encryption to the PLC to sign in. When implementing/installing onto a new instrument, the `client_private_key.pem` (which needs to either be generated, or gotten from the appropriate instrument's `OPCUA` folder from the private network shares), `cert.txt` (which will need to be edited to reflect current username and password for the target PLC/server), and `OPCUA_01.cmd` should be moved from the Experiment Controls private network share `OPCUA` folder, to the instrument's configurations area, in a new folder that should be named `opcua`. If done properly, the `opcua` EPICS module should be able to pick up the user name and password, log in to the OPC server properly, and begin a connection. -## Do any settings in the PLC side need to be adjusted to get communicating properly? -On occasion, a client certificate needs to be trusted manually, from the PLC technician side. However, things *_should_* be set up on our PLCs currently deployed; this step is done in deployment/implementation. A security policy might be set that is not what the IOC is trying to use, if everything else seems fine but you are unable to connect. Lastly, another person might be connected to the server (perhaps testing an IOC or something), and they would need to be kicked off in order for the IOC to communicate properly. Speak with Tim Carter or a member of his team to see if this is the case. +## Communication +### Do any settings in the PLC side need to be adjusted to get communicating properly? +On occasion, a client certificate needs to be trusted manually, from the PLC technician side. However, things *_should_* be set up on our PLCs currently deployed; this step is done in deployment/implementation. A security policy might be set that is not what the IOC is trying to use, if everything else seems fine but you are unable to connect. Lastly, another person might be connected to the server (perhaps testing an IOC or something), and they would need to be kicked off in order for the IOC to communicate properly. Speak with Tim Carter or a member of the team, Instrumentation and Control Systems Group, to see if this is the case. -## Where are instrument-specific configs loaded from -We load instrument specific configs from the $(INSTRUMENT)/configurations/opcua/ folder. This `opcua` folder is created at implementation time, on the `NDX` machine. It should contain a `OPCUA_01.cmd` file, which contains any `DbLoadRecords` calls, and where paths are specified to the `db` files for that `NDX`'s specific `OPCUA` IOC. If an `NDX` is missing an `opcua` folder, create one; if you cannot find it's `OPCUA_01.cmd` file, it _should_ be placed in the Experiment Controls non-public network share, in the `OPCUA` folder, in a folder specific to that `NDX`. For example, `NDXMAPS`'s `OPCUA_01.cmd` file is in `/OPCUA/MAPS_OPCUA/`. +## Configuration +### Where are instrument-specific configs loaded from +We load instrument specific configs from the $(INSTRUMENT)/configurations/opcua/ folder. This `opcua` folder is created at implementation time, on the `NDX` machine. It should contain a `OPCUA_01.cmd` file, which contains any `dbLoadRecords` calls, and where paths are specified to the `db` files for that `NDX`'s specific `OPCUA` IOC. If an `NDX` is missing an `opcua` folder, create one; if you cannot find it's `OPCUA_01.cmd` file, it _should_ be placed in the Experiment Controls private network share, in the `OPCUA` folder, in a folder specific to that `NDX`. For example, `NDXMAPS`'s `OPCUA_01.cmd` file is in `/OPCUA/MAPS_OPCUA/`. -## Where are instrument-specific DBs defined +### Where are instrument-specific DBs defined Instrument specific `db` files are currently defined in `ioc/master/OPCUA/OPCUA-IOC-01App/Db`. Hence, the `db` files should have somewhat specific names so as to avoid confusion. - -## Any troubleshooting information (As a support/on call person, things to look out for) +## Troubleshooting As always, be sure to check the IOC log first, if something isn't working properly. If the IOC has connected properly to the server, the IOC log should print out something like the following: ``` # namespace 4 urn:OMRON:SomeOpcUaServer:FactoryAutomation