timex_datalink/notebook_adapter.rs
1//! Notebook adapter for sending data to Timex watches
2//!
3//! This module provides the serial communication functionality to transmit
4//! formatted packets to Timex Datalink watches.
5
6#[cfg(not(target_arch = "wasm32"))]
7use std::io;
8#[cfg(not(target_arch = "wasm32"))]
9use std::time::Duration;
10#[cfg(not(target_arch = "wasm32"))]
11use std::thread::sleep;
12
13/// Notebook adapter for sending data to Timex watches
14///
15/// This handles the serial communication with the watch, including
16/// timing constraints between bytes and packets.
17pub struct NotebookAdapter {
18 /// Path to the serial device
19 pub serial_device: String,
20
21 /// Time to sleep after sending each byte (in seconds)
22 pub byte_sleep: f32,
23
24 /// Time to sleep after sending a packet (in seconds)
25 pub packet_sleep: f32,
26
27 /// Enable verbose output
28 pub verbose: bool,
29}
30
31impl NotebookAdapter {
32 /// Default time to sleep after sending a byte (in seconds)
33 pub const BYTE_SLEEP_DEFAULT: f32 = 0.025;
34
35 /// Default time to sleep after sending a packet (in seconds)
36 pub const PACKET_SLEEP_DEFAULT: f32 = 0.25;
37
38 /// Create a new NotebookAdapter with the given parameters
39 ///
40 /// # Arguments
41 ///
42 /// * `serial_device` - Path to the serial device
43 /// * `byte_sleep` - Optional time to sleep after sending each byte (in seconds)
44 /// * `packet_sleep` - Optional time to sleep after sending a packet (in seconds)
45 /// * `verbose` - Whether to enable verbose output
46 pub fn new(
47 serial_device: String,
48 byte_sleep: Option<f32>,
49 packet_sleep: Option<f32>,
50 verbose: bool,
51 ) -> Self {
52 NotebookAdapter {
53 serial_device,
54 byte_sleep: byte_sleep.unwrap_or(Self::BYTE_SLEEP_DEFAULT),
55 packet_sleep: packet_sleep.unwrap_or(Self::PACKET_SLEEP_DEFAULT),
56 verbose,
57 }
58 }
59
60 /// Write packets to the serial device
61 ///
62 /// # Arguments
63 ///
64 /// * `packets` - A vector of packet byte vectors to send
65 ///
66 /// # Errors
67 ///
68 /// Returns an error if the serial device cannot be opened or if writing fails
69 #[cfg(not(target_arch = "wasm32"))]
70 pub fn write(&self, packets: &[Vec<u8>]) -> io::Result<()> {
71 let port = serial2::SerialPort::open(&self.serial_device, 9600)?;
72
73 for packet in packets {
74 for &byte in packet {
75 if self.verbose {
76 print!("{:02X} ", byte);
77 }
78
79 port.write(&[byte])?;
80
81 sleep(Duration::from_secs_f32(self.byte_sleep));
82 }
83
84 sleep(Duration::from_secs_f32(self.packet_sleep));
85
86 if self.verbose {
87 println!();
88 }
89 }
90
91 Ok(())
92 }
93
94 /// Stub implementation for wasm target
95 #[cfg(target_arch = "wasm32")]
96 pub fn write(&self, _packets: &[Vec<u8>]) -> Result<(), &'static str> {
97 Err("Serial port functionality is not available in WebAssembly")
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 // Add tests here if needed
104}