keep ota around for alter queries to it
This commit is contained in:
parent
65f6670ca4
commit
1397f5d775
@ -83,7 +83,7 @@ esp-println = { version = "0.15.0", features = ["esp32c6", "log-04"] }
|
|||||||
# for more networking protocol support see https://crates.io/crates/edge-net
|
# for more networking protocol support see https://crates.io/crates/edge-net
|
||||||
embassy-executor = { version = "0.7.0", features = [
|
embassy-executor = { version = "0.7.0", features = [
|
||||||
"log",
|
"log",
|
||||||
"task-arena-size-262144"
|
"task-arena-size-131072"
|
||||||
] }
|
] }
|
||||||
embassy-time = { version = "0.5.0", features = ["log"] }
|
embassy-time = { version = "0.5.0", features = ["log"] }
|
||||||
esp-hal-embassy = { version = "0.9.0", features = ["esp32c6", "log-04"] }
|
esp-hal-embassy = { version = "0.9.0", features = ["esp32c6", "log-04"] }
|
||||||
|
@ -7,7 +7,7 @@ use chrono::{DateTime, Utc};
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{format, string::String, vec::Vec};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::net::{IpAddr, Ipv4Addr};
|
use core::net::{IpAddr, Ipv4Addr};
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
@ -15,15 +15,18 @@ use embassy_executor::{SendSpawner, Spawner};
|
|||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{IpListenEndpoint, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
use embassy_net::{IpListenEndpoint, Ipv4Cidr, Runner, Stack, StackResources, StaticConfigV4};
|
||||||
use embassy_time::{Duration, Instant, Timer};
|
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::gpio::Input;
|
||||||
use esp_hal::rng::Rng;
|
use esp_hal::rng::Rng;
|
||||||
|
use esp_hal::rtc_cntl::sleep::RtcSleepConfig;
|
||||||
use esp_println::{print, println};
|
use esp_println::{print, println};
|
||||||
use esp_storage::FlashStorage;
|
use esp_storage::FlashStorage;
|
||||||
use esp_wifi::wifi::{
|
use esp_wifi::wifi::{
|
||||||
AccessPointConfiguration, Configuration, Interfaces, WifiController, WifiDevice, WifiEvent,
|
AccessPointConfiguration, Configuration, Interfaces, WifiController, WifiDevice, WifiEvent,
|
||||||
WifiState,
|
WifiState,
|
||||||
};
|
};
|
||||||
|
use log::{info, warn};
|
||||||
|
|
||||||
#[link_section = ".rtc.data"]
|
#[link_section = ".rtc.data"]
|
||||||
static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT];
|
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 boot_button: Input<'a>,
|
||||||
pub(crate) wall_clock_offset: u64,
|
pub(crate) wall_clock_offset: u64,
|
||||||
|
|
||||||
pub storage: FlashStorage,
|
pub ota: Ota<'static, FlashStorage>,
|
||||||
pub slot: usize,
|
pub ota_next: &'static PartitionEntry<'static>,
|
||||||
pub next_slot: usize,
|
|
||||||
pub ota_state: OtaImageState,
|
|
||||||
pub slot_addres: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IpInfo {
|
pub struct IpInfo {
|
||||||
@ -103,6 +103,36 @@ impl Esp<'_> {
|
|||||||
const CONFIG_FILE: &'static str = "/spiffs/config.cfg";
|
const CONFIG_FILE: &'static str = "/spiffs/config.cfg";
|
||||||
const BASE_PATH: &'static str = "/spiffs";
|
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 {
|
pub(crate) fn mode_override_pressed(&mut self) -> bool {
|
||||||
self.boot_button.is_low()
|
self.boot_button.is_low()
|
||||||
}
|
}
|
||||||
@ -119,6 +149,14 @@ impl Esp<'_> {
|
|||||||
//self.time()
|
//self.time()
|
||||||
todo!();
|
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> {
|
pub(crate) fn time(&mut self) -> DateTime<Utc> {
|
||||||
let wall_clock = Instant::now().as_millis() + self.wall_clock_offset;
|
let wall_clock = Instant::now().as_millis() + self.wall_clock_offset;
|
||||||
DateTime::from_timestamp_millis(wall_clock as i64).unwrap()
|
DateTime::from_timestamp_millis(wall_clock as i64).unwrap()
|
||||||
@ -231,6 +269,36 @@ impl Esp<'_> {
|
|||||||
anyhow::Ok(stack.clone())
|
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> {
|
pub(crate) async fn wifi(&mut self, network_config: &NetworkConfig) -> anyhow::Result<IpInfo> {
|
||||||
let _ssid = network_config
|
let _ssid = network_config
|
||||||
.ssid
|
.ssid
|
||||||
|
@ -3,7 +3,7 @@ use crate::hal::rtc::{BackupHeader, RTCModuleInteraction};
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
//use crate::hal::water::TankSensor;
|
//use crate::hal::water::TankSensor;
|
||||||
use crate::alloc::boxed::Box;
|
use crate::alloc::boxed::Box;
|
||||||
use crate::hal::{deep_sleep, BoardInteraction, FreePeripherals, Sensor};
|
use crate::hal::{BoardInteraction, FreePeripherals, Sensor};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::PlantControllerConfig,
|
config::PlantControllerConfig,
|
||||||
hal::battery::{BatteryInteraction, NoBatteryMonitor},
|
hal::battery::{BatteryInteraction, NoBatteryMonitor},
|
||||||
@ -91,8 +91,8 @@ impl<'a> BoardInteraction<'a> for Initial<'a> {
|
|||||||
bail!("Please configure board revision")
|
bail!("Please configure board revision")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
|
async fn deep_sleep(&mut self, duration_in_ms: u64) -> ! {
|
||||||
deep_sleep(duration_in_ms)
|
self.esp.deep_sleep(duration_in_ms).await;
|
||||||
}
|
}
|
||||||
fn is_day(&self) -> bool {
|
fn is_day(&self) -> bool {
|
||||||
false
|
false
|
||||||
|
@ -23,36 +23,25 @@ use alloc::boxed::Box;
|
|||||||
use alloc::format;
|
use alloc::format;
|
||||||
use anyhow::{Ok, Result};
|
use anyhow::{Ok, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use core::cell::OnceCell;
|
use embassy_executor::Spawner;
|
||||||
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 battery::BQ34Z100G1;
|
//use battery::BQ34Z100G1;
|
||||||
//use bq34z100::Bq34z100g1Driver;
|
//use bq34z100::Bq34z100g1Driver;
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::once_lock::OnceLock;
|
|
||||||
use embassy_time::{Duration, Timer};
|
|
||||||
use esp_bootloader_esp_idf::partitions::{
|
use esp_bootloader_esp_idf::partitions::{
|
||||||
AppPartitionSubType, DataPartitionSubType, PartitionEntry,
|
AppPartitionSubType, DataPartitionSubType, FlashRegion, PartitionEntry,
|
||||||
};
|
};
|
||||||
use esp_hal::clock::CpuClock;
|
use esp_hal::clock::CpuClock;
|
||||||
use esp_hal::gpio::{Input, InputConfig, Io, Pull};
|
use esp_hal::gpio::{Input, InputConfig, Io, Pull};
|
||||||
use esp_hal::timer::systimer::SystemTimer;
|
use esp_println::println;
|
||||||
use esp_println::{print, println};
|
|
||||||
use measurements::{Current, Voltage};
|
use measurements::{Current, Voltage};
|
||||||
|
|
||||||
use embassy_sync::mutex::{Mutex, MutexGuard};
|
use embassy_sync::mutex::Mutex;
|
||||||
use esp_alloc as _;
|
use esp_alloc as _;
|
||||||
use esp_backtrace 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::rng::Rng;
|
||||||
use esp_hal::timer::timg::TimerGroup;
|
use esp_hal::timer::timg::TimerGroup;
|
||||||
use esp_wifi::wifi::{
|
use esp_storage::FlashStorage;
|
||||||
AccessPointConfiguration, Configuration, WifiController, WifiDevice, WifiEvent, WifiState,
|
|
||||||
};
|
|
||||||
use esp_wifi::{init, EspWifiController};
|
use esp_wifi::{init, EspWifiController};
|
||||||
|
|
||||||
//Only support for 8 right now!
|
//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);
|
//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)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Sensor {
|
pub enum Sensor {
|
||||||
A,
|
A,
|
||||||
@ -103,7 +71,7 @@ pub trait BoardInteraction<'a> {
|
|||||||
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>;
|
fn get_battery_monitor(&mut self) -> &mut Box<dyn BatteryInteraction + Send>;
|
||||||
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send>;
|
fn get_rtc_module(&mut self) -> &mut Box<dyn RTCModuleInteraction + Send>;
|
||||||
fn set_charge_indicator(&mut self, charging: bool) -> Result<()>;
|
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;
|
fn is_day(&self) -> bool;
|
||||||
//should be multsampled
|
//should be multsampled
|
||||||
@ -209,14 +177,14 @@ impl PlantHal {
|
|||||||
InputConfig::default().with_pull(Pull::None),
|
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 timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||||
let esp_wifi_ctrl = &*mk_static!(
|
let esp_wifi_ctrl = &*mk_static!(
|
||||||
EspWifiController<'static>,
|
EspWifiController<'static>,
|
||||||
init(timg0.timer0, rng.clone()).unwrap()
|
init(timg0.timer0, rng.clone()).unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
let (mut controller, interfaces) =
|
let (controller, interfaces) =
|
||||||
esp_wifi::wifi::new(&esp_wifi_ctrl, peripherals.WIFI).unwrap();
|
esp_wifi::wifi::new(&esp_wifi_ctrl, peripherals.WIFI).unwrap();
|
||||||
|
|
||||||
use esp_hal::timer::systimer::SystemTimer;
|
use esp_hal::timer::systimer::SystemTimer;
|
||||||
@ -260,62 +228,60 @@ impl PlantHal {
|
|||||||
};
|
};
|
||||||
//
|
//
|
||||||
|
|
||||||
let mut storage = esp_storage::FlashStorage::new();
|
let tablebuffer: [u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN] =
|
||||||
let mut buffer = [0u8; 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 =
|
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
|
// List all partitions - this is just FYI
|
||||||
for i in 0..pt.len() {
|
for i in 0..pt.len() {
|
||||||
println!("{:?}", pt.get_partition(i));
|
println!("{:?}", pt.get_partition(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the OTA-data partition and show the currently active partition
|
let ota_data = pt
|
||||||
let ota_part = pt
|
|
||||||
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::Data(
|
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::Data(
|
||||||
DataPartitionSubType::Ota,
|
DataPartitionSubType::Ota,
|
||||||
))?
|
))?
|
||||||
.unwrap();
|
.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 ota_data = mk_static!(PartitionEntry, ota_data);
|
||||||
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 current_app = if current.number() == 0 {
|
let ota_data = ota_data.as_embedded_storage(storage_ota);
|
||||||
pt.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
let ota_data = mk_static!(FlashRegion<FlashStorage>, ota_data);
|
||||||
AppPartitionSubType::Ota0,
|
|
||||||
))
|
let mut ota = esp_bootloader_esp_idf::ota::Ota::new(ota_data)?;
|
||||||
} else {
|
|
||||||
pt.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
let ota_partition = match ota.current_slot()? {
|
||||||
AppPartitionSubType::Ota1,
|
Slot::None => {
|
||||||
))
|
panic!("No OTA slot found");
|
||||||
};
|
}
|
||||||
let app_address = match current_app {
|
Slot::Slot0 => pt
|
||||||
Result::Ok(part) => match part {
|
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
||||||
None => 0,
|
AppPartitionSubType::Ota0,
|
||||||
Some(entry) => entry.offset(),
|
))?
|
||||||
},
|
.unwrap(),
|
||||||
Err(_) => 0,
|
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 {
|
let mut esp = Esp {
|
||||||
rng,
|
rng,
|
||||||
controller: Some(controller),
|
controller: Some(controller),
|
||||||
interfaces: Some(interfaces),
|
interfaces: Some(interfaces),
|
||||||
boot_button,
|
boot_button,
|
||||||
mqtt_client: None,
|
mqtt_client: None,
|
||||||
storage,
|
ota,
|
||||||
slot: current.number(),
|
ota_next,
|
||||||
slot_addres: app_address,
|
|
||||||
next_slot: current.next().number(),
|
|
||||||
ota_state,
|
|
||||||
wall_clock_offset: 0,
|
wall_clock_offset: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
#![feature(never_type)]
|
||||||
#![deny(
|
#![deny(
|
||||||
clippy::mem_forget,
|
clippy::mem_forget,
|
||||||
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
|
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::mutex::{Mutex, MutexGuard};
|
||||||
use embassy_sync::once_lock::OnceLock;
|
use embassy_sync::once_lock::OnceLock;
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
|
use esp_alloc::heap_allocator;
|
||||||
use esp_bootloader_esp_idf::ota::OtaImageState;
|
use esp_bootloader_esp_idf::ota::OtaImageState;
|
||||||
use esp_hal::rom::ets_delay_us;
|
use esp_hal::rom::ets_delay_us;
|
||||||
use esp_hal::system::software_reset;
|
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.get_esp().set_restart_to_conf(false);
|
||||||
board
|
board
|
||||||
.board_hal
|
.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())
|
.mqtt_publish("/firmware/buildtime", version.build_time.as_bytes())
|
||||||
.await;
|
.await;
|
||||||
let _ = esp.mqtt_publish("/firmware/last_online", timezone_time.as_bytes());
|
let _ = esp.mqtt_publish("/firmware/last_online", timezone_time.as_bytes());
|
||||||
|
let state = esp.get_ota_state();
|
||||||
let _ = esp
|
let _ = esp
|
||||||
.mqtt_publish(
|
.mqtt_publish("/firmware/ota_state", state.as_bytes())
|
||||||
"/firmware/ota_state",
|
|
||||||
state_to_string(esp.ota_state).as_bytes(),
|
|
||||||
)
|
|
||||||
.await;
|
.await;
|
||||||
let slot = esp.slot;
|
let slot = esp.get_ota_slot();
|
||||||
let _ = esp
|
let _ = esp
|
||||||
.mqtt_publish("/firmware/ota_slot", format!("slot{slot}").as_bytes())
|
.mqtt_publish("/firmware/ota_slot", format!("slot{slot}").as_bytes())
|
||||||
.await;
|
.await;
|
||||||
@ -1123,17 +1124,11 @@ async fn get_version(
|
|||||||
let hash = &env!("VERGEN_GIT_SHA")[0..8];
|
let hash = &env!("VERGEN_GIT_SHA")[0..8];
|
||||||
|
|
||||||
let board = board.board_hal.get_esp();
|
let board = board.board_hal.get_esp();
|
||||||
let ota_slot = board.slot;
|
let ota_slot = board.get_ota_slot();
|
||||||
let address = board.slot_addres;
|
|
||||||
let partition = if ota_slot == 0 {
|
|
||||||
"ota_1 @ "
|
|
||||||
} else {
|
|
||||||
"ota_0 @ "
|
|
||||||
};
|
|
||||||
VersionInfo {
|
VersionInfo {
|
||||||
git_hash: branch + "@" + hash,
|
git_hash: branch + "@" + hash,
|
||||||
build_time: env!("VERGEN_BUILD_TIMESTAMP").to_owned(),
|
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
|
//offer ota and config mode
|
||||||
|
|
||||||
use crate::{
|
use crate::{get_version, log::LogMessage, BOARD_ACCESS};
|
||||||
config::PlantControllerConfig,
|
|
||||||
do_secure_pump, get_version,
|
|
||||||
hal::PLANT_COUNT,
|
|
||||||
log::LogMessage,
|
|
||||||
plant_state::{MoistureSensorState, PlantState},
|
|
||||||
VersionInfo, BOARD_ACCESS,
|
|
||||||
};
|
|
||||||
use alloc::boxed::Box;
|
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use anyhow::{bail, Context};
|
use core::fmt::{Debug, Display};
|
||||||
use chrono::DateTime;
|
|
||||||
use core::fmt::{Debug, Display, Pointer};
|
|
||||||
use core::future::Future;
|
|
||||||
use core::net::{IpAddr, Ipv4Addr, SocketAddr};
|
use core::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
use core::result::Result::Ok;
|
use core::result::Result::Ok;
|
||||||
use core::sync::atomic::AtomicBool;
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
use edge_http::io::server::{Connection, DefaultServer, Handler, Server};
|
use edge_http::io::server::{Connection, Handler, Server};
|
||||||
use edge_http::io::Error;
|
use edge_http::io::Error;
|
||||||
use edge_http::Method;
|
use edge_http::Method;
|
||||||
use edge_nal::TcpBind;
|
use edge_nal::TcpBind;
|
||||||
use edge_nal_embassy::{Tcp, TcpAccept, TcpBuffers};
|
use edge_nal_embassy::{Tcp, TcpBuffers};
|
||||||
use embassy_executor::Spawner;
|
use embassy_net::Stack;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_time::Instant;
|
||||||
use embassy_net::{IpListenEndpoint, Stack};
|
|
||||||
use embassy_time::{Duration, Instant, Timer};
|
|
||||||
use embedded_io_async::{Read, Write};
|
use embedded_io_async::{Read, Write};
|
||||||
use esp_println::{print, println};
|
use esp_println::println;
|
||||||
use esp_wifi::wifi::WifiController;
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -148,13 +134,6 @@ pub struct NightLampCommand {
|
|||||||
// anyhow::Ok(Some(json))
|
// 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(
|
// fn backup_config(
|
||||||
// request: &mut Request<&mut EspHttpConnection>,
|
// 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(
|
// fn pump_test(
|
||||||
// request: &mut Request<&mut EspHttpConnection>,
|
// request: &mut Request<&mut EspHttpConnection>,
|
||||||
@ -347,7 +309,9 @@ pub struct NightLampCommand {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
struct HttpHandler;
|
struct HttpHandler {
|
||||||
|
reboot_now: Arc<AtomicBool>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Handler for HttpHandler {
|
impl Handler for HttpHandler {
|
||||||
type Error<E>
|
type Error<E>
|
||||||
@ -389,6 +353,12 @@ impl Handler for HttpHandler {
|
|||||||
conn.write_all(include_bytes!("bundle.js")).await?;
|
conn.write_all(include_bytes!("bundle.js")).await?;
|
||||||
Some(200)
|
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 {
|
let json = match path {
|
||||||
"/version" => Some(get_version_web(conn).await),
|
"/version" => Some(get_version_web(conn).await),
|
||||||
@ -398,6 +368,7 @@ impl Handler for HttpHandler {
|
|||||||
"/get_config" => Some(get_config(conn).await),
|
"/get_config" => Some(get_config(conn).await),
|
||||||
"/files" => Some(list_files(conn).await),
|
"/files" => Some(list_files(conn).await),
|
||||||
"/log_localization" => Some(get_log_localization_config(conn).await),
|
"/log_localization" => Some(get_log_localization_config(conn).await),
|
||||||
|
"/log" => Some(get_log(conn).await),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
match json {
|
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>(
|
async fn get_log_localization_config<T, const N: usize>(
|
||||||
_request: &mut Connection<'_, T, N>,
|
_request: &mut Connection<'_, T, N>,
|
||||||
) -> Result<Option<String>, anyhow::Error> {
|
) -> 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();
|
let mut server: Server<2, 512, 10> = Server::new();
|
||||||
server
|
server
|
||||||
.run(Some(5000), acceptor, HttpHandler)
|
.run(Some(5000), acceptor, HttpHandler { reboot_now })
|
||||||
.await
|
.await
|
||||||
.expect("TODO: panic message");
|
.expect("TODO: panic message");
|
||||||
println!("Wait for connection...");
|
println!("Wait for connection...");
|
||||||
@ -790,47 +778,6 @@ pub async fn httpd(reboot_now: Arc<AtomicBool>, stack: Stack<'static>) {
|
|||||||
//server
|
//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(
|
// fn read_up_to_bytes_from_request(
|
||||||
// request: &mut Request<&mut EspHttpConnection<'_>>,
|
// request: &mut Request<&mut EspHttpConnection<'_>>,
|
||||||
// limit: Option<usize>,
|
// limit: Option<usize>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user