Gamesa Wind Turbines via Config Files

This plugin will read from the Gamesa OPCUA Server, and send the data to the Ardexa cloud. It can be used to discover data, and also log data to the local device, and send it to the Ardexa cloud. This plugin works by using configuration files to control the names of variables, tables and sources.

Configuration of the Ardexa Edge Device

Ensure you have read a copy of the manufacturer's operating and safety manual. Please review the manual for safety instructions. The Gamesa OPCUA Server is read via this plugin. The Gamesa OPCUA Server data is available from a default TCP Port 21380 on the IP address for which the OPCUA Server is located. Ardexa needs to know the IP address of the OPCUA server. Once the Ardexa edge device is installed on the plant's network, verify that it can "ping" the OPCUA Server using the following command in the REMOTE SHELL (replace the IP address with the IP address of the OPCUA Server):

ping -c 1 192.168.1.2

Also, check that the TCP Port for OPCUA Server is open. You can do this using the REMOTE SHELL, using the nmap command as follows.

nmap -sS -p 21380 192.168.1.2

Authentication

Gamesa OPCUA Servers require the following authentication related credentials for connection:

  1. Auth File. This will be of the form:

Username: {whatever}
Password: {whatever}
  1. The Application URI. This should match the certificate and should be something like: urn:example.org:FreeOpcUa:python-opcua.

  2. The Security String. The security string should be something like: Basic128Rsa15,SignAndEncrypt. BE AWARE OF THE FOLLOWING; in older versions of the plugin, the user had to manually insert the location of the public and private key into the security string. This is no longer required, as the plugin will automatically fill in the security string with the private and public keys, ONLY if they do not already exist.

  3. The Security Suffix. An OPCUA connection string may have a suffix associated with it. For example, OPCUA connection strings may be something like: "opc.tcp://192.168.1.10:21380/WindnetPro, where 21380 is the TCP port. The /WindnetPro at the end is a suffix. The default for this plugin is /WindnetPro, so unless it is different to this, there is no need to change it.

  4. Digital Certificates. Gamesa sites usually require digital certificates to be submitted to the OPCUA Server. The public and private key can be generated as follows. These certificates MUST be given to the OPCUA Server administrator so they can grant permissions based on these new keys.

git clone https://github.com/FreeOpcUa/python-opcua.git
cd python-opcua/examples
cp generate_certificate.sh ....
nano generate_certificate.sh ....
    organizationName = Ardexa
    -days 3550
chmod 755 generate_certificate.sh
    Country Name (2 letter code) [AU]:AU
    State or Province Name (full name) [Some-State]:ACT
    Locality Name (eg, city) []:Canberra
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Ardexa
    Organizational Unit Name (eg, section) []:DEV
    Common Name (e.g. server FQDN or YOUR name) []:gc
    Email Address []:[email protected]

Once this is done, copy the two *.pem files to the directory: /opt/ardexa/config/gamesa-opcua-ardexa, or use the upload button for the private and public keys. Make sure they are uploaded to the correct name. The OPCUA plugin will change the permission of the private key to 0600 (read only by the root user), if this hasn't been done already.

So in summary, the authentication and related items are:

  • --port This is an optional entry denoting the TCP Port of the OPC UA server. It is defaulted to 21380

  • --namespace_index. This is an optional entry only available when using discover. It is the namespace for which to discover variables. It is defaulted to 0

  • --auth_file ... this is the authentication file discussed above.

  • --suffix. This is the suffix, if one exists, as discussed above.

  • --app_uri. This is the Application URI, if one exists, as discussed above.

  • --security_str. This is the Security String, if one exists, as discussed above.

  • --timeout. This is the OPCUA connection timeout. Note that a connection can take longer than the timeout, so long as the initial connection to the OPC UA server is less than the timeout value. The default is 10.0 seconds.

  • --report_connection_time. This is a flag (true/false) on whether reporting on OPC UA connection time is required. See below.

  • --public_key ... The public key

  • --private_key ... The public key

Discovering the OPCUA Tree

A OPCUA Server hosts data in Gamesa OPCUA plants. Data is organised as a tree structure. The OPCUA Server does not have tables like other wind plugins using ODBC. An example hierarchy is shown below.

In order to list the field names, the following command can be executed either on the REMOTE SHELL, or the via the plugin RUN DISCOVERY function. To run a discovery of the tree via the plugin's RUN DISCOVERY function, do the following:

  1. Ensure the the correct credentials for the server have been configured.

  2. Ensure the correct IP address for the OPCUA server.

  3. Select the required namespace. The default is 0.

  4. Select the required Depth. The default is 4.

  5. Select RUN DISCOVERY.

This will then show the available namespaces, and all the objects and fields below the root node. Each NodeID is displayed as something like ns=3;s=Turbine.WEA03. The ns is the namespace, and the s= is the string representation of the node. The output will be something like this:

The equivalent REMOTE SHELL command to view the OPCUA tree is:gamesa_opcua_ardexa discover tree IP_ADDRESS {parameters}. There two key arguments here are:

  1. Select the required --namespace argument. The default is 0.

  2. Select the required --depth. The default is 4.

