Made api access work on the esp
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@
|
|||||||
/target
|
/target
|
||||||
/Cargo.lock
|
/Cargo.lock
|
||||||
wifi-creds.txt
|
wifi-creds.txt
|
||||||
|
untis-creds.txt
|
||||||
@@ -30,6 +30,11 @@ epd-waveshare = "0.6.0"
|
|||||||
embedded-graphics = "0.8.1"
|
embedded-graphics = "0.8.1"
|
||||||
embedded-hal = "1.0.0"
|
embedded-hal = "1.0.0"
|
||||||
heapless = "0.8"
|
heapless = "0.8"
|
||||||
|
esp-idf-sys = "0.36.1"
|
||||||
|
anyhow = "1.0.99"
|
||||||
|
embedded-svc = "0.28.1"
|
||||||
|
untis = {path = "../untis-test/untis-rs"}
|
||||||
|
chrono = "0.4.41"
|
||||||
|
|
||||||
# --- Optional Embassy Integration ---
|
# --- Optional Embassy Integration ---
|
||||||
# esp-idf-svc = { version = "0.51", features = ["critical-section", "embassy-time-driver", "embassy-sync"] }
|
# esp-idf-svc = { version = "0.51", features = ["critical-section", "embassy-time-driver", "embassy-sync"] }
|
||||||
|
|||||||
157
src/main.rs
157
src/main.rs
@@ -1,17 +1,31 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use embedded_graphics::{mono_font::MonoTextStyleBuilder, prelude::Point, Drawable, text::{Baseline, Text, TextStyleBuilder}};
|
use chrono::{Datelike, Days, NaiveTime};
|
||||||
|
use embedded_graphics::{
|
||||||
|
mono_font::MonoTextStyleBuilder,
|
||||||
|
prelude::Point,
|
||||||
|
text::{Baseline, Text, TextStyleBuilder},
|
||||||
|
Drawable,
|
||||||
|
};
|
||||||
use epd_waveshare::{color::Color, epd7in5_v2::Epd7in5, prelude::WaveshareDisplay};
|
use epd_waveshare::{color::Color, epd7in5_v2::Epd7in5, prelude::WaveshareDisplay};
|
||||||
use esp_idf_hal::{delay::{Delay, Ets}, gpio::{Gpio19, PinDriver}, spi::{config, Spi, SpiDriver, SpiDriverConfig}};
|
use esp_idf_hal::{
|
||||||
use esp_idf_svc::{eventloop::EspSystemEventLoop, hal::{prelude::*, spi::SpiDeviceDriver}, nvs::EspDefaultNvsPartition, wifi::Configuration};
|
delay::{Ets},
|
||||||
use esp_idf_svc::wifi::{EspWifi, BlockingWifi};
|
gpio::{Gpio19, PinDriver},
|
||||||
use embedded_hal::delay::DelayNs;
|
spi::{config, SpiDriverConfig},
|
||||||
|
};
|
||||||
|
use esp_idf_svc::http::client::{Configuration as HttpConfig, EspHttpConnection};
|
||||||
|
use esp_idf_svc::wifi::{BlockingWifi, EspWifi};
|
||||||
|
use esp_idf_svc::{
|
||||||
|
eventloop::EspSystemEventLoop,
|
||||||
|
hal::{prelude::*, spi::SpiDeviceDriver},
|
||||||
|
nvs::EspDefaultNvsPartition,
|
||||||
|
wifi::Configuration,
|
||||||
|
};
|
||||||
|
use untis::{Date, Lesson};
|
||||||
|
|
||||||
|
|
||||||
//static mut display: epd_waveshare::epd7in5_v2::Display7in5 = epd_waveshare::epd7in5_v2::Display7in5::default();
|
fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
//static FRAMEBUF: [u8; 48000] = [63; 48000];
|
|
||||||
fn main() {
|
|
||||||
// It is necessary to call this function once. Otherwise some patches to the runtime
|
// 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
|
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
|
||||||
esp_idf_svc::sys::link_patches();
|
esp_idf_svc::sys::link_patches();
|
||||||
@@ -29,13 +43,10 @@ fn main() {
|
|||||||
let mosi = peripherals.pins.gpio23; // y
|
let mosi = peripherals.pins.gpio23; // y
|
||||||
let miso = peripherals.pins.gpio19; // aka. dc
|
let miso = peripherals.pins.gpio19; // aka. dc
|
||||||
|
|
||||||
|
|
||||||
let dc = PinDriver::output(miso).unwrap();
|
let dc = PinDriver::output(miso).unwrap();
|
||||||
|
|
||||||
|
|
||||||
log::info!("Initialized pins");
|
log::info!("Initialized pins");
|
||||||
|
|
||||||
|
|
||||||
let config = config::Config::new();
|
let config = config::Config::new();
|
||||||
|
|
||||||
let mut spi = SpiDeviceDriver::new_single(
|
let mut spi = SpiDeviceDriver::new_single(
|
||||||
@@ -45,63 +56,67 @@ fn main() {
|
|||||||
Option::<Gpio19>::None,
|
Option::<Gpio19>::None,
|
||||||
Some(cs),
|
Some(cs),
|
||||||
&SpiDriverConfig::default(),
|
&SpiDriverConfig::default(),
|
||||||
&config
|
&config,
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
log::info!("Initialized spi interface");
|
log::info!("Initialized spi interface");
|
||||||
|
|
||||||
// Allocating on the stack makes the chip crash. We gotta put it on the heap
|
// Allocating on the stack makes the chip crash. We gotta put it on the heap
|
||||||
let mut display = Box::new(epd_waveshare::epd7in5_v2::Display7in5::default());
|
let mut display = Box::new(epd_waveshare::epd7in5_v2::Display7in5::default());
|
||||||
display.set_rotation(epd_waveshare::prelude::DisplayRotation::Rotate0);
|
display.set_rotation(epd_waveshare::prelude::DisplayRotation::Rotate0);
|
||||||
|
|
||||||
let mut delay = Ets;
|
let mut delay = Ets;
|
||||||
|
|
||||||
let mut epd7in5 = Epd7in5::new(&mut spi, busy, dc, rst, &mut delay, None).unwrap();
|
let mut epd7in5 = Epd7in5::new(&mut spi, busy, dc, rst, &mut delay, None).unwrap();
|
||||||
log::info!("Created epd object");
|
|
||||||
|
|
||||||
|
|
||||||
// Create a file called wifi-creds.txt and write SSID and password into it separated by a line break
|
// Create a file called wifi-creds.txt and write SSID and password into it separated by a line break
|
||||||
let mut creds = include_str!("../wifi-creds.txt").split('\n');
|
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 ssid: heapless::String<32> =
|
||||||
let password: heapless::String<64> = heapless::String::<64>::from_str(creds.next().unwrap()).unwrap();
|
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
|
// Connecting to wifi
|
||||||
let sysloop = EspSystemEventLoop::take().unwrap();
|
let sysloop = EspSystemEventLoop::take().unwrap();
|
||||||
let nvs = EspDefaultNvsPartition::take().unwrap();
|
let nvs = EspDefaultNvsPartition::take().unwrap();
|
||||||
let mut wifi =
|
let mut wifi = BlockingWifi::wrap(
|
||||||
BlockingWifi::wrap(
|
EspWifi::new(peripherals.modem, sysloop.clone(), Some(nvs)).unwrap(),
|
||||||
EspWifi::new(peripherals.modem, sysloop.clone(), Some(nvs)).unwrap(), sysloop.clone()).unwrap();
|
sysloop.clone(),
|
||||||
wifi.set_configuration(&Configuration::Client(esp_idf_svc::wifi::ClientConfiguration {
|
)
|
||||||
ssid,
|
.unwrap();
|
||||||
password,
|
wifi.set_configuration(&Configuration::Client(
|
||||||
auth_method: esp_idf_svc::wifi::AuthMethod::WPA2WPA3Personal,
|
esp_idf_svc::wifi::ClientConfiguration {
|
||||||
..Default::default()
|
ssid,
|
||||||
})
|
password,
|
||||||
).unwrap();
|
auth_method: esp_idf_svc::wifi::AuthMethod::WPA2WPA3Personal,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
wifi.start().unwrap();
|
wifi.start().unwrap();
|
||||||
wifi.connect().unwrap();
|
wifi.connect().unwrap();
|
||||||
wifi.wait_netif_up().unwrap();
|
wifi.wait_netif_up().unwrap();
|
||||||
|
|
||||||
while !wifi.is_connected().unwrap(){
|
while !wifi.is_connected().unwrap() {}
|
||||||
let config = wifi.get_configuration().unwrap();
|
println!("Connected to wifi");
|
||||||
println!("Waiting for station {:?}", config);
|
|
||||||
}
|
|
||||||
|
|
||||||
let ip_info = wifi.wifi().sta_netif().get_ip_info().unwrap();
|
let ip_info = wifi.wifi().sta_netif().get_ip_info().unwrap();
|
||||||
|
|
||||||
|
let httpconnection = EspHttpConnection::new(&HttpConfig {
|
||||||
|
use_global_ca_store: true,
|
||||||
|
crt_bundle_attach: Some(esp_idf_sys::esp_crt_bundle_attach),
|
||||||
|
..Default::default()
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let tt = fetch_timetable(httpconnection);
|
||||||
|
|
||||||
draw_text(&mut display, &format!("{:#?}", ip_info), 5, 5);
|
draw_text(&mut display, &tt[3][5].clone().unwrap().subjects.first().as_ref().unwrap().name, 5, 5);
|
||||||
log::info!("Draw text done");
|
epd7in5.update_and_display_frame(&mut spi, &*display.buffer(), &mut delay)?;
|
||||||
|
epd7in5.sleep(&mut spi, &mut delay)?;
|
||||||
|
log::info!("Completed");
|
||||||
let res = epd7in5.update_and_display_frame(&mut spi, &*display.buffer(), &mut delay);
|
|
||||||
if let Err(e) = res{
|
|
||||||
log::info!("{}", e);
|
|
||||||
}
|
|
||||||
epd7in5.sleep(&mut spi, &mut delay).unwrap();
|
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_text(display: &mut epd_waveshare::epd7in5_v2::Display7in5, text: &str, x: i32, y: i32) {
|
fn draw_text(display: &mut epd_waveshare::epd7in5_v2::Display7in5, text: &str, x: i32, y: i32) {
|
||||||
@@ -113,6 +128,60 @@ fn draw_text(display: &mut epd_waveshare::epd7in5_v2::Display7in5, text: &str, x
|
|||||||
|
|
||||||
let text_style = TextStyleBuilder::new().baseline(Baseline::Top).build();
|
let text_style = TextStyleBuilder::new().baseline(Baseline::Top).build();
|
||||||
|
|
||||||
// The problem:
|
|
||||||
let _ = Text::with_text_style(text, Point::new(x, y), style, text_style).draw(display);
|
let _ = Text::with_text_style(text, Point::new(x, y), style, text_style).draw(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Timetable = [[Option<Lesson>;8]; 5];
|
||||||
|
|
||||||
|
fn transform_lessons(lessons: Vec<Lesson>) -> Box<Timetable>{
|
||||||
|
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()),
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut table: Box<[[Option<Lesson>; 8]; 5]> = Box::new([0u8; 5].map(|_| [0u8; 8].map(|_| Option::<Lesson>::None)));
|
||||||
|
|
||||||
|
for lesson in lessons {
|
||||||
|
let day_idx = lesson.date.weekday().num_days_from_monday() as usize;
|
||||||
|
|
||||||
|
let mut l = Cow::<Lesson>::Owned(lesson);
|
||||||
|
for (period_idx, time) in lookup.iter().enumerate(){
|
||||||
|
if l.start_time.0 < *time && &l.end_time.0 >= time{
|
||||||
|
table[day_idx][period_idx] = Some(l.into_owned());
|
||||||
|
l = Cow::Borrowed(&table[day_idx][period_idx].as_ref().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn fetch_timetable(client: EspHttpConnection) -> Box<Timetable> {
|
||||||
|
let mut creds = include_str!("../untis-creds.txt").split('\n');
|
||||||
|
|
||||||
|
let server = creds.next().unwrap();
|
||||||
|
let school_id = creds.next().unwrap();
|
||||||
|
let usr = creds.next().unwrap();
|
||||||
|
let password = creds.next().unwrap();
|
||||||
|
|
||||||
|
let mut s = untis::Client::login(
|
||||||
|
server,
|
||||||
|
school_id,
|
||||||
|
usr,
|
||||||
|
password,
|
||||||
|
client
|
||||||
|
).unwrap();
|
||||||
|
let cest = chrono::FixedOffset::east_opt(2 * 3600).unwrap();
|
||||||
|
let now = s.date().unwrap().with_timezone(&cest);
|
||||||
|
println!("Current time: {}", now);
|
||||||
|
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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user