Skip to content

Commit f36aee8

Browse files
committed
feat: save state to epoch (nvs)
1 parent f9915df commit f36aee8

File tree

5 files changed

+99
-7
lines changed

5 files changed

+99
-7
lines changed

src/buttons.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ async fn submit_reset_competitor(
244244
return Ok(false);
245245
}
246246

247-
state.reset_solve_state();
247+
state.reset_solve_state(None).await;
248248
Ok(false)
249249
}
250250

@@ -339,7 +339,7 @@ async fn delegate_hold(
339339

340340
state_val.time_confirmed = true;
341341
if !resp.should_scan_cards {
342-
state_val.reset_solve_state();
342+
state_val.reset_solve_state(Some(&state.nvs)).await;
343343
}
344344
}
345345
}

src/main.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use esp_hal::{
1414
prelude::*,
1515
timer::timg::TimerGroup,
1616
};
17-
use state::{get_ota_state, GlobalStateInner, Scene};
17+
use state::{get_ota_state, GlobalStateInner, SavedGlobalState, Scene};
1818
use structs::ConnSettings;
1919
use translations::init_translations;
2020
use utils::{
@@ -281,6 +281,13 @@ async fn main(spawner: Spawner) {
281281

282282
set_brownout_detection(true);
283283
global_state.state.lock().await.scene = Scene::WaitingForCompetitor;
284+
if let Some(saved_state) = SavedGlobalState::from_nvs(&nvs).await {
285+
global_state
286+
.state
287+
.lock()
288+
.await
289+
.parse_saved_state(saved_state);
290+
}
284291

285292
let mut counter = 0;
286293
loop {

src/rfid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ pub async fn rfid_task(
134134

135135
if resp.is_ok() {
136136
log::info!("solve_resp: {resp:?}");
137-
state.reset_solve_state();
137+
state.reset_solve_state(Some(&global_state.nvs)).await;
138138
}
139139
}
140140
}

src/stackmat.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::{
55
},
66
};
77
use adv_shift_registers::wrappers::ShifterValueRange;
8+
use alloc::string::ToString;
89
use embassy_time::{Instant, Timer};
910
use esp_hal::{gpio::AnyPin, peripherals::UART1, uart::UartRx};
1011

@@ -83,11 +84,19 @@ pub async fn stackmat_task(
8384
None
8485
};
8586

87+
if state.session_id.is_none() {
88+
state.session_id = Some(uuid::Uuid::new_v4().to_string());
89+
}
90+
8691
if state.current_competitor.is_some() {
8792
state.scene = Scene::Finished;
8893
} else if state.scene >= Scene::WaitingForCompetitor {
8994
state.scene = Scene::WaitingForCompetitor;
9095
}
96+
97+
if let Some(saved_state) = state.to_saved_global_state() {
98+
saved_state.to_nvs(&global_state.nvs).await;
99+
}
91100
}
92101
} else if parsed.0 == StackmatTimerState::Reset {
93102
let mut state = global_state.state.lock().await;

src/state.rs

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use alloc::{rc::Rc, string::String};
22
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, signal::Signal};
3-
use embassy_time::Instant;
3+
use embassy_time::{Duration, Instant};
44
use esp_hal_wifimanager::Nvs;
5+
use serde::{Deserialize, Serialize};
56

67
use crate::utils::signaled_mutex::SignaledMutex;
78

8-
pub static mut EPOCH_BASE: u64 = 1431212400;
9+
pub static mut EPOCH_BASE: u64 = 0;
910
pub static mut SLEEP_STATE: bool = false;
1011
pub static mut OTA_STATE: bool = false;
1112

@@ -125,6 +126,16 @@ pub struct SignaledGlobalStateInner {
125126
pub ota_update: Option<u8>,
126127
}
127128

129+
#[derive(Debug, Clone, Serialize, Deserialize)]
130+
pub struct SavedGlobalState {
131+
pub inspection_time: Option<u64>,
132+
pub solve_time: u64,
133+
pub penalty: i8,
134+
pub session_id: String,
135+
pub current_competitor: u64,
136+
// pub solve_epoch: u64
137+
}
138+
128139
impl SignaledGlobalStateInner {
129140
pub fn new() -> Self {
130141
Self {
@@ -176,7 +187,7 @@ impl SignaledGlobalStateInner {
176187
false
177188
}
178189

179-
pub fn reset_solve_state(&mut self) {
190+
pub async fn reset_solve_state(&mut self, save_nvs: Option<&Nvs>) {
180191
self.last_solve_time = self.solve_time;
181192

182193
self.solve_time = None;
@@ -189,5 +200,70 @@ impl SignaledGlobalStateInner {
189200
self.session_id = None;
190201
self.time_confirmed = false;
191202
self.scene = Scene::WaitingForCompetitor;
203+
204+
if let Some(nvs) = save_nvs {
205+
SavedGlobalState::clear_saved_global_state(nvs).await;
206+
}
207+
}
208+
209+
pub fn to_saved_global_state(&self) -> Option<SavedGlobalState> {
210+
log::warn!("TO_SAVED_GLOBAL_STATE: {self:?}");
211+
212+
Some(SavedGlobalState {
213+
session_id: self.session_id.clone()?,
214+
current_competitor: self.current_competitor?,
215+
penalty: self.penalty.unwrap_or(0),
216+
solve_time: self.solve_time?,
217+
inspection_time: self
218+
.inspection_end
219+
.map(|e| (e - self.inspection_start.unwrap_or(Instant::now())).as_millis()),
220+
})
221+
}
222+
223+
pub fn parse_saved_state(&mut self, saved: SavedGlobalState) {
224+
self.session_id = Some(saved.session_id);
225+
self.penalty = Some(saved.penalty);
226+
self.solve_time = Some(saved.solve_time);
227+
self.current_competitor = Some(saved.current_competitor);
228+
229+
if let Some(inspection_time) = saved.inspection_time {
230+
let now = Instant::now();
231+
self.inspection_end = now.checked_add(Duration::from_millis(inspection_time));
232+
self.inspection_start = Some(now);
233+
}
234+
235+
if saved.solve_time > 0 {
236+
self.scene = Scene::Finished;
237+
}
238+
}
239+
}
240+
241+
impl SavedGlobalState {
242+
pub async fn from_nvs(nvs: &Nvs) -> Option<Self> {
243+
let mut buf = [0; 1024];
244+
nvs.get_key(b"SAVED_GLOBAL_STATE", &mut buf).await.ok()?;
245+
let end_pos = buf.iter().position(|&x| x == 0x00).unwrap_or(buf.len());
246+
247+
serde_json::from_slice(&buf[..end_pos]).ok()
248+
}
249+
250+
pub async fn to_nvs(&self, nvs: &Nvs) {
251+
let res = serde_json::to_vec(&self);
252+
if let Ok(vec) = res {
253+
let res = nvs.append_key(b"SAVED_GLOBAL_STATE", &vec).await;
254+
if let Err(e) = res {
255+
log::error!(
256+
"{e:?} Faile to write to nvs! (SAVED_GLOBAL_STATE {})",
257+
vec.len()
258+
);
259+
}
260+
}
261+
}
262+
263+
pub async fn clear_saved_global_state(nvs: &Nvs) {
264+
let res = nvs.invalidate_key(b"SAVED_GLOBAL_STATE").await;
265+
if let Err(e) = res {
266+
log::error!("{e:?} Faile to invalidate nvs key! (SAVED_GLOBAL_STATE)",);
267+
}
192268
}
193269
}

0 commit comments

Comments
 (0)