pub struct Protocol3 { /* private fields */ }Expand description
Main Protocol 3 structure
This struct acts as a container for all Protocol 3 models that implement the PacketGenerator trait. It collects and orders packets from all models for transmission to the Timex Datalink watch.
Implementations§
Source§impl Protocol3
impl Protocol3
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new empty Protocol3 instance
Examples found in repository?
examples/protocol3_example.rs (line 49)
35fn main() {
36 // Get the serial port from command line arguments
37 let args: Vec<String> = env::args().collect();
38 let serial_port = match args.len() {
39 1 => {
40 println!("Serial port not specified. Running in preview mode only.");
41 println!("Usage: {} <serial_port_path>", args[0]);
42 println!(" Example: {} /dev/ttyUSB0", args[0]);
43 String::new() // Empty string for preview mode
44 },
45 _ => args[1].clone(),
46 };
47
48 // Create a new Protocol 3 instance
49 let mut protocol = Protocol3::new();
50
51 // Define the appointments
52 let appointments = vec![
53 Appointment::new(
54 system_time_from_date(2022, 10, 31, 19, 0),
55 "Scare the neighbors".to_string()
56 ),
57 Appointment::new(
58 system_time_from_date(2022, 11, 24, 17, 0),
59 "Feed the neighbors".to_string()
60 ),
61 Appointment::new(
62 system_time_from_date(2022, 12, 25, 14, 0),
63 "Spoil the neighbors".to_string()
64 ),
65 ];
66
67 // Define the anniversaries
68 let anniversaries = vec![
69 Anniversary::new(
70 system_time_from_date(1985, 7, 3, 0, 0),
71 "Release of Back to the Future".to_string()
72 ),
73 Anniversary::new(
74 system_time_from_date(1968, 4, 6, 0, 0),
75 "Release of 2001".to_string()
76 ),
77 ];
78
79 // Define the phone numbers
80 let phone_numbers = vec![
81 PhoneNumber::new(
82 "Marty McFly".to_string(),
83 "1112223333".to_string(),
84 Some("H".to_string())
85 ),
86 PhoneNumber::new(
87 "Doc Brown".to_string(),
88 "4445556666".to_string(),
89 Some("C".to_string())
90 ),
91 ];
92
93 // Define the lists
94 let lists = vec![
95 List::new(
96 "Muffler bearings".to_string(),
97 Some(2)
98 ),
99 List::new(
100 "Headlight fluid".to_string(),
101 Some(4)
102 ),
103 ];
104
105 // Add each component to the protocol
106 protocol.add(Sync::default());
107 protocol.add(Start);
108
109 // Add time settings - local time in zone 1
110 let time1 = SystemTime::now();
111 // Convert to DateTime for display
112 let duration = time1.duration_since(SystemTime::UNIX_EPOCH).unwrap();
113 let dt1 = DateTime::<Utc>::from_timestamp(duration.as_secs() as i64, 0).unwrap();
114 println!("Setting local time to: {}", dt1.format("%Y-%m-%d %H:%M:%S"));
115
116 protocol.add(Time {
117 zone: 1,
118 is_24h: false,
119 date_format: DateFormat::MonthDashDayDashYear,
120 time: time1,
121 name: CharString::new("HOME", true),
122 });
123
124 // Add time settings - UTC time in zone 2
125 let time2 = SystemTime::now();
126 protocol.add(Time {
127 zone: 2,
128 is_24h: true,
129 date_format: DateFormat::MonthDashDayDashYear,
130 time: time2,
131 name: CharString::new("UTC", true),
132 });
133
134 // Add alarms
135 protocol.add(Alarm {
136 number: 1,
137 audible: true,
138 hour: 9,
139 minute: 0,
140 message: CharString::new("Wake up", true),
141 });
142
143 protocol.add(Alarm {
144 number: 2,
145 audible: true,
146 hour: 9,
147 minute: 5,
148 message: CharString::new("For real", true),
149 });
150
151 protocol.add(Alarm {
152 number: 3,
153 audible: false,
154 hour: 9,
155 minute: 10,
156 message: CharString::new("Get up", true),
157 });
158
159 protocol.add(Alarm {
160 number: 4,
161 audible: true,
162 hour: 9,
163 minute: 15,
164 message: CharString::new("Or not", true),
165 });
166
167 protocol.add(Alarm {
168 number: 5,
169 audible: false,
170 hour: 11,
171 minute: 30,
172 message: CharString::new("Told you", true),
173 });
174
175 // Create a new EEPROM instance with all data
176 let mut eeprom = Eeprom::new();
177 eeprom.appointments = appointments;
178 eeprom.anniversaries = anniversaries;
179 eeprom.phone_numbers = phone_numbers;
180 eeprom.lists = lists;
181 eeprom.appointment_notification_minutes = Some(15);
182
183 // Add the EEPROM to the protocol
184 protocol.add(eeprom);
185
186 // Use absolute paths for the fixture files (commented out since not used)
187 // let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
188
189 // // Load a sound theme from the example SPC file
190 // println!("Loading sound theme from EXAMPLE.SPC...");
191 // let spc_path = base_path.join("fixtures").join("EXAMPLE.SPC");
192 // let sound_theme = match SoundTheme::from_spc_file(&spc_path) {
193 // Ok(theme) => theme,
194 // Err(e) => {
195 // println!("Warning: Could not load SPC file: {}. Using simulated data.", e);
196 // // Create a placeholder with minimal data for the example
197 // SoundTheme::new(vec![0; 32])
198 // }
199 // };
200 // protocol.add(sound_theme);
201
202 // Add sound options
203 protocol.add(SoundOptions {
204 hourly_chime: true,
205 button_beep: true,
206 });
207
208 // // Load a wrist app from the example ZAP file
209 // println!("Loading wrist app from EXAMPLE.ZAP...");
210 // let zap_path = base_path.join("fixtures").join("EXAMPLE.ZAP");
211 // let wrist_app = match WristApp::from_zap_file(&zap_path) {
212 // Ok(app) => app,
213 // Err(e) => {
214 // println!("Warning: Could not load ZAP file: {}. Using simulated data.", e);
215 // // Create a simulated wrist app with demo data
216 // let demo_data = vec![
217 // 49, 53, 48, 32, 100, 97, 116, 97, 58, 32, 76, 111, 114, 101, 109, 32,
218 // 105, 112, 115, 117, 109, 32, 100, 111, 108, 111, 114, 32, 115, 105, 116, 32,
219 // 97, 109, 101, 116, 44, 32, 99, 111, 110, 115, 101, 99, 116, 101, 116, 117,
220 // 114, 32, 97, 100, 105, 112, 105, 115, 99, 105, 110, 103, 32, 101, 108, 105,
221 // 116, 44, 32, 115, 101, 100, 32, 100, 111, 32, 101, 105, 117, 115, 109, 111,
222 // 100, 32, 116, 101, 109, 112, 111, 114, 32, 105, 110, 99, 105, 100, 105, 100,
223 // 117, 110, 116, 32, 117, 116, 32, 108, 97, 98, 111, 114, 101, 32, 101, 116,
224 // 32, 100, 111, 108, 111, 114, 101, 32, 109, 97, 103, 110, 97, 32, 97, 108,
225 // 105, 113, 117, 97, 46
226 // ];
227 // WristApp::new(demo_data)
228 // }
229 // };
230 // protocol.add(wrist_app);
231
232 // Add end command
233 protocol.add(End);
234
235 // Generate all packets
236 let packets = protocol.packets();
237
238 // Print number of packets
239 println!("Generated {} packets for Protocol 3", packets.len());
240
241 // Print packet summary
242 println!("\nPacket summary:");
243 for (i, packet) in packets.iter().enumerate().take(5) {
244 // Only print first few bytes to avoid overwhelming output
245 let preview_len = std::cmp::min(packet.len(), 16);
246 let preview: Vec<u8> = packet.iter().take(preview_len).cloned().collect();
247 println!("Packet {}: {} bytes, starts with {:02X?}{}",
248 i + 1, packet.len(), preview,
249 if packet.len() > preview_len { "..." } else { "" });
250 }
251 if packets.len() > 5 {
252 println!("... and {} more packets", packets.len() - 5);
253 }
254
255 // If a serial port was provided, transmit the data
256 if !serial_port.is_empty() {
257 println!("\nTransmitting data to the watch on port: {}", serial_port);
258
259 // Create the notebook adapter and send the packets
260 let adapter = NotebookAdapter::new(
261 serial_port,
262 Some(0.014), // Use faster sleep times for the example
263 Some(0.08), // Use faster sleep times for the example
264 true, // Enable verbose output
265 );
266
267 match adapter.write(&packets) {
268 Ok(_) => println!("\nSuccessfully transmitted data to the watch!"),
269 Err(e) => {
270 eprintln!("\nError transmitting data: {}", e);
271 process::exit(1);
272 }
273 }
274 } else {
275 println!("\nNo serial port specified. Run with a serial port to transmit data to the watch:");
276 println!("Example: cargo run --example protocol3_example /dev/ttyUSB0");
277 }
278}Sourcepub fn add<T: PacketGenerator + 'static>(&mut self, model: T)
pub fn add<T: PacketGenerator + 'static>(&mut self, model: T)
Add a model to the protocol
Examples found in repository?
examples/protocol3_example.rs (line 106)
35fn main() {
36 // Get the serial port from command line arguments
37 let args: Vec<String> = env::args().collect();
38 let serial_port = match args.len() {
39 1 => {
40 println!("Serial port not specified. Running in preview mode only.");
41 println!("Usage: {} <serial_port_path>", args[0]);
42 println!(" Example: {} /dev/ttyUSB0", args[0]);
43 String::new() // Empty string for preview mode
44 },
45 _ => args[1].clone(),
46 };
47
48 // Create a new Protocol 3 instance
49 let mut protocol = Protocol3::new();
50
51 // Define the appointments
52 let appointments = vec![
53 Appointment::new(
54 system_time_from_date(2022, 10, 31, 19, 0),
55 "Scare the neighbors".to_string()
56 ),
57 Appointment::new(
58 system_time_from_date(2022, 11, 24, 17, 0),
59 "Feed the neighbors".to_string()
60 ),
61 Appointment::new(
62 system_time_from_date(2022, 12, 25, 14, 0),
63 "Spoil the neighbors".to_string()
64 ),
65 ];
66
67 // Define the anniversaries
68 let anniversaries = vec![
69 Anniversary::new(
70 system_time_from_date(1985, 7, 3, 0, 0),
71 "Release of Back to the Future".to_string()
72 ),
73 Anniversary::new(
74 system_time_from_date(1968, 4, 6, 0, 0),
75 "Release of 2001".to_string()
76 ),
77 ];
78
79 // Define the phone numbers
80 let phone_numbers = vec![
81 PhoneNumber::new(
82 "Marty McFly".to_string(),
83 "1112223333".to_string(),
84 Some("H".to_string())
85 ),
86 PhoneNumber::new(
87 "Doc Brown".to_string(),
88 "4445556666".to_string(),
89 Some("C".to_string())
90 ),
91 ];
92
93 // Define the lists
94 let lists = vec![
95 List::new(
96 "Muffler bearings".to_string(),
97 Some(2)
98 ),
99 List::new(
100 "Headlight fluid".to_string(),
101 Some(4)
102 ),
103 ];
104
105 // Add each component to the protocol
106 protocol.add(Sync::default());
107 protocol.add(Start);
108
109 // Add time settings - local time in zone 1
110 let time1 = SystemTime::now();
111 // Convert to DateTime for display
112 let duration = time1.duration_since(SystemTime::UNIX_EPOCH).unwrap();
113 let dt1 = DateTime::<Utc>::from_timestamp(duration.as_secs() as i64, 0).unwrap();
114 println!("Setting local time to: {}", dt1.format("%Y-%m-%d %H:%M:%S"));
115
116 protocol.add(Time {
117 zone: 1,
118 is_24h: false,
119 date_format: DateFormat::MonthDashDayDashYear,
120 time: time1,
121 name: CharString::new("HOME", true),
122 });
123
124 // Add time settings - UTC time in zone 2
125 let time2 = SystemTime::now();
126 protocol.add(Time {
127 zone: 2,
128 is_24h: true,
129 date_format: DateFormat::MonthDashDayDashYear,
130 time: time2,
131 name: CharString::new("UTC", true),
132 });
133
134 // Add alarms
135 protocol.add(Alarm {
136 number: 1,
137 audible: true,
138 hour: 9,
139 minute: 0,
140 message: CharString::new("Wake up", true),
141 });
142
143 protocol.add(Alarm {
144 number: 2,
145 audible: true,
146 hour: 9,
147 minute: 5,
148 message: CharString::new("For real", true),
149 });
150
151 protocol.add(Alarm {
152 number: 3,
153 audible: false,
154 hour: 9,
155 minute: 10,
156 message: CharString::new("Get up", true),
157 });
158
159 protocol.add(Alarm {
160 number: 4,
161 audible: true,
162 hour: 9,
163 minute: 15,
164 message: CharString::new("Or not", true),
165 });
166
167 protocol.add(Alarm {
168 number: 5,
169 audible: false,
170 hour: 11,
171 minute: 30,
172 message: CharString::new("Told you", true),
173 });
174
175 // Create a new EEPROM instance with all data
176 let mut eeprom = Eeprom::new();
177 eeprom.appointments = appointments;
178 eeprom.anniversaries = anniversaries;
179 eeprom.phone_numbers = phone_numbers;
180 eeprom.lists = lists;
181 eeprom.appointment_notification_minutes = Some(15);
182
183 // Add the EEPROM to the protocol
184 protocol.add(eeprom);
185
186 // Use absolute paths for the fixture files (commented out since not used)
187 // let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
188
189 // // Load a sound theme from the example SPC file
190 // println!("Loading sound theme from EXAMPLE.SPC...");
191 // let spc_path = base_path.join("fixtures").join("EXAMPLE.SPC");
192 // let sound_theme = match SoundTheme::from_spc_file(&spc_path) {
193 // Ok(theme) => theme,
194 // Err(e) => {
195 // println!("Warning: Could not load SPC file: {}. Using simulated data.", e);
196 // // Create a placeholder with minimal data for the example
197 // SoundTheme::new(vec![0; 32])
198 // }
199 // };
200 // protocol.add(sound_theme);
201
202 // Add sound options
203 protocol.add(SoundOptions {
204 hourly_chime: true,
205 button_beep: true,
206 });
207
208 // // Load a wrist app from the example ZAP file
209 // println!("Loading wrist app from EXAMPLE.ZAP...");
210 // let zap_path = base_path.join("fixtures").join("EXAMPLE.ZAP");
211 // let wrist_app = match WristApp::from_zap_file(&zap_path) {
212 // Ok(app) => app,
213 // Err(e) => {
214 // println!("Warning: Could not load ZAP file: {}. Using simulated data.", e);
215 // // Create a simulated wrist app with demo data
216 // let demo_data = vec![
217 // 49, 53, 48, 32, 100, 97, 116, 97, 58, 32, 76, 111, 114, 101, 109, 32,
218 // 105, 112, 115, 117, 109, 32, 100, 111, 108, 111, 114, 32, 115, 105, 116, 32,
219 // 97, 109, 101, 116, 44, 32, 99, 111, 110, 115, 101, 99, 116, 101, 116, 117,
220 // 114, 32, 97, 100, 105, 112, 105, 115, 99, 105, 110, 103, 32, 101, 108, 105,
221 // 116, 44, 32, 115, 101, 100, 32, 100, 111, 32, 101, 105, 117, 115, 109, 111,
222 // 100, 32, 116, 101, 109, 112, 111, 114, 32, 105, 110, 99, 105, 100, 105, 100,
223 // 117, 110, 116, 32, 117, 116, 32, 108, 97, 98, 111, 114, 101, 32, 101, 116,
224 // 32, 100, 111, 108, 111, 114, 101, 32, 109, 97, 103, 110, 97, 32, 97, 108,
225 // 105, 113, 117, 97, 46
226 // ];
227 // WristApp::new(demo_data)
228 // }
229 // };
230 // protocol.add(wrist_app);
231
232 // Add end command
233 protocol.add(End);
234
235 // Generate all packets
236 let packets = protocol.packets();
237
238 // Print number of packets
239 println!("Generated {} packets for Protocol 3", packets.len());
240
241 // Print packet summary
242 println!("\nPacket summary:");
243 for (i, packet) in packets.iter().enumerate().take(5) {
244 // Only print first few bytes to avoid overwhelming output
245 let preview_len = std::cmp::min(packet.len(), 16);
246 let preview: Vec<u8> = packet.iter().take(preview_len).cloned().collect();
247 println!("Packet {}: {} bytes, starts with {:02X?}{}",
248 i + 1, packet.len(), preview,
249 if packet.len() > preview_len { "..." } else { "" });
250 }
251 if packets.len() > 5 {
252 println!("... and {} more packets", packets.len() - 5);
253 }
254
255 // If a serial port was provided, transmit the data
256 if !serial_port.is_empty() {
257 println!("\nTransmitting data to the watch on port: {}", serial_port);
258
259 // Create the notebook adapter and send the packets
260 let adapter = NotebookAdapter::new(
261 serial_port,
262 Some(0.014), // Use faster sleep times for the example
263 Some(0.08), // Use faster sleep times for the example
264 true, // Enable verbose output
265 );
266
267 match adapter.write(&packets) {
268 Ok(_) => println!("\nSuccessfully transmitted data to the watch!"),
269 Err(e) => {
270 eprintln!("\nError transmitting data: {}", e);
271 process::exit(1);
272 }
273 }
274 } else {
275 println!("\nNo serial port specified. Run with a serial port to transmit data to the watch:");
276 println!("Example: cargo run --example protocol3_example /dev/ttyUSB0");
277 }
278}Trait Implementations§
Auto Trait Implementations§
impl Freeze for Protocol3
impl !RefUnwindSafe for Protocol3
impl !Send for Protocol3
impl !Sync for Protocol3
impl Unpin for Protocol3
impl !UnwindSafe for Protocol3
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more