Files
vfd/examples/clock.rs
Кобелев Андрей Андреевич 446a710e01 init
2026-01-28 01:36:35 +05:00

151 lines
4.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// examples/clock_ru.rs
use anyhow::Result;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use m::vfd::VfdConfig;
use m::worker::VfdWorker;
fn run_date(args: &[&str]) -> Option<String> {
let out = std::process::Command::new("date")
.args(args)
.output()
.ok()?;
if !out.status.success() {
return None;
}
Some(String::from_utf8_lossy(&out.stdout).trim().to_string())
}
fn local_datetime_ddmmyyyy_hhmmss() -> String {
// 28.01.2006 12:03:34
run_date(&["+%d.%m.%Y %H:%M:%S"]).unwrap_or_else(|| "??.??.???? ??:??:??".to_string())
}
fn local_weekday_num_1_7() -> u8 {
// 1..7 (Mon..Sun)
run_date(&["+%u"])
.and_then(|s| s.parse::<u8>().ok())
.unwrap_or(1)
}
fn weekday_ru_full(n: u8) -> &'static str {
match n {
1 => "Понедельник",
2 => "Вторник",
3 => "Среда",
4 => "Четверг",
5 => "Пятница",
6 => "Суббота",
7 => "Воскресенье",
_ => "Понедельник",
}
}
fn weekday_ru_short(n: u8) -> &'static str {
match n {
1 => "Пн",
2 => "Вт",
3 => "Ср",
4 => "Чт",
5 => "Пт",
6 => "Сб",
7 => "Вс",
_ => "Пн",
}
}
fn time_of_day_ru(hour: u8) -> &'static str {
match hour {
5..=10 => "утро",
11..=16 => "день",
17..=22 => "вечер",
_ => "ночь",
}
}
fn extract_hour(datetime: &str) -> u8 {
// ожидаем "DD.MM.YYYY HH:MM:SS"
// берём HH как 2 символа после пробела
datetime
.split_whitespace()
.nth(1)
.and_then(|t| t.get(0..2))
.and_then(|hh| hh.parse::<u8>().ok())
.unwrap_or(12)
}
fn fit_to_width(s: &str, width: usize) -> String {
// простое “обрезать по символам”, чтобы кириллицу не порвать
let mut out = String::new();
for (i, ch) in s.chars().enumerate() {
if i >= width {
break;
}
out.push(ch);
}
out
}
fn main() -> Result<()> {
// args:
// 1) port (default: /dev/cu.usbmodem101)
// 2) width (default: 20)
// 3) brightness 1..4 (default: 2)
let port_name = std::env::args()
.nth(1)
.unwrap_or("/dev/cu.usbmodem101".into());
let width: usize = std::env::args()
.nth(2)
.as_deref()
.unwrap_or("20")
.parse()
.unwrap_or(20);
let brightness: u8 = std::env::args()
.nth(3)
.as_deref()
.unwrap_or("2")
.parse()
.unwrap_or(2);
let cfg = VfdConfig::new(port_name).with_width(width);
let worker = VfdWorker::start(cfg)?;
let vfd = worker.handle();
vfd.clear();
vfd.set_brightness(brightness);
loop {
let dt = local_datetime_ddmmyyyy_hhmmss();
let wd = local_weekday_num_1_7();
let hour = extract_hour(&dt);
let tod = time_of_day_ru(hour);
// 1 строка: "28.01.2006 12:03:34"
let line1 = fit_to_width(&dt, width);
// 2 строка: "Понедельник сейчас день"
// но если не влазит — "Пн сейчас день"
let full = format!("{} сейчас {}", weekday_ru_full(wd), tod);
let mut line2 = full;
if line2.chars().count() > width {
line2 = format!("{} сейчас {}", weekday_ru_short(wd), tod);
}
line2 = fit_to_width(&line2, width);
vfd.print_line_diff(1, line1)?;
vfd.print_line_diff(2, line2)?;
// чтобы обновлялось ровно раз в секунду (плюс/минус), можно “привязать” к UNIX time
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis();
let ms_to_next = 1000 - (now % 1000) as u64;
std::thread::sleep(Duration::from_millis(ms_to_next));
}
}