# Siemens SIMATIC S7+

The **S7+ protocol** allows Connectware to communicate directly and symbolically with Siemens **S7-1200** and **S7-1500** PLCs. It provides a simple, reliable way to read and write PLC variables, maintain live data streams via MQTT, and automatically recover from network interruptions. All while supporting a wide range of data types.

## Prerequisites

Before connecting to your PLC, make sure your setup meets the following requirements:

* Supported PLCs
  * Siemens S7-1200
  * Siemens S7-1500
* Limited support for
  * Siemens S7-300
  * Siemens S7-400
* Requirements for the Siemens PLC:
  * PUT/GET communication enabled in TIA Portal
  * TCP port 102 open and reachable from Connectware
  * Properly configured and exported symbol definitions
* Connectware 2.1.0 or newer

## Getting Started

Let us start with a minimal working example that connects to a PLC and reads a single Boolean variable.

{% stepper %}
{% step %}

#### Creating the Service Commissioning File

* Create a service commissioning file (for example, `s7plus.yml`) and copy the configuration below:

{% code title="s7plus.yml" lineNumbers="true" expandable="true" %}

```yaml
definitions:
  S7_BYTE_1: PLC_2.Blocks.Testsystem_DB11.Byte_0
  S7_BOOL_ARRAY_3: PLC_2.Blocks.TestsystemArrays_noOpt_DB14.BoolArray_3

resources:
  connection:
    type: Cybus::Connection
    properties:
      protocol: S7plus
      targetState: connected
      connection:
        host: !ref host
        port: !ref port
        rack: !ref rack
        slot: !ref slot
        ConnType: TCPIPTIA
        isOptimized: true # This is internal optimization of AGlink not PLC block optimization
        DevNr: !ref devicenr # Must be different in service commissioning file for parallel ops
        connectionTimeout: 30000 # Connection setup timeout (ms)
        operationTimeout: 5000 # Read/write operation timeout (ms)
        healthCheckInterval: 30000 # Health check probe interval (ms)
        healthCheckTimeout: 10000 # Health check timeout (ms)
        healthCheckFailureThreshold: 3 # Failed checks before reconnect
        connectionStrategy: # Automatic reconnection settings
          initialDelay: 5000 # First retry delay (ms)
          maxDelay: 30000 # Maximum backoff delay (ms)
          incrementFactor: 2 # Exponential growth factor

  #Scalar
  s7ReadByteEndpoint1:
    type: Cybus::Endpoint
    properties:
      protocol: S7plus
      connection: !ref connection
      topic: S7/BYTE_1/read
      read:
        dataType: BYTE
        nodeId: !ref S7_BYTE_1

  s7WriteByteEndpoint1:
    type: Cybus::Endpoint
    properties:
      protocol: S7plus
      connection: !ref connection
      topic: S7/BYTE_1
      write:
        nodeId: !ref S7_BYTE_1
        dataType: BYTE

  #Arrays

  S7_READ_BOOL_ARRAY_3:
    type: Cybus::Endpoint
    properties:
      protocol: S7plus
      connection: !ref connection
      topic: S7/BOOL_ARRAY_3/read
      read:
        nodeId: !ref S7_BOOL_ARRAY_3
        isArray: true
        dataType: BOOL
        arrayLength: 1024

  S7_WRITE_BOOL_ARRAY_3:
    type: Cybus::Endpoint
    properties:
      protocol: S7plus
      connection: !ref connection
      topic: S7/BOOL_ARRAY_3
      write:
        nodeId: !ref S7_BOOL_ARRAY_3
        isArray: true
        dataType: BOOL
        arrayLength: 1024
```

{% endcode %}

This configuration connects Connectware to your PLC, creates a symbolic reference to the variable `S7_BYTE_1`, and sets up an MQTT topic for reading its value.
{% endstep %}

{% step %}

#### Deploy and Verify

