Tags

Symbolic and typed access to PLC variables.

A Tag describes a typed value at a specific S7 address. Tags can be constructed from a PLC4X-style address string, or loaded in bulk from CSV, JSON, or TIA Portal XML exports.

from s7 import Client, Tag, load_tia_xml

client = Client()
client.connect("192.168.1.10", 0, 1)

# Ad-hoc access with PLC4X-style strings
speed = client.read_tag("DB1.DBD0:REAL")
running = client.read_tag("DB1.DBX4.0:BOOL")
client.write_tag("DB1.DBW6:INT", 1500)

# Batch read (uses optimizer when enabled)
values = client.read_tags(["DB1.DBD0:REAL", "DB1.DBW6:INT"])

# Load named tags from a TIA Portal XML export
tags = load_tia_xml("db1.xml")
temperature = client.read_tag(tags["Motor.Temperature"])

Address syntax

Two dialects are supported. Each has its own parser class that returns a subtype of Tag; a __str__ on each subtype round-trips to its source dialect.

PLC4X / Siemens STEP7PLC4XTag:

DB1.DBX0.0:BOOL          # bit in data block
DB1.DBB10:BYTE           # byte
DB1.DBW10:INT            # word (2 bytes)
DB1.DBD10:REAL           # double word (4 bytes)
DB1:10:INT               # short form (DB 1, offset 10)
DB1:10:STRING[20]        # variable-length string
DB1:10:REAL[5]           # array of 5 REALs
M10.5:BOOL               # Merker bit
MW20:WORD                # Merker word
I0.0:BOOL                # input bit
Q0.0:BOOL                # output bit

The leading % is optional (%DB1.DBX0.0:BOOL also works). The type suffix (:TYPE) is required.

nodeS7 / pyS7NodeS7Tag:

DB1,X0.0                 # bit in data block
DB1,B10                  # byte
DB1,W10                  # word (unsigned 16-bit)
DB1,I10                  # int (signed 16-bit)
DB1,DW10                 # dword / DB1,DI10 for dint
DB1,R4                   # real
DB1,LR8                  # lreal
DB1,S10.20               # string at offset 10, 20 chars
M10.5                    # marker bit
MB10, MW10, MD10, MR10   # marker typed
IW22, QR24               # input word, output real

Area shortcuts (M, I, Q, plus German E, A) imply the type via the trailing typecode; no :TYPE suffix is needed.

Autodetectparse_tag() picks the right parser based on syntax markers. Pass strict=False to accept bare short forms like M7.1 or IW22 (dispatched to the nodeS7 parser):

from snap7.tags import parse_tag

parse_tag("DB1.DBD0:REAL")       # → PLC4XTag
parse_tag("DB1,R0")              # → NodeS7Tag
parse_tag("M7.1")                # raises: ambiguous under strict=True
parse_tag("M7.1", strict=False)  # → NodeS7Tag (BOOL)

Supported types

BOOL, BYTE, CHAR, WCHAR, SINT, USINT, INT, UINT, WORD, DINT, UDINT, DWORD, LINT, ULINT, LWORD, REAL, LREAL, TIME, LTIME, TOD, LTOD, DATE, DT, LDT, DTL, STRING[n], WSTRING[n], FSTRING[n].

Arrays are supported for any fixed-size type via [count] suffix.

Optimized block access (S7CommPlus)

Warning

Symbolic (LID-based) access is experimental and requires real PLC testing. The wire-level implementation follows the S7CommPlusDriver reference but has not yet been validated against hardware.

S7-1200/1500 DBs with “Optimized block access” enabled (the default in TIA Portal V13+) do not use fixed byte offsets. The PLC internally relocates variables between downloads, so addresses like DB1.DBX0.0 are unreliable.

For optimized blocks, use from_access_string() with LIDs discovered via browse():

from s7 import Client, Tag

client = Client()
client.connect("192.168.1.10", 0, 1)

# Create a symbolic tag (LIDs come from browse)
tag = Tag.from_access_string(
    "8A0E0001.A",           # DB1, LID 0xA
    datatype="REAL",
    name="Motor.Speed",
    symbol_crc=0x12345678,  # optional layout version check
)

# Read/write via S7CommPlus symbolic access
speed = client.read_tag(tag)
client.write_tag(tag, 1500.0)

API reference

Tag addressing for S7 PLCs.

A Tag represents a typed value at a specific S7 address. Tags can be created from:

  • A PLC4X-style address string: PLC4XTag.parse("DB1.DBX0.0:BOOL")

  • A nodeS7-style address string: NodeS7Tag.parse("DB1,X0.0")

  • A dialect-agnostic dispatcher: parse_tag("DB1,R4")

  • A CSV file: load_csv()

  • A JSON file: load_json()

  • A TIA Portal XML export: load_tia_xml()

  • A live PLC browse: {t.name: t for t in client.browse()}

