> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Siemens S7 Route

> Connect to Siemens S7-200, S7-300, S7-400, S7-1200, and S7-1500 PLCs using native S7 protocol

## Siemens S7 Overview

The `SIEMENS_S7` route enables direct communication with Siemens S7 PLCs using the native S7 protocol (ISO-on-TCP). It supports all major S7 PLC families and provides access to data blocks, memory areas, inputs, outputs, timers, and counters.

<Tip>
  The S7 route uses native protocol communication, which is typically faster and more efficient than OPC UA for Siemens PLCs.
</Tip>

## Basic Syntax

```lot theme={null}
DEFINE ROUTE SiemensPLC WITH TYPE SIEMENS_S7
    ADD S7_CONFIG
        WITH IP "192.168.1.100"
        WITH CPU_TYPE "S71500"
        WITH RACK 0
        WITH SLOT 1
    ADD MAPPING ProcessData
        WITH EVERY 500 MILLISECONDS
        ADD TAG Temperature
            WITH ADDRESS "DB1.DBD100"
            WITH DATA_TYPE "REAL"
            WITH SOURCE_TOPIC "plc/temperature"
```

***

## Supported CPU Types

| CPU Type | Parameter Value | Typical Slot | Description           |
| -------- | --------------- | ------------ | --------------------- |
| S7-200   | `S7200`         | 0            | Compact micro PLCs    |
| S7-300   | `S7300`         | 2            | Modular PLCs          |
| S7-400   | `S7400`         | 2/3          | High-performance PLCs |
| S7-1200  | `S71200`        | 1            | Compact controllers   |
| S7-1500  | `S71500`        | 1            | Advanced controllers  |

<Note>
  For S7-1200/1500 PLCs, you may need to enable "Permit access with PUT/GET" in the PLC's protection settings (Hardware Configuration → Protection & Security).
</Note>

***

## Connection Configuration

### S7\_CONFIG Parameters

<ParamField path="IP" type="string" required>
  S7 PLC IP address.
</ParamField>

<ParamField path="CPU_TYPE" type="string" required>
  CPU type: `S7200`, `S7300`, `S7400`, `S71200`, or `S71500`.
</ParamField>

<ParamField path="RACK" type="integer">
  PLC rack number. Default: 0.
</ParamField>

<ParamField path="SLOT" type="integer">
  PLC slot number. Default: 1 for S7-1200/1500, 2 for S7-300/400.
</ParamField>

<ParamField path="CONNECTION_TYPE" type="string">
  Connection type: `PG` (Programming device), `OP` (Operator Panel), or `S7BASIC`. Default: PG.
</ParamField>

<ParamField path="RETRY_ATTEMPTS" type="integer">
  Number of retry attempts on failure. Default: 3.
</ParamField>

<ParamField path="RETRY_TIME_SECONDS" type="integer">
  Seconds to wait between retries. Default: 5.
</ParamField>

<ParamField path="REFRESH_TIME_MS" type="integer">
  Refresh time in milliseconds. Default: 1000.
</ParamField>

<ParamField path="READ_TIMEOUT" type="integer">
  Read timeout in milliseconds. Default: 5000.
</ParamField>

<ParamField path="WRITE_TIMEOUT" type="integer">
  Write timeout in milliseconds. Default: 5000.
</ParamField>

### Connection Examples

<Tabs>
  <Tab title="S7-1500">
    ```lot theme={null}
    ADD S7_CONFIG
        WITH IP "192.168.1.100"
        WITH CPU_TYPE "S71500"
        WITH RACK 0
        WITH SLOT 1
        WITH CONNECTION_TYPE "PG"
    ```
  </Tab>

  <Tab title="S7-1200">
    ```lot theme={null}
    ADD S7_CONFIG
        WITH IP "192.168.1.50"
        WITH CPU_TYPE "S71200"
        WITH RACK 0
        WITH SLOT 1
    ```
  </Tab>

  <Tab title="S7-300">
    ```lot theme={null}
    ADD S7_CONFIG
        WITH IP "192.168.1.30"
        WITH CPU_TYPE "S7300"
        WITH RACK 0
        WITH SLOT 2
    ```
  </Tab>

  <Tab title="S7-400">
    ```lot theme={null}
    ADD S7_CONFIG
        WITH IP "192.168.1.20"
        WITH CPU_TYPE "S7400"
        WITH RACK 0
        WITH SLOT 3
    ```
  </Tab>
</Tabs>

***

## S7 Addressing

### Address Format

S7 addresses follow the pattern: `<Area><Number>.<Offset>` or `<DB>.<Type><Offset>`

