combine all branches

This commit is contained in:
2025-06-19 13:05:47 +02:00
parent 751f07e6fd
commit e2cce88390
9 changed files with 939 additions and 909 deletions

View File

@@ -14,7 +14,6 @@ use esp_idf_sys::{
use esp_ota::{mark_app_valid, rollback_and_reboot};
use log::{log, LogMessage};
use once_cell::sync::Lazy;
use plant_hal::{PlantHal, PLANT_COUNT};
use serde::{Deserialize, Serialize};
use std::sync::MutexGuard;
use std::{
@@ -23,23 +22,15 @@ use std::{
};
mod config;
mod log;
pub mod plant_hal;
mod hal;
mod plant_state;
mod tank;
use crate::plant_hal::{BatteryInteraction, BoardHal, BoardInteraction, HAL};
use plant_state::PlantState;
use tank::*;
const MOIST_SENSOR_MAX_FREQUENCY: u32 = 6500; // 60kHz (500Hz margin)
const MOIST_SENSOR_MIN_FREQUENCY: u32 = 150; // this is really really dry, think like cactus levels
const FROM: (f32, f32) = (
MOIST_SENSOR_MIN_FREQUENCY as f32,
MOIST_SENSOR_MAX_FREQUENCY as f32,
);
const TO: (f32, f32) = (0_f32, 100_f32);
use crate::hal::{BoardInteraction, PlantHal, HAL, PLANT_COUNT};
use crate::hal::battery::BatteryInteraction;
use crate::hal::BoardHal::Initial;
pub static BOARD_ACCESS: Lazy<Mutex<HAL>> = Lazy::new(|| PlantHal::create().unwrap());
pub static STAY_ALIVE: Lazy<AtomicBool> = Lazy::new(|| AtomicBool::new(false));
@@ -218,9 +209,9 @@ fn safe_main() -> anyhow::Result<()> {
}
match board.board_hal {
BoardHal::Initial { .. } => {
Initial { .. } => {
//config upload will trigger reboot and then switch to selected board_hal
let _ = board.wifi_ap();
let _ = board.esp.wifi_ap();
drop(board);
let reboot_now = Arc::new(AtomicBool::new(false));
let _webserver = httpd(reboot_now.clone());
@@ -240,7 +231,7 @@ fn safe_main() -> anyhow::Result<()> {
if matches!(network_mode, NetworkMode::OFFLINE) && to_config {
println!("Could not connect to station and config mode forced, switching to ap mode!");
match board.wifi_ap() {
match board.esp.wifi_ap() {
Ok(_) => {
println!("Started ap, continuing")
}
@@ -395,7 +386,6 @@ fn safe_main() -> anyhow::Result<()> {
board.any_pump(false)?; // disable main power output, eg for a central pump with valve setup or a main water valve for the risk affine
}
}
update_plant_state(&mut plantstate, &mut board, &config, &timezone_time.timezone());
let is_day = board.is_day();
let state_of_charge = board.battery_monitor.state_charge_percent().unwrap_or(0);
@@ -445,7 +435,7 @@ fn safe_main() -> anyhow::Result<()> {
match serde_json::to_string(&light_state) {
Ok(state) => {
let _ = board.mqtt_publish( "/light", state.as_bytes());
let _ = board.esp.mqtt_publish( "/light", state.as_bytes());
}
Err(err) => {
println!("Error publishing lightstate {}", err);
@@ -453,16 +443,16 @@ fn safe_main() -> anyhow::Result<()> {
};
let deep_sleep_duration_minutes: u32 = if state_of_charge < 10 {
let _ = board.mqtt_publish( "/deepsleep", "low Volt 12h".as_bytes());
let _ = board.esp.mqtt_publish( "/deepsleep", "low Volt 12h".as_bytes());
12 * 60
} else if is_day {
let _ = board.mqtt_publish( "/deepsleep", "normal 20m".as_bytes());
let _ = board.esp.mqtt_publish( "/deepsleep", "normal 20m".as_bytes());
20
} else {
let _ = board.mqtt_publish( "/deepsleep", "night 1h".as_bytes());
let _ = board.esp.mqtt_publish( "/deepsleep", "night 1h".as_bytes());
60
};
let _ = board.mqtt_publish( "/state", "sleep".as_bytes());
let _ = board.esp.mqtt_publish( "/state", "sleep".as_bytes());
//determine next event
//is light out of work trigger soon?
@@ -511,7 +501,7 @@ fn obtain_tank_temperature(board: &mut MutexGuard<HAL>) -> anyhow::Result<f32> {
fn publish_tank_state(board: &mut MutexGuard<HAL>, tank_state: &TankState, water_temp: &anyhow::Result<f32>) {
match serde_json::to_string(&tank_state.as_mqtt_info(&board.config.tank, water_temp)) {
Ok(state) => {
let _ = board.mqtt_publish("/water", state.as_bytes());
let _ = board.esp.mqtt_publish("/water", state.as_bytes());
}
Err(err) => {
println!("Error publishing tankstate {}", err);
@@ -524,9 +514,9 @@ fn publish_plant_states(board: &mut MutexGuard<HAL>, timezone_time: &DateTime<Tz
match serde_json::to_string(&plant_state.to_mqtt_info(plant_conf, &timezone_time)) {
Ok(state) => {
let plant_topic = format!("/plant{}", plant_id + 1);
let _ = board.mqtt_publish(&plant_topic, state.as_bytes());
let _ = board.esp.mqtt_publish(&plant_topic, state.as_bytes());
//reduce speed as else messages will be dropped
Delay::new_default().delay_ms(200);
board.esp.delay.delay_ms(200);
}
Err(err) => {
println!("Error publishing plant state {}", err);
@@ -536,26 +526,27 @@ fn publish_plant_states(board: &mut MutexGuard<HAL>, timezone_time: &DateTime<Tz
}
fn publish_firmware_info(version: VersionInfo, address: u32, ota_state_string: &str, board: &mut MutexGuard<HAL>, ip_address: &String, timezone_time: DateTime<Tz>) {
let _ = board.mqtt_publish("/firmware/address", ip_address.as_bytes());
let _ = board.mqtt_publish( "/firmware/githash", version.git_hash.as_bytes());
let _ = board.mqtt_publish(
let _ = board.esp.mqtt_publish("/firmware/address", ip_address.as_bytes());
let _ = board.esp.mqtt_publish( "/firmware/githash", version.git_hash.as_bytes());
let _ = board.esp.mqtt_publish(
"/firmware/buildtime",
version.build_time.as_bytes(),
);
let _ = board.mqtt_publish(
let _ = board.esp.mqtt_publish(
"/firmware/last_online",
timezone_time.to_rfc3339().as_bytes(),
);
let _ = board.mqtt_publish( "/firmware/ota_state", ota_state_string.as_bytes());
let _ = board.mqtt_publish(
let _ = board.esp.mqtt_publish( "/firmware/ota_state", ota_state_string.as_bytes());
let _ = board.esp.mqtt_publish(
"/firmware/partition_address",
format!("{:#06x}", address).as_bytes(),
);
let _ = board.mqtt_publish( "/state", "online".as_bytes());
let _ = board.esp.mqtt_publish( "/state", "online".as_bytes());
}
fn try_connect_wifi_sntp_mqtt(board: &mut MutexGuard<HAL>) -> NetworkMode{
match board.wifi() {
let nw_conf = &board.config.network.clone();
match board.esp.wifi(nw_conf) {
Ok(ip_info) => {
let sntp_mode: SntpMode = match board.sntp(1000 * 10) {
Ok(new_time) => {
@@ -570,7 +561,8 @@ fn try_connect_wifi_sntp_mqtt(board: &mut MutexGuard<HAL>) -> NetworkMode{
}
};
let mqtt_connected = if let Some(_) = board.config.network.mqtt_url {
match board.mqtt() {
let nw_config = &board.config.network.clone();
match board.esp.mqtt(nw_config) {
Ok(_) => {
println!("Mqtt connection ready");
true
@@ -606,7 +598,7 @@ fn pump_info(board: &mut MutexGuard<HAL>, plant_id: usize, pump_active: bool, pu
let pump_topic = format!("/pump{}", plant_id + 1);
match serde_json::to_string(&pump_info) {
Ok(state) => {
let _ = board.mqtt_publish(&pump_topic, state.as_bytes());
let _ = board.esp.mqtt_publish(&pump_topic, state.as_bytes());
//reduce speed as else messages will be dropped
Delay::new_default().delay_ms(200);
}
@@ -619,8 +611,8 @@ fn pump_info(board: &mut MutexGuard<HAL>, plant_id: usize, pump_active: bool, pu
fn publish_battery_state(
board: &mut MutexGuard<'_, HAL<'_>>
) {
let state = board.get_battery_state();
let _ = board.mqtt_publish( "/battery", state.as_bytes());
let state = board.battery_monitor.get_battery_state();
let _ = board.esp.mqtt_publish( "/battery", state.as_bytes());
}
fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! {