pub struct Z21Station { /* private fields */ }Expand description
Represents an asynchronous connection to a Z21 station.
The Z21Station manages a UDP socket for communication with a Z21 station. It spawns a
background task to continuously listen for incoming packets and proceed these packets
over an internal logic.
Implementations§
Source§impl Z21Station
impl Z21Station
Sourcepub async fn new(bind_addr: &str) -> Result<Self>
pub async fn new(bind_addr: &str) -> Result<Self>
Creates a new connection to a Z21 station at the specified address.
This method establishes a UDP connection to the Z21 station, performs the initial handshake, and starts background tasks for maintaining the connection.
§Arguments
bind_addr- Network address of the Z21 station (typically “192.168.0.111:21105”)
§Returns
A new Z21Station instance if the connection is successful.
§Errors
Returns an io::Error if:
- The UDP socket cannot be bound or connected
- The initial handshake with the Z21 station fails
- The station does not respond within the timeout period
§Example
let station = Z21Station::new("192.168.0.111:21105").await?;Examples found in repository?
6async fn main() -> std::io::Result<()> {
7 let station = Arc::new(Z21Station::new("192.168.0.111:21105").await?);
8
9 // Control a locomotive with address 3
10 let loco = Loco::control(station.clone(), 4).await?;
11
12 // Subscribe to locomotive state changes
13 loco.subscribe_loco_state(Box::new(|state| {
14 println!(
15 "Locomotive speed: {}%",
16 state.speed_percentage.unwrap_or(0.)
17 );
18 }));
19
20 // Turn on the headlights
21 loco.set_headlights(true).await?;
22
23 // Set speed to 50% forward
24 loco.drive(50.0).await?;
25
26 // Wait for 5 seconds
27 tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
28
29 // Gradually stop
30 loco.stop().await?;
31
32 Ok(())
33}More examples
4async fn main() -> std::io::Result<()> {
5 // Create a connection to the Z21 station
6 let station = Arc::new(Z21Station::new("192.168.0.111:21105").await?);
7
8 // Get the serial number of the station
9 let serial = station.get_serial_number().await?;
10 println!("Z21 station serial number: {}", serial);
11
12 // Turn on track power
13 station.voltage_on().await?;
14
15 // Subscribe to system state updates
16 station.subscribe_system_state(
17 1.0,
18 Box::new(|state| {
19 println!("Main track voltage: {:.2}V", state.vcc_voltage);
20 println!("Temperature: {}°C", state.temperature);
21 println!("Current: {}mA", state.main_current);
22 }),
23 );
24
25 // Keep the application running
26 tokio::signal::ctrl_c().await?;
27
28 // Turn off track power before exiting
29 station.voltage_off().await?;
30 station.logout().await?;
31
32 Ok(())
33
34 //Ok(())
35}Sourcepub async fn voltage_off(&self) -> Result<()>
pub async fn voltage_off(&self) -> Result<()>
Turns off the track voltage.
This is equivalent to pressing the STOP button on the Z21 station or the MultiMaus controller. It cuts power to all tracks, stopping all locomotives immediately.
§Returns
Ok(()) if the command was successfully sent and acknowledged.
§Errors
Returns an io::Error if the command fails to send or no acknowledgment is received.
§Example
// Emergency stop all locomotives by cutting track power
station.voltage_off().await?;Examples found in repository?
4async fn main() -> std::io::Result<()> {
5 // Create a connection to the Z21 station
6 let station = Arc::new(Z21Station::new("192.168.0.111:21105").await?);
7
8 // Get the serial number of the station
9 let serial = station.get_serial_number().await?;
10 println!("Z21 station serial number: {}", serial);
11
12 // Turn on track power
13 station.voltage_on().await?;
14
15 // Subscribe to system state updates
16 station.subscribe_system_state(
17 1.0,
18 Box::new(|state| {
19 println!("Main track voltage: {:.2}V", state.vcc_voltage);
20 println!("Temperature: {}°C", state.temperature);
21 println!("Current: {}mA", state.main_current);
22 }),
23 );
24
25 // Keep the application running
26 tokio::signal::ctrl_c().await?;
27
28 // Turn off track power before exiting
29 station.voltage_off().await?;
30 station.logout().await?;
31
32 Ok(())
33
34 //Ok(())
35}Sourcepub async fn voltage_on(&self) -> Result<()>
pub async fn voltage_on(&self) -> Result<()>
Turns on the track voltage.
This restores power to the tracks after an emergency stop or when the system is first started. It also disables programming mode if it was active.
§Returns
Ok(()) if the command was successfully sent and acknowledged.
§Errors
Returns an io::Error if the command fails to send or no acknowledgment is received.
§Example
// Restore power to the tracks
station.voltage_on().await?;Examples found in repository?
4async fn main() -> std::io::Result<()> {
5 // Create a connection to the Z21 station
6 let station = Arc::new(Z21Station::new("192.168.0.111:21105").await?);
7
8 // Get the serial number of the station
9 let serial = station.get_serial_number().await?;
10 println!("Z21 station serial number: {}", serial);
11
12 // Turn on track power
13 station.voltage_on().await?;
14
15 // Subscribe to system state updates
16 station.subscribe_system_state(
17 1.0,
18 Box::new(|state| {
19 println!("Main track voltage: {:.2}V", state.vcc_voltage);
20 println!("Temperature: {}°C", state.temperature);
21 println!("Current: {}mA", state.main_current);
22 }),
23 );
24
25 // Keep the application running
26 tokio::signal::ctrl_c().await?;
27
28 // Turn off track power before exiting
29 station.voltage_off().await?;
30 station.logout().await?;
31
32 Ok(())
33
34 //Ok(())
35}Sourcepub async fn get_serial_number(&self) -> Result<u32>
pub async fn get_serial_number(&self) -> Result<u32>
Retrieves the serial number from the Z21 station.
§Returns
The Z21 station’s serial number as a 32-bit unsigned integer.
§Errors
Returns an io::Error if:
- Sending the request fails
- The response times out
- The response data is invalid (e.g., too short)
§Example
let serial = station.get_serial_number().await?;
println!("Z21 station serial number: {}", serial);Examples found in repository?
4async fn main() -> std::io::Result<()> {
5 // Create a connection to the Z21 station
6 let station = Arc::new(Z21Station::new("192.168.0.111:21105").await?);
7
8 // Get the serial number of the station
9 let serial = station.get_serial_number().await?;
10 println!("Z21 station serial number: {}", serial);
11
12 // Turn on track power
13 station.voltage_on().await?;
14
15 // Subscribe to system state updates
16 station.subscribe_system_state(
17 1.0,
18 Box::new(|state| {
19 println!("Main track voltage: {:.2}V", state.vcc_voltage);
20 println!("Temperature: {}°C", state.temperature);
21 println!("Current: {}mA", state.main_current);
22 }),
23 );
24
25 // Keep the application running
26 tokio::signal::ctrl_c().await?;
27
28 // Turn off track power before exiting
29 station.voltage_off().await?;
30 station.logout().await?;
31
32 Ok(())
33
34 //Ok(())
35}Sourcepub fn subscribe_system_state(
&self,
freq_in_sec: f64,
subscriber: Box<dyn Fn(SystemState) + Send + Sync>,
)
pub fn subscribe_system_state( &self, freq_in_sec: f64, subscriber: Box<dyn Fn(SystemState) + Send + Sync>, )
Subscribes to system state updates from the Z21 station.
This method sets up a polling mechanism to regularly request system state updates and calls the provided callback function whenever new state information is received.
§Arguments
freq_in_sec- Polling frequency in Hz (updates per second)subscriber- Callback function that receivesSystemStateupdates
§Example
station.subscribe_system_state(1.0, Box::new(|state| {
println!("Main track voltage: {:.2}V", state.main_track_voltage);
println!("Temperature: {}°C", state.temperature);
println!("Current: {}mA", state.current);
}));Examples found in repository?
4async fn main() -> std::io::Result<()> {
5 // Create a connection to the Z21 station
6 let station = Arc::new(Z21Station::new("192.168.0.111:21105").await?);
7
8 // Get the serial number of the station
9 let serial = station.get_serial_number().await?;
10 println!("Z21 station serial number: {}", serial);
11
12 // Turn on track power
13 station.voltage_on().await?;
14
15 // Subscribe to system state updates
16 station.subscribe_system_state(
17 1.0,
18 Box::new(|state| {
19 println!("Main track voltage: {:.2}V", state.vcc_voltage);
20 println!("Temperature: {}°C", state.temperature);
21 println!("Current: {}mA", state.main_current);
22 }),
23 );
24
25 // Keep the application running
26 tokio::signal::ctrl_c().await?;
27
28 // Turn off track power before exiting
29 station.voltage_off().await?;
30 station.logout().await?;
31
32 Ok(())
33
34 //Ok(())
35}Sourcepub async fn logout(&self) -> Result<()>
pub async fn logout(&self) -> Result<()>
Logs out from the Z21 station.
This method should be called at the end of a session to gracefully terminate the connection with the Z21 station.
§Returns
Ok(()) if the logout command was successfully sent.
§Errors
Returns an io::Error if the logout command fails to send.
§Example
// Clean up and disconnect from the Z21 station
station.logout().await?;Examples found in repository?
4async fn main() -> std::io::Result<()> {
5 // Create a connection to the Z21 station
6 let station = Arc::new(Z21Station::new("192.168.0.111:21105").await?);
7
8 // Get the serial number of the station
9 let serial = station.get_serial_number().await?;
10 println!("Z21 station serial number: {}", serial);
11
12 // Turn on track power
13 station.voltage_on().await?;
14
15 // Subscribe to system state updates
16 station.subscribe_system_state(
17 1.0,
18 Box::new(|state| {
19 println!("Main track voltage: {:.2}V", state.vcc_voltage);
20 println!("Temperature: {}°C", state.temperature);
21 println!("Current: {}mA", state.main_current);
22 }),
23 );
24
25 // Keep the application running
26 tokio::signal::ctrl_c().await?;
27
28 // Turn off track power before exiting
29 station.voltage_off().await?;
30 station.logout().await?;
31
32 Ok(())
33
34 //Ok(())
35}