This commit is contained in:
2022-10-24 22:20:55 +02:00
parent 91ca707245
commit 2370faa718
3 changed files with 62 additions and 28 deletions

View File

@ -101,11 +101,17 @@ pub async fn lights_task(state: &State) {
ClientMessage::SetBulbWakeTime { id, day, time } => { ClientMessage::SetBulbWakeTime { id, day, time } => {
if let Err(e) = lights_state.update(|lights_state| { if let Err(e) = lights_state.update(|lights_state| {
let schedule = lights_state.wake_schedule.entry(id.clone()).or_default(); let schedule = lights_state.wake_schedule.entry(id.clone()).or_default();
schedule.insert(day, time); if let Some(time) = time {
schedule.insert(day, time);
}
else {
schedule.remove(&day);
}
}).await { }).await {
error!("Failed to save wake schedule: {e}"); error!("Failed to save wake schedule: {e}");
}; };
if let Some(time) = time {
let handle = spawn(wake_task( let handle = spawn(wake_task(
state.client_message.subscribe(), state.client_message.subscribe(),
cmd.clone(), cmd.clone(),
@ -113,8 +119,13 @@ pub async fn lights_task(state: &State) {
day, day,
time, time,
)); ));
if let Some(old_handle) = wake_tasks.insert((id, day), handle) { if let Some(old_handle) = wake_tasks.insert((id, day), handle) {
old_handle.abort(); old_handle.abort();
}} else {
if let Some(old_handle) = wake_tasks.remove(&(id, day)) {
old_handle.abort();
}
} }
} }
_ => {} _ => {}

View File

@ -38,7 +38,7 @@ pub enum ClientMessage {
SetBulbWakeTime { SetBulbWakeTime {
id: BulbId, id: BulbId,
day: Weekday, day: Weekday,
time: NaiveTime, time: Option<NaiveTime>,
}, },
} }

View File

@ -6,23 +6,30 @@ use lighter_lib::{BulbId, BulbMode};
use seed::prelude::*; use seed::prelude::*;
use seed::{attrs, button, div, input, C}; use seed::{attrs, button, div, input, C};
use seed_router::Page; use seed_router::Page;
use std::collections::{BTreeMap, HashSet}; use std::collections::{BTreeMap, HashSet, HashMap};
use std::fmt::Write; use std::fmt::Write;
/// /lights page /// /lights page
#[derive(Default)] #[derive(Default)]
pub struct Model { pub struct Model {
bulb_states: BTreeMap<BulbId, BulbMode>, bulb_states: BTreeMap<BulbId, BulbState>,
bulb_map: BulbMap, bulb_map: BulbMap,
/// The currently selected bulb map groups /// the currently selected bulb map groups
selected_groups: HashSet<usize>, selected_groups: HashSet<usize>,
/// Whether the currently selected map groups have been interacted with /// whether the currently selected map groups have been interacted with
groups_interacted: bool, groups_interacted: bool,
color_picker: ColorPicker, color_picker: ColorPicker,
}
#[derive(Default, Clone)]
struct BulbState {
mode: BulbMode,
wake_schedule: HashMap<Weekday, NaiveTime>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -50,7 +57,11 @@ impl Page for Model {
match msg { match msg {
Msg::ServerMessage(msg) => match msg { Msg::ServerMessage(msg) => match msg {
ServerMessage::BulbState { id, mode: new_mode, wake_schedule } => { ServerMessage::BulbState { id, mode: new_mode, wake_schedule } => {
*self.bulb_states.entry(id).or_default() = new_mode *self.bulb_states.entry(id).or_default() = BulbState {
mode: new_mode,
wake_schedule,
};
//color_picker.set_color(mode.color); //color_picker.set_color(mode.color);
} }
ServerMessage::BulbMap(bulb_map) => { ServerMessage::BulbMap(bulb_map) => {
@ -82,7 +93,7 @@ impl Page for Model {
.and_then(|id| self.bulb_states.get(id)); .and_then(|id| self.bulb_states.get(id));
if let Some(bulb) = bulb { if let Some(bulb) = bulb {
self.color_picker.set_color(bulb.color); self.color_picker.set_color(bulb.mode.color);
} }
} }
} }
@ -111,12 +122,22 @@ impl Page for Model {
}); });
} }
Msg::LightTime(time, day) => { Msg::LightTime(time, day) => {
if let Ok(time) = NaiveTime::parse_from_str(&time, "%H:%M") { if time == "" {
self.for_selected_bulbs(|id, _| { self.for_selected_bulbs(|id, _| {
let message = ClientMessage::SetBulbWakeTime { let message = ClientMessage::SetBulbWakeTime {
id: id.clone(), id: id.clone(),
day, day,
time, time: None,
};
orders.notify(message);
});
}
else if let Ok(time) = NaiveTime::parse_from_str(&time, "%H:%M") {
self.for_selected_bulbs(|id, _| {
let message = ClientMessage::SetBulbWakeTime {
id: id.clone(),
day,
time: Some(time),
}; };
orders.notify(message); orders.notify(message);
}); });
@ -200,27 +221,29 @@ fn view(&self) -> Node<Self::Msg> {
] ]
}; };
let calendar_day = |day: Weekday| { let selected_bulb = self
div![
C![C.calendar_day],
day.to_string(),
input![
C![C.calendar_time_input],
attrs! {At::Placeholder => "7:30"},
input_ev(Ev::Input, move |input| Msg::LightTime(input, day))
],
]
};
let (_color, power) = self
.selected_groups .selected_groups
.iter() .iter()
.next() .next()
.and_then(|&index| self.bulb_map.groups.get(index)) .and_then(|&index| self.bulb_map.groups.get(index))
.and_then(|group| group.bulbs.first()) .and_then(|group| group.bulbs.first())
.and_then(|id| self.bulb_states.get(id)) .and_then(|id| self.bulb_states.get(id))
.map(|bulb| (bulb.color, bulb.power)) .cloned() // TODO: remove clone
.unwrap_or_default(); .unwrap_or_default();
let calendar_day = |day: Weekday| {
let time = selected_bulb.wake_schedule.get(&day).map(|t| t.to_string()).unwrap_or_default();
div![
C![C.calendar_day],
day.to_string(),
input![
C![C.calendar_time_input],
attrs! {At::Placeholder => time},
input_ev(Ev::Input, move |input| Msg::LightTime(input, day))
],
]
};
div![ div![
C![C.bulb_box], C![C.bulb_box],
@ -238,12 +261,12 @@ fn view(&self) -> Node<Self::Msg> {
.view() .view()
.map_msg(|msg| Msg::ColorPicker(msg)), .map_msg(|msg| Msg::ColorPicker(msg)),
button![ button![
if power { if selected_bulb.mode.power {
C![C.bulb_power_button, C.bulb_power_button_on] C![C.bulb_power_button, C.bulb_power_button_on]
} else { } else {
C![C.bulb_power_button] C![C.bulb_power_button]
}, },
ev(Ev::Click, move |_| Msg::SetBulbPower(!power)), ev(Ev::Click, move |_| Msg::SetBulbPower(!selected_bulb.mode.power)),
div![attrs! { At::Id => "switch_socket" }], div![attrs! { At::Id => "switch_socket" }],
div![attrs! { At::Id => "off_label" }, "Off"], div![attrs! { At::Id => "off_label" }, "Off"],
div![attrs! { At::Id => "on_label" }, "On"], div![attrs! { At::Id => "on_label" }, "On"],
@ -266,7 +289,7 @@ fn view(&self) -> Node<Self::Msg> {
} }
impl Model { impl Model {
fn for_selected_bulbs(&self, mut f: impl FnMut(&BulbId, &BulbMode)) { fn for_selected_bulbs(&self, mut f: impl FnMut(&BulbId, &BulbState)) {
self.selected_groups self.selected_groups
.iter() .iter()
.filter_map(|&index| self.bulb_map.groups.get(index)) .filter_map(|&index| self.bulb_map.groups.get(index))