Added current period indicator and update time to the layout

This commit is contained in:
zenonet
2025-09-18 21:25:24 +02:00
parent 079b94940e
commit 6741ecbf2c

View File

@@ -1,7 +1,7 @@
use std::borrow::Cow;
use std::str::FromStr;
use chrono::{format::Fixed, Datelike, Days, NaiveTime};
use chrono::{format::Fixed, DateTime, Datelike, Days, FixedOffset, NaiveTime};
use embedded_graphics::{
mono_font::{MonoTextStyle, MonoTextStyleBuilder},
prelude::{Dimensions, Point},
@@ -24,7 +24,7 @@ use esp_idf_svc::{
};
use u8g2_fonts::U8g2TextStyle;
use untis::{Date, Lesson};
use embedded_layout::{layout::linear::{FixedMargin, LinearLayout}, prelude::*};
use embedded_layout::{layout::linear::{spacing::DistributeFill, ElementSpacing, FixedMargin, LinearLayout}, prelude::*};
type Timetable = [[Option<Lesson>;8]; 5];
@@ -113,9 +113,9 @@ fn main() -> anyhow::Result<()> {
..Default::default()
})?;
let tt = fetch_timetable(httpconnection);
let (tt, now) = fetch_timetable(httpconnection);
draw_layout(&mut display, &tt);
draw_layout(&mut display, &tt, now);
//draw_text(&mut display, &tt[3][5].clone().unwrap().subjects.first().as_ref().unwrap().name, 5, 5);
epd7in5.update_and_display_frame(&mut spi, &*display.buffer(), &mut delay)?;
epd7in5.sleep(&mut spi, &mut delay)?;
@@ -124,34 +124,37 @@ fn main() -> anyhow::Result<()> {
Ok(())
}
fn draw_text(display: &mut epd_waveshare::epd7in5_v2::Display7in5, text: &str, x: i32, y: i32) {
let style = MonoTextStyleBuilder::new()
.font(&embedded_graphics::mono_font::ascii::FONT_10X20)
.text_color(Color::White)
.background_color(Color::Black)
.build();
let text_style = TextStyleBuilder::new().baseline(Baseline::Top).build();
let _ = Text::with_text_style(text, Point::new(x, y), style, text_style).draw(display);
}
fn draw_layout(display: &mut epd_waveshare::epd7in5_v2::Display7in5, timetable: &Timetable){
fn draw_layout(display: &mut epd_waveshare::epd7in5_v2::Display7in5, timetable: &Timetable, now: DateTime<FixedOffset>){
let display_area = display.bounding_box();
let margin = FixedMargin(10);
// let text_style = MonoTextStyle::new(&embedded_graphics::mono_font::ascii::FONT_10X20, Color::White);
let text_style = U8g2TextStyle::new(u8g2_fonts::fonts::u8g2_font_inr21_mf, Color::White);
let mut inverted_text_style = U8g2TextStyle::new(u8g2_fonts::fonts::u8g2_font_inr21_mf, Color::Black);
inverted_text_style.background_color = Some(Color::White);
let text_style_small = U8g2TextStyle::new(u8g2_fonts::fonts::u8g2_font_7x14_mr, Color::White);
let empty_str = String::from(" ");
let mut texts = timetable.iter().map(|day| day.iter().map(|l| {
if let Some(l) = l{
let day_of_week = now.weekday().num_days_from_monday(); // zero-indexed
let current_period = get_school_period(now.time());
let mut texts = timetable.iter().enumerate().map(|(day_index, day)| day.iter().enumerate().map(|(period, l)| {
let s = if let Some(l) = l{
Some(l.subjects.first().unwrap().name.as_str())
}else{
None
}
}).map(|s|{
Text::new(s.unwrap_or_else(|| &empty_str), Point::zero(), &text_style)
};
let text_style = if period as u8 == current_period && day_index as u32 == day_of_week{
&inverted_text_style
}else{
&text_style
};
Text::new(s.unwrap_or_else(|| &empty_str), Point::zero(), text_style)
}).collect::<Vec<_>>()).collect::<Vec<_>>();
let mut columns = texts.iter_mut().map(|day|
@@ -163,16 +166,44 @@ fn draw_layout(display: &mut epd_waveshare::epd7in5_v2::Display7in5, timetable:
let columns = Views::new(&mut columns);
LinearLayout::horizontal(columns)
let time_str = format!("{}", now.format("%Y-%m-%d %H:%M"));
let time_text = Text::new(&time_str, Point::zero(), &text_style_small);
let time_table_grid = LinearLayout::horizontal(columns)
.with_alignment(vertical::Center)
.with_spacing(margin)
.arrange();
LinearLayout::vertical(Chain::new(time_table_grid).append(time_text))
.with_alignment(horizontal::Center)
.with_spacing(DistributeFill(display_area.size.height-20))
.arrange()
.align_to(&display_area, horizontal::Center, vertical::Top)
.align_to(&display_area, horizontal::Center, vertical::Center)
.draw(display)
.unwrap();
}
fn get_school_period(time: NaiveTime) -> u8{
let lookup: [NaiveTime; 8] = [
(NaiveTime::from_hms_opt(8, 45, 0).unwrap()),
(NaiveTime::from_hms_opt(9, 35, 0).unwrap()),
(NaiveTime::from_hms_opt(10, 40, 0).unwrap()),
(NaiveTime::from_hms_opt(11, 30, 0).unwrap()),
(NaiveTime::from_hms_opt(12, 40, 0).unwrap()),
(NaiveTime::from_hms_opt(13, 30, 0).unwrap()),
(NaiveTime::from_hms_opt(14, 25, 0).unwrap()),
(NaiveTime::from_hms_opt(15, 15, 0).unwrap()),
];
for (index, period_time) in lookup.iter().enumerate(){
if time < *period_time{
return index as u8;
}
}
7u8
}
fn transform_lessons(lessons: Vec<Lesson>) -> Box<Timetable>{
let lookup: [NaiveTime; 8] = [
@@ -203,7 +234,7 @@ fn transform_lessons(lessons: Vec<Lesson>) -> Box<Timetable>{
}
fn fetch_timetable(client: EspHttpConnection) -> Box<Timetable> {
fn fetch_timetable(client: EspHttpConnection) -> (Box<Timetable>, DateTime<FixedOffset>) {
let mut creds = include_str!("../untis-creds.txt").split('\n');
let server = creds.next().unwrap();
@@ -224,5 +255,5 @@ fn fetch_timetable(client: EspHttpConnection) -> Box<Timetable> {
let date = now.date_naive().checked_add_days(Days::new(2)).unwrap();
let lessons = s.own_timetable_for_week(&Date(date)).unwrap();
transform_lessons(lessons)
(transform_lessons(lessons), now)
}