changed Day implementation

This commit is contained in:
Djeeberjr 2025-10-10 01:12:46 +02:00
parent 030a372949
commit f1b471c6d8
7 changed files with 85 additions and 47 deletions

View File

@ -9,7 +9,7 @@ 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};
include!(concat!(env!("OUT_DIR"), "/build_time.rs")); include!(concat!(env!("OUT_DIR"), "/build_time.rs"));
@ -45,31 +45,6 @@ impl RTCClock {
} }
} }
} }
pub async fn get_date(&mut self) -> Date {
let (year, month, day) = unix_to_ymd_string(self.get_time().await);
let mut buffer: Date = [0; 10];
// Write YYYY
buffer[0] = b'0' + ((year / 1000) % 10) as u8;
buffer[1] = b'0' + ((year / 100) % 10) as u8;
buffer[2] = b'0' + ((year / 10) % 10) as u8;
buffer[3] = b'0' + (year % 10) as u8;
buffer[4] = b'.';
// Write MM
buffer[5] = b'0' + (month / 10) as u8;
buffer[6] = b'0' + (month % 10) as u8;
buffer[7] = b'.';
// Write DD
buffer[8] = b'0' + (day / 10) as u8;
buffer[9] = b'0' + (day % 10) as u8;
buffer
}
} }
fn unix_to_ymd_string(timestamp: u64) -> (u16, u8, u8) { fn unix_to_ymd_string(timestamp: u64) -> (u16, u8, u8) {

View File

@ -4,7 +4,7 @@ use embedded_hal_bus::spi::ExclusiveDevice;
use embedded_sdmmc::{SdCard, TimeSource, Timestamp, VolumeIdx, VolumeManager}; use embedded_sdmmc::{SdCard, TimeSource, Timestamp, VolumeIdx, VolumeManager};
use esp_hal::{Blocking, gpio::Output, spi::master::Spi}; use esp_hal::{Blocking, gpio::Output, spi::master::Spi};
use crate::store::{AttendanceDay, Date, persistence::Persistence}; use crate::store::{AttendanceDay, day::Day, persistence::Persistence};
pub struct DummyTimesource; pub struct DummyTimesource;
@ -39,7 +39,7 @@ pub struct SDCardPersistence {
} }
impl Persistence for SDCardPersistence { impl Persistence for SDCardPersistence {
async fn load_day(&mut self, day: crate::store::Date) -> Option<AttendanceDay> { async fn load_day(&mut self, day: Day) -> Option<AttendanceDay> {
let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0)).unwrap(); let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0)).unwrap();
let mut root_dir = vol_0.open_root_dir().unwrap(); let mut root_dir = vol_0.open_root_dir().unwrap();
let mut file = root_dir.open_file_in_dir("day.jsn", embedded_sdmmc::Mode::ReadOnly); let mut file = root_dir.open_file_in_dir("day.jsn", embedded_sdmmc::Mode::ReadOnly);
@ -53,12 +53,13 @@ impl Persistence for SDCardPersistence {
let read = open_file.read(&mut read_buffer).unwrap(); let read = open_file.read(&mut read_buffer).unwrap();
open_file.close().unwrap(); open_file.close().unwrap();
let day: AttendanceDay = serde_json::from_slice(&read_buffer[..read]).unwrap(); // let day: AttendanceDay = serde_json::from_slice(&read_buffer[..read]).unwrap();
Some(day) // Some(day)
None
} }
async fn save_day(&mut self, day: Date, data: &AttendanceDay) { async fn save_day(&mut self, day: Day, data: &AttendanceDay) {
let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0)).unwrap(); let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0)).unwrap();
let mut root_dir = vol_0.open_root_dir().unwrap(); let mut root_dir = vol_0.open_root_dir().unwrap();
@ -78,15 +79,15 @@ impl Persistence for SDCardPersistence {
todo!() todo!()
} }
async fn list_days(&mut self) -> Vec<Date> { async fn list_days(&mut self) -> Vec<Day> {
let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0)).unwrap(); let mut vol_0 = self.vol_mgr.open_volume(VolumeIdx(0)).unwrap();
let mut root_dir = vol_0.open_root_dir().unwrap(); let mut root_dir = vol_0.open_root_dir().unwrap();
let mut days_dir = root_dir.open_dir("days").unwrap(); let mut days_dir = root_dir.open_dir("days").unwrap();
let mut days: Vec<[u8; 10]> = Vec::new(); let mut days: Vec<Day> = Vec::new();
days_dir days_dir
.iterate_dir(|e| { .iterate_dir(|e| {
days.push([0; 10]); days.push(Day::new(0));
}) })
.unwrap(); .unwrap();

View File

