Async Client
AsyncClient is the asyncio counterpart of Client. It has the
same PLC operations, and every method that talks to the PLC is a coroutine:
import asyncio
from s7 import AsyncClient
async def main() -> None:
async with AsyncClient() as client:
await client.connect("192.168.1.10", 0, 1)
data = await client.db_read(1, 0, 4)
await client.db_write(1, 0, bytearray([1, 2, 3, 4]))
asyncio.run(main())
Leaving the async with block disconnects the client.
Concurrency
An internal asyncio.Lock serialises each request and its reply, so several
coroutines can share one client:
async def read_all(client: AsyncClient) -> list[bytearray]:
return await asyncio.gather(
client.db_read(1, 0, 4),
client.db_read(1, 10, 4),
client.db_read(2, 0, 8),
)
The requests still go to the PLC one after the other; gather only lets the
rest of the application run while they wait. One client belongs to one event
loop. Do not call it from other threads.
Differences from Client
There is no heartbeat thread and no
heartbeat_intervalargument.is_alivereports the connection state seen by the last operation.read_multi_varsandwrite_multi_varsaccept only the dict form, andread_multi_varsandread_tagsread the items one after the other. There is no read optimizer and nomax_parallel. See Multi-Variable Read and Write.
s7.AsyncClient
Asynchronous client for the classic S7 protocol.
Uses asyncio streams for non-blocking I/O with an asyncio.Lock() to serialize send/receive cycles, ensuring safe concurrent use via asyncio.gather().
s7.AsyncClient and snap7.AsyncClient expose this same implementation.
- class snap7.async_client.AsyncClient(*, max_requests_per_second: float = 0, rate_limit_algorithm: Literal['fixed', 'token_bucket'] = 'fixed', rate_limit_behavior: Literal['block', 'raise'] = 'block', rate_limit_burst: int | None = None, on_operation: Callable[[str, float, bool], None] | None = None)[source]
Asynchronous client for classic S7 communication.
Uses asyncio streams for non-blocking I/O. An internal asyncio.Lock serializes each send+receive cycle so that concurrent coroutines (e.g. via asyncio.gather) never interleave on the same TCP socket.
For new projects, use
s7.AsyncClientinstead.Examples
>>> from s7 import AsyncClient >>> async with AsyncClient() as client: ... await client.connect("192.168.1.10", 0, 1) ... data = await client.db_read(1, 0, 4)
- async __aenter__() AsyncClient[source]
Async context manager entry.
- async cancel_force(area: Area, byte_offset: int, bit: int) None[source]
Cancel a forced I/O bit by clearing it in the process image.
Async equivalent of
snap7.client.Client.cancel_force().
- async clear_session_password() int[source]
Clear the session password, returning to the default protection level.
Sends an S7 USERDATA request (function group 5, subfunction 2).
- Returns:
0 on success.
- Raises:
S7ConnectionError – If not connected.
S7ProtocolError – If the PLC rejects the request.
- async connect(address: str, rack: int, slot: int, tcp_port: int = 102) AsyncClient[source]
Connect to S7 PLC.
- Parameters:
address – PLC IP address
rack – Rack number
slot – Slot number
tcp_port – TCP port (default 102)
- Returns:
Self for method chaining
- async connect_routed(host: str, router_rack: int, router_slot: int, subnet: int, dest_rack: int, dest_slot: int, port: int = 102, timeout: float = 5.0) AsyncClient[source]
Connect to an S7 PLC via a routing gateway on another subnet.
Warning
This method is experimental and may change in future versions.
- Parameters:
host – IP address of the routing gateway PLC
router_rack – Rack number of the gateway PLC
router_slot – Slot number of the gateway PLC
subnet – Subnet ID of the target network (0x0000-0xFFFF)
dest_rack – Rack number of the destination PLC
dest_slot – Slot number of the destination PLC
port – TCP port (default 102)
timeout – Connection timeout in seconds
- Returns:
Self for method chaining
- async db_fill(db_number: int, filler: int, size: int = 0) int[source]
Fill a DB with a filler byte.
- Parameters:
db_number – DB number to fill
filler – Byte value to fill with
size – DB size in bytes. If 0, determined via get_block_info().
- Returns:
0 on success
- async db_get(db_number: int, size: int = 0) bytearray[source]
Get entire DB.
- Parameters:
db_number – DB number to read
size – DB size in bytes. If 0, determined via get_block_info().
- Returns:
Entire DB contents
- async db_read(db_number: int, start: int, size: int) bytearray[source]
Read data from DB.
- Parameters:
db_number – DB number to read from
start – Start byte offset
size – Number of bytes to read
- Returns:
Data read from DB
- async db_read_array(db_number: int, start: int, count: int, fmt: str = '>f') list[Any][source]
Read count consecutive values of struct format fmt from a DB.
- async db_read_bool(db_number: int, byte_offset: int, bit_offset: int) bool[source]
Read a single bit from a DB.
- async db_read_byte(db_number: int, offset: int) int[source]
Read a BYTE (8-bit unsigned) from a DB.
- async db_read_dword(db_number: int, offset: int) int[source]
Read a DWORD (32-bit unsigned) from a DB.
- async db_read_lreal(db_number: int, offset: int) float[source]
Read a LREAL (64-bit float) from a DB.
- async db_read_real(db_number: int, offset: int) float[source]
Read a REAL (32-bit float) from a DB.
- async db_read_string(db_number: int, offset: int) str[source]
Read an S7 STRING from a DB (header first to learn the max length).
- async db_read_udint(db_number: int, offset: int) int[source]
Read a UDINT (32-bit unsigned) from a DB.
- async db_read_uint(db_number: int, offset: int) int[source]
Read a UINT (16-bit unsigned) from a DB.
- async db_read_word(db_number: int, offset: int) int[source]
Read a WORD (16-bit unsigned) from a DB.
- async db_read_wstring(db_number: int, offset: int) str[source]
Read an S7 WSTRING from a DB (header first to learn the max length).
- async db_write(db_number: int, start: int, data: bytearray) int[source]
Write data to DB.
- Parameters:
db_number – DB number to write to
start – Start byte offset
data – Data to write
- Returns:
0 on success
- async db_write_array(db_number: int, start: int, values: list[Any], fmt: str = '>f') int[source]
Write values packed with struct format fmt to a DB. Returns 0 on success.
- async db_write_bool(db_number: int, byte_offset: int, bit_offset: int, value: bool) None[source]
Write a single bit to a DB, preserving the other bits in the byte.
- async db_write_byte(db_number: int, offset: int, value: int) None[source]
Write a BYTE (8-bit unsigned) to a DB.
- async db_write_dint(db_number: int, offset: int, value: int) None[source]
Write a DINT (32-bit signed) to a DB.
- async db_write_dword(db_number: int, offset: int, value: int) None[source]
Write a DWORD (32-bit unsigned) to a DB.
- async db_write_int(db_number: int, offset: int, value: int) None[source]
Write an INT (16-bit signed) to a DB.
- async db_write_lreal(db_number: int, offset: int, value: float) None[source]
Write a LREAL (64-bit float) to a DB.
- async db_write_real(db_number: int, offset: int, value: float) None[source]
Write a REAL (32-bit float) to a DB.
- async db_write_string(db_number: int, offset: int, value: str, max_length: int = 254) None[source]
Write an S7 STRING with the given maximum length to a DB.
- async db_write_udint(db_number: int, offset: int, value: int) None[source]
Write a UDINT (32-bit unsigned) to a DB.
- async db_write_uint(db_number: int, offset: int, value: int) None[source]
Write a UINT (16-bit unsigned) to a DB.
- async db_write_word(db_number: int, offset: int, value: int) None[source]
Write a WORD (16-bit unsigned) to a DB.
- async db_write_wstring(db_number: int, offset: int, value: str, max_length: int = 254) None[source]
Write an S7 WSTRING with the given maximum length (in characters) to a DB.
- async eb_write(start: int, size: int, data: bytearray) int[source]
Write to process input area (PE).
- error_text(error_code: int) str
Get error text for error code.
- Parameters:
error_code – Error code to look up
- Returns:
Human-readable error text
- async force_bit(area: Area, byte_offset: int, bit: int, value: bool) None[source]
Force a single I/O bit in the process image.
Async equivalent of
snap7.client.Client.force_bit().
- async full_upload(block_type: Block, block_num: int) Tuple[bytearray, int][source]
Upload a block from PLC with header and footer info.
- async get_block_info(block_type: Block, db_number: int) TS7BlockInfo[source]
Get block information.
- async get_cpu_state() str[source]
Get the CPU operating state by reading SZL 0x0424.
Returns
"S7CpuStatusRun","S7CpuStatusStop"or"S7CpuStatusUnknown". Startup, HOLD and DEFECT are reported as"S7CpuStatusStop", as native Snap7 does.- Raises:
S7ConnectionError – If the client is not connected.
S7ProtocolError – If the PLC refuses SZL 0x0424 or its reply is too short.
- async get_order_code() S7OrderCode[source]
Get module order code and firmware version (SZL 0x0011).
- get_param(param: Parameter) int
Get client parameter.
- Parameters:
param – Parameter number
- Returns:
Parameter value
- get_pg_block_info(data: bytearray) TS7BlockInfo
Get block info from raw block data.
- Parameters:
data – Raw block data
- Returns:
Block information structure
- async get_protection() S7Protection[source]
Get protection settings (SZL 0x0232).
- property is_alive: bool
Whether the client is connected.
Unlike the synchronous client there is no background heartbeat, so this reflects the connection state seen by the last operation.
- async list_blocks() BlocksList[source]
List blocks available in PLC.
- async list_blocks_of_type(block_type: Block, max_count: int) List[int][source]
List blocks of a specific type.
Supports multi-packet responses.
- async read_area(area: Area, db_number: int, start: int, size: int) bytearray[source]
Read data from memory area.
Automatically splits into multiple requests if size exceeds PDU capacity.
- async read_diagnostic_buffer() list[dict[str, Any]][source]
Read the PLC diagnostic buffer (experimental), newest first.
Each entry is a dict with keys
event_id,timestampandinfo.
- async read_force_table() list[ForceEntry][source]
Read the PLC force table via SZL 0x0025.
Async equivalent of
snap7.client.Client.read_force_table().
- async read_multi_vars(items: List[dict[str, Any]]) Tuple[int, list[bytearray]][source]
Read multiple variables (sequentially, one read_area per item).
- Parameters:
items – List of item dicts with keys: area, db_number, start, size. Any number of items is accepted.
- Returns:
Tuple of (result_code, list_of_bytearrays)
- async read_szl(ssl_id: int, index: int = 0) S7SZL[source]
Read SZL (System Status List).
Supports multi-packet responses.
- async read_tag(tag: Tag | str, encoding: str = 'latin-1') Any[source]
Read a typed value by
Tagor PLC4X-style address string.
- async read_tags(tags: Sequence[Tag | str], encoding: str = 'latin-1') list[Any][source]
Read any number of tags, returning the values in input order.
- set_connection_params(address: str, local_tsap: int, remote_tsap: int) None
Set connection parameters.
- Parameters:
address – PLC IP address
local_tsap – Local TSAP
remote_tsap – Remote TSAP
- set_connection_type(connection_type: int) None
Set connection type.
- Parameters:
connection_type – Connection type (1=PG, 2=OP, 3=S7Basic)
- set_param(param: Parameter, value: int) int
Set client parameter.
- Parameters:
param – Parameter number
value – Parameter value
- Returns:
0 on success
- async set_session_password(password: str) int[source]
Set the session password to unlock a password-protected PLC.
Sends an S7 USERDATA request (function group 5, subfunction 1) with the encoded password.
- Parameters:
password – Plaintext password (max 8 ASCII characters).
- Returns:
0 on success.
- Raises:
S7ConnectionError – If not connected.
S7ProtocolError – If the PLC rejects the password.
- async upload(block_num: int) bytearray[source]
Upload block from PLC (3-step: START_UPLOAD, UPLOAD, END_UPLOAD).
- async write_area(area: Area, db_number: int, start: int, data: bytearray) int[source]
Write data to memory area.
Automatically splits into multiple requests if data exceeds PDU capacity.