# OPC DA

{% hint style="danger" %}
The OPC DA protocol may require root permissions in some constellations. If you experience problems with running this protocol, please make sure to install your service on an agent with root permissions as described in [agent orchestration](https://docs.cybus.io/1-10-0/documentation/agents).
{% endhint %}

The **OPC Data Access** (OPC DA) specification is an older protocol specification for real-time data from PLCs and devices, but nowadays this is mostly being superseded by [OPC UA](https://docs.cybus.io/1-10-0/documentation/industry-protocol-details/opc-ua).

In OPC DA, the endpoints are called *tags* and are referenced to by plain strings.

Endpoints can either refer to one single tag, using the property `tag`, or multiple tags in one network query, using the property `tags`.

Currently read, write and subscribe operations are possible.

Additionally, browsing all available data is available, too, by using the property `browse` and sending a message to the `req` sub-topic of this endpoint.

[Connection Properties](https://docs.cybus.io/1-10-0/documentation/industry-protocol-details/opc-da/opcdaconnection)

[Endpoint Properties](https://docs.cybus.io/1-10-0/documentation/industry-protocol-details/opc-da/opcdaendpoint)

## Input Format

To write data to a particular tag, first you need to define a write endpoint with a `tag` and `type` properties defined.

You can see an example of such endpoint on the provided commissioning file below.

Once you have a proper endpoint, you will need to send the following message with the value you want to write to the `/set` sub-topic of the endpoint, i.e. if there is an endpoint named *myEndpoint*, you need to send a message to the topic `myEndpoint/set` with the following payload:

{% code lineNumbers="true" %}

```yaml
{ 'value': 228736 }
```

{% endcode %}

### Output Format

If data is read from OPC DA the output will be provided as JSON object

{% code lineNumbers="true" %}

```yaml
{ 'timestamp': '<timestamp as given from OPC DA>', 'value': 'value' }
```

{% endcode %}

The *timestamp* as given from OPC DA is usually given in ISO 8601 form, which is a string of the following form: Year-Month-Date, then a `T` separator, followed by hour:minutes:second, followed by a period, and the milliseconds, and a `Z` suffix. Example: `2024-02-15T15:57:36.278Z`

The *value* is in one of two forms, depending on whether this endpoint requested a single `tag` or multiple `tags`.

If a single tag was requested, the value is just the literal value of the tag, such as an integer number. Example:

{% code lineNumbers="true" %}

```yaml
{ 'timestamp': '2021-11-15T16:12:22.835Z', 'value': 58.420013427734375 }
```

{% endcode %}

If multiple tags were requested, the value is a JSON object with the tag names as keys, and the tag’s values as values. Example:

{% code lineNumbers="true" %}

```yaml
{ 'timestamp': '2022-04-15T16:12:23.679Z', 'value': { 'Triangle Waves.Int4': 24690, 'Triangle Waves.Real4': 63.50001525878906 } }
```

{% endcode %}

## Browsing the tags

When intending to explore the available tags, the `browse` property of the endpoint is useful. To use this, define a `read` endpoint with the property `browse: 'flat'` as the only addressing property. (Alternatively, `browse: 'tree'` can be used, too.) To browse the tag list, send an empty MQTT message to the topic of the endpoint but with the suffix `/req` (“request”). The Connectware will run the browsing and return the result on the endpoint topic with the suffix `/res`.

For flat browsing, the result value is an array of strings, which are just the tag names. Example:

{% code lineNumbers="true" %}

```yaml
{
    'timestamp': '2022-04-15T16:12:23.679Z',
    'value':
        ['@ClientCount', 'Bucket Brigade.ArrayOfReal8', 'Bucket Brigade.ArrayOfString', 'Bucket Brigade.Boolean', 'Bucket Brigade.Int1', 'Bucket Brigade.Int2'],
}
```

{% endcode %}

For tree browsing, the result value is a JSON object tree structure representing the tag tree on the server. Example:

{% code lineNumbers="true" %}

```yaml
{
    'timestamp': '2022-04-15T16:12:23.679Z',
    'value':
        {
            '@ClientCount': '@ClientCount',
            'Simulation Items':
                {
                    'Bucket Brigade':
                        {
                            'ArrayOfReal8': 'Bucket Brigade.ArrayOfReal8',
                            'ArrayOfString': 'Bucket Brigade.ArrayOfString',
                            'Boolean': 'Bucket Brigade.Boolean',
                            'Int1': 'Bucket Brigade.Int1',
                            'Int2': 'Bucket Brigade.Int2',
                        },
                },
        },
}
```

{% endcode %}

## Service Commissioning File Example

{% file src="<https://3336740149-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl5qEJXpPlZtQMoQkkm1p%2Fuploads%2Fgit-blob-2564577fc7e6e44b3b1968adde71221f898249f4%2Fopcda-example.yml?alt=media>" %}

{% code title="opcda-example.yml" lineNumbers="true" %}

```yaml
---
description: >

    Accessing an OPC DA server

metadata:
    name: Using OPC DA Server
    version: 1.0.0
    icon: https://www.cybus.io/wp-content/uploads/2019/03/Cybus-logo-Claim-lang.svg
    provider: cybus
    homepage: https://www.cybus.io

parameters:
    opcdaHost:
        type: string
        description: Hostname or IP of the OPC DA server
        default: 192.168.0.1

    opcdaUser:
        type: string
        default: cybus

    opcdaPass:
        type: string
        default: PASSWORD

    initialReconnectDelay:
        type: integer
        default: 1000

    maxReconnectDelay:
        type: integer
        default: 30000

    factorReconnectDelay:
        type: integer
        default: 2

resources:
    opcdaConnection:
        type: Cybus::Connection
        properties:
            protocol: Opcda
            connection:
                host: !ref opcdaHost
                username: !ref opcdaUser
                password: !ref opcdaPass
                domain: 'WORKGROUP'
                classId: 'F8582CF2-88FB-11D0-B850-00C0F0104305'
                connectionStrategy:
                    initialDelay: !ref initialReconnectDelay
                    maxDelay: !ref maxReconnectDelay
                    incrementFactor: !ref factorReconnectDelay

    multipleTags:
        type: Cybus::Endpoint
        properties:
            protocol: Opcda
            connection: !ref opcdaConnection
            subscribe:
                interval: 2000
                tags:
                    - 'Triangle Waves.Int4'
                    - 'Triangle Waves.Real4'

    triangleWaveReal4:
        type: Cybus::Endpoint
        properties:
            protocol: Opcda
            connection: !ref opcdaConnection
            subscribe:
                interval: 2000
                tag: 'Triangle Waves.Real4'

    writeTag:
        type: Cybus::Endpoint
        properties:
            protocol: Opcda
            connection: !ref opcdaConnection
            write:
                tag: 'Triangle Waves.Int4'
                type: 'INTEGER'

    browse:
        type: Cybus::Endpoint
        properties:
            protocol: Opcda
            connection: !ref opcdaConnection
            read:
                browse: 'flat'
```

{% endcode %}