Two dialects are supported:

  • PLC4X / Siemens STEP7DB1.DBX0.0:BOOL, DB1:10:REAL, M10.5:BOOL, MW20:WORD. The colon-type suffix is required.

  • nodeS7 / pyS7DB1,X0.0, DB1,R4, M10.5, IW22. The comma separates DB from typecode; area shortcuts imply the type.

parse_tag() autodetects dialect from syntax markers (, → nodeS7, :TYPE → PLC4X). Pass strict=False to allow bare short forms like M7.1 or IW22 (dispatched to the nodeS7 parser).

Example:

from s7 import Client
from s7.tags import parse_tag, load_tia_xml

client = Client()
client.connect("192.168.1.10", 0, 1)

# Ad-hoc tag access (either dialect)
speed = client.read_tag(parse_tag("DB1.DBD0:REAL"))
speed = client.read_tag(parse_tag("DB1,R0"))

# Named tags from a file
tags = load_tia_xml("db1.xml")
temperature = client.read_tag(tags["Motor.Temperature"])
class snap7.tags.NodeS7Tag(area: Area, db_number: int, byte_offset: int, datatype: str, bit: int = 0, count: int = 1, name: str = '', access_sequence: list[int] = <factory>, symbol_crc: int = 0)[source]

A Tag parsed from nodeS7 / pyS7 syntax.

Example inputs accepted by parse():

  • DB1,X0.0 — DB bit (BOOL)

  • DB1,B10 — DB byte

  • DB1,W10 — DB word (unsigned 16-bit)

  • DB1,I10 — DB int (signed 16-bit)

  • DB1,DW10 / DB1,DI10 — DB dword / dint

  • DB1,R10 — DB real

  • DB1,LR10 — DB lreal

  • DB1,S10.20 — DB string (offset 10, 20 chars)

  • DB1,WS10.10 — DB wstring

  • M10.5 — marker bit (bit form, type is BOOL)

  • MB10, MW10, MD10, MR10 — marker byte/word/dword/real

  • IW22, QR24 — input word, output real

__str__() str[source]

Round-trip to nodeS7 syntax.

classmethod parse(address: str, name: str = '') NodeS7Tag[source]

Parse a nodeS7 / pyS7 style tag address string.

Raises:

ValueError – If the address is malformed.

class snap7.tags.PLC4XTag(area: Area, db_number: int, byte_offset: int, datatype: str, bit: int = 0, count: int = 1, name: str = '', access_sequence: list[int] = <factory>, symbol_crc: int = 0)[source]

A Tag parsed from PLC4X / Siemens STEP7 syntax.

Example inputs accepted by parse():

  • DB1.DBX0.0:BOOL — DB bit

  • DB1.DBB10:BYTE — DB byte

  • DB1.DBW10:INT — DB word (signed)

  • DB1.DBD10:REAL — DB double word

  • DB1:10:INT — short form

  • DB1:10:STRING[20] — variable-length string

  • DB1:0:REAL[5] — array of 5 REALs

  • M10.5:BOOL, MW20:WORD — marker bit / marker word

  • I0.0:BOOL, Q0.0:BOOL — input / output bit

  • A leading % is accepted and ignored.

The type suffix (:TYPE) is required. Use NodeS7Tag for the shorter nodeS7 / pyS7 convention.

__str__() str[source]

Round-trip to PLC4X syntax.

classmethod parse(address: str, name: str = '') PLC4XTag[source]

Parse a PLC4X-style tag address string.

Raises:

ValueError – If the address is malformed or lacks a type suffix.

class snap7.tags.Tag(area: Area, db_number: int, byte_offset: int, datatype: str, bit: int = 0, count: int = 1, name: str = '', access_sequence: list[int] = <factory>, symbol_crc: int = 0)[source]

A typed reference to a value in a PLC data area.

This is the canonical, dialect-agnostic representation used by the protocol layer. For parsing strings, prefer PLC4XTag, NodeS7Tag, or the parse_tag() dispatcher — each of those returns a subtype whose __str__ round-trips to its source dialect.

A Tag can address the PLC in two ways:

  1. Byte-offset access (classic, works on all S7 PLCs) — uses byte_offset and bit. Supported on S7-300/400 and on S7-1200/1500 DBs with “Optimized block access” disabled.

  2. Symbolic (LID-based) access (S7CommPlus, for optimized DBs) — uses access_sequence (a list of LID values navigating the PLC’s symbol tree) and optionally symbol_crc. Required for S7-1200/1500 DBs with “Optimized block access” enabled.

