mirror of
				https://github.com/Djeeberjr/fw-anwesenheit.git
				synced 2025-11-03 23:24:10 +00:00 
			
		
		
		
	changed Day implementation
This commit is contained in:
		
							parent
							
								
									030a372949
								
							
						
					
					
						commit
						f1b471c6d8
					
				@ -9,7 +9,7 @@ use esp_hal::{
 | 
			
		||||
};
 | 
			
		||||
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"));
 | 
			
		||||
 | 
			
		||||
@ -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) {
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ use embedded_hal_bus::spi::ExclusiveDevice;
 | 
			
		||||
use embedded_sdmmc::{SdCard, TimeSource, Timestamp, VolumeIdx, VolumeManager};
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ pub struct 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 root_dir = vol_0.open_root_dir().unwrap();
 | 
			
		||||
        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();
 | 
			
		||||
        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 root_dir = vol_0.open_root_dir().unwrap();
 | 
			
		||||
 | 
			
		||||
@ -78,15 +79,15 @@ impl Persistence for SDCardPersistence {
 | 
			
		||||
        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 root_dir = vol_0.open_root_dir().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
 | 
			
		||||
            .iterate_dir(|e| {
 | 
			
		||||
                days.push([0; 10]);
 | 
			
		||||
                days.push(Day::new(0));
 | 
			
		||||
            })
 | 
			
		||||
            .unwrap();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ extern crate alloc;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    init::sd_card::SDCardPersistence,
 | 
			
		||||
    store::{Date, IDStore, tally_id::TallyID},
 | 
			
		||||
    store::{IDStore, day::Day, tally_id::TallyID},
 | 
			
		||||
    webserver::start_webserver,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ async fn main(mut spawner: Spawner) {
 | 
			
		||||
            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;
 | 
			
		||||
 | 
			
		||||
                if added {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										63
									
								
								src/store/day.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/store/day.rs
									
									
									
									
									
										Normal 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(|_| ())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -2,19 +2,19 @@ use alloc::vec::Vec;
 | 
			
		||||
use serde::Deserialize;
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
 | 
			
		||||
use super::Date;
 | 
			
		||||
use super::IDMapping;
 | 
			
		||||
use crate::store::day::Day;
 | 
			
		||||
use crate::store::persistence::Persistence;
 | 
			
		||||
use crate::store::tally_id::TallyID;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Serialize, Deserialize, Debug)]
 | 
			
		||||
pub struct AttendanceDay {
 | 
			
		||||
    date: Date,
 | 
			
		||||
    date: Day,
 | 
			
		||||
    ids: Vec<TallyID>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl AttendanceDay {
 | 
			
		||||
    pub fn new(date: Date) -> Self {
 | 
			
		||||
    pub fn new(date: Day) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            date,
 | 
			
		||||
            ids: Vec::new(),
 | 
			
		||||
@ -46,7 +46,7 @@ impl<T: Persistence> IDStore<T> {
 | 
			
		||||
        //     None => IDMapping::new(),
 | 
			
		||||
        // };
 | 
			
		||||
 | 
			
		||||
        let current_date: Date = [0; 10];
 | 
			
		||||
        let current_date: Day = Day::new(0);
 | 
			
		||||
 | 
			
		||||
        let day = persistence_layer
 | 
			
		||||
            .load_day(current_date)
 | 
			
		||||
@ -72,7 +72,7 @@ impl<T: Persistence> IDStore<T> {
 | 
			
		||||
 | 
			
		||||
    /// Add a new id for 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 {
 | 
			
		||||
            let changed = self.current_day.add_id(id);
 | 
			
		||||
            if changed {
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,5 @@ mod id_mapping;
 | 
			
		||||
pub mod persistence;
 | 
			
		||||
mod id_store;
 | 
			
		||||
pub mod tally_id;
 | 
			
		||||
 | 
			
		||||
pub type Date = [u8; 10];
 | 
			
		||||
pub mod day;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
use alloc::vec::Vec;
 | 
			
		||||
 | 
			
		||||
use crate::store::{Date, IDMapping, id_store::AttendanceDay};
 | 
			
		||||
use crate::store::{IDMapping, day::Day, id_store::AttendanceDay};
 | 
			
		||||
 | 
			
		||||
pub trait Persistence {
 | 
			
		||||
    async fn load_day(&mut self, day: Date) -> Option<AttendanceDay>;
 | 
			
		||||
    async fn save_day(&mut self, day: Date, data: &AttendanceDay);
 | 
			
		||||
    async fn list_days(&mut self) -> Vec<Date>;
 | 
			
		||||
    async fn load_day(&mut self, day: Day) -> Option<AttendanceDay>;
 | 
			
		||||
    async fn save_day(&mut self, day: Day, data: &AttendanceDay);
 | 
			
		||||
    async fn list_days(&mut self) -> Vec<Day>;
 | 
			
		||||
 | 
			
		||||
    async fn load_mapping(&mut self) -> Option<IDMapping>;
 | 
			
		||||
    async fn save_mapping(&mut self, data: &IDMapping);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user