| Address      | Description                     | Example                               |
| ------------ | ------------------------------- | ------------------------------------- |
| `DBn.DBXx.y` | Data Block bit                  | `DB1.DBX0.0` - DB1, byte 0, bit 0     |
| `DBn.DBBx`   | Data Block byte                 | `DB1.DBB0` - DB1, byte 0              |
| `DBn.DBWx`   | Data Block word (16-bit)        | `DB1.DBW100` - DB1, word at byte 100  |
| `DBn.DBDx`   | Data Block double word (32-bit) | `DB1.DBD100` - DB1, dword at byte 100 |
| `Mx.y`       | Memory bit                      | `M0.0` - Marker byte 0, bit 0         |
| `MBx`        | Memory byte                     | `MB0` - Marker byte 0                 |
| `MWx`        | Memory word                     | `MW100` - Marker word at byte 100     |
| `MDx`        | Memory double word              | `MD100` - Marker dword at byte 100    |
| `Ix.y`       | Input bit                       | `I0.0` - Input byte 0, bit 0          |
| `IBx`        | Input byte                      | `IB0` - Input byte 0                  |
| `IWx`        | Input word                      | `IW0` - Input word at byte 0          |
| `Qx.y`       | Output bit                      | `Q0.0` - Output byte 0, bit 0         |
| `QBx`        | Output byte                     | `QB0` - Output byte 0                 |
| `QWx`        | Output word                     | `QW0` - Output word at byte 0         |
| `Tx`         | Timer                           | `T0` - Timer 0                        |
| `Cx`         | Counter                         | `C0` - Counter 0                      |

### Address Types

<ParamField path="ADDRESS_TYPE" type="string">
  Memory area type: `DATABLOCK`, `MEMORY`, `INPUT`, `OUTPUT`, `TIMER`, `COUNTER`.
</ParamField>

<Note>
  For most configurations, the ADDRESS\_TYPE is inferred from the address format. Use explicit ADDRESS\_TYPE when needed for clarity.
</Note>

***

## Data Types

| Data Type                            | S7 Type | Size     | Description             |
| ------------------------------------ | ------- | -------- | ----------------------- |
| `BOOL` / `BIT`                       | BOOL    | 1 bit    | Boolean value           |
| `BYTE`                               | BYTE    | 8 bits   | Unsigned 8-bit          |
| `SINT`                               | SINT    | 8 bits   | Signed 8-bit integer    |
| `USINT`                              | USINT   | 8 bits   | Unsigned 8-bit integer  |
| `WORD`                               | WORD    | 16 bits  | Unsigned 16-bit         |
| `INT` / `INT16`                      | INT     | 16 bits  | Signed 16-bit integer   |
| `UINT` / `UINT16`                    | UINT    | 16 bits  | Unsigned 16-bit integer |
| `DWORD`                              | DWORD   | 32 bits  | Unsigned 32-bit         |
| `DINT` / `INT32`                     | DINT    | 32 bits  | Signed 32-bit integer   |
| `UDINT` / `UINT32`                   | UDINT   | 32 bits  | Unsigned 32-bit integer |
| `LWORD`                              | LWORD   | 64 bits  | Unsigned 64-bit         |
| `LINT` / `INT64`                     | LINT    | 64 bits  | Signed 64-bit integer   |
| `ULINT` / `UINT64`                   | ULINT   | 64 bits  | Unsigned 64-bit integer |
| `REAL` / `FLOAT`                     | REAL    | 32 bits  | 32-bit floating point   |
| `LREAL` / `DOUBLE`                   | LREAL   | 64 bits  | 64-bit floating point   |
| `STRING`                             | STRING  | Variable | S7 string type          |
| `CHAR`                               | CHAR    | 8 bits   | Single character        |
| `WCHAR`                              | WCHAR   | 16 bits  | Wide character          |
| `TIME`                               | TIME    | 32 bits  | Time duration           |
| `DATE`                               | DATE    | 16 bits  | Date value              |
| `TOD`                                | TOD     | 32 bits  | Time of day             |
| `DTL` / `DATETIME` / `DATE_AND_TIME` | DTL     | 12 bytes | Date and time combined  |

***

## TAG Configuration

### Complete TAG Example

```lot theme={null}
ADD TAG ProcessTemperature
    WITH ADDRESS "DB1.DBD100"
    WITH ADDRESS_TYPE "DATABLOCK"
    WITH DATA_TYPE "REAL"
    WITH SOURCE_TOPIC "plc/process/temperature"
    WITH SCALING 1
    WITH OFFSET 0
    WITH UNIT "°C"
    WITH DECIMAL_PLACES 2
    WITH MIN_VALUE -50
    WITH MAX_VALUE 200
    WITH DEADBAND 0.5
    WITH PUBLISH_MODE "JSON"
    WITH WRITABLE "true"
    WITH DESTINATION_TOPIC "plc/process/temperature/set"
    WITH BYTE_ORDER "BIGENDIAN"
    WITH DESCRIPTION "Main process temperature"
```

