keep ota around for alter queries to it
This commit is contained in:
		@@ -7,7 +7,7 @@ use chrono::{DateTime, Utc};
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
 | 
			
		||||
use alloc::string::ToString;
 | 
			
		||||
use alloc::{string::String, vec::Vec};
 | 
			
		||||
use alloc::{format, string::String, vec::Vec};
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
use core::net::{IpAddr, Ipv4Addr};
 | 
			
		||||
use core::str::FromStr;
 | 
			
		||||
@@ -15,15 +15,18 @@ use embassy_executor::{SendSpawner, Spawner};
 | 
			
		||||
use embassy_net::tcp::TcpSocket;
 | 
			
		||||
use embassy_net::{IpListenEndpoint, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
 | 
			
		||||
use embassy_time::{Duration, Instant, Timer};
 | 
			
		||||
use esp_bootloader_esp_idf::ota::OtaImageState;
 | 
			
		||||
use esp_bootloader_esp_idf::ota::{Ota, OtaImageState, Slot};
 | 
			
		||||
use esp_bootloader_esp_idf::partitions::{Error, FlashRegion, PartitionEntry, PartitionTable};
 | 
			
		||||
use esp_hal::gpio::Input;
 | 
			
		||||
use esp_hal::rng::Rng;
 | 
			
		||||
use esp_hal::rtc_cntl::sleep::RtcSleepConfig;
 | 
			
		||||
use esp_println::{print, println};
 | 
			
		||||
use esp_storage::FlashStorage;
 | 
			
		||||
use esp_wifi::wifi::{
 | 
			
		||||
    AccessPointConfiguration, Configuration, Interfaces, WifiController, WifiDevice, WifiEvent,
 | 
			
		||||
    WifiState,
 | 
			
		||||
};
 | 
			
		||||
use log::{info, warn};
 | 
			
		||||
 | 
			
		||||
#[link_section = ".rtc.data"]
 | 
			
		||||
static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT];
 | 
			
		||||
