mirror of
https://github.com/Djeeberjr/fw-anwesenheit.git
synced 2026-04-30 18:49:09 +00:00
Compare commits
4 Commits
4a9ff47dcc
...
0f5ca88ae4
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f5ca88ae4 | |||
| 9dd2f88cbc | |||
| aa91d69f0b | |||
| b13ae76bc5 |
@@ -2,7 +2,7 @@ use embassy_time::{Duration, Timer};
|
|||||||
use esp_hal::{Async, uart::Uart};
|
use esp_hal::{Async, uart::Uart};
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
|
|
||||||
use crate::{TallyPublisher, store::TallyID};
|
use crate::TallyPublisher;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn rfid_reader_task(mut uart_device: Uart<'static, Async>, chan: TallyPublisher) {
|
pub async fn rfid_reader_task(mut uart_device: Uart<'static, Async>, chan: TallyPublisher) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use chrono::{TimeZone, Utc};
|
||||||
use ds3231::{
|
use ds3231::{
|
||||||
Config, DS3231, DS3231Error, InterruptControl, Oscillator, SquareWaveFrequency,
|
Config, DS3231, DS3231Error, InterruptControl, Oscillator, SquareWaveFrequency,
|
||||||
TimeRepresentation,
|
TimeRepresentation,
|
||||||
@@ -9,7 +10,6 @@ use esp_hal::{
|
|||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
|
|
||||||
use crate::{FEEDBACK_STATE, drivers, feedback, store::Date};
|
use crate::{FEEDBACK_STATE, drivers, feedback, store::Date};
|
||||||
use chrono::{TimeZone, Utc};
|
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/build_time.rs"));
|
include!(concat!(env!("OUT_DIR"), "/build_time.rs"));
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ impl RTCClock {
|
|||||||
pub async fn get_date(&mut self) -> Date {
|
pub async fn get_date(&mut self) -> Date {
|
||||||
let (year, month, day) = unix_to_ymd_string(self.get_time().await);
|
let (year, month, day) = unix_to_ymd_string(self.get_time().await);
|
||||||
|
|
||||||
let mut buffer: Date = [0; 10] ;
|
let mut buffer: Date = [0; 10];
|
||||||
|
|
||||||
// Write YYYY
|
// Write YYYY
|
||||||
buffer[0] = b'0' + ((year / 1000) % 10) as u8;
|
buffer[0] = b'0' + ((year / 1000) % 10) as u8;
|
||||||
@@ -70,7 +70,6 @@ impl RTCClock {
|
|||||||
|
|
||||||
buffer
|
buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unix_to_ymd_string(timestamp: u64) -> (u16, u8, u8) {
|
fn unix_to_ymd_string(timestamp: u64) -> (u16, u8, u8) {
|
||||||
@@ -82,11 +81,11 @@ fn unix_to_ymd_string(timestamp: u64) -> (u16, u8, u8) {
|
|||||||
|
|
||||||
// Convert to proleptic Gregorian date
|
// Convert to proleptic Gregorian date
|
||||||
civil_from_days(days_since_epoch as i64 + UNIX_OFFSET_DAYS as i64)
|
civil_from_days(days_since_epoch as i64 + UNIX_OFFSET_DAYS as i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function returns (year, month, day).
|
// This function returns (year, month, day).
|
||||||
// Based on the algorithm by Howard Hinnant.
|
// Based on the algorithm by Howard Hinnant.
|
||||||
fn civil_from_days(z: i64) -> (u16, u8, u8) {
|
fn civil_from_days(z: i64) -> (u16, u8, u8) {
|
||||||
let mut z = z;
|
let mut z = z;
|
||||||
z -= 60; // shift epoch for algorithm
|
z -= 60; // shift epoch for algorithm
|
||||||
let era = (z >= 0).then_some(z).unwrap_or(z - 146096) / 146097;
|
let era = (z >= 0).then_some(z).unwrap_or(z - 146096) / 146097;
|
||||||
@@ -98,7 +97,7 @@ fn unix_to_ymd_string(timestamp: u64) -> (u16, u8, u8) {
|
|||||||
let d = doy - (153 * mp + 2) / 5 + 1; // [1, 31]
|
let d = doy - (153 * mp + 2) / 5 + 1; // [1, 31]
|
||||||
let m = mp + (if mp < 10 { 3 } else { -9 }); // [1, 12]
|
let m = mp + (if mp < 10 { 3 } else { -9 }); // [1, 12]
|
||||||
((y + (m <= 2) as i64) as u16, m as u8, d as u8)
|
((y + (m <= 2) as i64) as u16, m as u8, d as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn rtc_config(i2c: I2c<'static, Async>) -> DS3231<I2c<'static, Async>> {
|
pub async fn rtc_config(i2c: I2c<'static, Async>) -> DS3231<I2c<'static, Async>> {
|
||||||
let mut rtc: DS3231<I2c<'static, Async>> = DS3231::new(i2c, RTC_ADDRESS);
|
let mut rtc: DS3231<I2c<'static, Async>> = DS3231::new(i2c, RTC_ADDRESS);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use embassy_time::{Delay, Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp_hal::{delay, gpio::Output, peripherals, rmt::ConstChannelAccess};
|
use esp_hal::{peripherals, rmt::ConstChannelAccess};
|
||||||
use esp_hal_smartled::SmartLedsAdapterAsync;
|
use esp_hal_smartled::SmartLedsAdapterAsync;
|
||||||
use init::hardware;
|
use log::debug;
|
||||||
use log::{debug, error, info};
|
|
||||||
use smart_leds::SmartLedsWriteAsync;
|
use smart_leds::SmartLedsWriteAsync;
|
||||||
use smart_leds::colors::{BLACK, GREEN, RED, YELLOW};
|
use smart_leds::colors::{BLACK, GREEN, RED, YELLOW};
|
||||||
use smart_leds::{brightness, colors::BLUE};
|
use smart_leds::{brightness, colors::BLUE};
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use bleps::att::Att;
|
|
||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
use ds3231::InterruptControl;
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::Stack;
|
use embassy_net::Stack;
|
||||||
|
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp_hal::gpio::{Input, InputConfig};
|
use esp_hal::Blocking;
|
||||||
|
use esp_hal::gpio::Input;
|
||||||
use esp_hal::i2c::master::Config;
|
use esp_hal::i2c::master::Config;
|
||||||
use esp_hal::peripherals::{
|
use esp_hal::peripherals::{
|
||||||
GPIO0, GPIO1, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23, I2C0, RMT, SPI2,
|
GPIO0, GPIO1, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23, I2C0, RMT, SPI2,
|
||||||
@@ -15,8 +12,6 @@ use esp_hal::peripherals::{
|
|||||||
};
|
};
|
||||||
use esp_hal::rmt::{ConstChannelAccess, Rmt};
|
use esp_hal::rmt::{ConstChannelAccess, Rmt};
|
||||||
use esp_hal::spi::master::{Config as Spi_config, Spi};
|
use esp_hal::spi::master::{Config as Spi_config, Spi};
|
||||||
|
|
||||||
use esp_hal::Blocking;
|
|
||||||
use esp_hal::time::Rate;
|
use esp_hal::time::Rate;
|
||||||
use esp_hal::timer::timg::TimerGroup;
|
use esp_hal::timer::timg::TimerGroup;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
@@ -28,16 +23,12 @@ use esp_hal::{
|
|||||||
uart::Uart,
|
uart::Uart,
|
||||||
};
|
};
|
||||||
use esp_hal_smartled::{SmartLedsAdapterAsync, buffer_size_async};
|
use esp_hal_smartled::{SmartLedsAdapterAsync, buffer_size_async};
|
||||||
use esp_println::dbg;
|
|
||||||
use esp_println::logger::init_logger;
|
use esp_println::logger::init_logger;
|
||||||
use log::{debug, error, info};
|
use log::{debug, error};
|
||||||
|
|
||||||
use crate::FEEDBACK_STATE;
|
|
||||||
use crate::init::network;
|
use crate::init::network;
|
||||||
use crate::init::sd_card::{setup_sdcard, SDCardPersistence};
|
use crate::init::sd_card::{SDCardPersistence, setup_sdcard};
|
||||||
use crate::init::wifi;
|
use crate::init::wifi;
|
||||||
use crate::store::AttendanceDay;
|
|
||||||
use crate::store::persistence::Persistence;
|
|
||||||
|
|
||||||
/*************************************************
|
/*************************************************
|
||||||
* GPIO Pinout Xiao Esp32c6
|
* GPIO Pinout Xiao Esp32c6
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use core::{net::Ipv4Addr, str::FromStr};
|
use core::{net::Ipv4Addr, str::FromStr};
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::{Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
use embassy_net::{Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
|
|||||||
13
src/main.rs
13
src/main.rs
@@ -10,7 +10,7 @@ use embassy_sync::{
|
|||||||
blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex},
|
blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex},
|
||||||
mutex::Mutex,
|
mutex::Mutex,
|
||||||
pubsub::{
|
pubsub::{
|
||||||
PubSubChannel, Publisher,
|
PubSubChannel, Publisher, Subscriber,
|
||||||
WaitResult::{Lagged, Message},
|
WaitResult::{Lagged, Message},
|
||||||
},
|
},
|
||||||
signal::Signal,
|
signal::Signal,
|
||||||
@@ -21,14 +21,14 @@ use esp_hal::{gpio::InputConfig, peripherals};
|
|||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use static_cell::make_static;
|
use static_cell::make_static;
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
init::sd_card::SDCardPersistence,
|
init::sd_card::SDCardPersistence,
|
||||||
store::{Date, IDStore, TallyID},
|
store::{Date, IDStore, TallyID},
|
||||||
webserver::start_webserver,
|
webserver::start_webserver,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern crate alloc;
|
|
||||||
|
|
||||||
mod drivers;
|
mod drivers;
|
||||||
mod feedback;
|
mod feedback;
|
||||||
mod init;
|
mod init;
|
||||||
@@ -39,6 +39,7 @@ static FEEDBACK_STATE: Signal<CriticalSectionRawMutex, feedback::FeedbackState>
|
|||||||
|
|
||||||
type TallyChannel = PubSubChannel<NoopRawMutex, TallyID, 8, 2, 1>;
|
type TallyChannel = PubSubChannel<NoopRawMutex, TallyID, 8, 2, 1>;
|
||||||
type TallyPublisher = Publisher<'static, NoopRawMutex, TallyID, 8, 2, 1>;
|
type TallyPublisher = Publisher<'static, NoopRawMutex, TallyID, 8, 2, 1>;
|
||||||
|
type TallySubscriber = Subscriber<'static, NoopRawMutex, TallyID, 8, 2, 1>;
|
||||||
type UsedStore = IDStore<SDCardPersistence>;
|
type UsedStore = IDStore<SDCardPersistence>;
|
||||||
|
|
||||||
#[esp_hal_embassy::main]
|
#[esp_hal_embassy::main]
|
||||||
@@ -54,12 +55,12 @@ async fn main(mut spawner: Spawner) {
|
|||||||
let shared_store = Rc::new(Mutex::new(store));
|
let shared_store = Rc::new(Mutex::new(store));
|
||||||
|
|
||||||
let chan: &'static mut TallyChannel = make_static!(PubSubChannel::new());
|
let chan: &'static mut TallyChannel = make_static!(PubSubChannel::new());
|
||||||
let publisher = chan.publisher().unwrap();
|
let publisher: TallyPublisher = chan.publisher().unwrap();
|
||||||
let mut sub = chan.subscriber().unwrap();
|
let mut sub: TallySubscriber = chan.subscriber().unwrap();
|
||||||
|
|
||||||
wait_for_stack_up(stack).await;
|
wait_for_stack_up(stack).await;
|
||||||
|
|
||||||
start_webserver(&mut spawner, stack, shared_store.clone());
|
start_webserver(&mut spawner, stack, shared_store.clone(), chan);
|
||||||
|
|
||||||
/****************************** Spawning tasks ***********************************/
|
/****************************** Spawning tasks ***********************************/
|
||||||
debug!("spawing NFC reader task...");
|
debug!("spawing NFC reader task...");
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use super::TallyID;
|
|
||||||
use alloc::collections::BTreeMap;
|
use alloc::collections::BTreeMap;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::TallyID;
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct Name {
|
pub struct Name {
|
||||||
pub first: String,
|
pub first: String,
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
use crate::drivers::rtc;
|
use alloc::vec::Vec;
|
||||||
use crate::drivers::rtc::RTCClock;
|
use serde::Deserialize;
|
||||||
use crate::store::persistence::Persistence;
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::Date;
|
use super::Date;
|
||||||
use super::IDMapping;
|
use super::IDMapping;
|
||||||
use super::TallyID;
|
use super::TallyID;
|
||||||
use alloc::vec::Vec;
|
use crate::store::persistence::Persistence;
|
||||||
use serde::Deserialize;
|
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct AttendanceDay {
|
pub struct AttendanceDay {
|
||||||
@@ -75,7 +73,6 @@ impl<T: Persistence> IDStore<T> {
|
|||||||
/// Add a new id for the current day
|
/// Add a new id for the current day
|
||||||
/// Returns false if ID is already present at the current day.
|
/// Returns false if ID is already present at the current day.
|
||||||
pub async fn add_id(&mut self, id: TallyID, current_date: Date) -> bool {
|
pub async fn add_id(&mut self, id: TallyID, current_date: Date) -> bool {
|
||||||
|
|
||||||
if self.current_day.date == current_date {
|
if self.current_day.date == current_date {
|
||||||
let changed = self.current_day.add_id(id);
|
let changed = self.current_day.add_id(id);
|
||||||
if changed {
|
if changed {
|
||||||
|
|||||||
@@ -1,9 +1,48 @@
|
|||||||
mod id_mapping;
|
use heapless::String;
|
||||||
pub mod persistence;
|
|
||||||
mod id_store;
|
|
||||||
|
|
||||||
pub use id_mapping::{IDMapping, Name};
|
pub use id_mapping::{IDMapping, Name};
|
||||||
pub use id_store::{IDStore,AttendanceDay};
|
pub use id_store::{IDStore,AttendanceDay};
|
||||||
|
|
||||||
|
mod id_mapping;
|
||||||
|
pub mod persistence;
|
||||||
|
mod id_store;
|
||||||
|
|
||||||
pub type TallyID = [u8; 6];
|
pub type TallyID = [u8; 6];
|
||||||
pub type Date = [u8; 10];
|
pub type Date = [u8; 10];
|
||||||
|
|
||||||
|
pub fn hex_string_to_tally_id(s: &str) -> Option<TallyID> {
|
||||||
|
let bytes = s.as_bytes();
|
||||||
|
if bytes.len() != 12 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut out: TallyID = [0;6];
|
||||||
|
for i in 0..6 {
|
||||||
|
let hi = hex_val(bytes[2 * i])?;
|
||||||
|
let lo = hex_val(bytes[2 * i + 1])?;
|
||||||
|
out[i] = (hi << 4) | lo;
|
||||||
|
}
|
||||||
|
Some(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tally_id_to_hex_string(bytes: TallyID) -> Option<String<12>> {
|
||||||
|
const HEX_CHARS: &[u8; 16] = b"0123456789abcdef";
|
||||||
|
let mut s: String<12> = String::new();
|
||||||
|
|
||||||
|
for &b in &bytes {
|
||||||
|
s.push(HEX_CHARS[(b >> 4) as usize] as char).ok()?;
|
||||||
|
s.push(HEX_CHARS[(b & 0x0F) as usize] as char).ok()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hex_val(b: u8) -> Option<u8> {
|
||||||
|
match b {
|
||||||
|
b'0'..=b'9' => Some(b - b'0'),
|
||||||
|
b'a'..=b'f' => Some(b - b'a' + 10),
|
||||||
|
b'A'..=b'F' => Some(b - b'A' + 10),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use picoserve::{
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
store::{Name, TallyID},
|
store::{Name, hex_string_to_tally_id},
|
||||||
webserver::app::AppState,
|
webserver::{app::AppState, sse::IDEvents},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@@ -16,30 +16,6 @@ pub struct NewMapping {
|
|||||||
name: Name,
|
name: Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hex_string_to_tally_id(s: &str) -> Option<TallyID> {
|
|
||||||
let bytes = s.as_bytes();
|
|
||||||
if bytes.len() != 24 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut out = [0u8; 12];
|
|
||||||
for i in 0..12 {
|
|
||||||
let hi = hex_val(bytes[2 * i])?;
|
|
||||||
let lo = hex_val(bytes[2 * i + 1])?;
|
|
||||||
out[i] = (hi << 4) | lo;
|
|
||||||
}
|
|
||||||
Some(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hex_val(b: u8) -> Option<u8> {
|
|
||||||
match b {
|
|
||||||
b'0'..=b'9' => Some(b - b'0'),
|
|
||||||
b'a'..=b'f' => Some(b - b'a' + 10),
|
|
||||||
b'A'..=b'F' => Some(b - b'A' + 10),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #[get("/api/idevent")]
|
* #[get("/api/idevent")]
|
||||||
* #[get("/api/csv")]
|
* #[get("/api/csv")]
|
||||||
@@ -64,3 +40,7 @@ pub async fn add_mapping(
|
|||||||
let tally_id = hex_string_to_tally_id(&data.id).unwrap();
|
let tally_id = hex_string_to_tally_id(&data.id).unwrap();
|
||||||
store.mapping.add_mapping(tally_id, data.name);
|
store.mapping.add_mapping(tally_id, data.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_idevent(State(state): State<AppState>) -> impl IntoResponse {
|
||||||
|
response::EventStream(IDEvents(state.chan.subscriber().unwrap()))
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,15 +3,17 @@ use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex};
|
|||||||
use picoserve::{AppWithStateBuilder, routing::get};
|
use picoserve::{AppWithStateBuilder, routing::get};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
TallyChannel, UsedStore,
|
||||||
webserver::{
|
webserver::{
|
||||||
api::{add_mapping, get_mapping},
|
api::{add_mapping, get_idevent, get_mapping},
|
||||||
assets::Assets,
|
assets::Assets,
|
||||||
}, UsedStore,
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub store: Rc<Mutex<CriticalSectionRawMutex, UsedStore>>,
|
pub store: Rc<Mutex<CriticalSectionRawMutex, UsedStore>>,
|
||||||
|
pub chan: &'static TallyChannel,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AppProps;
|
pub struct AppProps;
|
||||||
@@ -23,9 +25,6 @@ impl AppWithStateBuilder for AppProps {
|
|||||||
fn build_app(self) -> picoserve::Router<Self::PathRouter, AppState> {
|
fn build_app(self) -> picoserve::Router<Self::PathRouter, AppState> {
|
||||||
picoserve::Router::from_service(Assets)
|
picoserve::Router::from_service(Assets)
|
||||||
.route("/api/mapping", get(get_mapping).post(add_mapping))
|
.route("/api/mapping", get(get_mapping).post(add_mapping))
|
||||||
// .route(
|
.route("/api/idevent", get(get_idevent))
|
||||||
// "/api/idevent",
|
|
||||||
// get(move || response::EventStream(Events(self.chan))),
|
|
||||||
// )
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ use picoserve::{AppRouter, AppWithStateBuilder};
|
|||||||
use static_cell::make_static;
|
use static_cell::make_static;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
UsedStore,
|
TallyChannel, UsedStore,
|
||||||
webserver::app::{AppProps, AppState},
|
webserver::app::{AppProps, AppState},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod assets;
|
|
||||||
// mod sse;
|
|
||||||
mod api;
|
mod api;
|
||||||
mod app;
|
mod app;
|
||||||
|
mod assets;
|
||||||
|
mod sse;
|
||||||
|
|
||||||
pub const WEB_TAKS_SIZE: usize = 3; // Up this number if request start fail with Timeouts.
|
pub const WEB_TAKS_SIZE: usize = 3; // Up this number if request start fail with Timeouts.
|
||||||
|
|
||||||
@@ -22,10 +22,11 @@ pub fn start_webserver(
|
|||||||
spawner: &mut Spawner,
|
spawner: &mut Spawner,
|
||||||
stack: Stack<'static>,
|
stack: Stack<'static>,
|
||||||
store: Rc<Mutex<CriticalSectionRawMutex, UsedStore>>,
|
store: Rc<Mutex<CriticalSectionRawMutex, UsedStore>>,
|
||||||
|
chan: &'static TallyChannel,
|
||||||
) {
|
) {
|
||||||
let app = make_static!(AppProps.build_app());
|
let app = make_static!(AppProps.build_app());
|
||||||
|
|
||||||
let state = make_static!(AppState { store });
|
let state = make_static!(AppState { store, chan });
|
||||||
|
|
||||||
let config = make_static!(picoserve::Config::new(picoserve::Timeouts {
|
let config = make_static!(picoserve::Config::new(picoserve::Timeouts {
|
||||||
start_read_request: Some(Duration::from_secs(5)),
|
start_read_request: Some(Duration::from_secs(5)),
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ use embassy_time::{Duration, Timer};
|
|||||||
use log::warn;
|
use log::warn;
|
||||||
use picoserve::response;
|
use picoserve::response;
|
||||||
|
|
||||||
pub struct Events(pub TallySubscriber);
|
use crate::{TallySubscriber, store::tally_id_to_hex_string};
|
||||||
|
|
||||||
impl response::sse::EventSource for Events {
|
pub struct IDEvents(pub TallySubscriber);
|
||||||
|
|
||||||
|
impl response::sse::EventSource for IDEvents {
|
||||||
async fn write_events<W: picoserve::io::Write>(
|
async fn write_events<W: picoserve::io::Write>(
|
||||||
mut self,
|
mut self,
|
||||||
mut writer: response::sse::EventWriter<W>,
|
mut writer: response::sse::EventWriter<W>,
|
||||||
@@ -16,7 +18,9 @@ impl response::sse::EventSource for Events {
|
|||||||
match sel.await {
|
match sel.await {
|
||||||
embassy_futures::select::Either::First(msg) => match msg {
|
embassy_futures::select::Either::First(msg) => match msg {
|
||||||
embassy_sync::pubsub::WaitResult::Message(id) => {
|
embassy_sync::pubsub::WaitResult::Message(id) => {
|
||||||
writer.write_event("msg", id.to_string().as_str()).await?
|
writer
|
||||||
|
.write_event("msg", tally_id_to_hex_string(id).unwrap().as_str())
|
||||||
|
.await?
|
||||||
}
|
}
|
||||||
embassy_sync::pubsub::WaitResult::Lagged(_) => {
|
embassy_sync::pubsub::WaitResult::Lagged(_) => {
|
||||||
warn!("SSE subscriber got lagged");
|
warn!("SSE subscriber got lagged");
|
||||||
|
|||||||
Reference in New Issue
Block a user