|
|
|
@@ -5,7 +5,7 @@ use std::{
|
|
|
|
|
|
|
|
|
|
use anyhow::{bail, Result};
|
|
|
|
|
use chrono::{DateTime, Datelike, TimeDelta, Timelike, Utc};
|
|
|
|
|
use chrono_tz::{Europe::Berlin, Tz};
|
|
|
|
|
use chrono_tz::{TZ_VARIANTS, Tz};
|
|
|
|
|
|
|
|
|
|
use config::Mode;
|
|
|
|
|
use esp_idf_hal::delay::Delay;
|
|
|
|
@@ -30,8 +30,6 @@ mod tank;
|
|
|
|
|
|
|
|
|
|
use tank::*;
|
|
|
|
|
|
|
|
|
|
const TIME_ZONE: Tz = Berlin;
|
|
|
|
|
|
|
|
|
|
const MOIST_SENSOR_MAX_FREQUENCY: u32 = 5500; // 60kHz (500Hz margin)
|
|
|
|
|
const MOIST_SENSOR_MIN_FREQUENCY: u32 = 150; // this is really really dry, think like cactus levels
|
|
|
|
|
|
|
|
|
@@ -345,11 +343,14 @@ fn safe_main() -> anyhow::Result<()> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let timezone_time = cur.with_timezone(&TIME_ZONE);
|
|
|
|
|
let time_zone_string: String = config.network.timezone.to_string();
|
|
|
|
|
let time_zone = time_zone_string.parse::<Tz>().unwrap_or(Tz::UTC);
|
|
|
|
|
|
|
|
|
|
let timezone_time = cur.with_timezone(&time_zone);
|
|
|
|
|
println!(
|
|
|
|
|
"Running logic at utc {} and {} {}",
|
|
|
|
|
cur,
|
|
|
|
|
TIME_ZONE.name(),
|
|
|
|
|
time_zone.name(),
|
|
|
|
|
timezone_time
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
@@ -525,7 +526,7 @@ fn safe_main() -> anyhow::Result<()> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
update_plant_state(&mut plantstate, &mut board, &config);
|
|
|
|
|
update_plant_state(&mut plantstate, &mut board, &config, &timezone_time.timezone());
|
|
|
|
|
|
|
|
|
|
let is_day = board.is_day();
|
|
|
|
|
let state_of_charge = board.state_charge_percent().unwrap_or(0);
|
|
|
|
@@ -701,7 +702,7 @@ fn determine_state_target_moisture_for_plant(
|
|
|
|
|
Some(last_pump) => {
|
|
|
|
|
let next_pump = last_pump + duration;
|
|
|
|
|
if next_pump > cur {
|
|
|
|
|
let local_time = next_pump.with_timezone(&TIME_ZONE);
|
|
|
|
|
let local_time = next_pump.with_timezone(&cur.timezone());
|
|
|
|
|
state.next_pump = Some(local_time);
|
|
|
|
|
state.cooldown = true;
|
|
|
|
|
}
|
|
|
|
@@ -744,7 +745,7 @@ fn determine_state_timer_only_for_plant(
|
|
|
|
|
Some(last_pump) => {
|
|
|
|
|
let next_pump = last_pump + duration;
|
|
|
|
|
if next_pump > cur {
|
|
|
|
|
let europe_time = next_pump.with_timezone(&TIME_ZONE);
|
|
|
|
|
let europe_time = next_pump.with_timezone(&cur.timezone());
|
|
|
|
|
state.next_pump = Some(europe_time);
|
|
|
|
|
state.cooldown = true;
|
|
|
|
|
} else {
|
|
|
|
@@ -787,7 +788,7 @@ fn determine_state_timer_and_deadzone_for_plant(
|
|
|
|
|
Some(last_pump) => {
|
|
|
|
|
let next_pump = last_pump + duration;
|
|
|
|
|
if next_pump > cur {
|
|
|
|
|
let europe_time = next_pump.with_timezone(&TIME_ZONE);
|
|
|
|
|
let europe_time = next_pump.with_timezone(&cur.timezone());
|
|
|
|
|
state.next_pump = Some(europe_time);
|
|
|
|
|
state.cooldown = true;
|
|
|
|
|
}
|
|
|
|
@@ -864,6 +865,7 @@ fn update_plant_state(
|
|
|
|
|
plantstate: &mut [PlantState; PLANT_COUNT],
|
|
|
|
|
board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>,
|
|
|
|
|
config: &PlantControllerConfig,
|
|
|
|
|
timezone: &Tz
|
|
|
|
|
) {
|
|
|
|
|
for plant in 0..PLANT_COUNT {
|
|
|
|
|
let state = &plantstate[plant];
|
|
|
|
@@ -882,8 +884,8 @@ fn update_plant_state(
|
|
|
|
|
b_raw: &state.b_raw.unwrap_or(0).to_string(),
|
|
|
|
|
active: state.active,
|
|
|
|
|
mode: &mode,
|
|
|
|
|
last_pump: &time_to_string_utc(board.last_pump_time(plant)),
|
|
|
|
|
next_pump: &time_to_string(state.next_pump),
|
|
|
|
|
last_pump: &time_to_string_utc(board.last_pump_time(plant), timezone),
|
|
|
|
|
next_pump: &time_to_string(state.next_pump, timezone),
|
|
|
|
|
consecutive_pump_count: state.consecutive_pump_count,
|
|
|
|
|
cooldown: state.cooldown,
|
|
|
|
|
dry: state.dry,
|
|
|
|
@@ -963,15 +965,15 @@ fn main() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn time_to_string_utc(value_option: Option<DateTime<Utc>>) -> String {
|
|
|
|
|
let converted = value_option.and_then(|utc| Some(utc.with_timezone(&TIME_ZONE)));
|
|
|
|
|
return time_to_string(converted);
|
|
|
|
|
fn time_to_string_utc(value_option: Option<DateTime<Utc>>, timezone: &Tz) -> String {
|
|
|
|
|
let converted = value_option.and_then(|utc| Some(utc.with_timezone(timezone)));
|
|
|
|
|
return time_to_string(converted, timezone);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn time_to_string(value_option: Option<DateTime<Tz>>) -> String {
|
|
|
|
|
fn time_to_string(value_option: Option<DateTime<Tz>>, timezone: &Tz) -> String {
|
|
|
|
|
match value_option {
|
|
|
|
|
Some(value) => {
|
|
|
|
|
let europe_time = value.with_timezone(&TIME_ZONE);
|
|
|
|
|
let europe_time = value.with_timezone(timezone);
|
|
|
|
|
if europe_time.year() > 2023 {
|
|
|
|
|
return europe_time.to_rfc3339();
|
|
|
|
|
} else {
|
|
|
|
|