use std::time::SystemTime;
use std::env;
use std::process;
use chrono::{TimeZone, Utc};
use timex_datalink::PacketGenerator;
use timex_datalink::NotebookAdapter;
use timex_datalink::protocol_4::{
Protocol4,
alarm::Alarm,
eeprom::{
Anniversary,
Appointment,
List,
PhoneNumber,
Eeprom,
phone_number::PhoneType,
list::Priority,
NotificationMinutes,
},
time::{Time, DateFormat},
sound_options::SoundOptions,
sound_theme::SoundTheme,
wrist_app::WristApp,
start::Start,
sync::Sync,
end::End,
};
use timex_datalink::char_encoders::{CharString, EepromString, PhoneString};
fn main() {
let args: Vec<String> = env::args().collect();
let serial_port = match args.len() {
1 => {
println!("Usage: {} <serial_port_path>", args[0]);
println!(" Example: {} /dev/ttyUSB0", args[0]);
process::exit(1);
},
_ => args[1].clone(),
};
let appointments = vec![
Appointment {
time: system_time_from_date(2022, 10, 31, 19, 0, 0),
message: EepromString::new("Scare the neighbors"),
},
Appointment {
time: system_time_from_date(2022, 11, 24, 17, 0, 0),
message: EepromString::new("Feed the neighbors"),
},
Appointment {
time: system_time_from_date(2022, 12, 25, 14, 0, 0),
message: EepromString::new("Spoil the neighbors"),
},
];
let anniversaries = vec![
Anniversary {
time: system_time_from_date(1985, 7, 3, 0, 0, 0),
anniversary: EepromString::new("Release of Back to the Future"),
},
Anniversary {
time: system_time_from_date(1968, 4, 6, 0, 0, 0),
anniversary: EepromString::new("Release of 2001"),
},
];
let phone_numbers = vec![
PhoneNumber {
name: EepromString::new("Marty McFly"),
number: PhoneString::new("1112223333"),
phone_type: PhoneType::Home,
},
PhoneNumber {
name: EepromString::new("Doc Brown"),
number: PhoneString::new("4445556666"),
phone_type: PhoneType::Cell,
},
];
let lists = vec![
List {
list_entry: EepromString::new("Muffler bearings"),
priority: Some(Priority::Two),
},
List {
list_entry: EepromString::new("Headlight fluid"),
priority: Some(Priority::Four),
},
];
let time1 = SystemTime::now();
let mut protocol = Protocol4::new();
protocol.add(Sync { length: 100 });
protocol.add(Start {});
protocol.add(Time {
zone: 1,
is_24h: false,
date_format: DateFormat::MonthDashDayDashYear,
time: time1,
name: CharString::new("PDT", true),
});
protocol.add(Time {
zone: 2,
is_24h: true,
date_format: DateFormat::MonthDashDayDashYear,
time: time1,
name: CharString::new("GMT", true),
});
protocol.add(Alarm {
number: 1,
audible: true,
time: system_time_from_time(9, 0),
message: CharString::new("Wake up", false),
});
protocol.add(Alarm {
number: 2,
audible: true,
time: system_time_from_time(9, 5),
message: CharString::new("For real", false),
});
protocol.add(Alarm {
number: 3,
audible: false,
time: system_time_from_time(9, 10),
message: CharString::new("Get up", false),
});
protocol.add(Alarm {
number: 4,
audible: true,
time: system_time_from_time(18, 0), message: CharString::new("Or not", false),
});
protocol.add(Alarm {
number: 5,
audible: false,
time: system_time_from_time(14, 0), message: CharString::new("Told you", false),
});
protocol.add(SoundOptions {
hourly_chime: true,
button_beep: true,
});
protocol.add(SoundTheme {
sound_theme_data: vec![0x00, 0x01, 0x02, 0x03],
});
let eeprom = Eeprom {
appointments,
anniversaries,
lists,
phone_numbers,
appointment_notification_minutes: Some(NotificationMinutes::FifteenMinutes),
};
protocol.add(eeprom);
protocol.add(WristApp {
wrist_app_data: vec![0x00, 0x01, 0x02, 0x03],
});
protocol.add(End {});
let all_packets = protocol.packets();
println!("Created Protocol4 structure with all components");
println!("- Generated {} packet groups", all_packets.len());
for (i, packet) in all_packets.iter().enumerate() {
let preview: Vec<u8> = packet.iter().take(6).cloned().collect();
println!("Packet group {}: {} bytes, starts with {:02X?}...", i, packet.len(), preview);
}
println!("\nTransmitting data to the watch on port: {}", serial_port);
let adapter = NotebookAdapter::new(
serial_port,
None, None, true, );
match adapter.write(&all_packets) {
Ok(_) => println!("\nSuccessfully transmitted data to the watch!"),
Err(e) => {
eprintln!("\nError transmitting data: {}", e);
process::exit(1);
}
}
}
fn system_time_from_date(year: i32, month: u32, day: u32, hour: u32, min: u32, sec: u32) -> SystemTime {
let naive_dt = chrono::NaiveDate::from_ymd_opt(year, month, day)
.unwrap()
.and_hms_opt(hour, min, sec)
.unwrap();
let dt = Utc.from_utc_datetime(&naive_dt);
if dt.timestamp() >= 0 {
SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(dt.timestamp() as u64)
} else {
SystemTime::UNIX_EPOCH - std::time::Duration::from_secs((-dt.timestamp()) as u64)
}
}
fn system_time_from_time(hour: u32, min: u32) -> SystemTime {
let naive_dt = chrono::NaiveDate::from_ymd_opt(2000, 1, 1)
.unwrap()
.and_hms_opt(hour, min, 0)
.unwrap();
let dt = Utc.from_utc_datetime(&naive_dt);
SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(dt.timestamp() as u64)
}