Merge branch 'develop' into housekeeping and clippy and spellcheck
This commit is contained in:
169
rust/src/main.rs
169
rust/src/main.rs
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
config::BoardVersion::INITIAL,
|
||||
hal::{PlantHal, HAL, PLANT_COUNT},
|
||||
webserver::webserver::httpd,
|
||||
webserver::httpd,
|
||||
};
|
||||
use anyhow::bail;
|
||||
use chrono::{DateTime, Datelike, Timelike, Utc};
|
||||
@@ -12,7 +12,7 @@ use esp_idf_sys::{
|
||||
esp_ota_img_states_t, esp_ota_img_states_t_ESP_OTA_IMG_ABORTED,
|
||||
esp_ota_img_states_t_ESP_OTA_IMG_INVALID, esp_ota_img_states_t_ESP_OTA_IMG_NEW,
|
||||
esp_ota_img_states_t_ESP_OTA_IMG_PENDING_VERIFY, esp_ota_img_states_t_ESP_OTA_IMG_UNDEFINED,
|
||||
esp_ota_img_states_t_ESP_OTA_IMG_VALID, vTaskDelay,
|
||||
esp_ota_img_states_t_ESP_OTA_IMG_VALID,
|
||||
};
|
||||
use esp_ota::{mark_app_valid, rollback_and_reboot};
|
||||
use hal::battery::BatteryState;
|
||||
@@ -28,13 +28,12 @@ mod hal;
|
||||
mod log;
|
||||
mod plant_state;
|
||||
mod tank;
|
||||
mod webserver;
|
||||
|
||||
pub static BOARD_ACCESS: Lazy<Mutex<HAL>> = Lazy::new(|| PlantHal::create().unwrap());
|
||||
pub static STAY_ALIVE: Lazy<AtomicBool> = Lazy::new(|| AtomicBool::new(false));
|
||||
|
||||
mod webserver {
|
||||
pub mod webserver;
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
enum WaitType {
|
||||
@@ -69,7 +68,7 @@ struct LightState {
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
|
||||
///mqtt stuct to track pump activities
|
||||
///mqtt struct to track pump activities
|
||||
struct PumpInfo {
|
||||
enabled: bool,
|
||||
pump_ineffective: bool,
|
||||
@@ -175,16 +174,7 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
println!("cur is {}", cur);
|
||||
match board
|
||||
.board_hal
|
||||
.get_battery_monitor()
|
||||
.average_current_milli_ampere()
|
||||
{
|
||||
Ok(charging) => {
|
||||
let _ = board.board_hal.set_charge_indicator(charging > 20);
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
update_charge_indicator(&mut board);
|
||||
|
||||
if board.board_hal.get_esp().get_restart_to_conf() {
|
||||
log(LogMessage::ConfigModeSoftwareOverride, 0, 0, "", "");
|
||||
@@ -265,7 +255,7 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
address,
|
||||
ota_state_string,
|
||||
&mut board,
|
||||
&ip_address,
|
||||
ip_address,
|
||||
timezone_time,
|
||||
);
|
||||
publish_battery_state(&mut board);
|
||||
@@ -426,7 +416,7 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
.board_hal
|
||||
.get_battery_monitor()
|
||||
.get_battery_state()
|
||||
.unwrap_or(hal::battery::BatteryState::Unknown);
|
||||
.unwrap_or(BatteryState::Unknown);
|
||||
|
||||
let mut light_state = LightState {
|
||||
enabled: board.board_hal.get_config().night_lamp.enabled,
|
||||
@@ -556,6 +546,26 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
.deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64);
|
||||
}
|
||||
|
||||
fn update_charge_indicator(board: &mut MutexGuard<HAL>) {
|
||||
//we have mppt controller, ask it for charging current
|
||||
if let Ok(current) = board.board_hal.get_mptt_current() {
|
||||
let _ = board
|
||||
.board_hal
|
||||
.set_charge_indicator(current.as_milliamperes() > 20_f64);
|
||||
}
|
||||
//fallback to battery controller and ask it instead
|
||||
else if let Ok(charging) = board
|
||||
.board_hal
|
||||
.get_battery_monitor()
|
||||
.average_current_milli_ampere()
|
||||
{
|
||||
let _ = board.board_hal.set_charge_indicator(charging > 20);
|
||||
} else {
|
||||
//who knows
|
||||
let _ = board.board_hal.set_charge_indicator(false);
|
||||
}
|
||||
}
|
||||
|
||||
fn obtain_tank_temperature(board: &mut MutexGuard<HAL>) -> anyhow::Result<f32> {
|
||||
//multisample should be moved to water_temperature_c
|
||||
let mut attempt = 1;
|
||||
@@ -608,7 +618,7 @@ fn publish_plant_states(
|
||||
.zip(&board.board_hal.get_config().plants.clone())
|
||||
.enumerate()
|
||||
{
|
||||
match serde_json::to_string(&plant_state.to_mqtt_info(plant_conf, &timezone_time)) {
|
||||
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
|
||||
@@ -679,7 +689,7 @@ fn try_connect_wifi_sntp_mqtt(board: &mut MutexGuard<HAL>) -> NetworkMode {
|
||||
SntpMode::OFFLINE
|
||||
}
|
||||
};
|
||||
let mqtt_connected = if let Some(_) = board.board_hal.get_config().network.mqtt_url {
|
||||
let mqtt_connected = if board.board_hal.get_config().network.mqtt_url.is_some() {
|
||||
let nw_config = &board.board_hal.get_config().network.clone();
|
||||
match board.board_hal.get_esp().mqtt(nw_config) {
|
||||
Ok(_) => {
|
||||
@@ -750,76 +760,59 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! {
|
||||
let delay = wait_type.blink_pattern();
|
||||
let mut led_count = 8;
|
||||
let mut pattern_step = 0;
|
||||
|
||||
let delay_handle = Delay::new_default();
|
||||
loop {
|
||||
unsafe {
|
||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
update_charge_indicator(&mut board);
|
||||
|
||||
//we have mppt controller, ask it for charging current
|
||||
if let Ok(current) = board.board_hal.get_mptt_current() {
|
||||
let _ = board.board_hal.set_charge_indicator(current.as_milliamperes() > 20_f64);
|
||||
}
|
||||
//fallback to battery controller and ask it instead
|
||||
else if let Ok(charging) = board
|
||||
.board_hal
|
||||
.get_battery_monitor()
|
||||
.average_current_milli_ampere()
|
||||
{
|
||||
let _ = board.board_hal.set_charge_indicator(charging > 20);
|
||||
}
|
||||
else {
|
||||
//who knows
|
||||
let _ = board.board_hal.set_charge_indicator(false);
|
||||
}
|
||||
|
||||
match wait_type {
|
||||
WaitType::MissingConfig => {
|
||||
// Keep existing behavior: circular filling pattern
|
||||
led_count %= 8;
|
||||
led_count += 1;
|
||||
for i in 0..8 {
|
||||
let _ = board.board_hal.fault(i, i < led_count);
|
||||
}
|
||||
}
|
||||
WaitType::ConfigButton => {
|
||||
// Alternating pattern: 1010 1010 -> 0101 0101
|
||||
pattern_step = (pattern_step + 1) % 2;
|
||||
for i in 0..8 {
|
||||
let _ = board.board_hal.fault(i, (i + pattern_step) % 2 == 0);
|
||||
}
|
||||
}
|
||||
WaitType::MqttConfig => {
|
||||
// Moving dot pattern
|
||||
pattern_step = (pattern_step + 1) % 8;
|
||||
for i in 0..8 {
|
||||
let _ = board.board_hal.fault(i, i == pattern_step);
|
||||
}
|
||||
match wait_type {
|
||||
WaitType::MissingConfig => {
|
||||
// Keep existing behavior: circular filling pattern
|
||||
led_count %= 8;
|
||||
led_count += 1;
|
||||
for i in 0..8 {
|
||||
let _ = board.board_hal.fault(i, i < led_count);
|
||||
}
|
||||
}
|
||||
|
||||
board.board_hal.general_fault(true);
|
||||
drop(board);
|
||||
vTaskDelay(delay);
|
||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
board.board_hal.general_fault(false);
|
||||
|
||||
// Clear all LEDs
|
||||
for i in 0..8 {
|
||||
let _ = board.board_hal.fault(i, false);
|
||||
WaitType::ConfigButton => {
|
||||
// Alternating pattern: 1010 1010 -> 0101 0101
|
||||
pattern_step = (pattern_step + 1) % 2;
|
||||
for i in 0..8 {
|
||||
let _ = board.board_hal.fault(i, (i + pattern_step) % 2 == 0);
|
||||
}
|
||||
}
|
||||
drop(board);
|
||||
vTaskDelay(delay);
|
||||
WaitType::MqttConfig => {
|
||||
// Moving dot pattern
|
||||
pattern_step = (pattern_step + 1) % 8;
|
||||
for i in 0..8 {
|
||||
let _ = board.board_hal.fault(i, i == pattern_step);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if wait_type == WaitType::MqttConfig
|
||||
&& !STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed)
|
||||
{
|
||||
reboot_now.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
if reboot_now.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
//ensure clean http answer
|
||||
Delay::new_default().delay_ms(500);
|
||||
BOARD_ACCESS.lock().unwrap().board_hal.deep_sleep(1);
|
||||
}
|
||||
board.board_hal.general_fault(true);
|
||||
drop(board);
|
||||
//cannot use shared delay as that is inside the mutex here
|
||||
delay_handle.delay_ms(delay);
|
||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
board.board_hal.general_fault(false);
|
||||
|
||||
// Clear all LEDs
|
||||
for i in 0..8 {
|
||||
let _ = board.board_hal.fault(i, false);
|
||||
}
|
||||
drop(board);
|
||||
delay_handle.delay_ms(delay);
|
||||
|
||||
if wait_type == WaitType::MqttConfig
|
||||
&& !STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed)
|
||||
{
|
||||
reboot_now.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
if reboot_now.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
//ensure clean http answer
|
||||
Delay::new_default().delay_ms(500);
|
||||
BOARD_ACCESS.lock().unwrap().board_hal.deep_sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -827,7 +820,7 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! {
|
||||
fn main() {
|
||||
let result = safe_main();
|
||||
match result {
|
||||
// this should not get triggered, safe_main should not return but go into deep sleep with sensbile
|
||||
// this should not get triggered, safe_main should not return but go into deep sleep with sensible
|
||||
// timeout, this is just a fallback
|
||||
Ok(_) => {
|
||||
println!("Main app finished, restarting");
|
||||
@@ -849,13 +842,13 @@ fn main() {
|
||||
}
|
||||
|
||||
pub fn in_time_range(cur: &DateTime<Tz>, start: u8, end: u8) -> bool {
|
||||
let curhour = cur.hour() as u8;
|
||||
let current_hour = cur.hour() as u8;
|
||||
//eg 10-14
|
||||
if start < end {
|
||||
curhour > start && curhour < end
|
||||
current_hour > start && current_hour < end
|
||||
} else {
|
||||
//eg 20-05
|
||||
curhour > start || curhour < end
|
||||
current_hour > start || current_hour < end
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user