Merge branch 'fix/docs-and-small-improvements' into develop
This commit is contained in:
commit
ec15deab06
105
rust/src/main.rs
105
rust/src/main.rs
@ -62,36 +62,72 @@ enum WaitType {
|
||||
MqttConfig,
|
||||
}
|
||||
|
||||
impl WaitType {
|
||||
fn blink_pattern(&self) -> u32 {
|
||||
match self {
|
||||
WaitType::MissingConfig => 500_u32,
|
||||
WaitType::ConfigButton => 100_u32,
|
||||
WaitType::MqttConfig => 200_u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
|
||||
/// Light State tracking data for mqtt
|
||||
struct LightState {
|
||||
/// led is on
|
||||
active: bool,
|
||||
/// led should not be on at this time of day
|
||||
out_of_work_hour: bool,
|
||||
/// battery is low so do not use led
|
||||
battery_low: bool,
|
||||
/// the sun is up
|
||||
is_day: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
/// State of a single plant to be tracked
|
||||
///
|
||||
/// TODO can some state be replaced with functions
|
||||
/// TODO unify with PlantStateMQTT
|
||||
struct PlantState {
|
||||
/// state of humidity sensor on bank a
|
||||
a: Option<u8>,
|
||||
/// raw measured frequency value for sensor on bank a in hertz
|
||||
a_raw: Option<u32>,
|
||||
/// state of humidity sensor on bank b
|
||||
b: Option<u8>,
|
||||
/// raw measured frequency value for sensor on bank b in hertz
|
||||
b_raw: Option<u32>,
|
||||
/// how often has the logic determined that plant should have been irrigated but wasn't
|
||||
consecutive_pump_count: u32,
|
||||
after_p: Option<u8>,
|
||||
/// plant needs to be watered
|
||||
do_water: bool,
|
||||
/// is plant considerd to be dry according to settings
|
||||
dry: bool,
|
||||
/// is pump currently running
|
||||
active: bool,
|
||||
/// TODO: convert this to an Option<PumpErorr> enum for every case that can happen
|
||||
pump_error: bool,
|
||||
/// if pump count has increased higher than configured limit
|
||||
not_effective: bool,
|
||||
/// plant irrigation cooldown is active
|
||||
cooldown: bool,
|
||||
/// we want to irrigate but tank is empty
|
||||
no_water: bool,
|
||||
///TODO: combine with field a using Result
|
||||
sensor_error_a: Option<SensorError>,
|
||||
///TODO: combine with field b using Result
|
||||
sensor_error_b: Option<SensorError>,
|
||||
/// pump should not be watered at this time of day
|
||||
out_of_work_hour: bool,
|
||||
/// next time when pump should activate
|
||||
next_pump: Option<DateTime<Tz>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
/// humidity sensor error
|
||||
enum SensorError {
|
||||
Unknown,
|
||||
ShortCircuit { hz: f32, max: f32 },
|
||||
@ -99,13 +135,23 @@ enum SensorError {
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
/// State data for water tank
|
||||
///
|
||||
/// TODO unify with TankStateMQTT
|
||||
struct TankState {
|
||||
/// is there enough water in the tank
|
||||
enough_water: bool,
|
||||
/// warning that water needs to be refilled soon
|
||||
warn_level: bool,
|
||||
/// estimation how many ml are still in tank
|
||||
left_ml: u32,
|
||||
/// if there is was an issue with the water level sensor
|
||||
/// TODO merge with left_ml as Result<u32, error_type>
|
||||
sensor_error: bool,
|
||||
/// raw water sensor value
|
||||
raw: u16,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct TankStateMQTT {
|
||||
enough_water: bool,
|
||||
@ -196,23 +242,15 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
log(log::LogMessage::FilesystemMount, free_space.free_size as u32,
|
||||
free_space.total_size as u32, &free_space.used_size.to_string(), "");
|
||||
|
||||
let mut cur = board.get_rtc_time().or_else(|err| {
|
||||
println!("rtc module error: {:?}", err);
|
||||
board.general_fault(true);
|
||||
board.time()
|
||||
}).map_err(|err| -> Result<(), _>{
|
||||
bail!("time error {}", err);
|
||||
}).unwrap();
|
||||
|
||||
let mut cur = match board.get_rtc_time() {
|
||||
Ok(time) => time,
|
||||
Err(err) => {
|
||||
println!("rtc module error: {}", err);
|
||||
board.general_fault(true);
|
||||
let time = board.time();
|
||||
match time {
|
||||
Ok(cur) => cur,
|
||||
Err(err) => {
|
||||
bail!("time error {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//check if we know the time current > 2020
|
||||
//check if we know the time current > 2020 (plausibility check, this code is newer than 2020)
|
||||
if cur.year() < 2020 {
|
||||
to_config = true;
|
||||
log(log::LogMessage::YearInplausibleForceConfig, 0,0,"","");
|
||||
@ -893,18 +931,14 @@ fn update_plant_state(
|
||||
}
|
||||
|
||||
fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! {
|
||||
let delay = match wait_type {
|
||||
WaitType::MissingConfig => 500_u32,
|
||||
WaitType::ConfigButton => 100_u32,
|
||||
WaitType::MqttConfig => 200_u32,
|
||||
};
|
||||
let delay = wait_type.blink_pattern();
|
||||
|
||||
let mut led_count = 8;
|
||||
loop {
|
||||
// TODO implement actually different blink patterns instead of modulating blink duration
|
||||
if wait_type == WaitType::MissingConfig {
|
||||
led_count = led_count + 1;
|
||||
if led_count > 8 {
|
||||
led_count = 1;
|
||||
}
|
||||
led_count %= 8;
|
||||
led_count += 1;
|
||||
};
|
||||
unsafe {
|
||||
//do not trigger watchdog
|
||||
@ -914,17 +948,14 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! {
|
||||
BOARD_ACCESS.lock().unwrap().general_fault(true);
|
||||
vTaskDelay(delay);
|
||||
BOARD_ACCESS.lock().unwrap().general_fault(false);
|
||||
//TODO move locking outside of loop and drop afterwards
|
||||
for i in 0..8 {
|
||||
BOARD_ACCESS.lock().unwrap().fault(i, false);
|
||||
}
|
||||
vTaskDelay(delay);
|
||||
match wait_type {
|
||||
WaitType::MissingConfig => {}
|
||||
WaitType::ConfigButton => {}
|
||||
WaitType::MqttConfig => {
|
||||
if !STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
reboot_now.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
if wait_type == WaitType::MqttConfig {
|
||||
if !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) {
|
||||
@ -939,16 +970,18 @@ 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
|
||||
// timeout, this is just a fallback
|
||||
Ok(_) => {
|
||||
println!("Main app finished, restarting");
|
||||
BOARD_ACCESS.lock().unwrap().set_restart_to_conf(false);
|
||||
BOARD_ACCESS.lock().unwrap().deep_sleep(1);
|
||||
}
|
||||
// if safe_main exists with error, rollback to known good ota version
|
||||
Err(err) => {
|
||||
println!("Failed main {}", err);
|
||||
let rollback_successful = rollback_and_reboot();
|
||||
println!("Failed to rollback :(");
|
||||
rollback_successful.unwrap();
|
||||
let _rollback_successful = rollback_and_reboot();
|
||||
panic!("Failed to rollback :(");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user