cleanup reboot logic, fix json upload
This commit is contained in:
		| @@ -10,7 +10,17 @@ use chrono_tz::{Europe::Berlin, Tz}; | |||||||
| use config::Mode; | use config::Mode; | ||||||
| use esp_idf_hal::delay::Delay; | use esp_idf_hal::delay::Delay; | ||||||
| use esp_idf_sys::{ | use esp_idf_sys::{ | ||||||
|     esp_deep_sleep, esp_ota_get_app_partition_count, esp_ota_get_running_partition, esp_ota_get_state_partition, esp_ota_img_states_t, esp_ota_img_states_t_ESP_OTA_IMG_ABORTED, esp_ota_img_states_t_ESP_OTA_IMG_INVALID, esp_ota_img_states_t_ESP_OTA_IMG_NEW, esp_ota_img_states_t_ESP_OTA_IMG_PENDING_VERIFY, esp_ota_img_states_t_ESP_OTA_IMG_UNDEFINED, esp_ota_img_states_t_ESP_OTA_IMG_VALID, esp_restart, esp_sleep_enable_ext1_wakeup, esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW, vTaskDelay, CONFIG_FREERTOS_HZ |     esp_ota_get_app_partition_count,  | ||||||
|  |     esp_ota_get_running_partition,  | ||||||
|  |     esp_ota_get_state_partition,  | ||||||
|  |     esp_ota_img_states_t,  | ||||||
|  |     esp_ota_img_states_t_ESP_OTA_IMG_ABORTED,  | ||||||
|  |     esp_ota_img_states_t_ESP_OTA_IMG_INVALID,  | ||||||
|  |     esp_ota_img_states_t_ESP_OTA_IMG_NEW,  | ||||||
|  |     esp_ota_img_states_t_ESP_OTA_IMG_PENDING_VERIFY,  | ||||||
|  |     esp_ota_img_states_t_ESP_OTA_IMG_UNDEFINED,  | ||||||
|  |     esp_ota_img_states_t_ESP_OTA_IMG_VALID,  | ||||||
|  |     vTaskDelay | ||||||
| }; | }; | ||||||
| use log::error; | use log::error; | ||||||
| use once_cell::sync::Lazy; | use once_cell::sync::Lazy; | ||||||
| @@ -460,8 +470,7 @@ fn safe_main() -> anyhow::Result<()> { | |||||||
|                 board.last_pump_time(plant); |                 board.last_pump_time(plant); | ||||||
|                 state.active = true; |                 state.active = true; | ||||||
|                 for _ in 0..plant_config.pump_time_s { |                 for _ in 0..plant_config.pump_time_s { | ||||||
|                     unsafe { vTaskDelay(CONFIG_FREERTOS_HZ) }; |                     Delay::new_default().delay_ms(1000); | ||||||
|                     //info message or something? |  | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 board.pump(plant, false)?; |                 board.pump(plant, false)?; | ||||||
| @@ -557,10 +566,7 @@ fn safe_main() -> anyhow::Result<()> { | |||||||
|         let _webserver = httpd(reboot_now.clone()); |         let _webserver = httpd(reboot_now.clone()); | ||||||
|         wait_infinity(WaitType::MqttConfig, reboot_now.clone()); |         wait_infinity(WaitType::MqttConfig, reboot_now.clone()); | ||||||
|     } |     } | ||||||
|     unsafe {  |     board.deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64); | ||||||
|         esp_sleep_enable_ext1_wakeup(0b10u64, esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW); |  | ||||||
|         esp_deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64)  |  | ||||||
|     }; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn publish_battery_state( | fn publish_battery_state( | ||||||
| @@ -949,8 +955,7 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if reboot_now.load(std::sync::atomic::Ordering::Relaxed) { |             if reboot_now.load(std::sync::atomic::Ordering::Relaxed) { | ||||||
|                 println!("Rebooting"); |                 BOARD_ACCESS.lock().unwrap().deep_sleep( 1); | ||||||
|                 esp_restart(); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -961,7 +966,7 @@ fn main() { | |||||||
|     match result { |     match result { | ||||||
|         Ok(_) => { |         Ok(_) => { | ||||||
|             println!("Main app finished, restarting"); |             println!("Main app finished, restarting"); | ||||||
|             unsafe { esp_restart() }; |             BOARD_ACCESS.lock().unwrap().deep_sleep(1); | ||||||
|         } |         } | ||||||
|         Err(err) => { |         Err(err) => { | ||||||
|             println!("Failed main {}", err); |             println!("Failed main {}", err); | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ use embedded_hal_bus::i2c::MutexDevice; | |||||||
| use embedded_svc::wifi::{ | use embedded_svc::wifi::{ | ||||||
|     AccessPointConfiguration, AccessPointInfo, AuthMethod, ClientConfiguration, Configuration, |     AccessPointConfiguration, AccessPointInfo, AuthMethod, ClientConfiguration, Configuration, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| use esp_idf_hal::adc::oneshot::config::AdcChannelConfig; | use esp_idf_hal::adc::oneshot::config::AdcChannelConfig; | ||||||
| use esp_idf_hal::adc::oneshot::{AdcChannelDriver, AdcDriver}; | use esp_idf_hal::adc::oneshot::{AdcChannelDriver, AdcDriver}; | ||||||
| use esp_idf_hal::adc::{attenuation, Resolution}; | use esp_idf_hal::adc::{attenuation, Resolution}; | ||||||
| @@ -23,6 +24,8 @@ use esp_idf_svc::wifi::EspWifi; | |||||||
| use measurements::Temperature; | use measurements::Temperature; | ||||||
| use once_cell::sync::Lazy; | use once_cell::sync::Lazy; | ||||||
| use plant_ctrl2::sipo::ShiftRegister40; | use plant_ctrl2::sipo::ShiftRegister40; | ||||||
|  | use esp_idf_sys::esp_deep_sleep; | ||||||
|  | use esp_idf_sys::esp_restart; | ||||||
|  |  | ||||||
| use anyhow::{anyhow, Context}; | use anyhow::{anyhow, Context}; | ||||||
| use anyhow::{bail, Ok, Result}; | use anyhow::{bail, Ok, Result}; | ||||||
| @@ -53,6 +56,7 @@ use esp_idf_sys::{esp, esp_spiffs_check, gpio_hold_dis, gpio_hold_en, vTaskDelay | |||||||
| use one_wire_bus::OneWire; | use one_wire_bus::OneWire; | ||||||
|  |  | ||||||
| use crate::config::{self, PlantControllerConfig}; | use crate::config::{self, PlantControllerConfig}; | ||||||
|  | use crate::espota::mark_app_valid; | ||||||
| use crate::{plant_hal, to_string, STAY_ALIVE}; | use crate::{plant_hal, to_string, STAY_ALIVE}; | ||||||
|  |  | ||||||
| //Only support for 8 right now! | //Only support for 8 right now! | ||||||
| @@ -196,6 +200,21 @@ pub struct BatteryState { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl PlantCtrlBoard<'_> { | impl PlantCtrlBoard<'_> { | ||||||
|  |     pub fn deep_sleep(&mut self, duration_in_ms:u64) -> !{ | ||||||
|  |         unsafe {  | ||||||
|  |             //if we dont do this here, we might just revert a newly flashed firmeware | ||||||
|  |             mark_app_valid(); | ||||||
|  |             //allow early wakup by pressing the boot button | ||||||
|  |             if duration_in_ms == 0 { | ||||||
|  |                 esp_restart(); | ||||||
|  |             } else { | ||||||
|  |                 // esp_sleep_enable_ext1_wakeup(0b10u64, esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW); | ||||||
|  |                 esp_deep_sleep(duration_in_ms);  | ||||||
|  |             } | ||||||
|  |             | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     pub fn get_battery_state(&mut self) -> BatteryState { |     pub fn get_battery_state(&mut self) -> BatteryState { | ||||||
|         let bat = BatteryState { |         let bat = BatteryState { | ||||||
|             voltage_milli_volt: to_string(self.voltage_milli_volt()), |             voltage_milli_volt: to_string(self.voltage_milli_volt()), | ||||||
|   | |||||||
| @@ -4,8 +4,6 @@ use std::{ | |||||||
|     str::from_utf8, |     str::from_utf8, | ||||||
|     sync::{atomic::AtomicBool, Arc}, |     sync::{atomic::AtomicBool, Arc}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| use esp_idf_svc::io::BufRead; |  | ||||||
| use crate::{ | use crate::{ | ||||||
|     espota::OtaUpdate, get_version, map_range_moisture, plant_hal::FileInfo, BOARD_ACCESS, |     espota::OtaUpdate, get_version, map_range_moisture, plant_hal::FileInfo, BOARD_ACCESS, | ||||||
| }; | }; | ||||||
| @@ -56,11 +54,8 @@ pub struct TestPump { | |||||||
| fn write_time( | fn write_time( | ||||||
|     request: &mut Request<&mut EspHttpConnection>, |     request: &mut Request<&mut EspHttpConnection>, | ||||||
| ) -> Result<Option<std::string::String>, anyhow::Error> { | ) -> Result<Option<std::string::String>, anyhow::Error> { | ||||||
|     let mut buf = [0_u8; 3072]; |     let actual_data = read_up_to_bytes_from_request(request, None)?; | ||||||
|     let read = request.read(&mut buf)?; |     let time: SetTime = serde_json::from_slice(&actual_data)?; | ||||||
|     let actual_data = &buf[0..read]; |  | ||||||
|     println!("Raw data {}", from_utf8(actual_data)?); |  | ||||||
|     let time: SetTime = serde_json::from_slice(actual_data)?; |  | ||||||
|     let parsed = DateTime::parse_from_rfc3339(time.time).map_err(|err| anyhow::anyhow!(err))?; |     let parsed = DateTime::parse_from_rfc3339(time.time).map_err(|err| anyhow::anyhow!(err))?; | ||||||
|     let mut board = BOARD_ACCESS.lock().unwrap(); |     let mut board = BOARD_ACCESS.lock().unwrap(); | ||||||
|     board.set_rtc_time(&parsed.to_utc())?; |     board.set_rtc_time(&parsed.to_utc())?; | ||||||
| @@ -144,16 +139,14 @@ fn get_config( | |||||||
| fn set_config( | fn set_config( | ||||||
|     request: &mut Request<&mut EspHttpConnection>, |     request: &mut Request<&mut EspHttpConnection>, | ||||||
| ) -> Result<Option<std::string::String>, anyhow::Error> { | ) -> Result<Option<std::string::String>, anyhow::Error> { | ||||||
|     let mut buf = [0_u8; 3072]; |     let all = read_up_to_bytes_from_request(request, Some(3072))?; | ||||||
|     let read = request.read(&mut buf)?; |     let config: PlantControllerConfig = serde_json::from_slice(&all)?; | ||||||
|     let actual_data = &buf[0..read]; |  | ||||||
|     println!("Raw data {}", from_utf8(actual_data).unwrap()); |  | ||||||
|     let config: PlantControllerConfig = serde_json::from_slice(actual_data)?; |  | ||||||
|     let mut board = BOARD_ACCESS.lock().unwrap(); |     let mut board = BOARD_ACCESS.lock().unwrap(); | ||||||
|     board.set_config(&config)?; |     board.set_config(&config)?; | ||||||
|     anyhow::Ok(Some("saved".to_owned())) |     anyhow::Ok(Some("saved".to_owned())) | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| fn get_battery_state( | fn get_battery_state( | ||||||
|     _request: &mut Request<&mut EspHttpConnection>, |     _request: &mut Request<&mut EspHttpConnection>, | ||||||
| ) -> Result<Option<std::string::String>, anyhow::Error> { | ) -> Result<Option<std::string::String>, anyhow::Error> { | ||||||
| @@ -172,9 +165,8 @@ fn get_version_web( | |||||||
| fn pump_test( | fn pump_test( | ||||||
|     request: &mut Request<&mut EspHttpConnection>, |     request: &mut Request<&mut EspHttpConnection>, | ||||||
| ) -> Result<Option<std::string::String>, anyhow::Error> { | ) -> Result<Option<std::string::String>, anyhow::Error> { | ||||||
|     let mut buf = [0_u8; 3072]; |     let actual_data = read_up_to_bytes_from_request(request, None)?; | ||||||
|     let read = request.read(&mut buf)?; |     let pump_test: TestPump = serde_json::from_slice(&actual_data)?; | ||||||
|     let pump_test: TestPump = serde_json::from_slice(&buf[0..read])?; |  | ||||||
|     let mut board = BOARD_ACCESS.lock().unwrap(); |     let mut board = BOARD_ACCESS.lock().unwrap(); | ||||||
|     board.test_pump(pump_test.pump)?; |     board.test_pump(pump_test.pump)?; | ||||||
|     anyhow::Ok(None) |     anyhow::Ok(None) | ||||||
| @@ -285,7 +277,7 @@ fn query_param(uri: &str, param_name: &str) -> Option<std::string::String> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> { | pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> { | ||||||
|     let server_config = Configuration { |     let server_config = Configuration { | ||||||
|         stack_size: 32768, |         stack_size: 32768, | ||||||
|         ..Default::default() |         ..Default::default() | ||||||
| @@ -358,6 +350,25 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> { | |||||||
|             handle_error_to500(request, list_files) |             handle_error_to500(request, list_files) | ||||||
|         }) |         }) | ||||||
|         .unwrap(); |         .unwrap(); | ||||||
|  |     let reboot_now_for_reboot = reboot_now.clone(); | ||||||
|  |     server | ||||||
|  |     .fn_handler("/reboot", Method::Post, move |_| { | ||||||
|  |         BOARD_ACCESS | ||||||
|  |             .lock() | ||||||
|  |             .unwrap() | ||||||
|  |             .set_restart_to_conf(true); | ||||||
|  |         reboot_now_for_reboot.store(true, std::sync::atomic::Ordering::Relaxed);              | ||||||
|  |         anyhow::Ok(()) | ||||||
|  |     }) | ||||||
|  |     .unwrap(); | ||||||
|  |  | ||||||
|  |     let reboot_now_for_exit = reboot_now.clone(); | ||||||
|  |     server | ||||||
|  |     .fn_handler("/exit", Method::Post, move |_| { | ||||||
|  |         reboot_now_for_exit.store(true, std::sync::atomic::Ordering::Relaxed);        | ||||||
|  |         anyhow::Ok(()) | ||||||
|  |     }) | ||||||
|  |     .unwrap(); | ||||||
|     server |     server | ||||||
|         .fn_handler("/file", Method::Get, move |request| { |         .fn_handler("/file", Method::Get, move |request| { | ||||||
|             let filename = query_param(request.uri(), "filename").unwrap(); |             let filename = query_param(request.uri(), "filename").unwrap(); | ||||||
| @@ -407,6 +418,8 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> { | |||||||
|                 .unwrap() |                 .unwrap() | ||||||
|                 .get_file_handle(&filename, true); |                 .get_file_handle(&filename, true); | ||||||
|             match file_handle { |             match file_handle { | ||||||
|  |                 //TODO get free filesystem size, check against during write if not to large | ||||||
|  |  | ||||||
|                 Ok(mut file_handle) => { |                 Ok(mut file_handle) => { | ||||||
|                     const BUFFER_SIZE: usize = 512; |                     const BUFFER_SIZE: usize = 512; | ||||||
|                     let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE]; |                     let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE]; | ||||||
| @@ -482,7 +495,6 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> { | |||||||
|             anyhow::Ok(()) |             anyhow::Ok(()) | ||||||
|         }) |         }) | ||||||
|         .unwrap(); |         .unwrap(); | ||||||
|  |  | ||||||
|     server |     server | ||||||
|         .fn_handler("/", Method::Get, move |request| { |         .fn_handler("/", Method::Get, move |request| { | ||||||
|             let mut response = request.into_ok_response()?; |             let mut response = request.into_ok_response()?; | ||||||
| @@ -559,3 +571,25 @@ fn handle_error_to500( | |||||||
|     } |     } | ||||||
|     return anyhow::Ok(()); |     return anyhow::Ok(()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | fn read_up_to_bytes_from_request(request: &mut Request<&mut EspHttpConnection<'_>>, limit: Option<usize>) -> Result<Vec<u8>, anyhow::Error> { | ||||||
|  |     let max_read = limit.unwrap_or(1024); | ||||||
|  |     let mut data_store = Vec::new(); | ||||||
|  |     let mut total_read = 0; | ||||||
|  |     loop{ | ||||||
|  |         let mut buf = [0_u8; 64]; | ||||||
|  |         let read = request.read(&mut buf)?; | ||||||
|  |         if read == 0 { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         let actual_data = &buf[0..read]; | ||||||
|  |         total_read += read; | ||||||
|  |         if total_read > max_read{ | ||||||
|  |             bail!("Request too large {total_read} > {max_read}"); | ||||||
|  |         } | ||||||
|  |         data_store.push(actual_data.to_owned()); | ||||||
|  |     } | ||||||
|  |     let allvec = data_store.concat(); | ||||||
|  |     println!("Raw data {}", from_utf8(&allvec)?); | ||||||
|  |     Ok(allvec) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -116,6 +116,9 @@ | |||||||
|   <br> |   <br> | ||||||
|   <textarea id="json" cols=50 rows=10></textarea> |   <textarea id="json" cols=50 rows=10></textarea> | ||||||
|   <script src="bundle.js"></script> |   <script src="bundle.js"></script> | ||||||
|  |  | ||||||
|  |   <button id="exit">Exit</button> | ||||||
|  |   <button id="reboot">Reboot</button> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
| <div id="progressPane" class="progressPane"> | <div id="progressPane" class="progressPane"> | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ export class Controller { | |||||||
|         controller.timeView.update(time.native, time.rtc) |         controller.timeView.update(time.native, time.rtc) | ||||||
|       }) |       }) | ||||||
|       .catch(error => { |       .catch(error => { | ||||||
|           controller.timeView.update("n/a","n/a") |         controller.timeView.update("n/a", "n/a") | ||||||
|         console.log(error); |         console.log(error); | ||||||
|       }); |       }); | ||||||
|   } |   } | ||||||
| @@ -43,12 +43,12 @@ export class Controller { | |||||||
|   uploadNewFirmware(file: File) { |   uploadNewFirmware(file: File) { | ||||||
|     var current = 0; |     var current = 0; | ||||||
|     var max = 100; |     var max = 100; | ||||||
|     controller.progressview.addProgress("ota_upload", (current/max) *100 , "Uploading firmeware ("+current+"/" + max+")") |     controller.progressview.addProgress("ota_upload", (current / max) * 100, "Uploading firmeware (" + current + "/" + max + ")") | ||||||
|     var ajax = new XMLHttpRequest(); |     var ajax = new XMLHttpRequest(); | ||||||
|     ajax.upload.addEventListener("progress", event => { |     ajax.upload.addEventListener("progress", event => { | ||||||
|       current = event.loaded/1000; |       current = event.loaded / 1000; | ||||||
|       max = event.total/1000; |       max = event.total / 1000; | ||||||
|       controller.progressview.addProgress("ota_upload", (current/max) *100 , "Uploading firmeware ("+current+"/" + max+")") |       controller.progressview.addProgress("ota_upload", (current / max) * 100, "Uploading firmeware (" + current + "/" + max + ")") | ||||||
|     }, false); |     }, false); | ||||||
|     ajax.addEventListener("load", () => { |     ajax.addEventListener("load", () => { | ||||||
|       //TODO wait for reboot here! |       //TODO wait for reboot here! | ||||||
| @@ -97,7 +97,7 @@ export class Controller { | |||||||
|       .then(text => statusCallback(text)) |       .then(text => statusCallback(text)) | ||||||
|     controller.progressview.removeProgress("set_config") |     controller.progressview.removeProgress("set_config") | ||||||
|   } |   } | ||||||
|   syncRTCFromBrowser(){ |   syncRTCFromBrowser() { | ||||||
|     controller.progressview.addIndeterminate("write_rtc", "Writing RTC") |     controller.progressview.addIndeterminate("write_rtc", "Writing RTC") | ||||||
|     var value: SetTime = { |     var value: SetTime = { | ||||||
|       time: new Date().toISOString() |       time: new Date().toISOString() | ||||||
| @@ -122,12 +122,12 @@ export class Controller { | |||||||
|   testPlant(plantId: number) { |   testPlant(plantId: number) { | ||||||
|     let counter = 0 |     let counter = 0 | ||||||
|     let limit = 30 |     let limit = 30 | ||||||
|     controller.progressview.addProgress("test_pump", counter/limit*100, "Testing pump " + (plantId+1) + " for " + (limit-counter)+"s") |     controller.progressview.addProgress("test_pump", counter / limit * 100, "Testing pump " + (plantId + 1) + " for " + (limit - counter) + "s") | ||||||
|  |  | ||||||
|     let timerId: string | number | NodeJS.Timeout | undefined |     let timerId: string | number | NodeJS.Timeout | undefined | ||||||
|     function updateProgress(){ |     function updateProgress() { | ||||||
|       counter++; |       counter++; | ||||||
|       controller.progressview.addProgress("test_pump", counter/limit*100, "Testing pump " + (plantId+1) + " for " + (limit-counter)+"s") |       controller.progressview.addProgress("test_pump", counter / limit * 100, "Testing pump " + (plantId + 1) + " for " + (limit - counter) + "s") | ||||||
|       timerId = setTimeout(updateProgress, 1000); |       timerId = setTimeout(updateProgress, 1000); | ||||||
|  |  | ||||||
|     } |     } | ||||||
| @@ -151,7 +151,7 @@ export class Controller { | |||||||
|       ) |       ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getConfig(): PlantControllerConfig{ |   getConfig(): PlantControllerConfig { | ||||||
|     return { |     return { | ||||||
|       network: controller.networkView.getConfig(), |       network: controller.networkView.getConfig(), | ||||||
|       tank: controller.tankView.getConfig(), |       tank: controller.tankView.getConfig(), | ||||||
| @@ -163,12 +163,12 @@ export class Controller { | |||||||
|   scanWifi() { |   scanWifi() { | ||||||
|     let counter = 0 |     let counter = 0 | ||||||
|     let limit = 5 |     let limit = 5 | ||||||
|     controller.progressview.addProgress("scan_ssid", counter/limit*100, "Scanning for SSIDs for " + (limit-counter)+"s") |     controller.progressview.addProgress("scan_ssid", counter / limit * 100, "Scanning for SSIDs for " + (limit - counter) + "s") | ||||||
|  |  | ||||||
|     let timerId: string | number | NodeJS.Timeout | undefined |     let timerId: string | number | NodeJS.Timeout | undefined | ||||||
|     function updateProgress(){ |     function updateProgress() { | ||||||
|       counter++; |       counter++; | ||||||
|       controller.progressview.addProgress("scan_ssid", counter/limit*100, "Scanning for SSIDs for " + (limit-counter)+"s") |       controller.progressview.addProgress("scan_ssid", counter / limit * 100, "Scanning for SSIDs for " + (limit - counter) + "s") | ||||||
|       timerId = setTimeout(updateProgress, 1000); |       timerId = setTimeout(updateProgress, 1000); | ||||||
|  |  | ||||||
|     } |     } | ||||||
| @@ -200,15 +200,15 @@ export class Controller { | |||||||
|     this.plantViews.setConfig(current.plants); |     this.plantViews.setConfig(current.plants); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   measure_moisture (){ |   measure_moisture() { | ||||||
|     let counter = 0 |     let counter = 0 | ||||||
|     let limit = 2 |     let limit = 2 | ||||||
|     controller.progressview.addProgress("measure_moisture", counter/limit*100, "Measure Moisture " + (limit-counter)+"s") |     controller.progressview.addProgress("measure_moisture", counter / limit * 100, "Measure Moisture " + (limit - counter) + "s") | ||||||
|  |  | ||||||
|     let timerId: string | number | NodeJS.Timeout | undefined |     let timerId: string | number | NodeJS.Timeout | undefined | ||||||
|     function updateProgress(){ |     function updateProgress() { | ||||||
|       counter++; |       counter++; | ||||||
|       controller.progressview.addProgress("measure_moisture", counter/limit*100, "Measure Moisture " + (limit-counter)+"s") |       controller.progressview.addProgress("measure_moisture", counter / limit * 100, "Measure Moisture " + (limit - counter) + "s") | ||||||
|       timerId = setTimeout(updateProgress, 1000); |       timerId = setTimeout(updateProgress, 1000); | ||||||
|  |  | ||||||
|     } |     } | ||||||
| @@ -230,14 +230,48 @@ export class Controller { | |||||||
|       }); |       }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   exit() { | ||||||
|  |     fetch(PUBLIC_URL + "/exit", { | ||||||
|  |       method: "POST", | ||||||
|  |     }) | ||||||
|  |     controller.progressview.addIndeterminate("rebooting", "Returned to normal mode, you can close this site now") | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   waitForReboot() { | ||||||
|  |     console.log("Check if controller online again") | ||||||
|  |     fetch(PUBLIC_URL + "/version", { | ||||||
|  |       method: "POST", | ||||||
|  |       signal: AbortSignal.timeout(5000) | ||||||
|  |     }).then(response => { | ||||||
|  |       console.log("Reached controller, reloading") | ||||||
|  |       window.location.reload(); | ||||||
|  |     }) | ||||||
|  |       .catch(err => { | ||||||
|  |         console.log("Not reached yet, retrying") | ||||||
|  |         setTimeout(controller.waitForReboot, 1000) | ||||||
|  |       }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   reboot() { | ||||||
|  |     fetch(PUBLIC_URL + "/reboot", { | ||||||
|  |       method: "POST", | ||||||
|  |     }) | ||||||
|  |     controller.progressview.addIndeterminate("rebooting", "Rebooting") | ||||||
|  |     setTimeout(this.waitForReboot, 1000) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   readonly rebootBtn: HTMLButtonElement | ||||||
|  |   readonly exitBtn: HTMLButtonElement | ||||||
|   readonly timeView: TimeView; |   readonly timeView: TimeView; | ||||||
|   readonly plantViews: PlantViews; |   readonly plantViews: PlantViews; | ||||||
|   readonly networkView: NetworkConfigView; |   readonly networkView: NetworkConfigView; | ||||||
|   readonly tankView: TankConfigView; |   readonly tankView: TankConfigView; | ||||||
|   readonly nightLampView: NightLampView; |   readonly nightLampView: NightLampView; | ||||||
|   readonly submitView: SubmitView; |   readonly submitView: SubmitView; | ||||||
|   readonly firmWareView : OTAView; |   readonly firmWareView: OTAView; | ||||||
|   readonly progressview: ProgressView; |   readonly progressview: ProgressView; | ||||||
|   readonly batteryView: BatteryView; |   readonly batteryView: BatteryView; | ||||||
|   constructor() { |   constructor() { | ||||||
| @@ -250,6 +284,14 @@ export class Controller { | |||||||
|     this.submitView = new SubmitView(this) |     this.submitView = new SubmitView(this) | ||||||
|     this.firmWareView = new OTAView(this) |     this.firmWareView = new OTAView(this) | ||||||
|     this.progressview = new ProgressView(this) |     this.progressview = new ProgressView(this) | ||||||
|  |     this.rebootBtn = document.getElementById("reboot") as HTMLButtonElement | ||||||
|  |     this.rebootBtn.onclick = () => { | ||||||
|  |       controller.reboot(); | ||||||
|  |     } | ||||||
|  |     this.exitBtn = document.getElementById("exit") as HTMLButtonElement | ||||||
|  |     this.exitBtn.onclick = () => { | ||||||
|  |       controller.exit(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| const controller = new Controller(); | const controller = new Controller(); | ||||||
| @@ -258,4 +300,5 @@ controller.updateBatteryData(); | |||||||
| controller.downloadConfig(); | controller.downloadConfig(); | ||||||
| //controller.measure_moisture(); | //controller.measure_moisture(); | ||||||
| controller.version(); | controller.version(); | ||||||
|  | controller.progressview.removeProgress("rebooting"); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user