warnings to zero :)

This commit is contained in:
Empire 2025-02-27 20:35:44 +01:00
parent 2ae363b6d2
commit b2d5cf6416
6 changed files with 62 additions and 336 deletions

View File

@ -86,6 +86,7 @@ bincode = "1.3.3"
ringbuffer = "0.15.0"
text-template = "0.1.0"
strum_macros = "0.27.0"
esp-ota = { version = "0.2.2", features = ["log"] }
[patch.crates-io]
@ -94,7 +95,6 @@ strum_macros = "0.27.0"
#esp-idf-sys = { git = "https://github.com/empirephoenix/esp-idf-sys.git" }
#esp-idf-sys = { git = "https://github.com/esp-rs/esp-idf-sys.git" }
#esp-idf-svc = { git = "https://github.com/esp-rs/esp-idf-svc.git" }
ds323x = { git = "https://github.com/empirephoenix/ds323x-rs.git" }
#bq34z100 = { path = "../../bq34z100_rust" }
[build-dependencies]

View File

@ -1,266 +0,0 @@
use core::fmt;
use core::mem;
use core::ptr;
use esp_idf_sys::{
esp_ota_abort, esp_ota_begin, esp_ota_end, esp_ota_get_next_update_partition, esp_ota_handle_t,
esp_ota_mark_app_invalid_rollback_and_reboot, esp_ota_mark_app_valid_cancel_rollback,
esp_ota_set_boot_partition, esp_ota_write, esp_partition_t, esp_restart, ESP_ERR_FLASH_OP_FAIL,
ESP_ERR_FLASH_OP_TIMEOUT, ESP_ERR_INVALID_ARG, ESP_ERR_INVALID_SIZE, ESP_ERR_INVALID_STATE,
ESP_ERR_NOT_FOUND, ESP_ERR_NO_MEM, ESP_ERR_OTA_PARTITION_CONFLICT, ESP_ERR_OTA_ROLLBACK_FAILED,
ESP_ERR_OTA_ROLLBACK_INVALID_STATE, ESP_ERR_OTA_SELECT_INFO_INVALID,
ESP_ERR_OTA_VALIDATE_FAILED, ESP_FAIL, ESP_OK, OTA_SIZE_UNKNOWN,
};
pub type Result<T> = core::result::Result<T, Error>;
/// An error that can happen during ESP OTA operations.
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
}
impl Error {
pub(crate) fn from_kind(kind: ErrorKind) -> Self {
Self { kind }
}
/// Returns the kind of error as an enum, that can be matched on.
pub fn kind(&self) -> ErrorKind {
self.kind
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.kind.fmt(f)
}
}
impl std::error::Error for Error {}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub enum ErrorKind {
/// No suitable partition for writing OTA update to found.
NoOtaPartition,
/// Cannot allocate memory for OTA operation.
AllocFailed,
/// Rollback enabled, but the currently running application is still pending. The currently
/// running application must confirm itself before downloading and flashing a new app.
InvalidRollbackState,
/// First byte of image contains invalid app image magic byte.
InvalidMagicByte,
/// Flash write operation timed out.
FlashTimeout,
/// Flash write operation failed.
FlashFailed,
/// OTA data partition has invalid contents.
InvalidOtaPartitionData,
/// The [`OtaUpdate`] handle was finalized before any app image was written to it.
NothingWritten,
/// OTA image is invalid (either not a valid app image, or - if secure boot is enabled - signature failed to verify.)
InvalidImage,
/// If flash encryption is enabled, this result indicates an internal error writing the final encrypted bytes to flash.
WritingEncryptedFailed,
/// The rollback failed.
RollbackFailed,
/// The rollback is not possible due to flash does not have any apps.
RollbackFailedNoApps,
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use ErrorKind::*;
match self {
NoOtaPartition => "No suitable partition for writing OTA update to found",
AllocFailed => "Cannot allocate memory for OTA operation",
InvalidRollbackState => {
"Rollback enabled, but the currently running application is still pending"
}
InvalidMagicByte => "First byte of image contains invalid app image magic byte",
FlashTimeout => "Flash write operation timed out",
FlashFailed => "Flash write operation failed",
InvalidOtaPartitionData => "OTA data partition has invalid contents",
NothingWritten => "OtaUpdate was never written to",
InvalidImage => "OTA image is invalid",
WritingEncryptedFailed => "Internal error writing the final encrypted bytes to flash",
RollbackFailed => "The rollback failed",
RollbackFailedNoApps => {
"The rollback is not possible due to flash does not have any apps"
}
}
.fmt(f)
}
}
/// Represents an ongoing OTA update.
///
/// Dropping this object before calling [`finalize`](OtaUpdate::finalize) will abort the update.
#[derive(Debug)]
pub struct OtaUpdate {
partition: *const esp_partition_t,
ota_handle: esp_ota_handle_t,
}
impl OtaUpdate {
/// Starts an OTA update to the next OTA compatible partition.
///
/// Finds next partition round-robin, starting from the current running partition.
/// The entire partition is erased.
pub fn begin() -> Result<Self> {
let partition = unsafe { esp_ota_get_next_update_partition(ptr::null()) };
if partition.is_null() {
return Err(Error::from_kind(ErrorKind::NoOtaPartition));
}
let mut ota_handle = 0;
match unsafe { esp_ota_begin(partition, OTA_SIZE_UNKNOWN as usize, &mut ota_handle) } {
ESP_OK => Ok(()),
ESP_ERR_INVALID_ARG => panic!("Invalid partition or out_handle"),
ESP_ERR_NO_MEM => Err(Error::from_kind(ErrorKind::AllocFailed)),
ESP_ERR_OTA_PARTITION_CONFLICT => Err(Error::from_kind(ErrorKind::NoOtaPartition)),
ESP_ERR_NOT_FOUND => panic!("Partition argument not found in partition table"),
ESP_ERR_OTA_SELECT_INFO_INVALID => {
Err(Error::from_kind(ErrorKind::InvalidOtaPartitionData))
}
ESP_ERR_INVALID_SIZE => panic!("Partition doesnt fit in configured flash size"),
ESP_ERR_FLASH_OP_TIMEOUT => Err(Error::from_kind(ErrorKind::FlashTimeout)),
ESP_ERR_FLASH_OP_FAIL => Err(Error::from_kind(ErrorKind::FlashFailed)),
ESP_ERR_OTA_ROLLBACK_INVALID_STATE => {
Err(Error::from_kind(ErrorKind::InvalidRollbackState))
}
code => panic!("Unexpected esp_ota_begin return code: {}", code),
}?;
Ok(Self {
partition,
ota_handle,
})
}
/// Write app image data to partition.
///
/// This method can be called multiple times as data is received during the OTA operation.
/// Data is written sequentially to the partition.
///
/// The format of the app image can be read about in the main README and crate documentation.
pub fn write(&mut self, app_image_chunk: &[u8]) -> Result<()> {
let chunk_ptr = app_image_chunk.as_ptr() as *const _;
let chunk_len = app_image_chunk.len();
match unsafe { esp_ota_write(self.ota_handle, chunk_ptr, chunk_len) } {
ESP_OK => Ok(()),
ESP_ERR_INVALID_ARG => panic!("Invalid OTA handle"),
ESP_ERR_OTA_VALIDATE_FAILED => Err(Error::from_kind(ErrorKind::InvalidMagicByte)),
ESP_ERR_FLASH_OP_TIMEOUT => Err(Error::from_kind(ErrorKind::FlashTimeout)),
ESP_ERR_FLASH_OP_FAIL => Err(Error::from_kind(ErrorKind::FlashFailed)),
ESP_ERR_OTA_SELECT_INFO_INVALID => {
Err(Error::from_kind(ErrorKind::InvalidOtaPartitionData))
}
code => panic!("Unexpected esp_ota_write return code: {code}"),
}
}
/// Finish OTA update and validate newly written app image.
///
/// Unless you also call [`set_as_boot_partition`](CompletedOtaUpdate::set_as_boot_partition) the new app will not
/// start.
pub fn finalize(self) -> Result<CompletedOtaUpdate> {
match unsafe { esp_ota_end(self.ota_handle) } {
ESP_OK => Ok(()),
ESP_ERR_NOT_FOUND => panic!("Invalid OTA handle"),
ESP_ERR_INVALID_ARG => Err(Error::from_kind(ErrorKind::NothingWritten)),
ESP_ERR_OTA_VALIDATE_FAILED => Err(Error::from_kind(ErrorKind::InvalidImage)),
ESP_ERR_INVALID_STATE => Err(Error::from_kind(ErrorKind::WritingEncryptedFailed)),
code => panic!("Unexpected esp_ota_end return code: {code}"),
}?;
let partition = self.partition;
mem::forget(self);
Ok(CompletedOtaUpdate { partition })
}
/// Returns a raw pointer to the partition that the new app is/will be written to.
pub fn raw_partition(&self) -> *const esp_partition_t {
self.partition
}
}
impl Drop for OtaUpdate {
fn drop(&mut self) {
#[cfg(feature = "log")]
log::debug!("Aborting OTA update");
let abort_result_code = unsafe { esp_ota_abort(self.ota_handle) };
if abort_result_code != ESP_OK {
#[cfg(feature = "log")]
log::error!(
"Aborting the OTA update returned an unexpected code: {}",
abort_result_code
)
}
}
}
pub struct CompletedOtaUpdate {
partition: *const esp_partition_t,
}
impl CompletedOtaUpdate {
/// Sets the boot partition to the newly flashed OTA partition.
pub fn set_as_boot_partition(&mut self) -> Result<()> {
match unsafe { esp_ota_set_boot_partition(self.partition) } {
ESP_OK => Ok(()),
ESP_ERR_INVALID_ARG => panic!("Invalid partition sent to esp_ota_set_boot_partition"),
ESP_ERR_OTA_VALIDATE_FAILED => Err(Error::from_kind(ErrorKind::InvalidImage)),
ESP_ERR_NOT_FOUND => panic!("OTA data partition not found"),
ESP_ERR_FLASH_OP_TIMEOUT => Err(Error::from_kind(ErrorKind::FlashTimeout)),
ESP_ERR_FLASH_OP_FAIL => Err(Error::from_kind(ErrorKind::FlashFailed)),
code => panic!("Unexpected esp_ota_set_boot_partition code: {}", code),
}
}
/// Restarts the CPU. If [`set_as_boot_partition`](CompletedOtaUpdate::set_as_boot_partition) was
/// called and completed successfully, the CPU will boot into the newly written app.
///
/// After successful restart, CPU reset reason will be SW_CPU_RESET. Peripherals
/// (except for WiFi, BT, UART0, SPI1, and legacy timers) are not reset.
pub fn restart(self) -> ! {
unsafe { esp_restart() }
}
/// Returns a raw pointer to the partition that the new app was written to.
pub fn raw_partition(&self) -> *const esp_partition_t {
self.partition
}
}
/// Call this function to indicate that the running app is working well.
///
/// Should be called (at least) the first time a new app starts up after
/// being flashed.
pub fn mark_app_valid() {
match unsafe { esp_ota_mark_app_valid_cancel_rollback() } {
ESP_OK => (),
code => panic!(
"Unexpected esp_ota_mark_app_valid_cancel_rollback code: {}",
code
),
}
}
/// Call this function to roll back to the previously workable app with reboot.
///
/// If rolling back failed, it returns an error, otherwise this function never returns,
/// as the CPU is rebooting.
pub fn rollback_and_reboot() -> Result<core::convert::Infallible> {
match unsafe { esp_ota_mark_app_invalid_rollback_and_reboot() } {
ESP_FAIL => Err(Error::from_kind(ErrorKind::RollbackFailed)),
ESP_ERR_OTA_ROLLBACK_FAILED => Err(Error::from_kind(ErrorKind::RollbackFailedNoApps)),
code => panic!(
"Unexpected esp_ota_mark_app_invalid_rollback_and_reboot code: {}",
code
),
}
}

