pub struct S7Client<T: AsyncRead + AsyncWrite + Unpin + Send> { /* private fields */ }Implementations§
Source§impl<T: AsyncRead + AsyncWrite + Unpin + Send> S7Client<T>
impl<T: AsyncRead + AsyncWrite + Unpin + Send> S7Client<T>
pub async fn from_transport(transport: T, params: ConnectParams) -> Result<Self>
Sourcepub fn request_timeout(&self) -> Duration
pub fn request_timeout(&self) -> Duration
Return the current request timeout.
Sourcepub async fn get_exec_time(&self) -> u32
pub async fn get_exec_time(&self) -> u32
Returns the execution time of the last completed S7 operation in milliseconds.
Measures full round-trip: from send to response received. Equivalent to C Cli_GetExecTime.
Sourcepub async fn is_connected(&self) -> bool
pub async fn is_connected(&self) -> bool
Returns whether the transport connection is alive.
Set to false when any I/O error is encountered.
Equivalent to C Cli_GetConnected.
Sourcepub async fn set_request_timeout(&self, timeout: Duration)
pub async fn set_request_timeout(&self, timeout: Duration)
Update the request timeout at runtime.
This affects subsequent recv_s7 calls made by this client instance.
Sourcepub fn get_param(&self, name: &str) -> Result<Duration>
pub fn get_param(&self, name: &str) -> Result<Duration>
Read a client parameter by name.
Supported names: "request_timeout", "connect_timeout", "pdu_size".
Sourcepub fn set_param(&mut self, name: &str, value: Duration) -> Result<()>
pub fn set_param(&mut self, name: &str, value: Duration) -> Result<()>
Set a client parameter at runtime.
Supported names: "request_timeout" (Duration).
pub async fn db_read(&self, db: u16, start: u32, length: u16) -> Result<Bytes>
Sourcepub async fn read_area(
&self,
area: Area,
db_number: u16,
start: u32,
element_count: u16,
transport: TransportSize,
) -> Result<Bytes>
pub async fn read_area( &self, area: Area, db_number: u16, start: u32, element_count: u16, transport: TransportSize, ) -> Result<Bytes>
Read from any PLC area with explicit transport size.
For DB areas use db_read. For Marker/Timer/Counter use this method.
Timer (area=Timer, transport=Timer) and Counter (area=Counter, transport=Counter)
use element-index addressing (no ×8 shift) and return 2 bytes per element.
Sourcepub async fn read_multi_vars(
&self,
items: &[MultiReadItem],
) -> Result<Vec<Bytes>>
pub async fn read_multi_vars( &self, items: &[MultiReadItem], ) -> Result<Vec<Bytes>>
Read multiple PLC regions in one or more S7 PDU exchanges.
Automatically batches items when the item count would exceed the Siemens hard
limit of 20 per PDU, or when the encoded request or response would exceed the
negotiated PDU size. Returns one Bytes per item in input order.
Unlike db_read, this accepts any Area and TransportSize.
Sourcepub async fn write_multi_vars(&self, items: &[MultiWriteItem]) -> Result<()>
pub async fn write_multi_vars(&self, items: &[MultiWriteItem]) -> Result<()>
Write multiple PLC regions in one or more S7 PDU exchanges.
Automatically batches items when the count or encoded size would exceed the
negotiated PDU size or the Siemens hard limit of 20 items per PDU.
Returns Ok(()) only when all items are acknowledged with return code 0xFF.
pub async fn db_write(&self, db: u16, start: u32, data: &[u8]) -> Result<()>
Sourcepub async fn write_area(
&self,
area: Area,
db_number: u16,
start: u32,
transport: TransportSize,
data: &[u8],
) -> Result<()>
pub async fn write_area( &self, area: Area, db_number: u16, start: u32, transport: TransportSize, data: &[u8], ) -> Result<()>
Write to any PLC area with explicit transport size.
For Timer/Counter areas the transport size byte in the request must match
the area (0x1D / 0x1C). For Marker use TransportSize::Byte.
Sourcepub async fn ab_read(
&self,
area: Area,
db_number: u16,
start: u32,
length: u16,
) -> Result<Bytes>
pub async fn ab_read( &self, area: Area, db_number: u16, start: u32, length: u16, ) -> Result<Bytes>
Read from any PLC area using absolute addressing.
A convenience wrapper around read_multi_vars
for a single area read.
Sourcepub async fn ab_write(
&self,
area: Area,
db_number: u16,
start: u32,
data: &[u8],
) -> Result<()>
pub async fn ab_write( &self, area: Area, db_number: u16, start: u32, data: &[u8], ) -> Result<()>
Write to any PLC area using absolute addressing.
A convenience wrapper around write_multi_vars
for a single area write.
Sourcepub async fn mb_read(&self, start: u32, length: u16) -> Result<Bytes>
pub async fn mb_read(&self, start: u32, length: u16) -> Result<Bytes>
Read Merker (flag) bytes starting at start, length bytes.
Sourcepub async fn mb_write(&self, start: u32, data: &[u8]) -> Result<()>
pub async fn mb_write(&self, start: u32, data: &[u8]) -> Result<()>
Write Merker (flag) bytes starting at start.
Sourcepub async fn eb_read(&self, start: u32, length: u16) -> Result<Bytes>
pub async fn eb_read(&self, start: u32, length: u16) -> Result<Bytes>
Read I/O input (EB) bytes starting at start, length bytes.
Sourcepub async fn eb_write(&self, start: u32, data: &[u8]) -> Result<()>
pub async fn eb_write(&self, start: u32, data: &[u8]) -> Result<()>
Write I/O input (EB) bytes starting at start.
Sourcepub async fn ib_read(&self, start: u32, length: u16) -> Result<Bytes>
pub async fn ib_read(&self, start: u32, length: u16) -> Result<Bytes>
Read I/O output (AB) bytes starting at start, length bytes.
Sourcepub async fn ib_write(&self, start: u32, data: &[u8]) -> Result<()>
pub async fn ib_write(&self, start: u32, data: &[u8]) -> Result<()>
Write I/O output (AB) bytes starting at start.
Sourcepub async fn tm_read(&self, start: u32, amount: u16) -> Result<Bytes>
pub async fn tm_read(&self, start: u32, amount: u16) -> Result<Bytes>
Read amount Timer words starting at timer index start.
Sourcepub async fn tm_write(&self, start: u32, data: &[u8]) -> Result<()>
pub async fn tm_write(&self, start: u32, data: &[u8]) -> Result<()>
Write Timer S5Time words. data must be amount * 2 bytes (one word per timer).
Sourcepub async fn ct_read(&self, start: u32, amount: u16) -> Result<Bytes>
pub async fn ct_read(&self, start: u32, amount: u16) -> Result<Bytes>
Read amount Counter BCD words starting at counter index start.
Sourcepub async fn ct_write(&self, start: u32, data: &[u8]) -> Result<()>
pub async fn ct_write(&self, start: u32, data: &[u8]) -> Result<()>
Write Counter BCD words. data must be amount * 2 bytes (one word per counter).
pub async fn read_szl(&self, szl_id: u16, szl_index: u16) -> Result<SzlResponse>
pub async fn read_clock(&self) -> Result<PlcDateTime>
Sourcepub async fn set_clock(&self, dt: &PlcDateTime) -> Result<()>
pub async fn set_clock(&self, dt: &PlcDateTime) -> Result<()>
Set the PLC clock (UserData function group 0x47 = clock, subfunction 0x02 = write).
Sourcepub async fn set_clock_to_now(&self) -> Result<()>
pub async fn set_clock_to_now(&self) -> Result<()>
Set the PLC clock to the host system time.
Uses std::time::SystemTime converted to a PlcDateTime. The
weekday field is set to 0 (unknown) since SystemTime does not carry it.
Sourcepub async fn force_bit(
&self,
area: Area,
byte_addr: u32,
bit: u8,
value: bool,
) -> Result<()>
pub async fn force_bit( &self, area: Area, byte_addr: u32, bit: u8, value: bool, ) -> Result<()>
Force a bit in the process image output (Q) or process image input (I).
area must be Area::ProcessOutput (Q) or Area::ProcessInput (I).
byte_addr is the byte address, bit is the bit number (0–7).
value is true to force to 1, false to force to 0.
For outputs (Q): writes directly to the process image output — effective on the next CPU scan cycle. For inputs (I): writes to the process image input — note that many CPUs will overwrite this on the next scan cycle unless the CPU is in STOP mode or the input is truly “forced” via the CPU’s force table (STEP7 “Force Variables” function).
Sourcepub async fn force_byte(
&self,
area: Area,
byte_addr: u32,
value: u8,
) -> Result<()>
pub async fn force_byte( &self, area: Area, byte_addr: u32, value: u8, ) -> Result<()>
Force a whole byte in the process image output (Q) or input (I).
Sourcepub async fn force_cancel_byte(&self, area: Area, byte_addr: u32) -> Result<()>
pub async fn force_cancel_byte(&self, area: Area, byte_addr: u32) -> Result<()>
Cancel force on a byte by writing 0x00 to it.
Sourcepub async fn read_force_list(&self) -> Result<Bytes>
pub async fn read_force_list(&self) -> Result<Bytes>
Read the SZL force table (SZL ID 0x0025) — returns raw SZL payload.
Returns an empty Bytes when the CPU reports no forced variables.
Sourcepub async fn read_szl_list(&self) -> Result<Vec<u16>>
pub async fn read_szl_list(&self) -> Result<Vec<u16>>
Read the list of all available SZL IDs from the PLC (SZL ID 0x0000).
Returns a Vec<u16> where each entry is a supported SZL ID.
Sourcepub async fn copy_ram_to_rom(&self) -> Result<()>
pub async fn copy_ram_to_rom(&self) -> Result<()>
Copy RAM data to ROM (function 0x43).
Copies the CPU’s work memory to its load memory (retain on power-off).
Sourcepub async fn compress(&self) -> Result<()>
pub async fn compress(&self) -> Result<()>
Compress the PLC work memory (function 0x42).
Reorganises memory to eliminate fragmentation. The PLC must be in STOP mode before calling this.
Sourcepub async fn memory_reset(&self) -> Result<()>
pub async fn memory_reset(&self) -> Result<()>
Memory Reset — clears all work memory blocks.
The PLC must be in STOP mode before calling this. After memory reset the CPU will no longer have any OBs, FBs, FCs or DBs; it must be re-programmed before it can be restarted.
Sourcepub async fn overall_reset(&self) -> Result<()>
pub async fn overall_reset(&self) -> Result<()>
Overall Reset — formats the entire PLC memory (load + work + retain).
More destructive than memory_reset: also wipes
the load memory (Flash/RAM card). PLC must be in STOP mode.
Sourcepub async fn upload_all_blocks(
&self,
block_types: &[u8],
) -> Result<Vec<(u8, u16, Vec<u8>)>>
pub async fn upload_all_blocks( &self, block_types: &[u8], ) -> Result<Vec<(u8, u16, Vec<u8>)>>
Upload all blocks of given types from the PLC.
Returns a Vec of (block_type, block_number, data) tuples.
Pass block_types as a slice of raw type bytes, e.g.
&[0x38, 0x41, 0x43, 0x45] for OB, DB, FC, FB.
Sourcepub async fn plc_stop(&self) -> Result<()>
pub async fn plc_stop(&self) -> Result<()>
Stop the PLC (S7 function code 0x29).
Sends a Job request with no additional data. Returns Ok(()) when the
PLC acknowledges the command, or an error if the PLC rejects it
(e.g., password-protected or CPU in a non-stoppable state).
Sourcepub async fn plc_hot_start(&self) -> Result<()>
pub async fn plc_hot_start(&self) -> Result<()>
Hot-start (warm restart) the PLC (S7 function code 0x28).
A warm restart retains the DB content and retentive memory.
Sourcepub async fn plc_cold_start(&self) -> Result<()>
pub async fn plc_cold_start(&self) -> Result<()>
Cold-start (full restart) the PLC (S7 function code 0x2A).
A cold start clears all DBs and non-retentive memory.
Sourcepub async fn get_plc_status(&self) -> Result<PlcStatus>
pub async fn get_plc_status(&self) -> Result<PlcStatus>
Read the current PLC status via SZL 0x0424.
Returns one of [PlcStatus::Run], [PlcStatus::Stop], or
[PlcStatus::Unknown].
Sourcepub async fn get_order_code(&self) -> Result<OrderCode>
pub async fn get_order_code(&self) -> Result<OrderCode>
Read the PLC order code (SZL ID 0x0011).
The order code is a 20-character ASCII string (e.g. "6ES7 317-2EK14-0AB0").
Sourcepub async fn get_cpu_info(&self) -> Result<CpuInfo>
pub async fn get_cpu_info(&self) -> Result<CpuInfo>
Read detailed CPU information (SZL ID 0x001C).
Returns module type, serial number, plant identification, copyright and module name fields pre-parsed from the SZL response. Handles both classic S7-300/400 and S7-1200/1500 response formats.
Sourcepub async fn get_cp_info(&self) -> Result<CpInfo>
pub async fn get_cp_info(&self) -> Result<CpInfo>
Read communication processor information (SZL ID 0x0131, index 0x0001).
Returns maximum PDU length, connection count, and baud rates.
Sourcepub async fn read_module_list(&self) -> Result<Vec<ModuleEntry>>
pub async fn read_module_list(&self) -> Result<Vec<ModuleEntry>>
Read the rack module list (SZL ID 0x00A0).
Each entry is a 2-byte module type identifier.
Sourcepub async fn list_blocks(&self) -> Result<BlockList>
pub async fn list_blocks(&self) -> Result<BlockList>
List all blocks in the PLC grouped by type.
Uses UserData function group 0x43 (grBlocksInfo), SubFun 0x01 (ListAll). Response: 7 entries of [Zero(1) BType(1) BCount(2)] = 28 bytes data.
Sourcepub async fn list_blocks_of_type(&self, block_type: u8) -> Result<Vec<u16>>
pub async fn list_blocks_of_type(&self, block_type: u8) -> Result<Vec<u16>>
List all block numbers of a given type (grBlocksInfo / SFun_ListBoT = 0x02).
block_type is the raw byte: 0x38=OB, 0x41=DB, 0x42=SDB, 0x43=FC,
0x44=SFC, 0x45=FB, 0x46=SFB.
Returns a sorted vec of block numbers.
Sourcepub async fn get_ag_block_info(
&self,
block_type: u8,
block_number: u16,
) -> Result<BlockInfo>
pub async fn get_ag_block_info( &self, block_type: u8, block_number: u16, ) -> Result<BlockInfo>
Get detailed information about a block stored on the PLC.
block_type should be one of the BlockType
discriminant values (e.g. 0x41 for DB, 0x38 for OB).
Sourcepub async fn get_pg_block_info(
&self,
block_type: u8,
block_number: u16,
) -> Result<BlockInfo>
pub async fn get_pg_block_info( &self, block_type: u8, block_number: u16, ) -> Result<BlockInfo>
Get detailed block information from the PG perspective.
Same fields as get_ag_block_info but the
information is from the programming-device viewpoint.
Sourcepub fn parse_block_info(data: &[u8]) -> Result<BlockInfo>
pub fn parse_block_info(data: &[u8]) -> Result<BlockInfo>
Parse block info from raw block bytes obtained via upload
or full_upload. No PLC connection required.
Equivalent to C Cli_GetPgBlockInfo offline parsing mode.
Sourcepub async fn set_session_password(&self, password: &str) -> Result<()>
pub async fn set_session_password(&self, password: &str) -> Result<()>
Set a session password for protected PLC access.
The password is obfuscated using the S7 nibble-swap + XOR-0x55 algorithm and sent as a Job PDU with function code 0x12. Passwords longer than 8 bytes are truncated.
Sourcepub async fn clear_session_password(&self) -> Result<()>
pub async fn clear_session_password(&self) -> Result<()>
Clear the session password on the PLC (function code 0x11).
Sourcepub async fn get_protection(&self) -> Result<Protection>
pub async fn get_protection(&self) -> Result<Protection>
Read the current protection level (SZL ID 0x0032, index 0x0004).
Returns the protection scheme identifiers and level;
password_set is true when the PLC reports a non-empty password.
Sourcepub async fn delete_block(
&self,
block_type: u8,
block_number: u16,
) -> Result<()>
pub async fn delete_block( &self, block_type: u8, block_number: u16, ) -> Result<()>
Delete a block from the PLC (S7 function code 0x1F).
Sourcepub async fn upload(&self, block_type: u8, block_number: u16) -> Result<Vec<u8>>
pub async fn upload(&self, block_type: u8, block_number: u16) -> Result<Vec<u8>>
Upload a PLC block via S7 PI-Upload (function 0x1D).
Returns the raw block bytes in Diagra format (20-byte header + payload).
Use [BlockData::from_bytes] to parse the result.
Sourcepub async fn full_upload(
&self,
block_type: u8,
block_number: u16,
) -> Result<Vec<u8>>
pub async fn full_upload( &self, block_type: u8, block_number: u16, ) -> Result<Vec<u8>>
Full-upload a PLC block including MC7 (executable) code (S7 function 0x1F).
Unlike upload which returns only the header/interface,
full_upload returns the complete block including executable code.
Sourcepub async fn get_pdu_length(&self) -> u16
pub async fn get_pdu_length(&self) -> u16
Return the negotiated PDU length in bytes.
Sourcepub async fn db_get(&self, db_number: u16) -> Result<Vec<u8>>
pub async fn db_get(&self, db_number: u16) -> Result<Vec<u8>>
Upload a DB block (convenience wrapper around upload).
Sourcepub async fn download(
&self,
block_type: u8,
block_number: u16,
data: &[u8],
) -> Result<()>
pub async fn download( &self, block_type: u8, block_number: u16, data: &[u8], ) -> Result<()>
Download a block to the PLC (S7 function 0x1E).
data should be in Diagra format (20-byte header + payload, as returned by
upload or built via [BlockData::to_bytes]).
Sourcepub async fn create_db(
&self,
db_number: u16,
size_bytes: u16,
attrs: Option<&BlockAttributes>,
) -> Result<()>
pub async fn create_db( &self, db_number: u16, size_bytes: u16, attrs: Option<&BlockAttributes>, ) -> Result<()>
Create a new empty DB on the PLC.
Downloads a minimal zero-filled DB block. The PLC must be in STOP mode
or support online DB creation (S7-400 / S7-1500). If attrs is
Some, the block attributes are applied before download.
Sourcepub async fn compare_blocks(
&self,
local: &[(u8, u16, Vec<u8>)],
report_plc_only: bool,
) -> Result<Vec<(u8, u16, BlockCmpResult)>>
pub async fn compare_blocks( &self, local: &[(u8, u16, Vec<u8>)], report_plc_only: bool, ) -> Result<Vec<(u8, u16, BlockCmpResult)>>
Compare local block data against blocks currently on the PLC.
For each (block_type, block_number, local_bytes) entry in local,
uploads the corresponding PLC block and compares CRC-32 checksums.
Also reports blocks that exist only on the PLC (missing locally) when
report_plc_only is true.
Source§impl S7Client<TcpTransport>
impl S7Client<TcpTransport>
pub async fn connect(addr: SocketAddr, params: ConnectParams) -> Result<Self>
Source§impl S7Client<UdpTransport>
impl S7Client<UdpTransport>
Sourcepub async fn connect_udp(
addr: SocketAddr,
params: ConnectParams,
) -> Result<Self>
pub async fn connect_udp( addr: SocketAddr, params: ConnectParams, ) -> Result<Self>
Connect to a PLC using UDP transport.