splitting wip

This commit is contained in:
2025-06-19 16:56:33 +02:00
parent c429c829b4
commit fc1991523a
9 changed files with 1553 additions and 1675 deletions

View File

@@ -1,27 +1,42 @@
use crate::config::{NetworkConfig, PlantControllerConfig};
use crate::hal::{CONSECUTIVE_WATERING_PLANT, LAST_WATERING_TIMESTAMP, LOW_VOLTAGE_DETECTED, PLANT_COUNT, RESTART_TO_CONF};
use crate::hal::PLANT_COUNT;
use crate::log::{log, LogMessage};
use crate::STAY_ALIVE;
use anyhow::{anyhow, bail, Context};
use chrono::{DateTime, Utc};
use embedded_svc::ipv4::IpInfo;
use embedded_svc::wifi::{AccessPointConfiguration, AuthMethod, ClientConfiguration, Configuration};
use embedded_svc::mqtt::client::QoS::{AtLeastOnce, ExactlyOnce};
use embedded_svc::wifi::{AccessPointConfiguration, AccessPointInfo, AuthMethod, ClientConfiguration, Configuration};
use esp_idf_hal::delay::Delay;
use esp_idf_hal::gpio::PinDriver;
use esp_idf_hal::gpio::{Level, PinDriver};
use esp_idf_svc::mqtt::client::{EspMqttClient, LwtConfiguration, MqttClientConfiguration};
use esp_idf_svc::wifi::config::{ScanConfig, ScanType};
use esp_idf_svc::wifi::EspWifi;
use esp_idf_sys::{esp_spiffs_info, vTaskDelay};
use serde::Serialize;
use std::ffi::CString;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::result::Result::Ok as OkStd;
use std::str::FromStr;
use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::time::Duration;
use embedded_svc::mqtt::client::QoS::{AtLeastOnce, ExactlyOnce};
use esp_idf_hal::i2c::I2cDriver;
use serde::Serialize;
use crate::STAY_ALIVE;
use esp_idf_svc::sntp;
use esp_idf_svc::sntp::SyncStatus;
use esp_idf_svc::systime::EspSystemTime;
#[link_section = ".rtc.data"]
static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT];
#[link_section = ".rtc.data"]
static mut CONSECUTIVE_WATERING_PLANT: [u32; PLANT_COUNT] = [0; PLANT_COUNT];
#[link_section = ".rtc.data"]
static mut LOW_VOLTAGE_DETECTED: bool = false;
#[link_section = ".rtc.data"]
static mut RESTART_TO_CONF: bool = false;
#[derive(Serialize, Debug)]
pub struct FileInfo {
@@ -61,8 +76,84 @@ impl ESP<'_> {
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
}
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) fn time(&mut self) -> anyhow::Result<DateTime<Utc>> {
let time = EspSystemTime {}.now().as_millis();
let smaller_time = time as i64;
let local_time = DateTime::from_timestamp_millis(smaller_time)
.ok_or(anyhow!("could not convert timestamp"))?;
anyhow::Ok(local_time)
}
pub(crate) fn wifi_scan(&mut self) -> anyhow::Result<Vec<AccessPointInfo>> {
self.wifi_driver.start_scan(
&ScanConfig {
scan_type: ScanType::Passive(Duration::from_secs(5)),
show_hidden: false,
..Default::default()
},
true,
)?;
anyhow::Ok(self.wifi_driver.get_scan_result()?)
}
pub(crate) fn last_pump_time(&self, plant: usize) -> Option<DateTime<Utc>> {
let ts = unsafe { LAST_WATERING_TIMESTAMP }[plant];
DateTime::from_timestamp_millis(ts)
}
pub(crate) fn store_last_pump_time(&mut self, plant: usize, time: DateTime<Utc>) {
unsafe {
LAST_WATERING_TIMESTAMP[plant] = time.timestamp_millis();
}
}
pub(crate) fn set_low_voltage_in_cycle(&mut self) {
unsafe {
LOW_VOLTAGE_DETECTED = true;
}
}
pub(crate) fn clear_low_voltage_in_cycle(&mut self) {
unsafe {
LOW_VOLTAGE_DETECTED = false;
}
}
pub(crate) fn low_voltage_in_cycle(&mut self) -> bool {
unsafe {
LOW_VOLTAGE_DETECTED
}
}
pub(crate) fn store_consecutive_pump_count(&mut self, plant: usize, count: u32) {
unsafe {
CONSECUTIVE_WATERING_PLANT[plant] = count;
}
}
pub(crate) fn consecutive_pump_count(&mut self, plant: usize) -> u32 {
unsafe { CONSECUTIVE_WATERING_PLANT[plant] }
}
pub(crate) fn get_restart_to_conf(&mut self) -> bool {
unsafe { RESTART_TO_CONF }
}
pub(crate) fn set_restart_to_conf(&mut self, to_conf: bool) {
unsafe {
RESTART_TO_CONF = to_conf;
}
}
pub(crate) fn wifi_ap(&mut self) -> anyhow::Result<()> {
let ssid = match self.get_config(){
let ssid = match self.load_config(){
Ok(config) => {
config.network.ap_ssid.clone()
}
@@ -145,12 +236,12 @@ impl ESP<'_> {
log(LogMessage::WifiInfo, 0, 0, "", &format!("{address:?}"));
anyhow::Ok(address)
}
pub(crate) fn get_config(&mut self) -> anyhow::Result<PlantControllerConfig> {
pub(crate) 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 set_config(&mut self, config: &PlantControllerConfig) -> anyhow::Result<()> {
pub(crate) fn save_config(&mut self, config: &PlantControllerConfig) -> anyhow::Result<()> {
let mut cfg = File::create(Self::CONFIG_FILE)?;
serde_json::to_writer(&mut cfg, &config)?;
println!("Wrote config config {:?}", config);
@@ -227,7 +318,7 @@ impl ESP<'_> {
filename: file.file_name().into_string().unwrap(),
size: file
.metadata()
.and_then(|it| anyhow::Result::Ok(it.len()))
.and_then(|it| Ok(it.len()))
.unwrap_or_default()
as usize,
};