Fix alarm time calculation
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use chrono::{Datelike, Local, NaiveTime, Weekday};
|
||||
use chrono::{DateTime, Datelike, Local, NaiveTime, Weekday};
|
||||
use common::{ClientMessage, ServerMessage};
|
||||
use lighter_lib::{BulbColor, BulbId};
|
||||
use lighter_manager::manager::{BulbCommand, BulbManager, BulbSelector};
|
||||
@ -143,25 +143,11 @@ async fn wake_task(
|
||||
time: NaiveTime,
|
||||
) {
|
||||
let now = Local::now();
|
||||
let day_num = day.num_days_from_monday();
|
||||
let now_day = now.weekday();
|
||||
let now_day_num = now_day.num_days_from_monday();
|
||||
|
||||
let mut alarm = now;
|
||||
if day_num >= now_day_num {
|
||||
// next alarm is this week
|
||||
alarm += chrono::Duration::days((day_num - now_day_num).into());
|
||||
alarm = alarm.date().and_time(time).unwrap();
|
||||
} else {
|
||||
// next alarm is next week
|
||||
alarm += chrono::Duration::weeks(1);
|
||||
alarm -= chrono::Duration::days((now_day_num - day_num).into());
|
||||
alarm = alarm.date().and_time(time).unwrap();
|
||||
}
|
||||
let mut alarm = next_alarm(now, day, time);
|
||||
|
||||
loop {
|
||||
info!("sleeping until {alarm}");
|
||||
sleep((alarm - Local::now()).to_std().unwrap()).await;
|
||||
sleep((alarm - now).to_std().unwrap()).await;
|
||||
alarm += chrono::Duration::weeks(1);
|
||||
|
||||
// slowly turn up brightness of bulb
|
||||
@ -189,6 +175,21 @@ async fn wake_task(
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the next alarm, from a weekday+time schedule.
|
||||
fn next_alarm(now: DateTime<Local>, day: Weekday, time: NaiveTime) -> DateTime<Local> {
|
||||
let day_of_alarm = day.num_days_from_monday() as i64;
|
||||
let day_now = now.weekday().num_days_from_monday() as i64;
|
||||
|
||||
let alarm = now + chrono::Duration::days(day_of_alarm - day_now);
|
||||
let mut alarm = alarm.date().and_time(time).unwrap();
|
||||
|
||||
if alarm <= now {
|
||||
alarm += chrono::Duration::weeks(1);
|
||||
}
|
||||
|
||||
alarm
|
||||
}
|
||||
|
||||
/// Wait until we receive a client request that mutates the given bulb
|
||||
async fn wait_for_bulb_command(
|
||||
bulb_id: &BulbId,
|
||||
@ -210,3 +211,31 @@ async fn wait_for_bulb_command(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use chrono::{offset::TimeZone, Local, NaiveTime, Weekday};
|
||||
|
||||
use super::next_alarm;
|
||||
|
||||
#[test]
|
||||
fn test_alarm_date() {
|
||||
const FMT: &str = "%Y-%m-%d %H:%M";
|
||||
let now = Local.datetime_from_str("2022-10-18 15:30", FMT).unwrap();
|
||||
let test_values = [
|
||||
(Weekday::Tue, (16, 30), "2022-10-18 16:30"),
|
||||
(Weekday::Tue, (14, 30), "2022-10-25 14:30"),
|
||||
(Weekday::Wed, (15, 30), "2022-10-19 15:30"),
|
||||
(Weekday::Mon, (15, 30), "2022-10-24 15:30"),
|
||||
];
|
||||
|
||||
for (day, (hour, min), expected) in test_values {
|
||||
let expected = Local.datetime_from_str(expected, FMT).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
next_alarm(now, day, NaiveTime::from_hms(hour, min, 0)),
|
||||
expected
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user