@ -25,7 +25,7 @@ extern crate alloc;
use crate::{ use crate::{
init::sd_card::SDCardPersistence, init::sd_card::SDCardPersistence,
store::{Date, IDStore, tally_id::TallyID}, store::{IDStore, day::Day, tally_id::TallyID},
webserver::start_webserver, webserver::start_webserver,
}; };
@ -86,7 +86,7 @@ async fn main(mut spawner: Spawner) {
Message(msg) => { Message(msg) => {
debug!("Got message: {msg:?}"); debug!("Got message: {msg:?}");
let day: Date = rtc.get_date().await; let day: Day = rtc.get_time().await.into();
let added = shared_store.lock().await.add_id(msg, day).await; let added = shared_store.lock().await.add_id(msg, day).await;
if added { if added {

63
src/store/day.rs Normal file
View File

@ -0,0 +1,63 @@
use core::fmt::Write;
use embedded_sdmmc::ShortFileName;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct Day(u32);
impl Day {
const SECONDS_PER_DAY: u64 = 86_400;
pub fn new(daystamp: u32) -> Self {
Day(daystamp)
}
pub fn new_from_timestamp(time: u64) -> Self {
let day = time / Self::SECONDS_PER_DAY;
if day > u32::MAX as u64 {
// TBH this would only happen if about 11 million years have passed
// I sure hope i don't have to work on this project any more then
// So we just cap it at this
Day(u32::MAX)
} else {
Day(day as u32)
}
}
pub fn to_timestamp(self) -> u64 {
(self.0 as u64) * Self::SECONDS_PER_DAY
}
pub fn to_string(self) -> heapless::String<8> {
let mut s: heapless::String<8> = heapless::String::new();
write!(s, "{:08X}", self.0).unwrap();
s
}
pub fn from_hex_str(s: &str) -> Result<Self, &'static str> {
if s.len() > 8 {
return Err("hex string too long");
}
u32::from_str_radix(s, 16)
.map_err(|_| "invalid hex string")
.map(Day)
}
}
impl From<u64> for Day {
fn from(value: u64) -> Self {
Self::new_from_timestamp(value)
}
}
impl TryFrom<ShortFileName> for Day {
type Error = ();
fn try_from(value: ShortFileName) -> Result<Self, Self::Error> {
let name = core::str::from_utf8(value.base_name()).map_err(|_| ())?;
Self::from_hex_str(name).map_err(|_| ())
}
}

View File

@ -2,19 +2,19 @@ use alloc::vec::Vec;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use super::Date;
use super::IDMapping; use super::IDMapping;
use crate::store::day::Day;
use crate::store::persistence::Persistence; use crate::store::persistence::Persistence;
use crate::store::tally_id::TallyID; use crate::store::tally_id::TallyID;
#[derive(Clone, Serialize, Deserialize, Debug)] #[derive(Clone, Serialize, Deserialize, Debug)]
pub struct AttendanceDay { pub struct AttendanceDay {
date: Date, date: Day,
ids: Vec<TallyID>, ids: Vec<TallyID>,
} }
impl AttendanceDay { impl AttendanceDay {
pub fn new(date: Date) -> Self { pub fn new(date: Day) -> Self {
Self { Self {
date, date,
ids: Vec::new(), ids: Vec::new(),
@ -46,7 +46,7 @@ impl<T: Persistence> IDStore<T> {
// None => IDMapping::new(), // None => IDMapping::new(),
// }; // };
let current_date: Date = [0; 10]; let current_date: Day = Day::new(0);
let day = persistence_layer let day = persistence_layer
.load_day(current_date) .load_day(current_date)
@ -72,7 +72,7 @@ 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: Day) -> 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 {

View File

@ -5,6 +5,5 @@ mod id_mapping;
pub mod persistence; pub mod persistence;
mod id_store; mod id_store;
pub mod tally_id; pub mod tally_id;
pub mod day;
pub type Date = [u8; 10];

View File

@ -1,11 +1,11 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use crate::store::{Date, IDMapping, id_store::AttendanceDay}; use crate::store::{IDMapping, day::Day, id_store::AttendanceDay};
pub trait Persistence { pub trait Persistence {
async fn load_day(&mut self, day: Date) -> Option<AttendanceDay>; async fn load_day(&mut self, day: Day) -> Option<AttendanceDay>;
async fn save_day(&mut self, day: Date, data: &AttendanceDay); async fn save_day(&mut self, day: Day, data: &AttendanceDay);
async fn list_days(&mut self) -> Vec<Date>; async fn list_days(&mut self) -> Vec<Day>;
async fn load_mapping(&mut self) -> Option<IDMapping>; async fn load_mapping(&mut self) -> Option<IDMapping>;
async fn save_mapping(&mut self, data: &IDMapping); async fn save_mapping(&mut self, data: &IDMapping);