1. [Install](https://docs.cybus.io/documentation/services/setting-up-and-configuring-services/installing-services) and [enable](https://docs.cybus.io/documentation/services/setting-up-and-configuring-services/enabling-services) the service commissioning file.
2. Subscribe to the topic `S7/BYTE_1/read`. You should start seeing live data from your PLC almost immediately.
3. To confirm the connection, open the logs and look for messages indicating a successful connection to the PLC.
4. If the connection was established correctly, you are now ready to expand your configuration with more variables, write access, and array support.
   {% endstep %}
   {% endstepper %}

## Configuration Reference

For detailed information about all available configuration options, see:

* [Connection Properties](https://docs.cybus.io/connectors/shop-floor-connectors/siemens-simatic-s7+/s7plusconnection)
* [Endpoint Properties](https://docs.cybus.io/connectors/shop-floor-connectors/siemens-simatic-s7+/s7plusendpoint)

## Symbolic Addressing

Symbolic addressing uses TIA Portal symbol names for fully type-safe and human-readable access.

**Connection type:** `TCPIPTIA`

**Symbol loading:** The PLC serves the symbols automatically at first connection time. Connectware stores them in memory for subsequent use. Depending on network latency and the number of symbols on the PLC, initial symbol loading may take a few seconds. Subsequent reconnections take only a few milliseconds.

Connectware supports saving symbols to a file for use in connections. This reduces connection times to sub-seconds and is more robust against network latency and symbol count. It can also be backed up and reused.

**Example**

{% code lineNumbers="true" %}

```yaml
read:
  nodeId: 'PLC_1.Blocks.Data_block_1.Temperature'
  dataType: REAL
```

{% endcode %}

## Supported Data Types

| S7 Type | Size (bytes) | JavaScript Type | Notes                              |
| ------- | ------------ | --------------- | ---------------------------------- |
| BOOL    | 1 bit        | boolean         | true/false                         |
| BYTE    | 1            | number          | 0 to 255 (unsigned)                |
| WORD    | 2            | number          | 0 to 65535 (unsigned)              |
| DWORD   | 4            | number          | 0 to 4294967295 (unsigned)         |
| INT     | 2            | number          | -32768 to 32767 (signed)           |
| DINT    | 4            | number          | -2147483648 to 2147483647 (signed) |
| REAL    | 4            | number          | IEEE 754 single precision          |
| CHAR    | 1            | string          | Single Latin-1 character           |
| STRING  | variable     | string          | Latin-1 encoded (max 254 chars)    |
| WCHAR   | 2            | string          | UTF-16 character                   |
| WSTRING | variable     | string          | UTF-16LE encoded (max 8191 chars)  |

### Validation Rules

* **Integer types:** Reject non-integer values and out-of-range values.
* **BOOL:** Requires boolean input (true/false).
* **CHAR:** Accepts numeric 0-255 or exactly 1 Latin-1 character.
* **WCHAR:** Must convert to exactly 2 bytes UTF-16LE (1 code unit).
* **STRING:** Max 254 characters after Latin-1 conversion.
* **WSTRING:** Max 16382 bytes after UTF-16LE conversion (8191 characters).
* **REAL/LREAL:** Reject values exceeding IEEE 754 range (non-infinity).
* **Arrays:** Element count must match arrayLength exactly.

Invalid inputs will throw error logs.

{% hint style="warning" %}
**Performance impact:** Larger data types consume more PLC resources. Choose the smallest data type that meets your requirements. For example, use `INT` instead of `DINT` if values stay within -32768 to 32767.
{% endhint %}

### Array Support

* Recommended: 512 elements or less for optimal performance
* Maximum: 1024 elements (up to 10,000 elements when PLC working memory allows)
* Supported for all [data types](#supported-data-types)

{% hint style="warning" %}
Arrays larger than 512 elements may experience performance degradation and increased PLC load.
{% endhint %}

**Example**

{% code lineNumbers="true" %}

```yaml
read:
  nodeId: 'PLC_1.Blocks.DataBlock1.BoolArray'
  isArray: true
  dataType: BOOL
  arrayLength: 512
```

{% endcode %}

## Timeouts and Health Monitoring

Timeouts and health checks define how Connectware manages communication reliability. E.g. how long it waits for responses, detects connection loss, and restores contact automatically.

### Connection Timeout

When Connectware connects to a PLC for the first time, it has to load all symbols from the TIA Portal project. This process can take from a few seconds to several minutes, depending on the size of your project and the speed of your network.

The **connection timeout** defines how long Connectware will wait before deciding that the connection attempt has failed. By default, it’s set to 30000 ms (30 seconds). This is suitable for most small and mid-sized projects. If your PLC holds thousands of symbols or is connected through a slow network, increase this to 60–90 seconds to prevent timeouts during startup.

### Operation Timeout

Once the connection is established, every read and write operation follows its own time limit, defined by the operation timeout. This setting determines how long Connectware will wait for each individual data request.

The default value is 5000 ms (5 seconds). That is usually enough for single variables or small datasets. For large array reads or busy industrial networks, increase it to 10–15 seconds.

Shorter timeouts give quicker feedback on failures. However, on heavily loaded systems, they may cause false timeouts even when the PLC is still healthy.

### Health Checks

To ensure long-term reliability, Connectware runs background health checks that regularly test the connection to the PLC.

Each check sends a small ping request and waits for a response. If several checks in a row fail, Connectware automatically disconnects and attempts to reconnect.

**Example**

In the following configuration, Connectware checks the PLC every 30 seconds, waits up to 10 seconds for a reply, and reconnects after three missed responses.

{% code lineNumbers="true" %}

```yaml
connection:
  healthCheckInterval: 30000
  healthCheckTimeout: 10000
  healthCheckFailureThreshold: 3
```

{% endcode %}

### Recommended Health Check Values

| Network Type | Interval | Timeout  | Failures |
| ------------ | -------- | -------- | -------- |
| Stable       | 15000 ms | 5000 ms  | 3        |
| Typical      | 30000 ms | 10000 ms | 3        |
| Unstable     | 60000 ms | 15000 ms | 2        |

Keep the health check timeout slightly lower than `operationTimeout`, and use intervals between 15–60 seconds depending on network quality. You can disable checks with `healthCheckInterval: 0`, though this is not recommended for production.

{% hint style="warning" %}
Health checks consume PLC resources. For PLCs under heavy load or with many concurrent connections, consider increasing intervals to 60+ seconds or disabling checks temporarily during high-traffic periods (not recommended for production).
{% endhint %}

## Performance and Optimization

This section explains how to improve performance, reduce latency, and keep your setup stable under load.

### Typical Performance

| Operation                 | Typical Time | Notes                                                                                     |
| ------------------------- | ------------ | ----------------------------------------------------------------------------------------- |
| Scalar read/write         | 30–100 ms    | Depends on PLC and network                                                                |
| Array read/write          | 100–500 ms   | Larger arrays take longer                                                                 |
| Reconnection (cached)     | < 1 s        | With in-memory symbol caching enabled                                                     |
| Symbol loading (no cache) | 5–240 s      | Large TIA projects. Typically time >10s, but depends on the number of symbols on the PLC. |

### When to Adjust Optional Parameters

| Scenario                           | Recommended Adjustments                                                    |
| ---------------------------------- | -------------------------------------------------------------------------- |
| Large TIA Projects (1000+ symbols) | Increase `connectionTimeout` to 60-90s, enable `useSymbolCacheFile`        |
| High Network Latency               | Increase `operationTimeout` to 10-15s, `healthCheckTimeout` to 15s         |
| PLC Under Heavy Load               | Increase `healthCheckInterval` to 60s+, reduce subscription polling to 5s+ |
| Unstable Networks                  | Lower `healthCheckFailureThreshold` to 2, increase retry delays            |
| Multi-Factory Deployment           | Configure `symbolCacheFilePath` to shared location for config reuse        |

### Polling and Subscriptions

Too many subscriptions or very fast polling can overload the PLC.

For most real-time applications, a polling interval of 1–2 seconds is ideal. If your data changes less frequently, you can increase the interval to 3–5 seconds.

Another way to reduce load is to group values into arrays or structured datasets so that multiple points are read in one go instead of as separate requests.

{% code lineNumbers="true" %}

```yaml
subscribe:
  interval: 2000 # Poll every 2 seconds
  nodeId: !ref S7_BOOL_ARRAY_3
  dataType: BOOL
```

{% endcode %}

### Timeout Tuning

In larger setups or when working over slower networks, the default timeout settings may be too short. Extend them to avoid unnecessary disconnects and retries.

The following parameters are especially important to review:

| Parameter           | Default  | Recommended (Large Projects) |
| ------------------- | -------- | ---------------------------- |
| `connectionTimeout` | 30000 ms | 60000–90000 ms               |
| `operationTimeout`  | 5000 ms  | 8000–15000 ms                |

**Example**

{% code lineNumbers="true" %}

```yaml
connection:
  connectionTimeout: 60000
  operationTimeout: 10000
```

{% endcode %}

### Load Management

When load becomes an issue, start by increasing the polling interval (`subscribe.interval`) to cut down on network traffic. If multiple connections are used in parallel, assign each one a unique `devicenr` to prevent conflicts.

Keeping health checks enabled improves stability by detecting issues early, and applying exponential backoff for reconnect attempts ensures that the system does not flood the network when recovering from errors.

**Example**

{% code lineNumbers="true" %}

```yaml
connectionStrategy:
  initialDelay: 5000
  maxDelay: 30000
  incrementFactor: 2
```

{% endcode %}

## Troubleshooting

This section helps you quickly diagnose and resolve the most common issues encountered when using the S7+ protocol.

### Connection Failed: Cannot Reach PLC

* Error message: `Connection failed: Cannot reach PLC`
* PLC does not appear to respond to connection attempts.

**Possible Causes**

* Incorrect IP address or hostname.
* Firewall blocking port 102.
* PLC not configured for S7+ (PUT/GET) communication.
* Network connectivity issue.

**How to Fix**

1. Test the network connection:

{% code lineNumbers="true" %}

```bash
ping 192.168.1.100
```

{% endcode %}

2. Check if the PLC is listening on port 102:

{% code lineNumbers="true" %}

```bash
telnet 192.168.1.100 102
```

{% endcode %}

3. Verify PLC communication settings in the TIA Portal:
   * Select **Device Configuration** > **General** > **Protection & Security** > **Connection mechanisms**.
   * Ensure **Permit access with PUT/GET communication** is enabled.

### Timeout Errors During Connection

* Connection attempt takes too long or fails with a timeout.
* Logs show: `Timeout while connecting to PLC`.

**Possible Causes**

* `connectionTimeout` too short for symbol loading.
* Large TIA Portal project (many symbols).
* High network latency or unstable connection.

**How to Fix**

Increase the connection timeout to allow more time for symbol loading:

{% code lineNumbers="true" %}

```yaml
connection:
  connectionTimeout: 60000 # Increase from default 30000 ms
```

{% endcode %}

### Timeout Errors During Read/Write Operations

* Errors such as `Read timeout` or `Write timeout`.
* Operations take longer than expected.

**Possible Causes**

* `operationTimeout` too short for PLC response.
* PLC overloaded with too many read/write requests.
* Network latency.
* Large array operations (>512 elements).

**How to Fix**

Increase the operation timeout:

{% code lineNumbers="true" %}

```yaml
connection:
  operationTimeout: 10000 # Increase from default 5000 ms
```

{% endcode %}

For large array operations:

{% code lineNumbers="true" %}

```yaml
connection:
  operationTimeout: 15000 # For 1024-element arrays
```

{% endcode %}

Reduce polling frequency to lighten PLC load:

{% code lineNumbers="true" %}

```yaml
subscribe:
  interval: 2000 # Increase from 1000 ms
```

{% endcode %}

### Invalid `dataType` Errors

* Error message: `Invalid dataType` or unexpected values when reading/writing.

**Possible Causes**

* The `dataType` in the service YAML does not match the PLC variable type.
* Attempting to write a value incompatible with the PLC variable type.

**How to Fix**

Ensure the declared data type matches the PLC definition:

{% code lineNumbers="true" %}

```yaml
properties:
  dataType: REAL # Must match the PLC variable type
```

{% endcode %}

For arrays, ensure the declared length matches the PLC array:

{% code lineNumbers="true" %}

```yaml
properties:
  isArray: true
  arrayLength: 10 # Must match PLC definition
```

{% endcode %}

### Memory or Performance Issues

* High CPU usage or delayed response times.
* Logs show: `Queue depth unusually high: X`.
* Health check delays or dropped messages.

**Possible Causes**

* Too many concurrent subscriptions.
* Polling intervals too aggressive.
* Network congestion or PLC load.

**How to Fix**

Reduce the number of subscriptions or increase polling intervals:

{% code lineNumbers="true" %}

```yaml
subscribe:
  interval: 5000 # Slow down polling
```

{% endcode %}

Monitor logs for errors and warnings:

{% code lineNumbers="true" %}

```bash
docker logs platform-service-manager-1 --follow
```

{% endcode %}

Pay attention to these messages:

* `"Queue depth unusually high: X"` signals overload—slow down your subscription intervals. Reduce your polling rate.
* `"Health check passed"` indicates healthy communication.
* `"Ping successful"` shows the PLC is reachable and active.

### Log Message Reference

| Log Message                     | Meaning                    | Recommended Action              |
| ------------------------------- | -------------------------- | ------------------------------- |
| `Connected successfully to PLC` | Connection established     | Normal operation                |
| `Health check passed`           | PLC responsive             | Normal operation                |
| `Queue depth unusually high: X` | High message queue         | Reduce polling frequency        |
| `Reconnection attempt X`        | Auto-reconnect in progress | Wait for reconnection           |
| `Read/Write operation timeout`  | Operation took too long    | Increase timeout or reduce load |
