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}