### TAG Parameters

<AccordionGroup>
  <Accordion title="Address Configuration">
    <ParamField path="ADDRESS" type="string" required>
      S7 address in standard notation (e.g., `DB1.DBW100`, `M0.0`, `I0.0`, `Q0.0`).
    </ParamField>

    <ParamField path="ADDRESS_TYPE" type="string">
      Address type: `DATABLOCK`, `MEMORY`, `INPUT`, `OUTPUT`, `TIMER`, `COUNTER`.
    </ParamField>

    <ParamField path="DATA_TYPE" type="string" required>
      S7 data type: `BOOL`, `BYTE`, `WORD`, `DWORD`, `INT`, `DINT`, `REAL`, `STRING`.
    </ParamField>
  </Accordion>

  <Accordion title="Value Transformation">
    <ParamField path="SCALING" type="double">
      Multiplier applied to raw value. Default: 1.0.
    </ParamField>

    <ParamField path="OFFSET" type="double">
      Value added after scaling. Default: 0.0.
    </ParamField>

    <ParamField path="DECIMAL_PLACES" type="integer">
      Number of decimal places in output. Default: 2.
    </ParamField>
  </Accordion>

  <Accordion title="Filtering">
    <ParamField path="MIN_VALUE" type="double">
      Minimum allowed value.
    </ParamField>

    <ParamField path="MAX_VALUE" type="double">
      Maximum allowed value.
    </ParamField>

    <ParamField path="DEADBAND" type="double">
      Minimum change to trigger publish. Default: 0.0.
    </ParamField>
  </Accordion>

  <Accordion title="Publishing">
    <ParamField path="SOURCE_TOPIC" type="string">
      Topic where PLC values are published. Subscribe here to receive sensor data.
    </ParamField>

    <ParamField path="PUBLISH_MODE" type="string">
      Output format: `VALUE_ONLY` or `JSON`. Default: VALUE\_ONLY.
    </ParamField>

    <ParamField path="UNIT" type="string">
      Engineering unit (e.g., °C, bar, RPM).
    </ParamField>
  </Accordion>

  <Accordion title="Write Configuration">
    <ParamField path="WRITABLE" type="boolean">
      Allow writing to this address. Default: false.
    </ParamField>

    <ParamField path="DESTINATION_TOPIC" type="string">
      Topic to send write commands. Publish a value here to write it to the PLC.
    </ParamField>
  </Accordion>
</AccordionGroup>

***

## Event-Based Operations

For on-demand S7 operations (not polling), use the EVENT syntax. Publish a message to SOURCE\_TOPIC to trigger the operation; the route executes it and publishes the result to DESTINATION\_TOPIC.

### Supported Operations

| Operation | Description                       | Query Parameters                |
| --------- | --------------------------------- | ------------------------------- |
| `READ`    | Read data from a memory address   | `address`, `data_type`, `count` |
| `WRITE`   | Write a value to a memory address | `address`, `data_type`, `value` |

### Query Parameters

| Parameter   | Description                                      | Example                        |
| ----------- | ------------------------------------------------ | ------------------------------ |
| `operation` | Operation type: `READ` or `WRITE`                | `READ`                         |
| `address`   | S7 address in standard notation                  | `DB1.DBW0`, `MW100`, `I0.0`    |
| `data_type` | S7 data type                                     | `WORD`, `REAL`, `BOOL`, `DINT` |
| `count`     | Number of consecutive values to read (READ only) | `10`                           |
| `value`     | Value to write (WRITE only)                      | `42`, `23.5`, `true`           |

### Read Example

Read 10 words from Data Block 1 on demand:

```lot theme={null}
ADD EVENT ReadOnDemand
    WITH SOURCE_TOPIC "s7/commands/read"
    WITH DESTINATION_TOPIC "s7/responses/read"
    WITH QUERY "{operation: READ, address: DB1.DBW0, data_type: WORD, count: 10}"
```

### Write Example

Write a REAL value to Data Block 10 on demand:

```lot theme={null}
ADD EVENT WriteSetpoint
    WITH SOURCE_TOPIC "s7/commands/write"
    WITH DESTINATION_TOPIC "s7/responses/write"
    WITH QUERY "{operation: WRITE, address: DB10.DBD4, data_type: REAL, value: 75.0}"
```

***

