|
|
|
|
@@ -1,8 +1,4 @@
|
|
|
|
|
use std::{
|
|
|
|
|
fmt::Display,
|
|
|
|
|
sync::{atomic::AtomicBool, Arc, Mutex},
|
|
|
|
|
};
|
|
|
|
|
use std::sync::MutexGuard;
|
|
|
|
|
use crate::{config::PlantControllerConfig, webserver::webserver::httpd};
|
|
|
|
|
use anyhow::bail;
|
|
|
|
|
use chrono::{DateTime, Datelike, Timelike, Utc};
|
|
|
|
|
use chrono_tz::Tz;
|
|
|
|
|
@@ -18,19 +14,24 @@ 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::{PlantCtrlBoard, PlantHal, PLANT_COUNT};
|
|
|
|
|
use plant_hal::{EspHal, PlantHalFactory, PLANT_COUNT};
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use crate::{config::PlantControllerConfig, webserver::webserver::httpd};
|
|
|
|
|
use std::sync::MutexGuard;
|
|
|
|
|
use std::{
|
|
|
|
|
fmt::Display,
|
|
|
|
|
sync::{atomic::AtomicBool, Arc, Mutex},
|
|
|
|
|
};
|
|
|
|
|
mod config;
|
|
|
|
|
mod log;
|
|
|
|
|
pub mod plant_hal;
|
|
|
|
|
mod plant_state;
|
|
|
|
|
mod tank;
|
|
|
|
|
|
|
|
|
|
use crate::plant_hal::{BoardV3X, SpecificBoard};
|
|
|
|
|
use plant_state::PlantState;
|
|
|
|
|
use tank::*;
|
|
|
|
|
|
|
|
|
|
pub static BOARD_ACCESS: Lazy<Mutex<PlantCtrlBoard>> = Lazy::new(|| PlantHal::create().unwrap());
|
|
|
|
|
pub static BOARD_ACCESS: Lazy<Mutex<Box<dyn SpecificBoard + Send>>> = Lazy::new(|| PlantHalFactory::create_v3().unwrap());
|
|
|
|
|
pub static STAY_ALIVE: Lazy<AtomicBool> = Lazy::new(|| AtomicBool::new(false));
|
|
|
|
|
|
|
|
|
|
mod webserver {
|
|
|
|
|
@@ -150,7 +151,7 @@ fn safe_main() -> anyhow::Result<()> {
|
|
|
|
|
};
|
|
|
|
|
log(LogMessage::PartitionState, 0, 0, "", ota_state_string);
|
|
|
|
|
|
|
|
|
|
let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap();
|
|
|
|
|
let mut board: std::sync::MutexGuard<'_, BoardV3X> = BOARD_ACCESS.lock().unwrap();
|
|
|
|
|
board.general_fault(false);
|
|
|
|
|
|
|
|
|
|
log(LogMessage::MountingFilesystem, 0, 0, "", "");
|
|
|
|
|
@@ -484,7 +485,7 @@ fn safe_main() -> anyhow::Result<()> {
|
|
|
|
|
board.deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn obtain_tank_temperature(board: &mut MutexGuard<PlantCtrlBoard>) -> anyhow::Result<f32> {
|
|
|
|
|
fn obtain_tank_temperature(board: &mut MutexGuard<EspHal<BoardV3X>>) -> anyhow::Result<f32> {
|
|
|
|
|
//multisample should be moved to water_temperature_c
|
|
|
|
|
let mut attempt = 1;
|
|
|
|
|
let water_temp: Result<f32, anyhow::Error> = loop {
|
|
|
|
|
@@ -506,7 +507,7 @@ fn obtain_tank_temperature(board: &mut MutexGuard<PlantCtrlBoard>) -> anyhow::Re
|
|
|
|
|
water_temp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn publish_tank_state(board: &mut MutexGuard<PlantCtrlBoard>, config: &PlantControllerConfig, tank_state: &TankState, water_temp: &anyhow::Result<f32>) {
|
|
|
|
|
fn publish_tank_state(board: &mut MutexGuard<BoardV3X>, config: &PlantControllerConfig, tank_state: &TankState, water_temp: &anyhow::Result<f32>) {
|
|
|
|
|
match serde_json::to_string(&tank_state.as_mqtt_info(&config.tank, water_temp)) {
|
|
|
|
|
Ok(state) => {
|
|
|
|
|
let _ = board.mqtt_publish(&config, "/water", state.as_bytes());
|
|
|
|
|
@@ -517,7 +518,7 @@ fn publish_tank_state(board: &mut MutexGuard<PlantCtrlBoard>, config: &PlantCont
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn publish_plant_states(board: &mut MutexGuard<PlantCtrlBoard>, config: &PlantControllerConfig, timezone_time: &DateTime<Tz>, plantstate: &[PlantState; 8]) {
|
|
|
|
|
fn publish_plant_states(board: &mut MutexGuard<EspHal<BoardV3X>>, config: &PlantControllerConfig, timezone_time: &DateTime<Tz>, plantstate: &[PlantState; 8]) {
|
|
|
|
|
for (plant_id, (plant_state, plant_conf)) in plantstate.iter().zip(&config.plants).enumerate() {
|
|
|
|
|
match serde_json::to_string(&plant_state.to_mqtt_info(plant_conf, &timezone_time)) {
|
|
|
|
|
Ok(state) => {
|
|
|
|
|
@@ -533,7 +534,7 @@ fn publish_plant_states(board: &mut MutexGuard<PlantCtrlBoard>, config: &PlantCo
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn publish_firmware_info(version: VersionInfo, address: u32, ota_state_string: &str, board: &mut MutexGuard<PlantCtrlBoard>, config: &PlantControllerConfig, ip_address: &String, timezone_time: DateTime<Tz>) {
|
|
|
|
|
fn publish_firmware_info(version: VersionInfo, address: u32, ota_state_string: &str, board: &mut MutexGuard<EspHal<BoardV3X>>, config: &PlantControllerConfig, ip_address: &String, timezone_time: DateTime<Tz>) {
|
|
|
|
|
let _ = board.mqtt_publish(&config, "/firmware/address", ip_address.as_bytes());
|
|
|
|
|
let _ = board.mqtt_publish(&config, "/firmware/githash", version.git_hash.as_bytes());
|
|
|
|
|
let _ = board.mqtt_publish(
|
|
|
|
|
@@ -555,7 +556,7 @@ fn publish_firmware_info(version: VersionInfo, address: u32, ota_state_string: &
|
|
|
|
|
let _ = board.mqtt_publish(&config, "/state", "online".as_bytes());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn try_connect_wifi_sntp_mqtt(board: &mut MutexGuard<PlantCtrlBoard>, config: &PlantControllerConfig) -> NetworkMode{
|
|
|
|
|
fn try_connect_wifi_sntp_mqtt(board: &mut MutexGuard<EspHal<BoardV3X>>, config: &PlantControllerConfig) -> NetworkMode{
|
|
|
|
|
match board.wifi(
|
|
|
|
|
config.network.ssid.clone().unwrap(),
|
|
|
|
|
config.network.password.clone(),
|
|
|
|
|
@@ -603,7 +604,7 @@ fn try_connect_wifi_sntp_mqtt(board: &mut MutexGuard<PlantCtrlBoard>, config: &P
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//TODO clean this up? better state
|
|
|
|
|
fn pump_info(board: &mut MutexGuard<PlantCtrlBoard>, config: &PlantControllerConfig, plant_id: usize, pump_active: bool, pump_ineffective: bool) {
|
|
|
|
|
fn pump_info(board: &mut MutexGuard<EspHal>, config: &PlantControllerConfig, plant_id: usize, pump_active: bool, pump_ineffective: bool) {
|
|
|
|
|
let pump_info = PumpInfo {
|
|
|
|
|
enabled: pump_active,
|
|
|
|
|
pump_ineffective
|
|
|
|
|
@@ -622,7 +623,7 @@ fn pump_info(board: &mut MutexGuard<PlantCtrlBoard>, config: &PlantControllerCon
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn publish_battery_state(
|
|
|
|
|
board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>,
|
|
|
|
|
board: &mut std::sync::MutexGuard<'_, EspHal<'_>>,
|
|
|
|
|
config: &PlantControllerConfig,
|
|
|
|
|
) {
|
|
|
|
|
let bat = board.get_battery_state();
|
|
|
|
|
|