For example: gamesa_opcua_ardexa discover tree 10.1.2.3 --port 21380 --auth_file /opt/ardexa/config/gamesa-opcua-ardexa/auth_file --app_uri urn:example.org:FreeOpcUa:python-opcua --security_str Basic256Sha256,SignAndEncrypt --private_key /opt/ardexa/config/gamesa-opcua-ardexa/my_private_key.pem --public_key /opt/ardexa/config/gamesa-opcua-ardexa/my_cert.pem --namespace_index 0 --depth 3

Discovering Fields

In order to list all the field names below a node, the following command can be executed either on the REMOTE SHELL, or the via the plugin RUN DISCOVERY function. To run a discovery via the plugin's RUN DISCOVERY function, do the following:

  1. Ensure the the correct credentials for the server have been configured.

  2. Ensure the correct IP address for the OPCUA server.

  3. Select the required node. All the values below this node will be displayed. This will be something like: "ns=3;s=Turbine.WEA03"

  4. Select RUN DISCOVERY.

The output of this command will show all the fields below the ns=3;s=GMS.PGM_1_1 node, along with their data types, units and values. This will be something like:

Here is another example from the ns=3;s=Turbine.WEA01 node:

The equivalent REMOTE SHELL command to view OPCUA tree values is:gamesa_opcua_ardexa discover fields IP_ADDRESS NODE_ID {parameters}. There two key arguments here are:

  1. The IP_ADDRESS is ip address of the OPCUA server

  2. The NODE_ID is node string of the OPCUA server, below which to collect the values. This will be something like: "ns=3;s=Turbine.WEA03"

For example: gamesa_opcua_ardexa discover fields 10.1.2.3 "ns=3;s=Turbine.WEA01" --port 21380 --auth_file /opt/ardexa/config/gamesa-opcua-ardexa/auth_file --app_uri urn:example.org:FreeOpcUa:python-opcua --security_str Basic256Sha256,SignAndEncrypt --private_key /opt/ardexa/config/gamesa-opcua-ardexa/my_private_key.pem --public_key /opt/ardexa/config/gamesa-opcua-ardexa/my_cert.pem

Discovering Data Using Custom Mapping File

The primary purpose of a configuration file driven plugin is to provide as much flexibility as possible when defining what to capture and what to call each field. This plugin is able to read a mapping file to undertaken one or more of the following tasks:

  1. Only collecting required variables and ignoring anything else.

  2. Renaming all or selected variables to something else.

  3. Scaling variables.

  4. Changing units.

  5. Sending data to customised tables and sources in the Ardexa cloud.

The mapping file is a comma separated file containing 7 items as follows:

  1. Ardexa Table. This is the name of the Ardexa table, where the data will be copied.

  2. Ardexa Source. This is the Ardexa source name given to the data.

  3. Ardexa Variable Name. This is the name given to the variable as it will appear in the Ardexa cloud.

  4. OPCUA Node. This is the OPCUA node that holds the variable. This name IS case sensitive. See the output from Discovering Fields

  5. Type. The Ardexa variable type. Can be one of decimal, int, keyword or date

  6. Units. The units if the variable. May be empty.

  7. Scale. The scale of the variable. May be empty

Here is an example of a mapping file:

Note:

  1. Anything starting with # is a comment and can be ignored.

The above mapping file will produce the following output:

The equivalent REMOTE SHELL command to view the mapping file values is:gamesa_opcua_ardexa discover data IP_ADDRESS MAPPING_FILE {parameters}. There two key arguments here are:

  1. The IP_ADDRESS is ip address of the OPCUA server

  2. The MAPPING_FILE is the mapping file. This is described above.

For example: gamesa_opcua_ardexa discover data 10.1.2.3 /opt/ardexa/config/gamesa-opcua-ardexa/full_mapping.csv --port 21380 --auth_file /opt/ardexa/config/gamesa-opcua-ardexa/auth_file --app_uri urn:example.org:FreeOpcUa:python-opcua --security_str Basic256Sha256,SignAndEncrypt --private_key /opt/ardexa/config/gamesa-opcua-ardexa/my_private_key.pem --public_key /opt/ardexa/config/gamesa-opcua-ardexa/my_cert.pem

Discovering Data Using Custom "Per Source" Files

Instead of using a single mapping file (as discussed above), a separate file for each "source" can be used in conjunction with the file system to produce the desired table/source names. If the "mapping file" argument ends with the (exact) name per_source (an empty file with this exact name, path does not matter), then the plugin will recursively look for files in the directory /opt/ardexa/config/gamesa-opcua-ardexa/per-source. The file structure is very similar to that used in /opt/ardexa/logs, where the first directory is the Ardexa Table, and any subsequent directories, plus the file name (minus the extension) will form the Ardexa Source Name. For example, take the following file structure:

This file structure will produce one source (WEA1/turbine1) that will log data to the Ardexa table called test_gamesa_per_source. The contents of the file is the same as the single mapping file, minus the "Table" and "Source Name" fields.

  1. Ardexa Variable Name. This is the name given to the variable as it will appear in the Ardexa cloud.

  2. OPCUA Node. This is the OPCUA node that holds the variable. This name IS case sensitive. See the output from Discovering Fields

  3. Type. The Ardexa variable type. Can be one of decimal, int, keyword or date

  4. Units. The units if the variable. May be empty.

  5. Scale. The scale of the variable. May be empty

Here is an example of two mapping files:

  • turbine1.csv

Note:

  1. Anything starting with # is a comment and can be ignored.

The above "per source" mapping files will produce the following output. Notice the table and source names.

The equivalent REMOTE SHELL command to view the per source mapping file values is:gamesa_opcua_ardexa discover data IP_ADDRESS MAPPING_FILE {parameters}. There two key arguments here are:

  1. The IP_ADDRESS is ip address of the OPCUA server

  2. The MAPPING_FILE argument must end with the name per_source (an empty file with this exact name, path does not matter), then the plugin will recursively look for files in the directory /opt/ardexa/config/gamesa-opcua-ardexa/per-source.

For example: gamesa_opcua_ardexa discover data 10.242.52.99 /opt/ardexa/config/gamesa-opcua-ardexa/per_source --port 21380 --auth_file /opt/ardexa/config/gamesa-opcua-ardexa/auth_file --app_uri urn:example.org:FreeOpcUa:python-opcua --security_str Basic256Sha256,SignAndEncrypt --private_key /opt/ardexa/config/gamesa-opcua-ardexa/my_private_key.pem --public_key /opt/ardexa/config/gamesa-opcua-ardexa/my_cert.pem --required_source "WEA3/turbine3"

Remember that the per-source directory must be created, as follows: mkdir -p /opt/ardexa/config/gamesa-opcua-ardexa/per-source. Then create directories and files as required, and in accordance with the discussion above. Make sure you use the "--required_source" argument to view the required source

"Per Source" Mapping Generator

As discussed above, mapping files allow as much flexibility as possible. There is a very high probability that most of the time, the same OEM input field will need to be to mapped to the same output field name (such as an IEC name), for all the turbines at a site. To assist with this repetitive process, the plugin includes a generate sub-command that will accept a template CSV file, which describes the general mapping and applies it to any turbines that can be automatically discovered. The template file for a per source generate command will look like a "mapping" file discussed above, except that the first 2 columns (table and source) have been removed. This is an example "per source" mapping file:

Note a few things:

  1. The source name must be either {turbine} or {grid}.

  2. The OPCUA Name is the name that will be a partial match for the full OPCUA name. For example the OPCUA Name of ActivePower will match the OPCUA full name of Turbine.WEA01.Turbine.WEA01.ActivePower. Make sure these names match the case, as they ARE case sensitive

The equivalent REMOTE SHELL command to view the per source mapping file values is:gamesa_opcua_ardexa generate IP_ADDRESS MAPPING_FILE NODE_ID TABLE SOURCE {parameters}. There five key arguments here are:

  1. The IP_ADDRESS is the ip address of the OPCUA server

  2. The MAPPING_FILE argument is the template file to use to create the mapping.

  3. The NODE_ID is the node from which to start looking for the turbine parameters.

  4. The TABLE is the table name, which is the sub-directory created below the /opt/ardexa/config/gamesa-opcua-ardexa/per_source path.

  5. The SOURCE will be the filename (and the Ardexa source), created below the /opt/ardexa/config/gamesa-opcua-ardexa/per_source/{TABLE} path.

For example: gamesa_opcua_ardexa generate 10.1.2.3 /opt/ardexa/config/gamesa-opcua-ardexa/oem-to-iec-test_v1.csv "ns=3;s=Turbine.WEA01" "gamesa_table" "turbine1" --port 21380 --auth_file /opt/ardexa/config/gamesa-opcua-ardexa/auth_file --app_uri urn:example.org:FreeOpcUa:python-opcua --security_str Basic256Sha256,SignAndEncrypt --private_key /opt/ardexa/config/gamesa-opcua-ardexa/my_private_key.pem --public_key /opt/ardexa/config/gamesa-opcua-ardexa/my_cert.pem

Running this command will create the following directories and files.

The data can then be discovered using the section titled Discovering Data Using Custom "Per Source" Files above, to display the data

Log

Logging data to the cloud can be enacted via the Ardexa Front End. The equivalent REMOTE SHELL command is:gamesa_opcua_ardexa log {IP_ADDRESS} {PER_SOURCE_FILE or MAPPING FILE} {..arguments}. The IP_ADDRESS is the ip address of the OPCUA server. The MAPPING_FILE argument must ends with the name "per_source" (an empty file with this exact name, path does not matter), then the plugin will recursively look for files in the directory /opt/ardexa/config/gamesa-opcua-ardexa/per-source. Otherwise, if a MAPPING FILE is used, it will use that log data. For example:

Make sure you use the "--required_source" argument to log the required source

Was this helpful?