### Rust PLC Connection Setup Method Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Demonstrates the Rust function signature for setting the S7 connection type. This is part of the initial setup for establishing communication with a Siemens PLC. ```rust pub fn set_connection_type(&mut self, connection_type: u16) ``` -------------------------------- ### Rust PLC Connection Workflow Example Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md A pseudo-code example illustrating a typical communication loop for a Rust application interacting with a PLC. It demonstrates checking connection status, attempting to reconnect if disconnected, and executing read/write operations, with a mechanism to detect severe errors and trigger a disconnection. ```rust while !exit_request{ if !Client.connected { let _ = client.connect_s71200_1500(ip_address); } if Client.connected { if !do_read_and_write() { // <-- returns false when severe error occurs Client.disconnect(); } } thread::sleep(100); } ``` -------------------------------- ### Write to PLC Data Block with Splitting (Rust) Source: https://context7.com/davenardella/rust7/llms.txt Writes byte arrays to a specified PLC data block starting at a given offset. This function automatically splits large data transfers into smaller telegrams. It requires a connection to the PLC and returns success or an error. The output includes write time and the number of chunks used. ```Rust use rust7::client::S7Client; fn main() { let mut client = S7Client::new(); let db_number: u16 = 100; if let Err(e) = client.connect_s71200_1500("192.168.0.100") { eprintln!("Connection failed: {}", e); return; } // Prepare 1024 bytes of data to write let mut data = vec![0u8; 1024]; for (i, val) in data.iter_mut().enumerate() { *val = (i % 256) as u8; } // Write to DB100 starting at offset 0 match client.write_db(db_number, 0, &data) { Ok(_) => { println!("Wrote {} bytes successfully", data.len()); println!("Job time: {:.3} ms", client.last_time); println!("Chunks: {} (automatically split)", client.chunks); }, Err(e) => { eprintln!("Write failed: {}", e); client.disconnect(); return; } } client.disconnect(); } ``` -------------------------------- ### Read PLC Data Block with Chunking (Rust) Source: https://context7.com/davenardella/rust7/llms.txt Reads bytes from a specified PLC data block starting at a given offset. This function automatically handles large transfers by chunking the data. It requires a connection to the PLC and returns the read bytes or an error. The output includes read time and the number of chunks used. ```Rust use rust7::client::S7Client; fn main() { let mut client = S7Client::new(); let db_number: u16 = 100; if let Err(e) = client.connect_s71200_1500("192.168.0.100") { eprintln!("Connection failed: {}", e); return; } // Read 462 bytes from DB100 starting at offset 0 let mut buffer = vec![0u8; 462]; match client.read_db(db_number, 0, &mut buffer) { Ok(_) => { println!("Read {} bytes successfully", buffer.len()); println!("Job time: {:.3} ms", client.last_time); println!("Chunks: {}", client.chunks); // Display data in hex format for (i, chunk) in buffer.chunks(16).enumerate() { print!("{:04X}: ", i * 16); for byte in chunk { print!("{:02X} ", byte); } println!(); } }, Err(e) => { eprintln!("Read failed: {}", e); client.disconnect(); return; } } client.disconnect(); } ``` -------------------------------- ### Read Data from S7 PLC Memory Area Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Reads a block of data from a specified S7 memory area (e.g., PE, PA, DB, MK). Requires the area code, DB number (if applicable), starting index, word length, and a mutable buffer to store the data. Returns an error if the read operation fails. ```rust pub fn read_area(&mut self, area: u8, db_number: u16, start: u16, wordlen: u8, buffer: &mut [u8]) -> Result<(), S7Error> ``` -------------------------------- ### Set S7 PLC TCP Connection Port Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Sets the TCP connection port for S7 communication. The default is 102, but this can be changed, for example, for NAT configurations. The port value must be greater than 0 to be effective. This method must be called before connecting. ```rust pub fn set_connection_port(&mut self, port: u16) ``` -------------------------------- ### Connect and Read from Siemens PLC using Rust Source: https://github.com/davenardella/rust7/blob/main/README.md Demonstrates how to use the Rust7 S7Client to establish a connection to a Siemens PLC (S71200/1500), read a specified number of bytes from a database, and disconnect. It includes error handling for connection and read operations, and prints the last job execution time. ```rust use rust7::client::{S7Client}; fn main() { let mut client = S7Client::new(); let db_number: u16 = 100; // Must exist into the PLC // Connection match client.connect_s71200_1500("192.168.0.100") { Ok(_) => { println!("Connected to PLC") }, Err(e) => { eprintln!("Connection failed: {}", e); return; } } // Reads 64 byte from DB100 println!(""); println!("Attempt to read 64 byte from DB100"); let mut read_buffer = vec![0u8; 64]; match client.read_db(db_number, 0, &mut read_buffer) { Ok(_) => { println!("Success!"); println!("Job time (ms) : {:.3}", client.last_time); }, Err(e) => eprintln!("Read failed: {}", e), } client.disconnect(); } ``` -------------------------------- ### Connect Rust S7 Client with Custom Rack and Slot Source: https://context7.com/davenardella/rust7/llms.txt Shows how to connect to S7-400, WinAC, or Sinamics drives by specifying custom rack and slot parameters. This is useful for hardware configurations that deviate from the default settings of other connection methods. Error handling and PDU length retrieval are included. Ensure to disconnect the client after operations. ```rust use rust7::client::S7Client; fn main() { let mut client = S7Client::new(); // Connect to S7-400 with rack=0, slot=3 let rack: u16 = 0; let slot: u16 = 3; match client.connect_rack_slot("192.168.2.10", rack, slot) { Ok(_) => { println!("Connected to S7-400 at rack {}, slot {}", rack, slot); println!("PDU negotiated: {} bytes", client.pdu_length); }, Err(e) => { eprintln!("Connection error: {}", e); return; } } client.disconnect(); } ``` -------------------------------- ### Create and Connect Rust S7 Client to S7-1200/1500 PLC Source: https://context7.com/davenardella/rust7/llms.txt Demonstrates creating a new S7 client instance and establishing a connection to an S7-1200 or S7-1500 PLC. It shows how to handle successful connections, retrieve negotiated PDU length and connection time, and manage connection errors. The client must be explicitly disconnected when finished. ```rust use rust7::client::S7Client; fn main() { // Create a new client with default settings let mut client = S7Client::new(); // Connect to S7-1200/1500 PLC (rack=0, slot=0) match client.connect_s71200_1500("192.168.0.100") { Ok(_) => { println!("Connected to PLC"); println!("PDU negotiated: {} bytes", client.pdu_length); println!("Connection time: {:.3} ms", client.last_time); }, Err(e) => { eprintln!("Connection failed: {}", e); return; } } // Client is now ready for read/write operations // Always disconnect when done client.disconnect(); } ``` -------------------------------- ### Configure Rust S7 Client Connection Parameters Source: https://context7.com/davenardella/rust7/llms.txt Demonstrates how to customize connection settings for the S7 client before establishing a connection. This includes setting custom timeouts for different connection phases, changing the connection type (e.g., to OP for HMI mode), and specifying a non-standard TCP port, which can be useful in NAT scenarios. After configuration, a connection is attempted with the new parameters. ```rust use rust7::client::{S7Client, CT_PG, CT_OP}; fn main() { let mut client = S7Client::new(); // Set custom timeouts (all in milliseconds) if let Err(e) = client.set_timeout(5000, 2000, 1000) { eprintln!("Failed to set timeout: {}", e); return; } // Change connection type to OP (HMI mode) if let Err(e) = client.set_connection_type(CT_OP) { eprintln!("Failed to set connection type: {}", e); return; } // Use non-standard port (for NAT scenarios) if let Err(e) = client.set_connection_port(2102) { eprintln!("Failed to set port: {}", e); return; } // Now connect with configured parameters match client.connect_s71200_1500("192.168.0.100") { Ok(_) => println!("Connected with custom parameters"), Err(e) => eprintln!("Connection failed: {}", e), } client.disconnect(); } ``` -------------------------------- ### Connect Rust S7 Client to S7-300 PLC Source: https://context7.com/davenardella/rust7/llms.txt Illustrates connecting to older S7-300 series PLCs using a predefined rack and slot configuration. This method is specific to S7-300 series hardware. It includes error handling for connection failures and prints the negotiated PDU length upon successful connection. Remember to disconnect the client after use. ```rust use rust7::client::S7Client; fn main() { let mut client = S7Client::new(); // Connect to S7-300 (rack=0, slot=2) match client.connect_s7300("192.168.1.50") { Ok(_) => { println!("Connected to S7-300 PLC"); println!("PDU length: {} bytes", client.pdu_length); }, Err(e) => { eprintln!("Connection failed: {}", e); return; } } client.disconnect(); } ``` -------------------------------- ### Rust: Connect to LOGO! PLC using TSAP Source: https://context7.com/davenardella/rust7/llms.txt Illustrates connecting to Siemens LOGO! and S7-200 PLCs using the TSAP (Transport Service Access Point) protocol in Rust. This method is for low-level connections, specifying local and remote TSAP values. It handles connection establishment and demonstrates a basic read operation. ```rust use rust7::client::S7Client; fn main() { let mut client = S7Client::new(); // TSAP format for LOGO! // Local TSAP: typically 0x0100 // Remote TSAP: 0x0200 for LOGO! 0BA7 and newer let local_tsap: u16 = 0x0100; let remote_tsap: u16 = 0x0200; match client.connect_tsap("192.168.0.50", local_tsap, remote_tsap) { Ok(_) => { println!("Connected to LOGO! via TSAP"); println!("Local TSAP: 0x{:04X}", local_tsap); println!("Remote TSAP: 0x{:04X}", remote_tsap); println!("PDU negotiated: {} bytes", client.pdu_length); }, Err(e) => { eprintln!("TSAP connection failed: {}", e); return; } } // Now can read/write using standard methods let mut buffer = vec![0u8; 32]; if let Ok(_) = client.read_db(1, 0, &mut buffer) { println!("Read {} bytes from LOGO!", buffer.len()); } client.disconnect(); } ``` -------------------------------- ### Rust: Robust Error Handling for S7 Communication Source: https://context7.com/davenardella/rust7/llms.txt Demonstrates comprehensive error handling for Siemens PLC communication using Rust. It distinguishes between recoverable and non-recoverable errors, implementing specific strategies for each, such as reconnection or parameter adjustment. This is crucial for maintaining production stability. ```rust use rust7::client::{S7Client, S7Error}; fn main() { let mut client = S7Client::new(); if let Err(e) = client.connect_s71200_1500("192.168.0.100") { eprintln!("Connection failed: {}", e); return; } let db_number: u16 = 100; let mut buffer = vec![0u8; 64]; match client.read_db(db_number, 0, &mut buffer) { Ok(_) => { println!("Read successful: {} bytes", buffer.len()); }, Err(e) => { match e { // Low-level errors - disconnect and reconnect required S7Error::Io(_) => { eprintln!("Network I/O error: {}", e); client.disconnect(); // Reconnection logic here }, S7Error::IsoInvalidHeader | S7Error::IsoInvalidTelegram | S7Error::IsoFragmentedPacket => { eprintln!("Protocol error: {}", e); client.disconnect(); // Reconnection logic here }, S7Error::ConnectionClosed => { eprintln!("Connection closed by peer"); client.disconnect(); }, // High-level errors - can continue with same connection S7Error::S7NotFound => { eprintln!("DB{} not found in PLC", db_number); // Check PLC configuration }, S7Error::S7InvalidAddress => { eprintln!("Invalid address - check offset/size or DB optimization"); // Adjust read parameters }, S7Error::InvalidFunParameter => { eprintln!("Invalid function parameter"); // Fix parameter values }, // Other errors _ => { eprintln!("Error: {}", e); } } } } client.disconnect(); } ``` -------------------------------- ### Connect to Siemens PLC using Rack and Slot Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Connects to a Siemens PLC/Drive using specified Rack and Slot hardware configuration parameters. This method is necessary for S7-400, WinAC, or other Siemens hardware like Drives where Rack and Slot can vary. For S7-300 and S7-1200/1500, fixed values can be used via helper methods. Requires the PLC's IPv4 address, rack, and slot. ```rust pub fn connect_rack_slot(&mut self, ip: &str, rack: u16, slot: u16) -> Result<() ``` -------------------------------- ### PLC Connection Loop with Reconnection (Rust) Source: https://context7.com/davenardella/rust7/llms.txt Implements a continuous communication loop with automatic PLC connection management. It attempts to connect to the PLC, performs read/write operations within a loop, and automatically attempts to reconnect if the connection is lost. Includes error handling and configurable cycle times. Requires a running S7 PLC and network connectivity. ```rust use rust7::client::S7Client; use std::thread; use std::time::Duration; fn main() { let mut client = S7Client::new(); let ip_address = "192.168.0.100"; let db_number: u16 = 100; let mut exit_requested = false; // Main communication loop while !exit_requested { // Automatic connection management if !client.connected { match client.connect_s71200_1500(ip_address) { Ok(_) => { println!("Connected to PLC at {}", ip_address); println!("PDU: {} bytes", client.pdu_length); }, Err(e) => { eprintln!("Connection attempt failed: {}", e); thread::sleep(Duration::from_millis(5000)); continue; } } } // Perform read/write operations if client.connected { if !do_read_and_write(&mut client, db_number) { // Low-level error occurred - disconnect and retry println!("Communication error - disconnecting"); client.disconnect(); } } // Cycle time thread::sleep(Duration::from_millis(100)); } client.disconnect(); } fn do_read_and_write(client: &mut S7Client, db_number: u16) -> bool { // Read operation let mut buffer = vec![0u8; 64]; if let Err(e) = client.read_db(db_number, 0, &mut buffer) { eprintln!("Read error: {}", e); return false; // Signal disconnect needed } // Process data... // Write operation let write_data = vec![0x42; 32]; if let Err(e) = client.write_db(db_number, 100, &write_data) { eprintln!("Write error: {}", e); return false; // Signal disconnect needed } true // Success - continue with current connection } ``` -------------------------------- ### Read PLC Process Image Areas (Rust) Source: https://context7.com/davenardella/rust7/llms.txt Reads data from Process Input (PE), Process Output (PA), and Merker (MK) memory areas of a Siemens S7 PLC. It connects to the PLC, reads specified byte ranges from each area, prints the data, and then disconnects. Requires a running S7 PLC and network connectivity. ```rust use rust7::client::{S7Client, S7_AREA_PE, S7_AREA_PA, S7_AREA_MK, S7_WL_BYTE}; fn main() { let mut client = S7Client::new(); if let Err(e) = client.connect_s71200_1500("192.168.0.100") { eprintln!("Connection failed: {}", e); return; } // Read 16 bytes from Process Inputs (I0 to I15) let mut inputs = vec![0u8; 16]; match client.read_area(S7_AREA_PE, 0, 0, S7_WL_BYTE, &mut inputs) { Ok(_) => { println!("Process Inputs (I0-I15):"); for (i, byte) in inputs.iter().enumerate() { println!(" I{}: 0x{:02X}", i, byte); } }, Err(e) => eprintln!("Read inputs failed: {}", e), } // Read 8 bytes from Merkers (M0 to M7) let mut merkers = vec![0u8; 8]; match client.read_area(S7_AREA_MK, 0, 0, S7_WL_BYTE, &mut merkers) { Ok(_) => { println!("Merkers (M0-M7): {:02X?}", merkers); }, Err(e) => eprintln!("Read merkers failed: {}", e), } // Read Process Outputs (Q0 to Q3) let mut outputs = vec![0u8; 4]; match client.read_area(S7_AREA_PA, 0, 0, S7_WL_BYTE, &mut outputs) { Ok(_) => { println!("Process Outputs: {:02X?}", outputs); }, Err(e) => eprintln!("Read outputs failed: {}", e), } client.disconnect(); } ``` -------------------------------- ### Connect to S7-300 PLC Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md A helper method for connecting to the S7-300 PLC family. This is equivalent to calling `connect_rack_slot` with rack=0 and slot=2. The PLC's IPv4 address is required. ```rust pub fn connect_s7300(&mut self, ip: &str) -> Result<(), S7Error> ``` -------------------------------- ### Write to PLC Memory Areas (Rust) Source: https://context7.com/davenardella/rust7/llms.txt Writes data to Data Block (DB) and Merker (MK) memory areas of a Siemens S7 PLC. It connects to the PLC, writes a byte array to a specified DB offset, writes data to merker addresses, and then disconnects. Requires a running S7 PLC and network connectivity. ```rust use rust7::client::{S7Client, S7_AREA_DB, S7_AREA_MK, S7_WL_BYTE}; fn main() { let mut client = S7Client::new(); if let Err(e) = client.connect_s71200_1500("192.168.0.100") { eprintln!("Connection failed: {}", e); return; } // Write 10 bytes to DB200 starting at offset 50 let data = vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA]; let db_number: u16 = 200; let start_offset: u16 = 50; match client.write_area(S7_AREA_DB, db_number, start_offset, S7_WL_BYTE, &data) { Ok(_) => { println!("Wrote {} bytes to DB{} at offset {}", data.len(), db_number, start_offset); println!("Job time: {:.3} ms", client.last_time); }, Err(e) => { eprintln!("Write to DB failed: {}", e); client.disconnect(); return; } } // Write to Merker area (M100-M103) let merker_data = vec![0x01, 0x02, 0x03, 0x04]; match client.write_area(S7_AREA_MK, 0, 100, S7_WL_BYTE, &merker_data) { Ok(_) => { println!("Wrote to merkers M100-M103"); }, Err(e) => { eprintln!("Write to merkers failed: {}", e); } } client.disconnect(); } ``` -------------------------------- ### Write Data Block (DB) (Rust) Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md A simplified helper method to write a block of bytes to a specific Data Block (DB). It internally uses `write_area` with `S7_AREA_DB` and `S7_WL_BYTE`. The number of bytes written is determined by the provided buffer size. ```rust pub fn write_db(&mut self, db_number: u16, start: u16, buffer: &[u8]) -> Result<(), S7Error> ``` -------------------------------- ### Read Data Block (DB) (Rust) Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md A simplified helper method to read a block of bytes from a specific Data Block (DB). It internally uses `read_area` with `S7_AREA_DB` and `S7_WL_BYTE`. The number of bytes read is determined by the provided buffer size. ```rust pub fn read_db(&mut self, db_number: u16, start: u16, buffer: &mut [u8]) -> Result<(), S7Error> ``` -------------------------------- ### Connect to Siemens PLC using TSAP Records Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md The most fundamental connection method, used for devices like LOGO! or S7-200. It connects to a Siemens ISO-Hardware using TSAP records and is internally called by other connection methods. Requires the PLC's IPv4 address, local TSAP, and remote TSAP. The default connection port is 102, unless changed by `set_connection_port()`. ```rust pub fn connect_tsap(&mut self, ip: &str, local_tsap: u16, remote_tsap: u16) -> Result<(), S7Error> ``` -------------------------------- ### Connect to S7-1200/1500 PLC Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md A helper method to establish a connection to S7-1200 or S7-1500 PLC families. It is equivalent to calling `connect_rack_slot` with rack=0 and slot=0. Requires the PLC's IPv4 address. ```rust pub fn connect_s71200_1500(&mut self, ip: &str) -> Result<(), S7Error> ``` -------------------------------- ### Set S7 PLC Connection Type Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Configures the connection type for the S7 PLC. Available types are CT_PG (programming device), CT_OP (HMI), and CT_S7 (generic device). CT_PG is the default. Use CT_OP or CT_S7 for older PLCs with limited communication resources if connection issues arise. The client must not be connected when calling this method. ```rust pub fn set_connection_type(&mut self, connection_type: ConnectionType) -> Result<(), S7Error> ``` -------------------------------- ### Read Individual PLC Bit (Rust) Source: https://context7.com/davenardella/rust7/llms.txt Reads a single bit from various S7 memory areas, including Data Blocks (DB) and Markers (MK). This function allows for precise bit-level access without reading entire bytes. It requires establishing a PLC connection and specifies the memory area, byte number, and bit index. ```Rust use rust7::client::{S7Client, S7_AREA_DB, S7_AREA_MK}; fn main() { let mut client = S7Client::new(); if let Err(e) = client.connect_s71200_1500("192.168.0.100") { eprintln!("Connection failed: {}", e); return; } // Read DB100.DBX47.5 (byte 47, bit 5) let db_number: u16 = 100; let byte_num: u16 = 47; let bit_idx: u8 = 5; match client.read_bit(S7_AREA_DB, db_number, byte_num, bit_idx) { Ok(value) => { println!("DB{}.DBX{}.{} = {}", db_number, byte_num, bit_idx, value); println!("Job time: {:.3} ms", client.last_time); }, Err(e) => { eprintln!("Read bit failed: {}", e); client.disconnect(); return; } } // Read a merker bit M10.3 (byte 10, bit 3) match client.read_bit(S7_AREA_MK, 0, 10, 3) { Ok(value) => { println!("M10.3 = {}", value); }, Err(e) => { eprintln!("Read merker failed: {}", e); } } client.disconnect(); } ``` -------------------------------- ### Set Operation Timeouts for S7 Communication Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Sets the timeouts for TCP connection, read operations, and write operations in milliseconds. Values must be greater than 0 to be effective. This method should be called before establishing a connection. ```rust pub fn set_timeout(&mut self, co_timeout_ms: u64, rd_timeout_ms: u64, wr_timeout_ms: u64 ) ``` -------------------------------- ### Write Bit to S7 Memory Area in Rust Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Writes a single bit to a specified S7 memory area. This function is a convenience wrapper around `write_area()` for bit-level operations. It takes the memory area, DB number, byte number, bit index, and the boolean value to write. It returns Ok(()) on success or an S7Error on failure. ```rust pub fn write_bit(&mut self, area: u8, db_number: u16, byte_num: u16, bit_idx: u8, value: bool) -> Result<(), S7Error> ``` -------------------------------- ### Write S7 Memory Area (Rust) Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Writes a block of data to a specific S7 memory area. Supports various areas like Process Inputs, Outputs, Merkers, and Data Blocks. Handles bit and byte access, with specific notes for bit manipulation. Errors can be low-level network issues or high-level address problems. ```rust pub fn write_area(&mut self, area: u8, db_number: u16, start: u16, wordlen: u8, data: &[u8]) -> Result<(), S7Error> ``` -------------------------------- ### Write Individual PLC Bit (Rust) Source: https://context7.com/davenardella/rust7/llms.txt Writes a boolean value (true or false) to a specific bit within PLC memory areas like Data Blocks (DB) or Process Outputs (PA). This operation ensures that adjacent bits are not affected. It requires an active PLC connection, the memory area, address, and the desired boolean value. ```Rust use rust7::client::{S7Client, S7_AREA_DB, S7_AREA_PA}; fn main() { let mut client = S7Client::new(); if let Err(e) = client.connect_s71200_1500("192.168.0.100") { eprintln!("Connection failed: {}", e); return; } // Write 'false' to DB100.DBX16.0 let db_number: u16 = 100; match client.write_bit(S7_AREA_DB, db_number, 16, 0, false) { Ok(_) => { println!("DB100.DBX16.0 set to false"); println!("Job time: {:.3} ms", client.last_time); }, Err(e) => { eprintln!("Write bit failed: {}", e); client.disconnect(); return; } } // Write 'true' to output bit Q5.2 (Process Outputs area) // Note: Writing to outputs may not persist due to PLC scan cycle match client.write_bit(S7_AREA_PA, 0, 5, 2, true) { Ok(_) => { println!("Q5.2 set to true"); }, Err(e) => { eprintln!("Write output failed: {}", e); } } client.disconnect(); } ``` -------------------------------- ### S7 Client Connection Status Field in Rust Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Represents the client's connection status to the PLC. This is a boolean flag indicating whether the client believes it is connected. Note that this is a memory flag and may not reflect the actual real-time connection state. ```rust pub connected: bool ``` -------------------------------- ### Read Bit from S7 Memory Area in Rust Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Reads a single bit from a specified S7 memory area. This function is a convenience wrapper around `read_area()` for bit-level operations. It takes the memory area, DB number, byte number, and bit index as input. It returns a boolean indicating the bit's state or an S7Error. ```rust pub fn read_bit(&mut self, area: u8, db_number: u16, byte_num: u16, bit_idx: u8) -> Result ``` -------------------------------- ### S7 Client Data Chunks Field in Rust Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Indicates the number of chunks the data was divided into for the last read or write operation. This field is primarily intended for advanced performance tuning and will be 0 if an error occurred. ```rust pub chunks: usize ``` -------------------------------- ### S7 Client Last Operation Time Field in Rust Source: https://github.com/davenardella/rust7/blob/main/doc/Documentation.md Stores the duration in milliseconds of the last operation performed by the S7 client. If an error occurred during the last operation, this value will be 0.0. ```rust pub last_time: f64 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.