@@ -72,11 +75,8 @@ pub struct Esp<'a> {
 | 
			
		||||
    pub boot_button: Input<'a>,
 | 
			
		||||
    pub(crate) wall_clock_offset: u64,
 | 
			
		||||
 | 
			
		||||
    pub storage: FlashStorage,
 | 
			
		||||
    pub slot: usize,
 | 
			
		||||
    pub next_slot: usize,
 | 
			
		||||
    pub ota_state: OtaImageState,
 | 
			
		||||
    pub slot_addres: u32,
 | 
			
		||||
    pub ota: Ota<'static, FlashStorage>,
 | 
			
		||||
    pub ota_next: &'static PartitionEntry<'static>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct IpInfo {
 | 
			
		||||
@@ -103,6 +103,36 @@ impl Esp<'_> {
 | 
			
		||||
    const CONFIG_FILE: &'static str = "/spiffs/config.cfg";
 | 
			
		||||
    const BASE_PATH: &'static str = "/spiffs";
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn get_ota_slot(&mut self) -> String {
 | 
			
		||||
        match self.ota.current_slot() {
 | 
			
		||||
            Ok(slot) => {
 | 
			
		||||
                format!("{:?}", slot)
 | 
			
		||||
            }
 | 
			
		||||
            Err(err) => {
 | 
			
		||||
                format!("{:?}", err)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn get_ota_state(&mut self) -> String {
 | 
			
		||||
        match self.ota.current_ota_state() {
 | 
			
		||||
            Ok(state) => {
 | 
			
		||||
                format!("{:?}", state)
 | 
			
		||||
            }
 | 
			
		||||
            Err(err) => {
 | 
			
		||||
                format!("{:?}", err)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // let current = ota.current_slot()?;
 | 
			
		||||
    // println!(
 | 
			
		||||
    //     "current image state {:?} (only relevant if the bootloader was built with auto-rollback support)",
 | 
			
		||||
    //     ota.current_ota_state()
 | 
			
		||||
    // );
 | 
			
		||||
    // println!("current {:?} - next {:?}", current, current.next());
 | 
			
		||||
    // let ota_state = ota.current_ota_state()?;
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn mode_override_pressed(&mut self) -> bool {
 | 
			
		||||
        self.boot_button.is_low()
 | 
			
		||||
    }
 | 
			
		||||
@@ -119,6 +149,14 @@ impl Esp<'_> {
 | 
			
		||||
        //self.time()
 | 
			
		||||
        todo!();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn flash_ota(&mut self) -> anyhow::Result<()> {
 | 
			
		||||
        let mut storage_ota_next = FlashStorage::new();
 | 
			
		||||
        let ota_next = self.ota_next.as_embedded_storage(&mut storage_ota_next);
 | 
			
		||||
 | 
			
		||||
        bail!("not implemented")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn time(&mut self) -> DateTime<Utc> {
 | 
			
		||||
        let wall_clock = Instant::now().as_millis() + self.wall_clock_offset;
 | 
			
		||||
        DateTime::from_timestamp_millis(wall_clock as i64).unwrap()
 | 
			
		||||
@@ -231,6 +269,36 @@ impl Esp<'_> {
 | 
			
		||||
        anyhow::Ok(stack.clone())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
 | 
			
		||||
        let mut cfg = RtcSleepConfig::deep();
 | 
			
		||||
 | 
			
		||||
        let cur = self.ota.current_ota_state().unwrap();
 | 
			
		||||
        //we made it till here, so fine
 | 
			
		||||
        if cur == OtaImageState::PendingVerify {
 | 
			
		||||
            self.ota
 | 
			
		||||
                .set_current_ota_state(OtaImageState::Valid)
 | 
			
		||||
                .expect("Could not set image to valid");
 | 
			
		||||
        }
 | 
			
		||||
        //unsafe {
 | 
			
		||||
        // //allow early wakeup by pressing the boot button
 | 
			
		||||
        if duration_in_ms == 0 {
 | 
			
		||||
            loop {
 | 
			
		||||
                info!("todo reboot")
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            loop {
 | 
			
		||||
                info!("todo deepsleep")
 | 
			
		||||
            }
 | 
			
		||||
            //     //configure gpio 1 to wakeup on low, reused boot button for this
 | 
			
		||||
            //     esp_sleep_enable_ext1_wakeup(
 | 
			
		||||
            //         0b10u64,
 | 
			
		||||
            //         esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW,
 | 
			
		||||
            //     );
 | 
			
		||||
            //     esp_deep_sleep(duration_in_ms);
 | 
			
		||||
        }
 | 
			
		||||
        //};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) async fn wifi(&mut self, network_config: &NetworkConfig) -> anyhow::Result<IpInfo> {
 | 
			
		||||
        let _ssid = network_config
 | 
			
		||||
            .ssid
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ use crate::hal::rtc::{BackupHeader, RTCModuleInteraction};
 | 
			
		||||
use alloc::vec::Vec;
 | 
			
		||||
//use crate::hal::water::TankSensor;
 | 
			
		||||
use crate::alloc::boxed::Box;
 | 
			
		||||
use crate::hal::{deep_sleep, BoardInteraction, FreePeripherals, Sensor};
 | 
			
		||||
use crate::hal::{BoardInteraction, FreePeripherals, Sensor};
 | 
			
		||||
use crate::{
 | 
			
		||||
    config::PlantControllerConfig,
 | 
			
		||||
    hal::battery::{BatteryInteraction, NoBatteryMonitor},
 | 
			
		||||
@@ -91,8 +91,8 @@ impl<'a> BoardInteraction<'a> for Initial<'a> {
 | 
			
		||||
        bail!("Please configure board revision")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
 | 
			
		||||
        deep_sleep(duration_in_ms)
 | 
			
		||||
    async fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
 | 
			
		||||
        self.esp.deep_sleep(duration_in_ms).await;
 | 
			
		||||
    }
 | 
			
		||||
    fn is_day(&self) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
 
 | 
			
		||||
@@ -23,36 +23,25 @@ use alloc::boxed::Box;
 | 
			
		||||
use alloc::format;
 | 
			
		||||
use anyhow::{Ok, Result};
 | 
			
		||||
use async_trait::async_trait;
 | 
			
		||||
use core::cell::OnceCell;
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
use core::net::Ipv4Addr;
 | 
			
		||||
use core::str::FromStr;
 | 
			
		||||
use embassy_executor::{SendSpawner, Spawner};
 | 
			
		||||
use embassy_net::tcp::{Error, TcpSocket};
 | 
			
		||||
use embassy_net::{IpListenEndpoint, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
//use battery::BQ34Z100G1;
 | 
			
		||||
//use bq34z100::Bq34z100g1Driver;
 | 
			
		||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
 | 
			
		||||
use embassy_sync::once_lock::OnceLock;
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
use esp_bootloader_esp_idf::partitions::{
 | 
			
		||||
    AppPartitionSubType, DataPartitionSubType, PartitionEntry,
 | 
			
		||||
    AppPartitionSubType, DataPartitionSubType, FlashRegion, PartitionEntry,
 | 
			
		||||
};
 | 
			
		||||
use esp_hal::clock::CpuClock;
 | 
			
		||||
use esp_hal::gpio::{Input, InputConfig, Io, Pull};
 | 
			
		||||
use esp_hal::timer::systimer::SystemTimer;
 | 
			
		||||
use esp_println::{print, println};
 | 
			
		||||
use esp_println::println;
 | 
			
		||||
use measurements::{Current, Voltage};
 | 
			
		||||
 | 
			
		||||
use embassy_sync::mutex::{Mutex, MutexGuard};
 | 
			
		||||
use embassy_sync::mutex::Mutex;
 | 
			
		||||
use esp_alloc as _;
 | 
			
		||||
use esp_backtrace as _;
 | 
			
		||||
use esp_hal::analog::adc::Adc;
 | 
			
		||||
use esp_bootloader_esp_idf::ota::Slot;
 | 
			
		||||
use esp_hal::rng::Rng;
 | 
			
		||||
use esp_hal::timer::timg::TimerGroup;
 | 
			
		||||
use esp_wifi::wifi::{
 | 
			
		||||
    AccessPointConfiguration, Configuration, WifiController, WifiDevice, WifiEvent, WifiState,
 | 
			
		||||
};
 | 
			
		||||
use esp_storage::FlashStorage;
 | 
			
		||||
use esp_wifi::{init, EspWifiController};
 | 
			
		||||
 | 
			
		||||
//Only support for 8 right now!
 | 
			
		||||
@@ -62,27 +51,6 @@ const TANK_MULTI_SAMPLE: usize = 11;
 | 
			
		||||
 | 
			
		||||
//pub static I2C_DRIVER: LazyLock<Mutex<CriticalSectionRawMutex,I2cDriver<'static>>> = LazyLock::new(PlantHal::create_i2c);
 | 
			
		||||
 | 
			
		||||
fn deep_sleep(_duration_in_ms: u64) -> ! {
 | 
			
		||||
    //unsafe {
 | 
			
		||||
    // //if we don't do this here, we might just revert newly flashed firmware
 | 
			
		||||
    // mark_app_valid();
 | 
			
		||||
    // //allow early wakeup by pressing the boot button
 | 
			
		||||
    // if duration_in_ms == 0 {
 | 
			
		||||
    //     esp_restart();
 | 
			
		||||
    // } else {
 | 
			
		||||
    //     //configure gpio 1 to wakeup on low, reused boot button for this
 | 
			
		||||
    //     esp_sleep_enable_ext1_wakeup(
 | 
			
		||||
    //         0b10u64,
 | 
			
		||||
    //         esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW,
 | 
			
		||||
    //     );
 | 
			
		||||
    //     esp_deep_sleep(duration_in_ms);
 | 
			
		||||
    // }
 | 
			
		||||
    loop {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
    //};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
pub enum Sensor {
 | 
			
		||||
    A,
 | 
			
		||||
@@ -103,7 +71,7 @@ pub trait BoardInteraction<'a> {
 | 
			
		||||
    fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>;
 | 
			
		||||
    fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send>;
 | 
			
		||||
    fn set_charge_indicator(&mut self, charging: bool) -> Result<()>;
 | 
			
		||||
    fn deep_sleep(&mut self, duration_in_ms: u64) -> !;
 | 
			
		||||
    async fn deep_sleep(&mut self, duration_in_ms: u64) -> !;
 | 
			
		||||
 | 
			
		||||
    fn is_day(&self) -> bool;
 | 
			
		||||
    //should be multsampled
 | 
			
		||||
@@ -209,14 +177,14 @@ impl PlantHal {
 | 
			
		||||
            InputConfig::default().with_pull(Pull::None),
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let mut rng = Rng::new(peripherals.RNG);
 | 
			
		||||
        let rng = Rng::new(peripherals.RNG);
 | 
			
		||||
        let timg0 = TimerGroup::new(peripherals.TIMG0);
 | 
			
		||||
        let esp_wifi_ctrl = &*mk_static!(
 | 
			
		||||
            EspWifiController<'static>,
 | 
			
		||||
            init(timg0.timer0, rng.clone()).unwrap()
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let (mut controller, interfaces) =
 | 
			
		||||
        let (controller, interfaces) =
 | 
			
		||||
            esp_wifi::wifi::new(&esp_wifi_ctrl, peripherals.WIFI).unwrap();
 | 
			
		||||
 | 
			
		||||
        use esp_hal::timer::systimer::SystemTimer;
 | 
			
		||||
@@ -260,62 +228,60 @@ impl PlantHal {
 | 
			
		||||
        };
 | 
			
		||||
        //
 | 
			
		||||
 | 
			
		||||
        let mut storage = esp_storage::FlashStorage::new();
 | 
			
		||||
        let mut buffer = [0u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN];
 | 
			
		||||
        let tablebuffer: [u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN] =
 | 
			
		||||
            [0u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN];
 | 
			
		||||
        let tablebuffer = mk_static!(
 | 
			
		||||
            [u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN],
 | 
			
		||||
            tablebuffer
 | 
			
		||||
        );
 | 
			
		||||
        let storage_ota = mk_static!(FlashStorage, FlashStorage::new());
 | 
			
		||||
        let pt =
 | 
			
		||||
            esp_bootloader_esp_idf::partitions::read_partition_table(&mut storage, &mut buffer)?;
 | 
			
		||||
            esp_bootloader_esp_idf::partitions::read_partition_table(storage_ota, tablebuffer)?;
 | 
			
		||||
 | 
			
		||||
        // List all partitions - this is just FYI
 | 
			
		||||
        for i in 0..pt.len() {
 | 
			
		||||
            println!("{:?}", pt.get_partition(i));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Find the OTA-data partition and show the currently active partition
 | 
			
		||||
        let ota_part = pt
 | 
			
		||||
        let ota_data = pt
 | 
			
		||||
            .find_partition(esp_bootloader_esp_idf::partitions::PartitionType::Data(
 | 
			
		||||
                DataPartitionSubType::Ota,
 | 
			
		||||
            ))?
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        let mut ota_part = ota_part.as_embedded_storage(&mut storage);
 | 
			
		||||
        println!("Found ota data");
 | 
			
		||||
 | 
			
		||||
        let mut ota = esp_bootloader_esp_idf::ota::Ota::new(&mut ota_part)?;
 | 
			
		||||
        let current = ota.current_slot()?;
 | 
			
		||||
        println!(
 | 
			
		||||
            "current image state {:?} (only relevant if the bootloader was built with auto-rollback support)",
 | 
			
		||||
            ota.current_ota_state()
 | 
			
		||||
        );
 | 
			
		||||
        println!("current {:?} - next {:?}", current, current.next());
 | 
			
		||||
        let ota_state = ota.current_ota_state()?;
 | 
			
		||||
        let ota_data = mk_static!(PartitionEntry, ota_data);
 | 
			
		||||
 | 
			
		||||
        let current_app = if current.number() == 0 {
 | 
			
		||||
            pt.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
 | 
			
		||||
                AppPartitionSubType::Ota0,
 | 
			
		||||
            ))
 | 
			
		||||
        } else {
 | 
			
		||||
            pt.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
 | 
			
		||||
                AppPartitionSubType::Ota1,
 | 
			
		||||
            ))
 | 
			
		||||
        };
 | 
			
		||||
        let app_address = match current_app {
 | 
			
		||||
            Result::Ok(part) => match part {
 | 
			
		||||
                None => 0,
 | 
			
		||||
                Some(entry) => entry.offset(),
 | 
			
		||||
            },
 | 
			
		||||
            Err(_) => 0,
 | 
			
		||||
        let ota_data = ota_data.as_embedded_storage(storage_ota);
 | 
			
		||||
        let ota_data = mk_static!(FlashRegion<FlashStorage>, ota_data);
 | 
			
		||||
 | 
			
		||||
        let mut ota = esp_bootloader_esp_idf::ota::Ota::new(ota_data)?;
 | 
			
		||||
 | 
			
		||||
        let ota_partition = match ota.current_slot()? {
 | 
			
		||||
            Slot::None => {
 | 
			
		||||
                panic!("No OTA slot found");
 | 
			
		||||
            }
 | 
			
		||||
            Slot::Slot0 => pt
 | 
			
		||||
                .find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
 | 
			
		||||
                    AppPartitionSubType::Ota0,
 | 
			
		||||
                ))?
 | 
			
		||||
                .unwrap(),
 | 
			
		||||
            Slot::Slot1 => pt
 | 
			
		||||
                .find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
 | 
			
		||||
                    AppPartitionSubType::Ota1,
 | 
			
		||||
                ))?
 | 
			
		||||
                .unwrap(),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let ota_next = mk_static!(PartitionEntry, ota_partition);
 | 
			
		||||
 | 
			
		||||
        let mut esp = Esp {
 | 
			
		||||
            rng,
 | 
			
		||||
            controller: Some(controller),
 | 
			
		||||
            interfaces: Some(interfaces),
 | 
			
		||||
            boot_button,
 | 
			
		||||
            mqtt_client: None,
 | 
			
		||||
            storage,
 | 
			
		||||
            slot: current.number(),
 | 
			
		||||
            slot_addres: app_address,
 | 
			
		||||
            next_slot: current.next().number(),
 | 
			
		||||
            ota_state,
 | 
			
		||||
            ota,
 | 
			
		||||
            ota_next,
 | 
			
		||||
            wall_clock_offset: 0,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
#![no_std]
 | 
			
		||||
#![no_main]
 | 
			
		||||
#![feature(never_type)]
 | 
			
		||||
#![deny(
 | 
			
		||||
    clippy::mem_forget,
 | 
			
		||||
    reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
 | 
			
		||||
@@ -30,6 +31,7 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
 | 
			
		||||
use embassy_sync::mutex::{Mutex, MutexGuard};
 | 
			
		||||
use embassy_sync::once_lock::OnceLock;
 | 
			
		||||
use embassy_time::Timer;
 | 
			
		||||
use esp_alloc::heap_allocator;
 | 
			
		||||
use esp_bootloader_esp_idf::ota::OtaImageState;
 | 
			
		||||
use esp_hal::rom::ets_delay_us;
 | 
			
		||||
use esp_hal::system::software_reset;
 | 
			
		||||
@@ -601,7 +603,8 @@ async fn safe_main(spawner: Spawner) -> anyhow::Result<()> {
 | 
			
		||||
        board.board_hal.get_esp().set_restart_to_conf(false);
 | 
			
		||||
        board
 | 
			
		||||
            .board_hal
 | 
			
		||||
            .deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64);
 | 
			
		||||
            .deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64)
 | 
			
		||||
            .await;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -851,13 +854,11 @@ async fn publish_firmware_info(
 | 
			
		||||
        .mqtt_publish("/firmware/buildtime", version.build_time.as_bytes())
 | 
			
		||||
        .await;
 | 
			
		||||
    let _ = esp.mqtt_publish("/firmware/last_online", timezone_time.as_bytes());
 | 
			
		||||
    let state = esp.get_ota_state();
 | 
			
		||||
    let _ = esp
 | 
			
		||||
        .mqtt_publish(
 | 
			
		||||
            "/firmware/ota_state",
 | 
			
		||||
            state_to_string(esp.ota_state).as_bytes(),
 | 
			
		||||
        )
 | 
			
		||||
        .mqtt_publish("/firmware/ota_state", state.as_bytes())
 | 
			
		||||
        .await;
 | 
			
		||||
    let slot = esp.slot;
 | 
			
		||||
    let slot = esp.get_ota_slot();
 | 
			
		||||
    let _ = esp
 | 
			
		||||
        .mqtt_publish("/firmware/ota_slot", format!("slot{slot}").as_bytes())
 | 
			
		||||
        .await;
 | 
			
		||||
@@ -1123,17 +1124,11 @@ async fn get_version(
 | 
			
		||||
    let hash = &env!("VERGEN_GIT_SHA")[0..8];
 | 
			
		||||
 | 
			
		||||
    let board = board.board_hal.get_esp();
 | 
			
		||||
    let ota_slot = board.slot;
 | 
			
		||||
    let address = board.slot_addres;
 | 
			
		||||
    let partition = if ota_slot == 0 {
 | 
			
		||||
        "ota_1 @ "
 | 
			
		||||
    } else {
 | 
			
		||||
        "ota_0 @ "
 | 
			
		||||
    };
 | 
			
		||||
    let ota_slot = board.get_ota_slot();
 | 
			
		||||
    VersionInfo {
 | 
			
		||||
        git_hash: branch + "@" + hash,
 | 
			
		||||
        build_time: env!("VERGEN_BUILD_TIMESTAMP").to_owned(),
 | 
			
		||||
        partition: partition.to_owned() + &address.to_string(),
 | 
			
		||||
        partition: ota_slot,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +1,22 @@
 | 
			
		||||
//offer ota and config mode
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    config::PlantControllerConfig,
 | 
			
		||||
    do_secure_pump, get_version,
 | 
			
		||||
    hal::PLANT_COUNT,
 | 
			
		||||
    log::LogMessage,
 | 
			
		||||
    plant_state::{MoistureSensorState, PlantState},
 | 
			
		||||
    VersionInfo, BOARD_ACCESS,
 | 
			
		||||
};
 | 
			
		||||
use alloc::boxed::Box;
 | 
			
		||||
use crate::{get_version, log::LogMessage, BOARD_ACCESS};
 | 
			
		||||
use alloc::string::{String, ToString};
 | 
			
		||||
use alloc::sync::Arc;
 | 
			
		||||
use alloc::vec::Vec;
 | 
			
		||||
use anyhow::{bail, Context};
 | 
			
		||||
use chrono::DateTime;
 | 
			
		||||
use core::fmt::{Debug, Display, Pointer};
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
use core::fmt::{Debug, Display};
 | 
			
		||||
use core::net::{IpAddr, Ipv4Addr, SocketAddr};
 | 
			
		||||
use core::result::Result::Ok;
 | 
			
		||||
use core::sync::atomic::AtomicBool;
 | 
			
		||||
use edge_http::io::server::{Connection, DefaultServer, Handler, Server};
 | 
			
		||||
use core::sync::atomic::{AtomicBool, Ordering};
 | 
			
		||||
use edge_http::io::server::{Connection, Handler, Server};
 | 
			
		||||
use edge_http::io::Error;
 | 
			
		||||
use edge_http::Method;
 | 
			
		||||
use edge_nal::TcpBind;
 | 
			
		||||
use edge_nal_embassy::{Tcp, TcpAccept, TcpBuffers};
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_net::tcp::TcpSocket;
 | 
			
		||||
use embassy_net::{IpListenEndpoint, Stack};
 | 
			
		||||
use embassy_time::{Duration, Instant, Timer};
 | 
			
		||||
use edge_nal_embassy::{Tcp, TcpBuffers};
 | 
			
		||||
use embassy_net::Stack;
 | 
			
		||||
use embassy_time::Instant;
 | 
			
		||||
use embedded_io_async::{Read, Write};
 | 
			
		||||
use esp_println::{print, println};
 | 
			
		||||
use esp_wifi::wifi::WifiController;
 | 
			
		||||
use esp_println::println;
 | 
			
		||||
use log::info;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
@@ -148,13 +134,6 @@ pub struct NightLampCommand {
 | 
			
		||||
//     anyhow::Ok(Some(json))
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
// fn get_config(
 | 
			
		||||
//     _request: &mut Request<&mut EspHttpConnection>,
 | 
			
		||||
// ) -> Result<Option<std::string::String>, anyhow::Error> {
 | 
			
		||||
//     let mut board = BOARD_ACCESS.lock().expect("Should never fail");
 | 
			
		||||
//     let json = serde_json::to_string(&board.board_hal.get_config())?;
 | 
			
		||||
//     anyhow::Ok(Some(json))
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
// fn backup_config(
 | 
			
		||||
//     request: &mut Request<&mut EspHttpConnection>,
 | 
			
		||||
@@ -218,23 +197,6 @@ pub struct NightLampCommand {
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// fn get_log(
 | 
			
		||||
//     _request: &mut Request<&mut EspHttpConnection>,
 | 
			
		||||
// ) -> Result<Option<std::string::String>, anyhow::Error> {
 | 
			
		||||
//     let output = crate::log::get_log();
 | 
			
		||||
//     anyhow::Ok(Some(serde_json::to_string(&output)?))
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
// fn get_log_localization_config() -> Result<std::string::String, anyhow::Error> {
 | 
			
		||||
//     anyhow::Ok(serde_json::to_string(
 | 
			
		||||
//         &LogMessage::to_log_localisation_config(),
 | 
			
		||||
//     )?)
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// fn pump_test(
 | 
			
		||||
//     request: &mut Request<&mut EspHttpConnection>,
 | 
			
		||||
@@ -347,7 +309,9 @@ pub struct NightLampCommand {
 | 
			
		||||
//     }
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
struct HttpHandler;
 | 
			
		||||
struct HttpHandler {
 | 
			
		||||
    reboot_now: Arc<AtomicBool>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Handler for HttpHandler {
 | 
			
		||||
    type Error<E>
 | 
			
		||||
@@ -389,6 +353,12 @@ impl Handler for HttpHandler {
 | 
			
		||||
                    conn.write_all(include_bytes!("bundle.js")).await?;
 | 
			
		||||
                    Some(200)
 | 
			
		||||
                }
 | 
			
		||||
                "/reboot" => {
 | 
			
		||||
                    let mut board = BOARD_ACCESS.get().await.lock().await;
 | 
			
		||||
                    board.board_hal.get_esp().set_restart_to_conf(true);
 | 
			
		||||
                    self.reboot_now.store(true, Ordering::Relaxed);
 | 
			
		||||
                    Some(200)
 | 
			
		||||
                }
 | 
			
		||||
                &_ => {
 | 
			
		||||
                    let json = match path {
 | 
			
		||||
                        "/version" => Some(get_version_web(conn).await),
 | 
			
		||||
@@ -398,6 +368,7 @@ impl Handler for HttpHandler {
 | 
			
		||||
                        "/get_config" => Some(get_config(conn).await),
 | 
			
		||||
                        "/files" => Some(list_files(conn).await),
 | 
			
		||||
                        "/log_localization" => Some(get_log_localization_config(conn).await),
 | 
			
		||||
                        "/log" => Some(get_log(conn).await),
 | 
			
		||||
                        _ => None,
 | 
			
		||||
                    };
 | 
			
		||||
                    match json {
 | 
			
		||||
@@ -425,6 +396,23 @@ impl Handler for HttpHandler {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//     .fn_handler("/reboot", Method::Post, move |_| {
 | 
			
		||||
//         BOARD_ACCESS
 | 
			
		||||
//             .lock()
 | 
			
		||||
//             .unwrap()
 | 
			
		||||
//             .board_hal
 | 
			
		||||
//             .get_esp()
 | 
			
		||||
//             .set_restart_to_conf(true);
 | 
			
		||||
//         reboot_now_for_reboot.store(true, std::sync::atomic::Ordering::Relaxed);
 | 
			
		||||
//         anyhow::Ok(())
 | 
			
		||||
 | 
			
		||||
async fn get_log<T, const N: usize>(
 | 
			
		||||
    _request: &mut Connection<'_, T, N>,
 | 
			
		||||
) -> Result<Option<String>, anyhow::Error> {
 | 
			
		||||
    let output = crate::log::get_log().await;
 | 
			
		||||
    anyhow::Ok(Some(serde_json::to_string(&output)?))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn get_log_localization_config<T, const N: usize>(
 | 
			
		||||
    _request: &mut Connection<'_, T, N>,
 | 
			
		||||
) -> Result<Option<String>, anyhow::Error> {
 | 
			
		||||
@@ -512,7 +500,7 @@ pub async fn httpd(reboot_now: Arc<AtomicBool>, stack: Stack<'static>) {
 | 
			
		||||
 | 
			
		||||
    let mut server: Server<2, 512, 10> = Server::new();
 | 
			
		||||
    server
 | 
			
		||||
        .run(Some(5000), acceptor, HttpHandler)
 | 
			
		||||
        .run(Some(5000), acceptor, HttpHandler { reboot_now })
 | 
			
		||||
        .await
 | 
			
		||||
        .expect("TODO: panic message");
 | 
			
		||||
    println!("Wait for connection...");
 | 
			
		||||
@@ -790,47 +778,6 @@ pub async fn httpd(reboot_now: Arc<AtomicBool>, stack: Stack<'static>) {
 | 
			
		||||
    //server
 | 
			
		||||
}
 | 
			
		||||
//
 | 
			
		||||
// fn cors_response(
 | 
			
		||||
//     request: Request<&mut EspHttpConnection>,
 | 
			
		||||
//     status: u16,
 | 
			
		||||
//     body: &str,
 | 
			
		||||
// ) -> Result<(), anyhow::Error> {
 | 
			
		||||
//     let headers = [
 | 
			
		||||
//         ("Access-Control-Allow-Origin", "*"),
 | 
			
		||||
//         ("Access-Control-Allow-Headers", "*"),
 | 
			
		||||
//         ("Access-Control-Allow-Methods", "*"),
 | 
			
		||||
//     ];
 | 
			
		||||
//     let mut response = request.into_response(status, None, &headers)?;
 | 
			
		||||
//     response.write(body.as_bytes())?;
 | 
			
		||||
//     response.flush()?;
 | 
			
		||||
//     anyhow::Ok(())
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
// type AnyhowHandler =
 | 
			
		||||
//     fn(&mut Request<&mut EspHttpConnection>) -> Result<Option<std::string::String>, anyhow::Error>;
 | 
			
		||||
// fn handle_error_to500(
 | 
			
		||||
//     mut request: Request<&mut EspHttpConnection>,
 | 
			
		||||
//     chain: AnyhowHandler,
 | 
			
		||||
// ) -> Result<(), anyhow::Error> {
 | 
			
		||||
//     let error = chain(&mut request);
 | 
			
		||||
//     match error {
 | 
			
		||||
//         Ok(answer) => match answer {
 | 
			
		||||
//             Some(json) => {
 | 
			
		||||
//                 cors_response(request, 200, &json)?;
 | 
			
		||||
//             }
 | 
			
		||||
//             None => {
 | 
			
		||||
//                 cors_response(request, 200, "")?;
 | 
			
		||||
//             }
 | 
			
		||||
//         },
 | 
			
		||||
//         Err(err) => {
 | 
			
		||||
//             let error_text = err.to_string();
 | 
			
		||||
//             log::info!("error handling process {}", error_text);
 | 
			
		||||
//             cors_response(request, 500, &error_text)?;
 | 
			
		||||
//         }
 | 
			
		||||
//     }
 | 
			
		||||
//     anyhow::Ok(())
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
// fn read_up_to_bytes_from_request(
 | 
			
		||||
//     request: &mut Request<&mut EspHttpConnection<'_>>,
 | 
			
		||||
//     limit: Option<usize>,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user