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 STEP7 — PLC4XTag:
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 / pyS7 — NodeS7Tag:
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.
Autodetect — parse_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 STEP7 —
DB1.DBX0.0:BOOL,DB1:10:REAL,M10.5:BOOL,MW20:WORD. The colon-type suffix is required.nodeS7 / pyS7 —
DB1,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 byteDB1,W10— DB word (unsigned 16-bit)DB1,I10— DB int (signed 16-bit)DB1,DW10/DB1,DI10— DB dword / dintDB1,R10— DB realDB1,LR10— DB lrealDB1,S10.20— DB string (offset 10, 20 chars)DB1,WS10.10— DB wstringM10.5— marker bit (bit form, type is BOOL)MB10,MW10,MD10,MR10— marker byte/word/dword/realIW22,QR24— input word, output real
- 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 bitDB1.DBB10:BYTE— DB byteDB1.DBW10:INT— DB word (signed)DB1.DBD10:REAL— DB double wordDB1:10:INT— short formDB1:10:STRING[20]— variable-length stringDB1:0:REAL[5]— array of 5 REALsM10.5:BOOL,MW20:WORD— marker bit / marker wordI0.0:BOOL,Q0.0:BOOL— input / output bitA leading
%is accepted and ignored.
The type suffix (
:TYPE) is required. UseNodeS7Tagfor the shorter nodeS7 / pyS7 convention.
- 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 theparse_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:
Byte-offset access (classic, works on all S7 PLCs) — uses
byte_offsetandbit. Supported on S7-300/400 and on S7-1200/1500 DBs with “Optimized block access” disabled.Symbolic (LID-based) access (S7CommPlus, for optimized DBs) — uses
access_sequence(a list of LID values navigating the PLC’s symbol tree) and optionallysymbol_crc. Required for S7-1200/1500 DBs with “Optimized block access” enabled.
If
access_sequenceis set, it takes precedence overbyte_offset.- area
The S7 memory area (DB, MK, PE, PA).
- Type:
- 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
- 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
Tagconfigured 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 orparse_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
lidkey, 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
Tagobjects.
- 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
Tagobjects.
- 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
Tagobjects.
- 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
Tagobjects.
- 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:
- Parameters:
address – Tag address string.
strict – When
True(default), require one of the dialect markers above. Bare short forms likeM7.1orIW22raiseValueError. WhenFalse, bare forms are dispatched to the nodeS7 parser (which accepts them).name – Optional tag name to store on the resulting Tag.
- Returns:
- Raises:
ValueError – If the input is ambiguous under strict mode, or if the selected parser fails to parse.