Siemens Step7


ezvpn-fld-step7 is a service (provided as Docker container image) acting as a broker between multiple Siemens PLCs that uses Step7 protocol and one MQTT broker.

It can:

  • read data from Siemens PLCs and publish to MQTT topics
  • subscribe to MQTT topics and write incoming messages to Siemens PLCs

It is compatible with S7-300 S7-400 S7-1200 and S7-1500 Siemens PLCs.

Siemens Step7 Schema

Using ezvpn-fld-step7, allows you to:

  • write to your Siemens PLC by sending text messages to MQTT.
  • read from your devices by subscribing to MQTT topics.

Please remember to enable the external PLC communication to allow read/write from third party software.

Enable PLC communication in Siemens TIA PORTAL

Check Permit access with PUT/GET communication from remote partner in Device configuration and Protection & Security Properties.

TIA Portal

Uncheck Optimize block access in Attributes and Data Block Properties.

TIA Portal

Compile the project and download the new software to the PLC for the changes to take effect.

How to use it

ezvpn-fld-step7 is a Docker container image pre-configured to communicate with ezvpn-mqtt. In case you need to use it with your MQTT broker, please refer to the section below regarding customization.

If used with ezvpn-mqtt, only one environment variable must be provided: FLD_CFG.

FLD_CFG is a string representing a JSON object, describing the PLC configuration, addresses, polling, subscription, and writable addresses.

