diff --git a/src/main.rs b/src/main.rs index 3760dda..3300a32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,7 +30,7 @@ use esp_idf_svc::{ nvs::EspDefaultNvsPartition, wifi::Configuration, }; -use esp_idf_sys::esp_deep_sleep; +use esp_idf_sys::{esp_deep_sleep, esp_deep_sleep_wake_stub_fn_t}; use u8g2_fonts::U8g2TextStyle; use untis::{Date, Lesson, LessonCode}; use embedded_layout::{layout::linear::{spacing::DistributeFill, FixedMargin, LinearLayout}, prelude::*}; @@ -46,6 +46,8 @@ static mut FETCHING_FAIL_COUNT: Option = None; #[unsafe(link_section = ".rtc.data")] static mut ERROR_MSG: Option<[u8; 2048]> = None; +static mut WEEK_OFFSET: i32 = 0; + fn main() -> anyhow::Result<()> { // It is necessary to call this function once. Otherwise some patches to the runtime // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 @@ -57,16 +59,12 @@ fn main() -> anyhow::Result<()> { log::info!("Took peripherals"); - let busy = PinDriver::input(peripherals.pins.gpio17).unwrap(); - let rst = PinDriver::output(peripherals.pins.gpio16).unwrap(); - let cs = peripherals.pins.gpio5; - let clk = peripherals.pins.gpio18; - let mosi = peripherals.pins.gpio23; - let miso = peripherals.pins.gpio19; // aka. dc - - let dc = PinDriver::output(miso).unwrap(); - - + let mut creds = include_str!("../wifi-creds.txt").split('\n'); + let ssid: heapless::String<32> = + heapless::String::<32>::from_str(creds.next().unwrap()).unwrap(); + let password: heapless::String<64> = + heapless::String::<64>::from_str(creds.next().unwrap()).unwrap(); + std::panic::set_hook(Box::new(|panic|{ let msg: String = format!("{}", panic);/* if let Some(s) = panic.payload().downcast_ref::<&str>() { format!("{s:?}") @@ -92,6 +90,15 @@ fn main() -> anyhow::Result<()> { })); + let busy = PinDriver::input(peripherals.pins.gpio17).unwrap(); + let rst = PinDriver::output(peripherals.pins.gpio16).unwrap(); + let cs = peripherals.pins.gpio5; + let clk = peripherals.pins.gpio18; + let mosi = peripherals.pins.gpio23; + let miso = peripherals.pins.gpio19; // aka. dc + + let dc = PinDriver::output(miso).unwrap(); + log::info!("Initialized pins"); let config = config::Config::new(); @@ -153,15 +160,13 @@ fn main() -> anyhow::Result<()> { } } - let mut creds = include_str!("../wifi-creds.txt").split('\n'); - let ssid: heapless::String<32> = - heapless::String::<32>::from_str(creds.next().unwrap()).unwrap(); - let password: heapless::String<64> = - heapless::String::<64>::from_str(creds.next().unwrap()).unwrap(); - + + + // Connecting to wifi let sysloop = EspSystemEventLoop::take()?; let nvs = EspDefaultNvsPartition::take()?; + let mut wifi = BlockingWifi::wrap( EspWifi::new(peripherals.modem, sysloop.clone(), Some(nvs))?, sysloop.clone(), @@ -176,10 +181,18 @@ fn main() -> anyhow::Result<()> { }, ))?; - wifi.start() - .and_then(|_| wifi.connect()) - .and_then(|_| wifi.wait_netif_up()) - .and_then(|_| loop {if wifi.is_connected().unwrap() {break Ok(());}})?; + fn err() -> !{ + println!("No wifi available. Sleeping for 5 minutes"); + unsafe{ + // retry in 5 minutes + esp_deep_sleep(5*60*1000_000) + } + } + + wifi.start().unwrap_or_else(|_| err()); + wifi.connect().unwrap_or_else(|_| err()); + wifi.wait_netif_up().unwrap_or_else(|_| err()); + loop {if wifi.is_connected().unwrap_or_else(|_| err()) {break;}}; unsafe { FETCHING_FAIL_COUNT = None; @@ -197,6 +210,9 @@ fn main() -> anyhow::Result<()> { *writer.write().unwrap() = Some(Command::Timetable); + unsafe{ + WEEK_OFFSET = request.header("week").and_then(|w| w.parse::().ok()).unwrap_or_default(); + } // Retrieve html String let html = String::from("OK"); @@ -550,10 +566,10 @@ fn fetch_timetable(client: EspHttpConnection) -> anyhow::Result<(Box, password, client ).or_else(|e| None.context(format!("{:?}", e)))?; - let cest = chrono::FixedOffset::east_opt(2 * 3600).unwrap(); - let now = s.date().context("Untis client provided no time but time is necessary for the requesting the timetable")?.with_timezone(&cest); + let cet = chrono::FixedOffset::east_opt(1 * 3600).unwrap(); + let now = s.date().context("Untis client provided no time but time is necessary for the requesting the timetable")?.with_timezone(&cet); println!("Current time: {}", now); - let date = now.date_naive().checked_add_days(Days::new(2)).unwrap(); + let date = now.date_naive().checked_add_days(Days::new(2)).unwrap().checked_add_signed(TimeDelta::weeks(unsafe { WEEK_OFFSET } as i64 )).unwrap(); let lessons = s.own_timetable_for_week(&Date(date)).or_else(|e| None.context(format!("{:?}", e)))?; Ok((transform_lessons(lessons), now))