## Complete Examples

<Tabs>
  <Tab title="Basic Data Block Reading">
    Read values from a data block:

    ```lot theme={null}
    DEFINE ROUTE ProductionPLC WITH TYPE SIEMENS_S7
        ADD S7_CONFIG
            WITH IP "192.168.1.100"
            WITH CPU_TYPE "S71500"
            WITH RACK 0
            WITH SLOT 1
        ADD MAPPING ProductionData
            WITH EVERY 500 MILLISECONDS
            ADD TAG Temperature
                WITH ADDRESS "DB1.DBD0"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "plc/temperature"
                WITH UNIT "°C"
            ADD TAG Pressure
                WITH ADDRESS "DB1.DBD4"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "plc/pressure"
                WITH UNIT "bar"
            ADD TAG Speed
                WITH ADDRESS "DB1.DBW8"
                WITH DATA_TYPE "INT"
                WITH SOURCE_TOPIC "plc/speed"
                WITH UNIT "RPM"
            ADD TAG Running
                WITH ADDRESS "DB1.DBX10.0"
                WITH DATA_TYPE "BOOL"
                WITH SOURCE_TOPIC "plc/running"
    ```
  </Tab>

  <Tab title="Memory and I/O">
    Read markers, inputs, and outputs:

    ```lot theme={null}
    DEFINE ROUTE IOMonitor WITH TYPE SIEMENS_S7
        ADD S7_CONFIG
            WITH IP "192.168.1.100"
            WITH CPU_TYPE "S71200"
            WITH RACK 0
            WITH SLOT 1
        ADD MAPPING DigitalIO
            WITH EVERY 100 MILLISECONDS
            ADD TAG StartButton
                WITH ADDRESS "I0.0"
                WITH ADDRESS_TYPE "INPUT"
                WITH DATA_TYPE "BOOL"
                WITH SOURCE_TOPIC "plc/io/start"
            ADD TAG StopButton
                WITH ADDRESS "I0.1"
                WITH ADDRESS_TYPE "INPUT"
                WITH DATA_TYPE "BOOL"
                WITH SOURCE_TOPIC "plc/io/stop"
            ADD TAG MotorRunning
                WITH ADDRESS "Q0.0"
                WITH ADDRESS_TYPE "OUTPUT"
                WITH DATA_TYPE "BOOL"
                WITH SOURCE_TOPIC "plc/io/motor"
            ADD TAG SystemReady
                WITH ADDRESS "M0.0"
                WITH ADDRESS_TYPE "MEMORY"
                WITH DATA_TYPE "BOOL"
                WITH SOURCE_TOPIC "plc/status/ready"
    ```
  </Tab>

  <Tab title="Bidirectional Control">
    Read process values and write setpoints:

    ```lot theme={null}
    DEFINE ROUTE ControlLoop WITH TYPE SIEMENS_S7
        ADD S7_CONFIG
            WITH IP "192.168.1.100"
            WITH CPU_TYPE "S71500"
            WITH RACK 0
            WITH SLOT 1
        ADD MAPPING ControlData
            WITH EVERY 200 MILLISECONDS
            ADD TAG ProcessValue
                WITH ADDRESS "DB10.DBD0"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "control/pv"
                WITH UNIT "°C"
                WITH PUBLISH_MODE "JSON"
            ADD TAG Setpoint
                WITH ADDRESS "DB10.DBD4"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "control/sp"
                WITH UNIT "°C"
                WITH WRITABLE "true"
                WITH DESTINATION_TOPIC "control/sp/set"
                WITH MIN_VALUE 0
                WITH MAX_VALUE 100
            ADD TAG Output
                WITH ADDRESS "DB10.DBD8"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "control/output"
                WITH UNIT "%"
            ADD TAG ManualMode
                WITH ADDRESS "DB10.DBX12.0"
                WITH DATA_TYPE "BOOL"
                WITH SOURCE_TOPIC "control/manual"
                WITH WRITABLE "true"
                WITH DESTINATION_TOPIC "control/manual/set"
    ```
  </Tab>

  <Tab title="Multiple Polling Rates">
    Optimize with different update frequencies:

    ```lot theme={null}
    DEFINE ROUTE OptimizedPLC WITH TYPE SIEMENS_S7
        ADD S7_CONFIG
            WITH IP "192.168.1.100"
            WITH CPU_TYPE "S71500"
            WITH RACK 0
            WITH SLOT 1
        
        ADD MAPPING FastLoop
            WITH EVERY 100 MILLISECONDS
            ADD TAG CriticalAlarm
                WITH ADDRESS "DB1.DBX0.0"
                WITH DATA_TYPE "BOOL"
                WITH SOURCE_TOPIC "plc/alarms/critical"
            ADD TAG MotorSpeed
                WITH ADDRESS "DB1.DBD10"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "plc/motor/speed"
        
        ADD MAPPING MediumLoop
            WITH EVERY 1 SECOND
            ADD TAG Temperature
                WITH ADDRESS "DB2.DBD0"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "plc/process/temp"
            ADD TAG Pressure
                WITH ADDRESS "DB2.DBD4"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "plc/process/pressure"
        
        ADD MAPPING SlowLoop
            WITH EVERY 10 SECONDS
            ADD TAG ProductionCount
                WITH ADDRESS "DB3.DBD0"
                WITH DATA_TYPE "DINT"
                WITH SOURCE_TOPIC "plc/production/count"
            ADD TAG RuntimeHours
                WITH ADDRESS "DB3.DBD4"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "plc/stats/runtime"
    ```
  </Tab>

  <Tab title="Combined (Cyclic + On-Demand)">
    Continuous monitoring with on-demand read and write events in the same route:

    ```lot theme={null}
    DEFINE ROUTE FullS7Setup WITH TYPE SIEMENS_S7
        ADD S7_CONFIG
            WITH IP "192.168.1.100"
            WITH CPU_TYPE "S71500"
            WITH RACK 0
            WITH SLOT 1
        
        ADD MAPPING ProcessData
            WITH EVERY 500 MILLISECONDS
            ADD TAG Temperature
                WITH ADDRESS "DB1.DBD0"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "plc/temperature"
                WITH UNIT "°C"
            ADD TAG Pressure
                WITH ADDRESS "DB1.DBD4"
                WITH DATA_TYPE "REAL"
                WITH SOURCE_TOPIC "plc/pressure"
                WITH UNIT "bar"
        
        ADD EVENT ReadBlock
            WITH SOURCE_TOPIC "s7/commands/read"
            WITH DESTINATION_TOPIC "s7/responses/read"
            WITH QUERY "{operation: READ, address: DB2.DBW0, data_type: WORD, count: 20}"
        
        ADD EVENT WriteSetpoint
            WITH SOURCE_TOPIC "s7/commands/write"
            WITH DESTINATION_TOPIC "s7/responses/write"
            WITH QUERY "{operation: WRITE, address: DB1.DBD8, data_type: REAL, value: 0}"
    ```

    The MAPPING continuously reads temperature and pressure from DB1. To trigger an on-demand read of 20 words from DB2, publish any message to `s7/commands/read`. To write a setpoint, publish to `s7/commands/write`.
  </Tab>
