backup info and read

This commit is contained in:
Empire 2025-01-22 22:21:54 +01:00
parent 8cc967cf68
commit 88be5951a6
9 changed files with 131 additions and 29 deletions

View File

@ -216,16 +216,7 @@ fn safe_main() -> anyhow::Result<()> {
//check if we know the time current > 2020
if cur.year() < 2020 {
println!("Running time estimation super fallback");
if board.is_day() {
//assume TZ safe times ;)
println!("Is day -> 15:00");
cur = *cur.with_hour(15).get_or_insert(cur);
} else {
println!("Is night -> 3:00");
cur = *cur.with_hour(3).get_or_insert(cur);
}
to_config = true;
}
println!("cur is {}", cur);

View File

@ -206,9 +206,9 @@ pub struct BatteryState {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct BackupHeader{
timestamp: i64,
pub timestamp: i64,
crc16: u16,
size: usize
pub size: usize
}
impl PlantCtrlBoard<'_> {
@ -227,6 +227,25 @@ impl PlantCtrlBoard<'_> {
};
}
pub fn get_backup_info(&mut self) -> Result<BackupHeader> {
let dummy = BackupHeader{
timestamp: 0,
crc16: 0,
size: 0,
};
let store = bincode::serialize(&dummy)?.len();
let mut header_page_buffer = vec![0_u8; store];
match self.eeprom.read_data(0, &mut header_page_buffer) {
OkStd(_) => {},
Err(err) => bail!("Error reading eeprom header {:?}", err),
};
println!("Raw header is {:?} with size {}", header_page_buffer , store);
let header:BackupHeader = bincode::deserialize(&header_page_buffer)?;
Ok(header)
}
pub fn get_backup_config(&mut self) -> Result<Vec<u8>> {
let dummy = BackupHeader{
timestamp: 0,

View File

@ -51,6 +51,12 @@ pub struct TestPump {
pump: usize,
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct WebBackupHeader{
timestamp: std::string::String,
size: usize
}
fn write_time(
request: &mut Request<&mut EspHttpConnection>,
) -> Result<Option<std::string::String>, anyhow::Error> {
@ -159,6 +165,26 @@ fn get_backup_config(
anyhow::Ok(Some(json))
}
fn backup_info(
_request: &mut Request<&mut EspHttpConnection>,
) -> Result<Option<std::string::String>, anyhow::Error> {
let mut board = BOARD_ACCESS.lock().unwrap();
let header = board.get_backup_info();
let json = match header {
Ok(h) => {
let timestamp = DateTime::from_timestamp_millis(h.timestamp).unwrap();
let wbh = WebBackupHeader{
timestamp: timestamp.to_rfc3339(),
size: h.size,
};
serde_json::to_string(&wbh)?
},
Err(_) => "{\"error\":\"Header could not be parsed\"".to_owned()
};
anyhow::Ok(Some(json))
}
fn set_config(
request: &mut Request<&mut EspHttpConnection>,
) -> Result<Option<std::string::String>, anyhow::Error> {
@ -392,6 +418,11 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
handle_error_to500(request, backup_config)
})
.unwrap();
server
.fn_handler("/backup_info", Method::Get, move |request| {
handle_error_to500(request, backup_info)
})
.unwrap();
server
.fn_handler("/files", Method::Get, move |request| {
handle_error_to500(request, list_files)

View File

@ -1,3 +1,8 @@
interface BackupHeader {
timestamp: string,
size: number
}
interface NetworkConfig {
ap_ssid: string,
ssid: string,

View File

@ -160,12 +160,7 @@
<div id="plants" class="plantlist"></div>
<div class="flexcontainer-rev">
<div>
<textarea id="json" cols=50 rows=10></textarea>
<button id="submit">Submit</button>
<button id="backup">Backup</button>
<button id="restorebackup">Restore</button>
<div id="submit_status"></div>
<div id = "submitview" class="subcontainer">
</div>
<div id="fileview" class="subcontainer">
</div>

View File

@ -19,6 +19,17 @@ import { BatteryView } from "./batteryview";
import { FileView } from './fileview';
export class Controller {
getBackupInfo() {
fetch(PUBLIC_URL + "/backup_info")
.then(response => response.json())
.then(json => json as BackupHeader)
.then(header => {
controller.submitView.setBackupInfo(header)
})
.catch(error => {
console.log(error);
});
}
updateFileList() {
fetch(PUBLIC_URL + "/files")
.then(response => response.json())
@ -142,10 +153,10 @@ export class Controller {
getBackupConfig() {
controller.progressview.addIndeterminate("get_backup_config", "Downloading Backup")
fetch(PUBLIC_URL + "/get_backup_config")
.then(response => response.json())
.then(response => response.text())
.then(loaded => {
controller.progressview.removeProgress("get_config")
alert(loaded)
controller.progressview.removeProgress("get_backup_config")
controller.submitView.setBackupJson(loaded);
})
}
@ -399,5 +410,6 @@ controller.downloadConfig();
//controller.measure_moisture();
controller.version();
controller.updateFileList();
controller.getBackupInfo();
controller.progressview.removeProgress("rebooting");

View File

@ -1,34 +1,60 @@
import { Controller } from "./main";
export class SubmitView {
json: HTMLInputElement;
json: HTMLDivElement;
submitFormBtn: HTMLButtonElement;
submit_status: HTMLElement;
backupBtn: HTMLButtonElement;
restoreBackupBtn: HTMLButtonElement;
backuptimestamp: HTMLElement;
backupsize: HTMLElement;
backupjson: HTMLElement;
constructor(controller: Controller) {
this.json = document.getElementById('json') as HTMLInputElement
(document.getElementById("submitview") as HTMLElement).innerHTML = require("./submitview.html")
let showJson = document.getElementById('showJson') as HTMLButtonElement
let rawdata = document.getElementById('rawdata') as HTMLElement
this.json = document.getElementById('json') as HTMLDivElement
this.backupjson = document.getElementById('backupjson') as HTMLDivElement
this.submitFormBtn = document.getElementById("submit") as HTMLButtonElement
this.backupBtn = document.getElementById("backup") as HTMLButtonElement
this.restoreBackupBtn = document.getElementById("restorebackup") as HTMLButtonElement
this.backuptimestamp = document.getElementById("backuptimestamp") as HTMLElement
this.backupsize = document.getElementById("backupsize") as HTMLElement
this.submit_status = document.getElementById("submit_status") as HTMLElement
this.submitFormBtn.onclick = () => {
controller.uploadConfig(this.json.value, (status: string) => {
controller.uploadConfig(this.json.textContent as string, (status: string) => {
this.submit_status.innerHTML = status;
});
}
this.backupBtn.onclick = () => {
controller.backupConfig(this.json.value, (status: string) => {
controller.backupConfig(this.json.textContent as string, (status: string) => {
this.submit_status.innerHTML = status;
});
}
this.restoreBackupBtn.onclick = () => {
controller.getBackupConfig();
}
showJson.onclick = () => {
if (rawdata.style.display == "none"){
rawdata.style.display = "flex";
} else {
rawdata.style.display = "none";
}
}
}
setBackupInfo(header: BackupHeader) {
this.backuptimestamp.innerText = header.timestamp
this.backupsize.innerText = header.size.toString()
}
setJson(pretty: string) {
this.json.value = pretty
this.json.textContent = pretty
}
setBackupJson(pretty: string) {
this.backupjson.textContent = pretty
}
}

View File

@ -0,0 +1,23 @@
<style>
.submitarea{
flex-grow: 1;
border-style: groove;
border-width: 1px;
overflow-wrap: break-word;
word-wrap: break-word;
overflow: scroll;
}
</style>
<button id="showJson">Show Json</button>
<div id="rawdata" class="flexcontainer" style="display: none;">
<div class="submitarea" id="json" contenteditable="true"></div>
<div class="submitarea" id="backupjson">backup will be here</div>
</div>
<button id="submit">Submit</button>
<div>BackupStatus:</div>
<div id="backuptimestamp"></div>
<div id="backupsize"></div>
<button id="backup">Backup</button>
<button id="restorebackup">Restore</button>
<div id="submit_status"></div>

View File

@ -9,7 +9,7 @@ console.log("Dev server is " + isDevServer);
var host;
if (isDevServer){
//ensure no trailing /
host = 'http://192.168.1.172';
host = 'http://10.23.43.24';
} else {
host = '';
}