more async migration

This commit is contained in:
2025-09-12 16:30:35 +02:00
parent 0d495d0f56
commit 79087c9353
11 changed files with 347 additions and 308 deletions

View File

@@ -6,7 +6,10 @@ use anyhow::{anyhow, bail, Context};
use chrono::{DateTime, Utc};
use serde::Serialize;
use alloc::{vec::Vec, string::{String, ToString}};
use alloc::{
string::{String, ToString},
vec::Vec,
};
#[link_section = ".rtc.data"]
static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT];
@@ -39,35 +42,38 @@ pub struct FileSystemSizeInfo {
}
pub struct MqttClient<'a> {
mqtt_client: EspMqttClient<'a>,
//mqtt_client: EspMqttClient<'a>,
base_topic: heapless::String<64>,
}
pub struct Esp<'a> {
pub(crate) mqtt_client: Option<MqttClient<'a>>,
pub(crate) wifi_driver: EspWifi<'a>,
pub(crate) boot_button: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Input>,
pub(crate) delay: Delay,
//pub(crate) wifi_driver: EspWifi<'a>,
//pub(crate) boot_button: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Input>,
}
struct AccessPointInfo {}
impl Esp<'_> {
const SPIFFS_PARTITION_NAME: &'static str = "storage";
const CONFIG_FILE: &'static str = "/spiffs/config.cfg";
const BASE_PATH: &'static str = "/spiffs";
pub(crate) fn mode_override_pressed(&mut self) -> bool {
self.boot_button.get_level() == Level::Low
todo!();
//self.boot_button.get_level() == Level::Low
}
pub(crate) fn sntp(&mut self, max_wait_ms: u32) -> anyhow::Result<DateTime<Utc>> {
let sntp = sntp::EspSntp::new_default()?;
let mut counter = 0;
while sntp.get_sync_status() != SyncStatus::Completed {
self.delay.delay_ms(100);
counter += 100;
if counter > max_wait_ms {
bail!("Reached sntp timeout, aborting")
}
}
self.time()
pub(crate) async fn sntp(&mut self, max_wait_ms: u32) -> anyhow::Result<DateTime<Utc>> {
//let sntp = sntp::EspSntp::new_default()?;
//let mut counter = 0;
//while sntp.get_sync_status() != SyncStatus::Completed {
// self.delay.delay_ms(100);
// counter += 100;
// if counter > max_wait_ms {
// bail!("Reached sntp timeout, aborting")
// }
//}
//self.time()
todo!();
}
pub(crate) fn time(&mut self) -> anyhow::Result<DateTime<Utc>> {
let time = EspSystemTime {}.now().as_millis();
@@ -76,7 +82,8 @@ impl Esp<'_> {
.ok_or(anyhow!("could not convert timestamp"))?;
anyhow::Ok(local_time)
}
pub(crate) fn wifi_scan(&mut self) -> anyhow::Result<Vec<AccessPointInfo>> {
pub(crate) async fn wifi_scan(&mut self) -> anyhow::Result<Vec<AccessPointInfo>> {
self.wifi_driver.start_scan(
&ScanConfig {
scan_type: ScanType::Passive(Duration::from_secs(5)),
@@ -128,7 +135,7 @@ impl Esp<'_> {
}
}
pub(crate) fn wifi_ap(&mut self) -> anyhow::Result<()> {
pub(crate) async fn wifi_ap(&mut self) -> anyhow::Result<()> {
let ssid = match self.load_config() {
Ok(config) => config.network.ap_ssid.clone(),
Err(_) => heapless::String::from_str("PlantCtrl Emergency Mode").unwrap(),
@@ -146,7 +153,7 @@ impl Esp<'_> {
anyhow::Ok(())
}
pub(crate) 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
.ssid
.clone()
@@ -208,33 +215,36 @@ impl Esp<'_> {
log(LogMessage::WifiInfo, 0, 0, "", &format!("{address:?}"));
anyhow::Ok(address)
}
pub(crate) fn load_config(&mut self) -> anyhow::Result<PlantControllerConfig> {
pub(crate) async fn load_config(&mut self) -> anyhow::Result<PlantControllerConfig> {
let cfg = File::open(Self::CONFIG_FILE)?;
let config: PlantControllerConfig = serde_json::from_reader(cfg)?;
anyhow::Ok(config)
}
pub(crate) fn save_config(&mut self, config: &PlantControllerConfig) -> anyhow::Result<()> {
pub(crate) async fn save_config(
&mut self,
config: &PlantControllerConfig,
) -> anyhow::Result<()> {
let mut cfg = File::create(Self::CONFIG_FILE)?;
serde_json::to_writer(&mut cfg, &config)?;
log::info!("Wrote config config {:?}", config);
anyhow::Ok(())
}
pub(crate) fn mount_file_system(&mut self) -> anyhow::Result<()> {
pub(crate) async fn mount_file_system(&mut self) -> anyhow::Result<()> {
log(LogMessage::MountingFilesystem, 0, 0, "", "");
let base_path = String::try_from("/spiffs")?;
let storage = String::try_from(Self::SPIFFS_PARTITION_NAME)?;
let conf = todo!();
//let conf = esp_idf_sys::esp_vfs_spiffs_conf_t {
//base_path: base_path.as_ptr(),
//partition_label: storage.as_ptr(),
//max_files: 5,
//format_if_mount_failed: true,
//base_path: base_path.as_ptr(),
//partition_label: storage.as_ptr(),
//max_files: 5,
//format_if_mount_failed: true,
//};
//TODO
//unsafe {
//esp_idf_sys::esp!(esp_idf_sys::esp_vfs_spiffs_register(&conf))?;
//esp_idf_sys::esp!(esp_idf_sys::esp_vfs_spiffs_register(&conf))?;
//}
let free_space = self.file_system_size()?;
@@ -247,7 +257,7 @@ impl Esp<'_> {
);
anyhow::Ok(())
}
fn file_system_size(&mut self) -> anyhow::Result<FileSystemSizeInfo> {
async fn file_system_size(&mut self) -> anyhow::Result<FileSystemSizeInfo> {
let storage = CString::new(Self::SPIFFS_PARTITION_NAME)?;
let mut total_size = 0;
let mut used_size = 0;
@@ -265,7 +275,7 @@ impl Esp<'_> {
})
}
pub(crate) fn list_files(&self) -> FileList {
pub(crate) async fn list_files(&self) -> FileList {
let storage = CString::new(Self::SPIFFS_PARTITION_NAME).unwrap();
let mut file_system_corrupt = None;
@@ -312,7 +322,7 @@ impl Esp<'_> {
iter_error,
}
}
pub(crate) fn delete_file(&self, filename: &str) -> anyhow::Result<()> {
pub(crate) async fn delete_file(&self, filename: &str) -> anyhow::Result<()> {
let filepath = Path::new(Self::BASE_PATH).join(Path::new(filename));
match fs::remove_file(filepath) {
OkStd(_) => anyhow::Ok(()),
@@ -321,7 +331,11 @@ impl Esp<'_> {
}
}
}
pub(crate) fn get_file_handle(&self, filename: &str, write: bool) -> anyhow::Result<File> {
pub(crate) async fn get_file_handle(
&self,
filename: &str,
write: bool,
) -> anyhow::Result<File> {
let filepath = Path::new(Self::BASE_PATH).join(Path::new(filename));
anyhow::Ok(if write {
File::create(filepath)?
@@ -361,20 +375,22 @@ impl Esp<'_> {
for i in 0..PLANT_COUNT {
log::info!(
"LAST_WATERING_TIMESTAMP[{}] = UTC {}",
i, LAST_WATERING_TIMESTAMP[i]
i,
LAST_WATERING_TIMESTAMP[i]
);
}
for i in 0..PLANT_COUNT {
log::info!(
"CONSECUTIVE_WATERING_PLANT[{}] = {}",
i, CONSECUTIVE_WATERING_PLANT[i]
i,
CONSECUTIVE_WATERING_PLANT[i]
);
}
}
}
}
pub(crate) fn mqtt(&mut self, network_config: &NetworkConfig) -> anyhow::Result<()> {
pub(crate) async fn mqtt(&mut self, network_config: &NetworkConfig) -> anyhow::Result<()> {
let base_topic = network_config
.base_topic
.as_ref()
@@ -491,7 +507,9 @@ impl Esp<'_> {
log::info!("Mqtt connection callback received, progressing");
match mqtt_connected_event_ok.load(std::sync::atomic::Ordering::Relaxed) {
true => {
log::info!("Mqtt did callback as connected, testing with roundtrip now");
log::info!(
"Mqtt did callback as connected, testing with roundtrip now"
);
//subscribe to roundtrip
client.subscribe(round_trip_topic.as_str(), ExactlyOnce)?;
client.subscribe(stay_alive_topic.as_str(), ExactlyOnce)?;
@@ -534,7 +552,11 @@ impl Esp<'_> {
}
bail!("Mqtt did not fire connection callback in time");
}
pub(crate) fn mqtt_publish(&mut self, subtopic: &str, message: &[u8]) -> anyhow::Result<()> {
pub(crate) async fn mqtt_publish(
&mut self,
subtopic: &str,
message: &[u8],
) -> anyhow::Result<()> {
if self.mqtt_client.is_none() {
return anyhow::Ok(());
}