</Tabs>

***

## S7-1200/1500 Setup

<Warning>
  S7-1200 and S7-1500 PLCs require additional configuration to allow external access.
</Warning>

### Enable PUT/GET Access

1. Open TIA Portal project
2. Navigate to **Device Configuration** → **Properties**
3. Go to **Protection & Security** → **Connection mechanisms**
4. Enable **Permit access with PUT/GET communication from remote partner**

### Optimized Block Access

For S7-1500, ensure data blocks are set to allow standard access:

1. Open the Data Block in TIA Portal
2. In Properties, uncheck **Optimized block access**
3. Compile and download to PLC

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Connection Refused">
    * Verify IP address is correct
    * Check PLC is in RUN mode
    * For S7-1200/1500: Enable PUT/GET access
    * Verify correct RACK and SLOT settings
    * Check firewall allows TCP port 102
  </Accordion>

  <Accordion title="Wrong Slot Error">
    Use correct slot for your CPU:

    * S7-1200/1500: Slot 1
    * S7-300: Slot 2
    * S7-400: Slot 2 or 3 (check hardware config)
  </Accordion>

  <Accordion title="Optimized Block Access Error">
    For S7-1500: Disable optimized block access in TIA Portal for data blocks you want to access.
  </Accordion>

  <Accordion title="Incorrect Values">
    * Verify address matches TIA Portal
    * Check DATA\_TYPE corresponds to PLC variable type
    * For multi-word types, verify byte offset is correct
    * Check BYTE\_ORDER if values seem swapped
  </Accordion>

  <Accordion title="Write Fails">
    * Ensure WRITABLE is set to "true"
    * Verify PLC is in RUN mode
    * Check access permissions in PLC
    * Confirm value is within MIN\_VALUE/MAX\_VALUE
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="OPC UA" icon="sitemap" href="./opcua">
    Cross-platform industrial communication.
  </Card>

  <Card title="ADS (Beckhoff)" icon="gear" href="./ads">
    Connect to TwinCAT systems.
  </Card>
</CardGroup>