The working example below represents an oversimplified case with:

  • two machines (extruder and pelletizer)
  • two thermocouples (one on the extruder tempextruder, one on the pelletizer tempdie), read-only
  • one pressure sensor (pressure), read-only
  • one temperature setpoint (tempSP), read-write
    "plcs": [
            "name": "extruder",
            "host": "",
            "port": 102,
            "rack": 0,
            "slot": 1
            "name": "pelletizer",
            "host": "",
            "port": 102,
            "rack": 0,
            "slot": 1
        }    ],
    "addresses": [
            "name": "tempextruder",
            "target": "extruder",
            "address": "DB1,W2"
            "name": "tempdie",
            "target": "pelletizer",
            "address": "DB1,W10"
            "name": "pressure",
            "target": "pelletizer",
            "address": "MW12"
            "name": "tempSP",
            "target": "extruder",
            "address": "MW10"
    "pollings": [
            "every": "3s",
            "plcs": ["extruder"],
            "sendAlways": true
            "cron": "* */5 * * * *",
            "plcs": ["pelletizer"],
            "sendAlways": false

    "writables": ["tempSP"]

Mapping configuration (FLD_CFG)

The JSON object has 4 array fields:

    "plcs": [],
    "addresses": [],
    "pollings": [],
    "writables": []

plcs (required): contains the list of the available Siemens PLC.

addresses (required): contains the list of the available addresses.

pollings (required): contains the list of the polling cycles.

writables (optional): contains the list of the available addresses (each address must be defined in the addresses section).


plcs is an array of objects, representing the available Siemens devices. The plcs array cannot be empty.

Each PLC is represented by the following object:

    "name": "<plc name>",
    "host": "<plc address or hostname>",
    "port": <plc port>,
    "rack": <rack number>,
    "slot": <slot number>,
    "localTSAP": <optional hex>,
    "remoteTSAP": <optional hex>

name and host are required.

port if not defined defaults to 102

rack please refer to Siemens documentation. Defaults to 0

slot please refer to Siemens documentation. Defaults to 2

localTSAP please refer to Siemens documentation.

remoteTSAP please refer to Siemens documentation.


addresses is an array of objects, representing the available Siemens variables. The addresses array cannot be empty.

Each address, if not in the writables array (see below), is treated as read-only. Every attempt to send values to read-only addresses will silently fail.

Each address is represented by the following object:

    "name": "<symbolic address name>",
    "target": "<a PLC defined in the plcs section>",
    "address": <Siemens format>,
    "isBitArray": true/false

isBitArray is optional and its default value is false. It must be set to true when managing bit values. When setting bit values to true, you must use either true or 1 as value. Any other value is treated as false.

The addresses are made up of three different components: Area, DataType, and Offset.

Area Syntax
Data Type SyntaxSignedness
IB0Byte at Offset 0 in the Inputs area
IW0Word at Offset 0 in the Inputs area
DB500,DI8DInt at Offset 8 in DataBlock 500
ISTRING24.50A String of length 50 starting at offset 24 in the Inputs area
IX20.3Bit 4 of the Byte at Offset 20 in the Inputs area

For additional information, please refer to Siemens documentation.


pollings represents a list of polling cycles on the Siemens PLCs. At least one polling must be defined.

Each polling has its independent polling frequency and it can span over different PLCs.

This is the structure of a polling object

    "every": "<frequency>",
    "cron": "<frequency time>",
    "timezone": "<timezone>",
    "plcs": [<plcs list>],
    "sendAlways": <polling or subscription>,
    "sendBatch": <batch or single>,
    "disableSingle": <send or not single measurements>

The data reading frequency is specified using the alternative every or cron syntax.

every or cron cannot both be defined in the same polling definition, choose which type of polling frequency should be used.

  • every: can be supplied in : human readable time format

  • cron: can be supplied in : cron time format

  • timezone: an optional timezone, see the list, to use for the cron expression. If not defined UTC is used.

  • plcs: is an array of plcs names, in string format.

  • sendAlways: is a boolean optional property. If absent or false, only changed values (from previous polling cycles) are sent to mqtt. Otherwise all the values are always sent.

At the first polling cycle, all the values are sent, even if sendAlways is false

sendBatch is a boolean optional property. Defaults to false. If true, all the measurements are sent in aggregated form to the MQTT topic specified on FROM_DEVICE_AGGREGATED_TOPIC_PREFIX environment variable.

The payload is a JSON with 2 properties on default topic aggregate/<protocol>:

    "ts": 1612043704952,
    "data": [
        { "address": "tempextruder", "value": 115, "ts": 1612043702457 },
        { "address": "tempdie", "value": 120, "ts": 1612043702457 }
  • ts value is the time at which the payload has been sent.
  • data is an array of all the measures to be sent on each polling cycle. Each array of data is a measurement as sent in single form.

The sendAlways setting affects both the single data and the aggregated data.

disableSingle is a boolean optional property. Defaults to false. If true the measurements are not sent to the MQTT topic specified on TO_DEVICE_TOPIC_PREFIX environment variable.


An array of address names, in string format. Each address in the list can be written.

Environment variables

When you start the ezvpn-fld-step7 image, you can adjust the instance's configuration by passing one or more environment variables to the docker run command.

  • FLD_CFG: Siemens mapping description, as documented above. Required.
  • MQTT_HOST: ip address / host name of the MQTT broker. Defaults to (In IOhubTM the variable is set to ezpn-mqtt value)
  • MQTT_PORT: MQTT broker port. Defaults to 1883.
  • FROM_DEVICE_TOPIC_PREFIX: MQTT topic use to publish values read from devices, defaults to fld/step7/r/.
  • TO_DEVICE_TOPIC_PREFIX: MQTT topic subscribed to get values to write on devices, defaults to fld/step7/w/.
  • FROM_DEVICE_AGGREGATED_TOPIC_PREFIX: MQTT topic use to publish values read from devices, defaults to aggregate/step7. Used if sendBatch is set to true.
  • NO_RETAIN: if true values are sent to MQTT_HOST without the retain flag; defaults to false.

With NO_RETAIN set to false, each client that subscribes to a topic pattern receives the retained message immediately after they subscribe.

The broker stores only one retained message per topic.

Examples in EXCH

Read a PLC address

Read an address from the PLC and write its value to an other OPC-UA PLC

writeField "opcua" "plc.setpoint" ${_v}

Write a value to the PLC

Write a 0-1000 Celsius temperature from the key-value DB to a PLC address, as a 16bit value.

writeField "step7" "setpoint" call(scale, 0, 1000, 0, 65535, db-key-value/temp)

Docker Container details


Supported architecture: amd64


  • fix on bit arrays
  • Parallel writes fix
  • Timezone added in cron expression
  • Fix error on plc connection
  • Fix string write
  • Smaller image
  • Cron expressions added
  • Fix on PLC disconnection
  • FROM_DEVICE_AGGREGATED_TOPIC_PREFIX Environment variable added
  • NO_RETAIN_FLAG Environment variable added
  • First Release