If access_sequence is set, it takes precedence over byte_offset.

area

The S7 memory area (DB, MK, PE, PA).

Type:

snap7.type.Area

db_number

DB number (0 for non-DB areas).

Type:

int

byte_offset

Start byte offset within the area (classic access).

Type:

int

datatype

S7 data type name (BOOL, INT, REAL, STRING[20], …).

Type:

str

bit

Bit index (0-7) for BOOL tags; 0 for others.

Type:

int

count

Array count (1 = scalar, >1 = array).

Type:

int

name

Optional tag name for debugging/logging.

Type:

str

access_sequence

LID path for S7CommPlus symbolic access (optimized DBs).

Type:

list[int]

symbol_crc

Symbol CRC for the PLC to validate layout version (0 = no check).

Type:

int

__str__() str[source]

Render as PLC4X syntax (default dialect for bare Tags).

classmethod from_access_string(access_string: str, datatype: str, *, name: str = '', symbol_crc: int = 0, count: int = 1) Tag[source]

Create a Tag from an S7CommPlus access string for optimized blocks.

The access string is a dot-separated sequence of hex IDs representing the path through the PLC’s symbol tree, e.g. "8A0E0001.A" (DB1, LID 0xA) for a variable in DB1 with optimized block access.

This format is used for S7-1200/1500 DBs with “Optimized block access” enabled. Byte offsets are unreliable for such blocks, so the PLC is addressed via the symbol tree instead.

Parameters:
  • access_string – Dot-separated hex IDs, e.g. "8A0E0001.A.1". The first ID is the AccessArea, remaining IDs are LIDs.

  • datatype – S7 type name (e.g. "REAL", "BOOL", "INT[5]").

  • name – Optional tag name.

  • symbol_crc – Symbol CRC from the PLC (0 = no check).

  • count – Array count (overridden if datatype includes [n]).

Returns:

A Tag configured for symbolic access.

Raises:

ValueError – If the access_string is not at least one hex component.

classmethod from_string(address: str, name: str = '') PLC4XTag[source]

Parse a PLC4X-style tag address string.

Kept for backwards compatibility; equivalent to PLC4XTag.parse(address, name). For new code, prefer the explicit dialect parsers or parse_tag().

property is_symbolic: bool

Whether this Tag uses S7CommPlus symbolic (LID-based) access.

property size: int

Total byte size of this tag (including array count).

snap7.tags.from_browse(variables: list[dict[str, Any]]) dict[str, Tag][source]

Build a dict of Tags from s7.Client.browse() results.

Warning

This function is experimental and may change.

When the browse result includes an lid key, the resulting Tag is configured for symbolic (LID-based) access suitable for optimized DBs. Otherwise it uses byte-offset access.

Parameters:

variables – List of variable-info dicts from client.browse().

Returns:

Dictionary mapping variable names to Tag objects.

snap7.tags.load_csv(source: str | Path) dict[str, Tag][source]

Load tags from a CSV file or string.

Expected columns: tag, db, offset, type. Optional column: bit.

Parameters:

source – Path to a CSV file, or inline CSV text.

Returns:

Dictionary mapping tag names to Tag objects.

snap7.tags.load_json(source: str | Path) dict[str, Tag][source]

Load tags from a JSON file or string.

Expected format: {"tag_name": {"db": N, "offset": M, "type": "T", "bit": B}, ...}

Parameters:

source – Path to a JSON file, or inline JSON text.

Returns:

Dictionary mapping tag names to Tag objects.

snap7.tags.load_tia_xml(source: str | Path) dict[str, Tag][source]

Load tags from a TIA Portal DB source XML export.

TIA Portal exports DB definitions via right-click > “Generate source from blocks”, producing XML with field names, offsets, and data types.

Parameters:

source – Path to an XML file exported from TIA Portal.

Returns:

Dictionary mapping tag names to Tag objects.

snap7.tags.parse_tag(address: str, *, strict: bool = True, name: str = '') Tag[source]

Autodetect dialect and parse a tag address string.

Dialect is detected from syntax markers:

  • A comma (,) selects NodeS7Tag.

  • A colon followed by a type (:TYPE) selects PLC4XTag.

Parameters:
  • address – Tag address string.

  • strict – When True (default), require one of the dialect markers above. Bare short forms like M7.1 or IW22 raise ValueError. When False, bare forms are dispatched to the nodeS7 parser (which accepts them).

  • name – Optional tag name to store on the resulting Tag.

Returns:

A PLC4XTag or NodeS7Tag depending on the dialect detected.

Raises:

ValueError – If the input is ambiguous under strict mode, or if the selected parser fails to parse.