8 个版本
0.3.2 | 2021 年 5 月 11 日 |
---|---|
0.3.1 | 2021 年 3 月 24 日 |
0.2.1 | 2021 年 3 月 21 日 |
0.1.0 | 2021 年 3 月 2 日 |
#243 in 日期和时间
50KB
413 行
timemachine
简化了基于每日时间的状态转换的处理。
关于
你是否曾需要根据一天中的某个时间来设置某些状态?比如说,从早上 7 点到 8 点处于一种状态,然后从早上 8 点到晚上 9 点处于另一种状态,然后从晚上 9 点到早上 7 点再是另一种状态?这会很快变成一个大麻烦!需要处理很多边缘情况,而且实现这些功能的代码会迅速变成一团糟。
为什么还要尝试?timemachine crate 让你轻松做到这一点! :D
(有关用例的更详细说明,请向下滚动)
功能 "napchart"(由两个示例使用)使用了处于测试阶段的 https://napchart.com API。
用法
将依赖项添加到您的 Cargo.toml
timemachine = "0.3.1"
以启用 napchart 支持
timemachine = [ version = "0.3.1", features = ["napchart"] ]
示例
-
cargorun --exampleauto_lights
从 stdin 获取配置并模拟 24 小时的灯光颜色 -
cargorun --examplenapchart_lights --特性napchart
类似于 auto_lights,但获取配置来自 https://napchart.com/3tbkt
灰色 = 灯光关闭,红色 = 灯光红色,其他情况下灯光白色 -
cargorun --examplenapchart_lights_option --特性napchart
类似于 napchart_lights,但获取其配置来自 https://napchart.com/cse2j
灰色 = 灯光关闭,红色 = 灯光红色,蓝色 = 灯光白色,其他情况下输出错误
等等,这是什么用呢?
假设你有一些 RGB 灯泡,你想让它们在一天中自动切换颜色。白天,你希望它们是白色的,晚上则希望关闭。让我们假设“白天”从早上 7 点持续到晚上 8 点,因此“晚上”是从晚上 8 点持续到早上 7 点。
用伪代码实现这个功能的简单方法是
if now() == 7AM {
lights.turn_on()
} else if now() == 8PM {
lights.turn_off()
}
你写下这段代码并运行它,但什么也没有发生!这段代码只更新了灯光的状态在早上 7 点和晚上 8 点的转换时间,所以除非你正好在这些时间运行它,否则它不会工作。
但是,这是一个简单的解决方案
if now() > 7AM && now() < 8PM {
lights.turn_on()
} else if now() > 8PM && now() < 7AM {
lights.turn_off()
}
你运行它,,,, 它工作了!!灯亮了!你拍拍自己的背,给自己贴了个贴纸。当然,我们现在每秒都在更新灯的状态 every second,但你很容易添加延迟来降低任何你喜欢的精度级别。
后来,当你正在玩你最喜欢的 MMOTCRPG,《巫师101》(TM),你瞥了一眼时钟,意识到已经11点了,远远超过了你的睡觉时间!你怎么又能犯同样的错误呢?你不是写了个程序在睡觉时间关灯,以免忘记吗?所有的灯都还亮着,你明天开会会累的!另一方面,你单枪匹马击败了Malistaire Drake,拯救了螺旋免于毁灭,所以并非全是坏事。你按下了开关(这是你物联网灯泡的一个 neat 内置手动切换),然后上床睡觉,决心明天找出这个bug。(如果你在阅读这段话时感到身心不适,请联系我们的法律部门 [email protected])
睡了一觉后,bug显然了。夜晚不是 8PM < now() < 7AM
!例如,11点已经是晚上8点之后,但也已经过了早上7点。1点是 在这两个时间之前!再次,这是一个简单的修复
if now() > 7AM && now() < 8PM {
lights.turn_on()
} else if now > 8PM || now() < 7AM {
lights.turn_off()
}
最后,你做到了。你的灯将在早上7点开到晚上8点,然后从晚上8点关到早上7点。是的!这实际上管用了!做得好!
几周后,你开始不喜欢你的设置。每天晚上8点,你家里的所有灯都会突然关掉,没有任何警告!事实上,每天晚上7:59 PM,你的大脑(总是那么聪明)会释放肾上腺素,像巴甫洛夫的狗一样期待着黑暗的到来。这不行!如果每天晚上都伴随着恐惧,你将无法睡个好觉!必须有一个解决方案。
事实上,有一个解决方案!你的物联网灯泡不仅连接到互联网,而且还是RGB的!也许你可以添加一种人工黄昏?是的,这应该有帮助。你打开你的代码并开始工作,
if now() > 7AM && now() < 7:30PM {
lights.turn_on()
lights.set_color("white")
} else if now() > 7:30PM && now() < 8PM {
lights.turn_on()
lights.set_color("red")
} else if now() > 8PM || now() < 6:30AM {
lights.turn_off()
} else if now() > 6:30AM && now() < 7AM {
lights.turn_on()
lights.set_color("red")
}
完美。绝对的天才。你不仅添加了人工黄昏,还添加了人工黎明!你对你的工作感到如此自豪,以至于你决定将其上传到 GitHub(TM) 并让其他人使用你的代码。其他人可能不会像你那样睡觉,所以你添加了一些参数来改变这些设置。
dawn_time = 6:30AM
day_time = 7AM
dusk_time = 7:30 PM
night_time = 8PM
if now() > day_time && now() < dusk_time {
lights.turn_on()
lights.set_color("white")
} else if now() > dusk_time && now() < night_time {
lights.turn_on()
lights.set_color("red")
} else if now() > night_time || now() < dawn_time {
lights.turn_off()
} else if now() > dawn_time && now() < day_time {
lights.turn_on()
lights.set_color("red")
}
几周后,有人在你仓库中打开了一个问题。“它不起作用,请帮助”幸运的是,他们上传了他们的配置文件
dawn_time = 10:30AM
day_time = 11AM
dusk_time = 12:30 AM
night_time = 1AM
你想了一会儿,意识到问题的所在。你假设人们会在午夜之前睡觉!这不应该是简单的修复吗?
嗯,也许,但这会变得很混乱,即使你修复了它,你的代码在像 dusk_time = 11:30 PM, night_time = 12:30 AM
这样的配置下仍然会出错。你不能假设这四个状态中的任何一个不会跨越午夜边界。
你应该从一开始就使用 timemachine
库!简单、直接,处理了所有边缘情况。今天试试 timemachine
吧!
// Full version of this snippet can be found in examples/auto_lights.rs!
pub enum State {
NightDark,
DuskDawnRed,
DayWhite,
}
fn main() {
let (dawn_time, day_time, dusk_time, night_time) = get_config();
let mut tm = TimeMachine::<State>::new();
tm.add_transition(dawn_time, State::DuskDawnRed);
tm.add_transition(day_time, State::DayWhite);
tm.add_transition(dusk_time, State::DuskDawnRed);
tm.add_transition(night_time, State::NightDark);
loop {
sleep_ms(1000);
match tm.get_state(now()) {
State::NightDark => lights.turn_off(),
State::DuskDawnRed => {
lights.set_color("red");
lights.turn_on();
},
State::DayWhite => {
lights.set_color("white");
lights.turn_on();
},
}
}
}
依赖项
~0–12MB
~128K SLoC