View File

@ -15,7 +15,7 @@ const BUFFER_SIZE:usize = 210;
#[link_section = ".rtc.data"]
static mut BUFFER:ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE> = ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE>::new();
#[allow(static_mut_refs)]
static BUFFER_ACCESS: Lazy<Mutex<&mut ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE>>> = Lazy::new(|| unsafe { Mutex::new(&mut BUFFER) });
@ -133,53 +133,53 @@ mod tests {
#[derive(IntoStaticStr, EnumIter, Serialize, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum LogMessage {
#[strum(serialize = "Reset due to {{txt_long}} requires rtc clear {{a}} and force config mode {{b}}")]
reset_reason,
ResetReason,
#[strum(serialize = "Current restart to conf mode {{a}}")]
restart_to_config,
RestartToConfig,
#[strum(serialize = "Current low voltage detection is {{a}}")]
low_voltage,
LowVoltage,
#[strum(serialize = "Error communicating with battery!! {{txt_long}}")]
battery_communication_error,
BatteryCommunicationError,
#[strum(serialize = "Tank sensor raw {{a}} percent {{b}}")]
sensor_tank_raw,
SensorTankRaw,
#[strum(serialize = "raw measure unscaled {{a}} hz {{b}}, plant {{txt_short}} sensor {{txt_long}}")]
raw_measure,
RawMeasure,
#[strum(serialize = "IP info: {{txt_long}}")]
wifi_info,
WifiInfo,
#[strum(serialize = "Plant:{{txt_short}} a:{{a}} b:{{b}}")]
test_sensor,
TestSensor,
#[strum(serialize = "Stay alive topic is {{txt_long}}")]
stay_alive,
StayAlive,
#[strum(serialize = "Connecting mqtt {{txt_short}} with id {{txt_long}}")]
mqtt_info,
MqttInfo,
#[strum(serialize = "Received stay alive with value {{txt_short}}")]
mqtt_stay_alive_rec,
MqttStayAliveRec,
#[strum(serialize = "Unknown topic recieved {{txt_long}}")]
unknown_topic,
UnknownTopic,
#[strum(serialize = "Partition state is {{txt_long}}")]
partition_state,
PartitionState,
#[strum(serialize = "Mounted Filesystem free {{a}} total {{b}} use {{txt_short}}")]
filesystem_mount,
FilesystemMount,
#[strum(serialize = "Mounting Filesystem, this will format the first time and needs quite some time!")]
mounting_filesystem,
MountingFilesystem,
#[strum(serialize = "Year inplausible, force config mode")]
year_inplausible_force_config,
YearInplausibleForceConfig,
#[strum(serialize = "Going to config mode, due to request from prior run")]
config_mode_software_override,
ConfigModeSoftwareOverride,
#[strum(serialize = "Going to config mode, due to request via config mode button")]
config_mode_button_override,
ConfigModeButtonOverride,
#[strum(serialize = "Going to normal mode")]
normal_run,
NormalRun,
#[strum(serialize = "Missing normal config, entering config mode {{txt_long}}")]
config_mode_missing_config,
ConfigModeMissingConfig,
#[strum(serialize = "startup state wifi {{a}} sntp {{b}} mqtt {{txt_short}}")]
startup_info,
StartupInfo,
#[strum(serialize = "Trying to pump for {{b}}s with pump {{a}} now dryrun: {{txt_short}}")]
pump_plant,
PumpPlant,
#[strum(serialize = "Enable main power dryrun: {{a}}")]
enable_main,
EnableMain,
#[strum(serialize = "Pumped multiple times, but plant is still to try attempt: {{a}} limit :: {{b}} plant: {{txt_short}}")]
consecutive_pump_count_limit
ConsecutivePumpCountLimit
}
impl LogMessage {

View File

@ -22,6 +22,7 @@ use esp_idf_sys::{
esp_ota_img_states_t_ESP_OTA_IMG_VALID,
vTaskDelay
};
use esp_ota::{mark_app_valid, rollback_and_reboot};
use log::log;
use once_cell::sync::Lazy;
use plant_hal::{PlantCtrlBoard, PlantHal, PLANT_COUNT};
@ -29,12 +30,10 @@ use serde::{Deserialize, Serialize};
use crate::{
config::PlantControllerConfig,
espota::{mark_app_valid, rollback_and_reboot},
webserver::webserver::httpd,
};
mod log;
mod config;
pub mod espota;
pub mod plant_hal;
@ -147,8 +146,7 @@ fn safe_main() -> anyhow::Result<()> {
bail!(
"stack too small: {} bail!",
esp_idf_sys::CONFIG_MAIN_TASK_STACK_SIZE
);
return Ok(());
)
}
println!("Startup Rust");
@ -186,16 +184,16 @@ fn safe_main() -> anyhow::Result<()> {
&format!("unknown {ota_state}")
}
};
log(log::LogMessage::partition_state, 0,0, "", ota_state_string);
log(log::LogMessage::PartitionState, 0,0, "", ota_state_string);
let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap();
board.general_fault(false);
log(log::LogMessage::mounting_filesystem, 0,0,"","");
log(log::LogMessage::MountingFilesystem, 0,0,"","");
board.mount_file_system()?;
let free_space = board.file_system_size()?;
log(log::LogMessage::filesystem_mount, free_space.free_size as u32,
log(log::LogMessage::FilesystemMount, free_space.free_size as u32,
free_space.total_size as u32, &free_space.used_size.to_string(), "");
@ -209,7 +207,6 @@ fn safe_main() -> anyhow::Result<()> {
Ok(cur) => cur,
Err(err) => {
bail!("time error {}", err);
DateTime::from_timestamp_millis(0).unwrap()
}
}
}
@ -218,13 +215,13 @@ fn safe_main() -> anyhow::Result<()> {
//check if we know the time current > 2020
if cur.year() < 2020 {
to_config = true;
log(log::LogMessage::year_inplausible_force_config, 0,0,"","");
log(log::LogMessage::YearInplausibleForceConfig, 0,0,"","");
}
println!("cur is {}", cur);
if board.get_restart_to_conf() {
log(log::LogMessage::config_mode_software_override, 0,0,"","");
log(log::LogMessage::ConfigModeSoftwareOverride, 0,0,"","");
for _i in 0..2 {
board.general_fault(true);
Delay::new_default().delay_ms(100);
@ -236,7 +233,7 @@ fn safe_main() -> anyhow::Result<()> {
board.set_restart_to_conf(false);
} else if board.is_mode_override() {
board.general_fault(true);
log(log::LogMessage::config_mode_button_override, 0,0,"","");
log(log::LogMessage::ConfigModeButtonOverride, 0,0,"","");
for _i in 0..5 {
board.general_fault(true);
Delay::new_default().delay_ms(100);
@ -258,7 +255,7 @@ fn safe_main() -> anyhow::Result<()> {
config = valid;
}
Err(err) => {
log(log::LogMessage::config_mode_missing_config, 0,0,"",&err.to_string());
log(log::LogMessage::ConfigModeMissingConfig, 0,0,"",&err.to_string());
//config upload will trigger reboot!
let _ = board.wifi_ap(Option::None);
drop(board);
@ -362,7 +359,7 @@ fn safe_main() -> anyhow::Result<()> {
publish_battery_state(&mut board, &config);
}
log(log::LogMessage::startup_info, wifi as u32, sntp as u32,&mqtt.to_string(),"");
log(log::LogMessage::StartupInfo, wifi as u32, sntp as u32,&mqtt.to_string(),"");
if to_config {
//check if client or ap mode and init wifi
@ -373,7 +370,7 @@ fn safe_main() -> anyhow::Result<()> {
let _webserver = httpd(reboot_now.clone());
wait_infinity(WaitType::ConfigButton, reboot_now.clone());
} else {
log(log::LogMessage::normal_run, 0,0,"","");
log(log::LogMessage::NormalRun, 0,0,"","");
}
@ -428,11 +425,10 @@ fn safe_main() -> anyhow::Result<()> {
let mut plantstate: [PlantState; PLANT_COUNT] = core::array::from_fn(|_| PlantState {
..Default::default()
});
let plant_to_pump = determine_next_plant(
determine_plant_state(
&mut plantstate,
timezone_time,
&tank_state,
water_frozen,
&config,
&mut board,
);
@ -440,7 +436,7 @@ fn safe_main() -> anyhow::Result<()> {
let pump_required = plantstate.iter().any(|it| it.do_water) && !water_frozen;
if pump_required {
log(log::LogMessage::enable_main, dry_run as u32,0,"","");
log(log::LogMessage::EnableMain, dry_run as u32,0,"","");
if !dry_run{
board.any_pump(true)?;
}
@ -452,11 +448,11 @@ fn safe_main() -> anyhow::Result<()> {
state.consecutive_pump_count = board.consecutive_pump_count(plant) + 1;
board.store_consecutive_pump_count(plant, state.consecutive_pump_count);
if state.consecutive_pump_count > plant_config.max_consecutive_pump_count as u32 {
log(log::LogMessage::consecutive_pump_count_limit, state.consecutive_pump_count as u32,plant_config.max_consecutive_pump_count as u32,&plant.to_string(),"");
log(log::LogMessage::ConsecutivePumpCountLimit, state.consecutive_pump_count as u32,plant_config.max_consecutive_pump_count as u32,&plant.to_string(),"");
state.not_effective = true;
board.fault(plant, true);
}
log(log::LogMessage::pump_plant, (plant + 1) as u32,plant_config.pump_time_s as u32,&dry_run.to_string(),"");
log(log::LogMessage::PumpPlant, (plant + 1) as u32,plant_config.pump_time_s as u32,&dry_run.to_string(),"");
board.store_last_pump_time(plant, cur);
board.last_pump_time(plant);
state.active = true;
@ -812,11 +808,10 @@ fn determine_state_timer_and_deadzone_for_plant(
}
}
fn determine_next_plant(
fn determine_plant_state(
plantstate: &mut [PlantState; PLANT_COUNT],
cur: DateTime<Tz>,
tank_state: &TankState,
water_frozen: bool,
config: &PlantControllerConfig,
board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>,
) {

View File

@ -1,8 +1,8 @@
use bq34z100::{Bq34Z100Error, Bq34z100g1, Bq34z100g1Driver};
use chrono_tz::Tz;
use ds323x::{DateTimeAccess, Ds323x};
use crate::log::{init, LogMessage};
use esp_ota::mark_app_valid;
use crate::log::LogMessage;
use eeprom24x::{Eeprom24x, Eeprom24xTrait, SlaveAddr};
use embedded_hal_bus::i2c::MutexDevice;
@ -23,7 +23,6 @@ use esp_idf_svc::mqtt::client::{EspMqttClient, LwtConfiguration, MqttClientConfi
use esp_idf_svc::nvs::EspDefaultNvsPartition;
use esp_idf_svc::wifi::config::{ScanConfig, ScanType};
use esp_idf_svc::wifi::EspWifi;
use log::logger;
use measurements::Temperature;
use once_cell::sync::Lazy;
use plant_ctrl2::sipo::ShiftRegister40;
@ -32,7 +31,6 @@ use esp_idf_sys::esp_restart;
use anyhow::{anyhow, Context};
use anyhow::{bail, Ok, Result};
use ringbuffer::{ConstGenericRingBuffer, RingBuffer};
use serde::{Deserialize, Serialize};
use std::ffi::CString;
use std::fs::{self, File};
@ -60,7 +58,6 @@ use esp_idf_sys::{gpio_hold_dis, gpio_hold_en, vTaskDelay, EspError};
use one_wire_bus::OneWire;
use crate::config::{self, PlantControllerConfig};
use crate::espota::mark_app_valid;
use crate::log::log;
use crate::{plant_hal, to_string, STAY_ALIVE};
@ -350,7 +347,7 @@ impl PlantCtrlBoard<'_> {
return bat;
}
pub fn list_files(&self, filename: &str) -> FileList {
pub fn list_files(&self) -> FileList {
let storage = CString::new(SPIFFS_PARTITION_NAME).unwrap();
let mut file_system_corrupt = Option::None;
@ -483,7 +480,7 @@ impl PlantCtrlBoard<'_> {
let r2 = median * 50.0 / (3.3 - median);
let mut percent = r2 / 190_f32 * 100_f32;
percent = percent.clamp(0.0, 100.0);
log(LogMessage::sensor_tank_raw, median as u32, percent as u32, "","");
log(LogMessage::SensorTankRaw, median as u32, percent as u32, "","");
return Ok(percent as u16);
}
@ -656,7 +653,7 @@ impl PlantCtrlBoard<'_> {
delay.delay_ms(10);
let unscaled = self.signal_counter.get_counter_value()? as i32;
let hz = (unscaled as f32 * factor) as u32;
log(LogMessage::raw_measure, unscaled as u32, hz as u32, &plant.to_string(), &format!("{sensor:?}"));
log(LogMessage::RawMeasure, unscaled as u32, hz as u32, &plant.to_string(), &format!("{sensor:?}"));
results[repeat] = hz;
}
results.sort();
@ -744,7 +741,7 @@ impl PlantCtrlBoard<'_> {
}
//update freertos registers ;)
let address = self.wifi_driver.sta_netif().get_ip_info()?;
log(LogMessage::wifi_info, 0 ,0,"", &format!("{address:?}"));
log(LogMessage::WifiInfo, 0 ,0,"", &format!("{address:?}"));
Ok(address)
}
@ -890,7 +887,7 @@ impl PlantCtrlBoard<'_> {
OkStd(b) => b as u32,
Err(_) => u32::MAX
};
log(LogMessage::test_sensor, aa ,bb,&plant.to_string(), "");
log(LogMessage::TestSensor, aa ,bb,&plant.to_string(), "");
}
Delay::new_default().delay_ms(10);
Ok(())
@ -939,7 +936,7 @@ impl PlantCtrlBoard<'_> {
let round_trip_ok = Arc::new(AtomicBool::new(false));
let round_trip_topic = format!("{}/internal/roundtrip", base_topic);
let stay_alive_topic = format!("{}/stay_alive", base_topic);
log(LogMessage::stay_alive, 0 ,0,"", &stay_alive_topic);
log(LogMessage::StayAlive, 0 ,0,"", &stay_alive_topic);
let mqtt_connected_event_received_copy = mqtt_connected_event_received.clone();
let mqtt_connected_event_ok_copy = mqtt_connected_event_ok.clone();
@ -947,7 +944,7 @@ impl PlantCtrlBoard<'_> {
let round_trip_topic_copy = round_trip_topic.clone();
let round_trip_ok_copy = round_trip_ok.clone();
let client_id = mqtt_client_config.client_id.unwrap_or("not set");
log(LogMessage::mqtt_info, 0 ,0,client_id, &mqtt_url);
log(LogMessage::MqttInfo, 0 ,0,client_id, &mqtt_url);
let mut client = EspMqttClient::new_cb(&mqtt_url, &mqtt_client_config, move |event| {
let payload = event.payload();
match payload {
@ -965,10 +962,10 @@ impl PlantCtrlBoard<'_> {
} else if topic.eq(stay_alive_topic_copy.as_str()) {
let value =
data.eq_ignore_ascii_case("true") || data.eq_ignore_ascii_case("1");
log(LogMessage::mqtt_stay_alive_rec, 0 ,0,&data, "");
log(LogMessage::MqttStayAliveRec, 0 ,0,&data, "");
STAY_ALIVE.store(value, std::sync::atomic::Ordering::Relaxed);
} else {
log(LogMessage::unknown_topic, 0 ,0,"", &topic);
log(LogMessage::UnknownTopic, 0 ,0,"", &topic);
}
}
}
@ -1417,7 +1414,7 @@ impl PlantHal {
init_rtc_store = true
},
};
log(LogMessage::reset_reason, init_rtc_store as u32, to_config_mode as u32, "",&format!("{reasons:?}"));
log(LogMessage::ResetReason, init_rtc_store as u32, to_config_mode as u32, "",&format!("{reasons:?}"));
if init_rtc_store {
unsafe {
LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
@ -1431,8 +1428,8 @@ impl PlantHal {
if to_config_mode{
RESTART_TO_CONF = true;
}
log(LogMessage::restart_to_config, RESTART_TO_CONF as u32, 0, "","");
log(LogMessage::low_voltage, LOW_VOLTAGE_DETECTED as u32, 0, "","");
log(LogMessage::RestartToConfig, RESTART_TO_CONF as u32, 0, "","");
log(LogMessage::LowVoltage, LOW_VOLTAGE_DETECTED as u32, 0, "","");
for i in 0..PLANT_COUNT {
println!(
"LAST_WATERING_TIMESTAMP[{}] = UTC {}",
@ -1510,7 +1507,7 @@ impl PlantHal {
},
Err(err) => {
log(LogMessage::battery_communication_error, 0 as u32, 0, "",&format!("{err:?})"));
log(LogMessage::BatteryCommunicationError, 0 as u32, 0, "",&format!("{err:?})"));
},
}
let shift_register_enable_invert = PinDriver::output(peripherals.pins.gpio21.downgrade())?;

View File

@ -5,11 +5,12 @@ use std::{
sync::{atomic::AtomicBool, Arc},
};
use crate::{
espota::OtaUpdate, get_version, log::LogMessage, map_range_moisture, plant_hal::{FileInfo, PLANT_COUNT}, BOARD_ACCESS
get_version, log::LogMessage, map_range_moisture, plant_hal::PLANT_COUNT, BOARD_ACCESS
};
use anyhow::bail;
use chrono::DateTime;
use esp_idf_sys::{esp_set_time_from_rtc, settimeofday, timeval, vTaskDelay};
use esp_idf_sys::{settimeofday, timeval, vTaskDelay};
use esp_ota::OtaUpdate;
use core::result::Result::Ok;
use embedded_svc::http::Method;
use esp_idf_hal::delay::Delay;
@ -248,11 +249,10 @@ fn wifi_scan(
}
fn list_files(
request: &mut Request<&mut EspHttpConnection>,
_request: &mut Request<&mut EspHttpConnection>,
) -> Result<Option<std::string::String>, anyhow::Error> {
let filename = query_param(request.uri(), "filename").unwrap_or_default();
let board = BOARD_ACCESS.lock().unwrap();
let result = board.list_files(&filename);
let result = board.list_files();
let file_list_json = serde_json::to_string(&result)?;
return anyhow::Ok(Some(file_list_json));
}