it works
This commit is contained in:
@ -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();
|
||||||
|
if let Some(time) = time {
|
||||||
schedule.insert(day, 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ pub enum ClientMessage {
|
|||||||
SetBulbWakeTime {
|
SetBulbWakeTime {
|
||||||
id: BulbId,
|
id: BulbId,
|
||||||
day: Weekday,
|
day: Weekday,
|
||||||
time: NaiveTime,
|
time: Option<NaiveTime>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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,28 +221,30 @@ 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],
|
||||||
div![
|
div![
|
||||||
@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user