This commit is contained in:
2025-08-29 17:14:15 +02:00
parent a38d704498
commit a8e17cda3b
29 changed files with 568 additions and 15 deletions

View File

@@ -58,7 +58,7 @@ pub struct TankConfig {
pub tank_warn_percent: u8,
pub tank_empty_percent: u8,
pub tank_full_percent: u8,
pub ml_per_pulse: f32
pub ml_per_pulse: f32,
}
impl Default for TankConfig {
fn default() -> Self {
@@ -111,6 +111,7 @@ pub struct PlantControllerConfig {
pub struct PlantConfig {
pub mode: PlantWateringMode,
pub target_moisture: f32,
pub min_moisture: f32,
pub pump_time_s: u16,
pub pump_limit_ml: u16,
pub pump_cooldown_min: u16,
@@ -131,6 +132,7 @@ impl Default for PlantConfig {
Self {
mode: PlantWateringMode::OFF,
target_moisture: 40.,
min_moisture: 30.,
pump_time_s: 30,
pump_limit_ml: 5000,
pump_cooldown_min: 60,

View File

@@ -22,6 +22,7 @@ use bq34z100::Bq34z100g1Driver;
use ds323x::{DateTimeAccess, Ds323x};
use eeprom24x::{Eeprom24x, SlaveAddr, Storage};
use embedded_hal_bus::i2c::MutexDevice;
use esp_idf_hal::pcnt::PCNT1;
use esp_idf_hal::{
adc::ADC1,
delay::Delay,
@@ -47,7 +48,6 @@ use once_cell::sync::Lazy;
use std::result::Result::Ok as OkStd;
use std::sync::Mutex;
use std::time::Duration;
use esp_idf_hal::pcnt::PCNT1;
//Only support for 8 right now!
pub const PLANT_COUNT: usize = 8;

View File

@@ -132,7 +132,7 @@ pub(crate) fn create_v3(
peripherals.gpio5,
tank_power_pin,
flow_sensor_pin,
peripherals.pcnt1
peripherals.pcnt1,
)?;
let mut signal_counter = PcntDriver::new(

View File

@@ -160,7 +160,7 @@ pub(crate) fn create_v4(
peripherals.gpio5,
tank_power_pin,
flow_sensor_pin,
peripherals.pcnt1
peripherals.pcnt1,
)?;
let mut signal_counter = PcntDriver::new(

View File

@@ -6,7 +6,9 @@ use esp_idf_hal::adc::oneshot::{AdcChannelDriver, AdcDriver};
use esp_idf_hal::adc::{attenuation, Resolution, ADC1};
use esp_idf_hal::delay::Delay;
use esp_idf_hal::gpio::{AnyIOPin, AnyInputPin, Gpio5, InputOutput, PinDriver, Pull};
use esp_idf_hal::pcnt::{PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex, PCNT1};
use esp_idf_hal::pcnt::{
PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex, PCNT1,
};
use esp_idf_sys::EspError;
use one_wire_bus::OneWire;
@@ -25,7 +27,7 @@ impl<'a> TankSensor<'a> {
gpio5: Gpio5,
tank_power_pin: AnyIOPin,
flow_sensor_pin: AnyIOPin,
pcnt1: PCNT1
pcnt1: PCNT1,
) -> anyhow::Result<TankSensor<'a>> {
let mut one_wire_pin =
PinDriver::input_output_od(one_wire_pin).expect("Failed to configure pin");
@@ -73,7 +75,6 @@ impl<'a> TankSensor<'a> {
},
)?;
Ok(TankSensor {
one_wire_bus,
tank_channel,

View File

@@ -591,16 +591,31 @@ pub fn do_secure_pump(
let mut first_error = true;
let mut pump_time_s = 0;
if !dry_run {
board.board_hal.get_tank_sensor().unwrap().reset_flow_meter();
board.board_hal.get_tank_sensor().unwrap().start_flow_meter();
board
.board_hal
.get_tank_sensor()
.unwrap()
.reset_flow_meter();
board
.board_hal
.get_tank_sensor()
.unwrap()
.start_flow_meter();
board.board_hal.pump(plant_id, true)?;
Delay::new_default().delay_ms(10);
for step in 0..plant_config.pump_time_s as usize {
let flow_value = board.board_hal.get_tank_sensor().unwrap().get_flow_meter_value();
let flow_value = board
.board_hal
.get_tank_sensor()
.unwrap()
.get_flow_meter_value();
flow_collector[step] = flow_value;
let flow_value_ml = flow_value as f32 * board.board_hal.get_config().tank.ml_per_pulse;
println!("Flow value is {} ml, limit is {} ml raw sensor {}", flow_value_ml, plant_config.pump_limit_ml, flow_value);
println!(
"Flow value is {} ml, limit is {} ml raw sensor {}",
flow_value_ml, plant_config.pump_limit_ml, flow_value
);
if flow_value_ml > plant_config.pump_limit_ml as f32 {
println!("Flow value is reached, stopping");
break;
@@ -672,9 +687,16 @@ pub fn do_secure_pump(
}
}
board.board_hal.get_tank_sensor().unwrap().stop_flow_meter();
let final_flow_value = board.board_hal.get_tank_sensor().unwrap().get_flow_meter_value();
let final_flow_value = board
.board_hal
.get_tank_sensor()
.unwrap()
.get_flow_meter_value();
let flow_value_ml = final_flow_value as f32 * board.board_hal.get_config().tank.ml_per_pulse;
println!("Final flow value is {} with {} ml", final_flow_value, flow_value_ml);
println!(
"Final flow value is {} with {} ml",
final_flow_value, flow_value_ml
);
current_collector.sort();
Ok(PumpResult {
median_current_ma: current_collector[current_collector.len() / 2],

View File

@@ -78,6 +78,7 @@ impl PumpState {
pub enum PlantWateringMode {
OFF,
TargetMoisture,
MinMoisture,
TimerOnly,
}
@@ -235,6 +236,30 @@ impl PlantState {
false
}
}
PlantWateringMode::MinMoisture => {
let (moisture_percent, _) = self.plant_moisture();
if let Some(moisture_percent) = moisture_percent {
if self.pump_in_timeout(plant_conf, current_time) {
false
} else if !in_time_range(
current_time,
plant_conf.pump_hour_start,
plant_conf.pump_hour_end,
) {
false
} else if (true) {
//if not cooldown min and below max
true
} else if (true) {
//if below min disable cooldown min
true
} else {
false
}
} else {
false
}
}
PlantWateringMode::TimerOnly => !self.pump_in_timeout(plant_conf, current_time),
}
}
@@ -268,7 +293,9 @@ impl PlantState {
.map(|t| t.with_timezone(&current_time.timezone())),
next_pump: if matches!(
plant_conf.mode,
PlantWateringMode::TimerOnly | PlantWateringMode::TargetMoisture
PlantWateringMode::TimerOnly
| PlantWateringMode::TargetMoisture
| PlantWateringMode::MinMoisture
) {
self.pump.previous_pump.and_then(|last_pump| {
last_pump