Prepared everything for http serving
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "untis-rs"]
|
||||
path = untis-rs
|
||||
url = https://github.com/zenonet/untis-rs.git
|
||||
@@ -35,7 +35,7 @@ heapless = "0.8"
|
||||
esp-idf-sys = "0.36.1"
|
||||
anyhow = "1.0.99"
|
||||
embedded-svc = "0.28.1"
|
||||
untis = {path = "../untis-test/untis-rs"}
|
||||
untis = { path = "untis-rs" }
|
||||
chrono = "0.4.41"
|
||||
embedded-layout = "0.4.2"
|
||||
u8g2-fonts = { version = "0.5.2", features = ["embedded_graphics_textstyle"] }
|
||||
|
||||
@@ -8,3 +8,4 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=14000
|
||||
# Workaround for https://github.com/espressif/esp-idf/issues/7631
|
||||
#CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n
|
||||
#CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n
|
||||
CONFIG_ESP_TASK_WDT_EN=n
|
||||
178
src/main.rs
178
src/main.rs
@@ -1,22 +1,30 @@
|
||||
use std::cell::RefCell;
|
||||
use std::num::NonZeroU16;
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::{borrow::Cow};
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Context;
|
||||
use chrono::{DateTime, Datelike, Days, FixedOffset, NaiveTime, TimeDelta, Weekday};
|
||||
use embedded_graphics::prelude::DrawTarget;
|
||||
use embedded_graphics::{
|
||||
prelude::{Dimensions, Point},
|
||||
text::{Text},
|
||||
Drawable,
|
||||
};
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use epd_waveshare::{color::Color, epd7in5_v2::Epd7in5, prelude::WaveshareDisplay};
|
||||
use esp_idf_hal::delay::Delay;
|
||||
use esp_idf_hal::modem::Modem;
|
||||
use esp_idf_hal::{
|
||||
delay::{Ets},
|
||||
gpio::{Gpio19, PinDriver},
|
||||
spi::{config, SpiDriverConfig},
|
||||
};
|
||||
use esp_idf_svc::http::Method;
|
||||
use esp_idf_svc::http::client::{Configuration as HttpConfig, EspHttpConnection};
|
||||
use esp_idf_svc::http::server::EspHttpServer;
|
||||
use esp_idf_svc::wifi::{BlockingWifi, EspWifi};
|
||||
use esp_idf_svc::{
|
||||
eventloop::EspSystemEventLoop,
|
||||
@@ -103,17 +111,21 @@ fn main() -> anyhow::Result<()> {
|
||||
|
||||
log::info!("Initialized spi interface");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Initialize the draw buffer
|
||||
// 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());
|
||||
display.set_rotation(epd_waveshare::prelude::DisplayRotation::Rotate0);
|
||||
|
||||
unsafe {
|
||||
WAKEUP_COUNTER += 1;
|
||||
}
|
||||
|
||||
let mut delay = Ets;
|
||||
|
||||
let mut epd7in5 = Epd7in5::new(&mut spi, busy, dc, rst, &mut delay, None).unwrap();
|
||||
epd7in5.sleep(&mut spi, &mut delay)?;
|
||||
log::info!("Completed");
|
||||
|
||||
unsafe{
|
||||
if let Some(error) = ERROR_MSG{
|
||||
|
||||
@@ -135,7 +147,6 @@ fn main() -> anyhow::Result<()> {
|
||||
.arrange()
|
||||
.draw(&mut *display).unwrap();
|
||||
|
||||
let mut epd7in5 = Epd7in5::new(&mut spi, busy, dc, rst, &mut delay, None).unwrap();
|
||||
epd7in5.update_and_display_frame(&mut spi, &*display.buffer(), &mut delay)?;
|
||||
epd7in5.sleep(&mut spi, &mut delay)?;
|
||||
|
||||
@@ -144,8 +155,102 @@ fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// Create a file called wifi-creds.txt and write SSID and password into it separated by a line break
|
||||
let (tt, now) = match fetch_data(peripherals.modem){
|
||||
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(),
|
||||
)?;
|
||||
|
||||
wifi.set_configuration(&Configuration::Client(
|
||||
esp_idf_svc::wifi::ClientConfiguration {
|
||||
ssid,
|
||||
password,
|
||||
auth_method: esp_idf_svc::wifi::AuthMethod::WPA2WPA3Personal,
|
||||
..Default::default()
|
||||
},
|
||||
))?;
|
||||
|
||||
wifi.start()
|
||||
.and_then(|_| wifi.connect())
|
||||
.and_then(|_| wifi.wait_netif_up())
|
||||
.and_then(|_| loop {if wifi.is_connected().unwrap() {break Ok(());}})?;
|
||||
|
||||
unsafe {
|
||||
FETCHING_FAIL_COUNT = None;
|
||||
}
|
||||
|
||||
|
||||
let mut httpserver = EspHttpServer::new(&esp_idf_svc::http::server::Configuration{
|
||||
http_port: 80,
|
||||
..Default::default()
|
||||
})?;
|
||||
|
||||
let do_update = Arc::new(RwLock::new(false));
|
||||
let writer = do_update.clone();
|
||||
httpserver.fn_handler("/", Method::Get, move |request| -> anyhow::Result<()> {
|
||||
|
||||
*writer.write().unwrap() = true;
|
||||
|
||||
|
||||
// Retrieve html String
|
||||
let html = String::from("OK");
|
||||
// Respond with OK status
|
||||
let mut response = request.into_ok_response()?;
|
||||
// Return Requested Object (Index Page)
|
||||
response.write(html.as_bytes())?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
loop {
|
||||
delay.delay_ns(100);
|
||||
|
||||
if *do_update.read().unwrap(){
|
||||
update_display_buffer(&mut display);
|
||||
println!("Rendered to buffer");
|
||||
epd7in5.wake_up(&mut spi, &mut delay)?;
|
||||
epd7in5.update_and_display_frame(&mut spi, &*display.buffer(), &mut delay)?;
|
||||
println!("Updated frame");
|
||||
epd7in5.sleep(&mut spi, &mut delay)?;
|
||||
println!("Sleep");
|
||||
unsafe {
|
||||
WAKEUP_COUNTER += 1;
|
||||
}
|
||||
|
||||
if let Ok(mut writer) = do_update.try_write(){
|
||||
*writer = false;
|
||||
println!("Successfully reset rw lock")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
drop(httpserver);
|
||||
drop(epd7in5);
|
||||
drop(spi);
|
||||
|
||||
//let next_wakeup_time = calculate_next_wakeuptime(now).context(format!("Failed to calculate next wakeup time for time {now}")).unwrap();
|
||||
//let seconds_until_wakeup = next_wakeup_time.timestamp() - now.timestamp();
|
||||
|
||||
wifi.disconnect().unwrap();
|
||||
wifi.stop().unwrap();
|
||||
|
||||
/* unsafe{
|
||||
esp_deep_sleep(seconds_until_wakeup as u64 * 1000_000);
|
||||
} */
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_display_buffer(display: &mut epd_waveshare::epd7in5_v2::Display7in5){
|
||||
let (tt, now) = match fetch_data(){
|
||||
Ok(d) => d,
|
||||
Err(e) => {
|
||||
let fail_count: u16 = unsafe {
|
||||
@@ -175,31 +280,12 @@ fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
FETCHING_FAIL_COUNT = None;
|
||||
}
|
||||
|
||||
|
||||
// We wanna panic here if this fails because retrying this in a couple of seconds is stupid
|
||||
let next_wakeup_time = calculate_next_wakeuptime(now).context(format!("Failed to calculate next wakeup time for time {now}")).unwrap();
|
||||
|
||||
display.clear(Color::Black).unwrap();
|
||||
// Render the layout
|
||||
draw_layout(&mut display, &tt, now, next_wakeup_time, include_str!("../wifi-creds.txt").split('\n').next().unwrap());
|
||||
|
||||
// Actually push changes to the display
|
||||
let mut epd7in5 = Epd7in5::new(&mut spi, busy, dc, rst, &mut delay, None).unwrap();
|
||||
epd7in5.update_and_display_frame(&mut spi, &*display.buffer(), &mut delay)?;
|
||||
epd7in5.sleep(&mut spi, &mut delay)?;
|
||||
log::info!("Completed");
|
||||
|
||||
drop(epd7in5);
|
||||
drop(spi);
|
||||
|
||||
let seconds_until_wakeup = next_wakeup_time.timestamp() - now.timestamp();
|
||||
|
||||
unsafe{
|
||||
esp_deep_sleep(seconds_until_wakeup as u64 * 1000_000);
|
||||
}
|
||||
draw_layout(display, &tt, now, next_wakeup_time, include_str!("../wifi-creds.txt").split('\n').next().unwrap());
|
||||
}
|
||||
|
||||
|
||||
@@ -247,38 +333,7 @@ fn calculate_next_wakeuptime(now: DateTime<FixedOffset>) -> Option<DateTime<Fixe
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_data(modem: Modem) -> anyhow::Result<(Box<Timetable>, DateTime<FixedOffset>)>{
|
||||
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(modem, sysloop.clone(), Some(nvs))?,
|
||||
sysloop.clone(),
|
||||
)?;
|
||||
|
||||
wifi.set_configuration(&Configuration::Client(
|
||||
esp_idf_svc::wifi::ClientConfiguration {
|
||||
ssid,
|
||||
password,
|
||||
auth_method: esp_idf_svc::wifi::AuthMethod::WPA2WPA3Personal,
|
||||
..Default::default()
|
||||
},
|
||||
))?;
|
||||
|
||||
wifi.start()
|
||||
.and_then(|_| wifi.connect())
|
||||
.and_then(|_| wifi.wait_netif_up())
|
||||
.and_then(|_| loop {if wifi.is_connected().unwrap() {break Ok(());}})?;
|
||||
|
||||
|
||||
println!("Connected to wifi");
|
||||
|
||||
fn fetch_data() -> anyhow::Result<(Box<Timetable>, DateTime<FixedOffset>)>{
|
||||
let httpconnection = EspHttpConnection::new(&HttpConfig {
|
||||
use_global_ca_store: true,
|
||||
crt_bundle_attach: Some(esp_idf_sys::esp_crt_bundle_attach),
|
||||
@@ -287,9 +342,6 @@ fn fetch_data(modem: Modem) -> anyhow::Result<(Box<Timetable>, DateTime<FixedOff
|
||||
|
||||
let res = fetch_timetable(httpconnection);
|
||||
|
||||
wifi.disconnect().unwrap();
|
||||
wifi.stop().unwrap();
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
|
||||
1
untis-rs
Submodule
1
untis-rs
Submodule
Submodule untis-rs added at 11e63a0a9c
Reference in New Issue
Block a user