Compare commits
3 Commits
542ff578bc
...
db0f7daa4c
| Author | SHA1 | Date | |
|---|---|---|---|
| db0f7daa4c | |||
| 6809a37d9d | |||
| 0ca09ed498 |
@@ -129,6 +129,8 @@ pub struct PlantConfig {
|
|||||||
pub min_pump_current_ma: u16,
|
pub min_pump_current_ma: u16,
|
||||||
pub max_pump_current_ma: u16,
|
pub max_pump_current_ma: u16,
|
||||||
pub ignore_current_error: bool,
|
pub ignore_current_error: bool,
|
||||||
|
pub fertilizer_s: u16,
|
||||||
|
pub fertilizer_cooldown_min: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlantConfig {
|
impl Default for PlantConfig {
|
||||||
@@ -150,6 +152,8 @@ impl Default for PlantConfig {
|
|||||||
min_pump_current_ma: 10,
|
min_pump_current_ma: 10,
|
||||||
max_pump_current_ma: 3000,
|
max_pump_current_ma: 3000,
|
||||||
ignore_current_error: true,
|
ignore_current_error: true,
|
||||||
|
fertilizer_s: 0,
|
||||||
|
fertilizer_cooldown_min: 1440, // 1 day default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT];
|
|||||||
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
||||||
static mut CONSECUTIVE_WATERING_PLANT: [u32; PLANT_COUNT] = [0; PLANT_COUNT];
|
static mut CONSECUTIVE_WATERING_PLANT: [u32; PLANT_COUNT] = [0; PLANT_COUNT];
|
||||||
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
||||||
|
static mut LAST_FERTILIZER_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT];
|
||||||
|
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
||||||
static mut LOW_VOLTAGE_DETECTED: i8 = 0;
|
static mut LOW_VOLTAGE_DETECTED: i8 = 0;
|
||||||
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))]
|
||||||
static mut RESTART_TO_CONF: i8 = 0;
|
static mut RESTART_TO_CONF: i8 = 0;
|
||||||
@@ -342,6 +344,14 @@ impl Esp<'_> {
|
|||||||
LAST_WATERING_TIMESTAMP[plant] = time.timestamp_millis();
|
LAST_WATERING_TIMESTAMP[plant] = time.timestamp_millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub(crate) fn last_fertilizer_time(&self, plant: usize) -> i64 {
|
||||||
|
unsafe { LAST_FERTILIZER_TIMESTAMP[plant] }
|
||||||
|
}
|
||||||
|
pub(crate) fn store_last_fertilizer_time(&mut self, plant: usize, time: DateTime<Utc>) {
|
||||||
|
unsafe {
|
||||||
|
LAST_FERTILIZER_TIMESTAMP[plant] = time.timestamp_millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
pub(crate) fn set_low_voltage_in_cycle(&mut self) {
|
pub(crate) fn set_low_voltage_in_cycle(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
LOW_VOLTAGE_DETECTED = 1;
|
LOW_VOLTAGE_DETECTED = 1;
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ pub trait BoardInteraction<'a> {
|
|||||||
async fn get_mptt_voltage(&mut self) -> FatResult<Voltage>;
|
async fn get_mptt_voltage(&mut self) -> FatResult<Voltage>;
|
||||||
async fn get_mptt_current(&mut self) -> FatResult<Current>;
|
async fn get_mptt_current(&mut self) -> FatResult<Current>;
|
||||||
async fn can_power(&mut self, state: bool) -> FatResult<()>;
|
async fn can_power(&mut self, state: bool) -> FatResult<()>;
|
||||||
|
async fn extra2(&mut self, enable: bool) -> FatResult<()>;
|
||||||
|
|
||||||
async fn backup_config(&mut self, config: &PlantControllerConfig) -> FatResult<()>;
|
async fn backup_config(&mut self, config: &PlantControllerConfig) -> FatResult<()>;
|
||||||
async fn read_backup(&mut self) -> FatResult<PlantControllerConfig>;
|
async fn read_backup(&mut self) -> FatResult<PlantControllerConfig>;
|
||||||
|
|||||||
@@ -484,6 +484,15 @@ impl<'a> BoardInteraction<'a> for V4<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn extra2(&mut self, enable: bool) -> FatResult<()> {
|
||||||
|
if enable {
|
||||||
|
self.extra2.set_high();
|
||||||
|
} else {
|
||||||
|
self.extra2.set_low();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn backup_config(&mut self, controller_config: &PlantControllerConfig) -> FatResult<()> {
|
async fn backup_config(&mut self, controller_config: &PlantControllerConfig) -> FatResult<()> {
|
||||||
let mut buffer: [u8; 4096 - BACKUP_HEADER_MAX_SIZE] = [0; 4096 - BACKUP_HEADER_MAX_SIZE];
|
let mut buffer: [u8; 4096 - BACKUP_HEADER_MAX_SIZE] = [0; 4096 - BACKUP_HEADER_MAX_SIZE];
|
||||||
let length = postcard::to_slice(controller_config, &mut buffer)?.len();
|
let length = postcard::to_slice(controller_config, &mut buffer)?.len();
|
||||||
|
|||||||
@@ -311,6 +311,10 @@ pub enum LogMessage {
|
|||||||
PumpOpenLoopCurrent,
|
PumpOpenLoopCurrent,
|
||||||
#[strum(serialize = "Pump Open current sensor required but did not work: ${number_a}")]
|
#[strum(serialize = "Pump Open current sensor required but did not work: ${number_a}")]
|
||||||
PumpMissingSensorCurrent,
|
PumpMissingSensorCurrent,
|
||||||
|
#[strum(
|
||||||
|
serialize = "Fertilizer applied for ${number_a}s on plant ${number_b} (last application ${txt_short} minutes ago)"
|
||||||
|
)]
|
||||||
|
FertilizerApplied,
|
||||||
#[strum(serialize = "MPPT Current sensor could not be reached")]
|
#[strum(serialize = "MPPT Current sensor could not be reached")]
|
||||||
MPPTError,
|
MPPTError,
|
||||||
#[strum(
|
#[strum(
|
||||||
|
|||||||
@@ -715,6 +715,35 @@ pub async fn do_secure_pump(
|
|||||||
let mut pump_time_ms: u32 = 0;
|
let mut pump_time_ms: u32 = 0;
|
||||||
|
|
||||||
if !dry_run {
|
if !dry_run {
|
||||||
|
// Run fertilizer pump first if configured and not in cooldown
|
||||||
|
if plant_config.fertilizer_s > 0 {
|
||||||
|
let current_time = board.board_hal.get_time().await;
|
||||||
|
let last_fertilizer = board.board_hal.get_esp().last_fertilizer_time(plant_id);
|
||||||
|
let elapsed_minutes = (current_time.timestamp() - last_fertilizer) / 60;
|
||||||
|
|
||||||
|
if elapsed_minutes >= plant_config.fertilizer_cooldown_min as i64 {
|
||||||
|
info!("Starting fertilizer pump for {} seconds (last fertilizer was {} minutes ago)",
|
||||||
|
plant_config.fertilizer_s, elapsed_minutes);
|
||||||
|
log(
|
||||||
|
LogMessage::FertilizerApplied,
|
||||||
|
plant_config.fertilizer_s as u32,
|
||||||
|
(plant_id + 1) as u32,
|
||||||
|
&elapsed_minutes.to_string(),
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
board.board_hal.extra2(true).await?;
|
||||||
|
Timer::after_millis(plant_config.fertilizer_s as u64 * 1000).await;
|
||||||
|
board.board_hal.extra2(false).await?;
|
||||||
|
info!("Fertilizer pump stopped");
|
||||||
|
|
||||||
|
// Store the current time as last fertilizer time
|
||||||
|
board.board_hal.get_esp().store_last_fertilizer_time(plant_id, current_time);
|
||||||
|
} else {
|
||||||
|
let remaining_minutes = plant_config.fertilizer_cooldown_min as i64 - elapsed_minutes;
|
||||||
|
info!("Skipping fertilizer (cooldown: {} minutes remaining)", remaining_minutes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
board.board_hal.get_tank_sensor()?.reset_flow_meter();
|
board.board_hal.get_tank_sensor()?.reset_flow_meter();
|
||||||
board.board_hal.get_tank_sensor()?.start_flow_meter();
|
board.board_hal.get_tank_sensor()?.start_flow_meter();
|
||||||
board.board_hal.pump(plant_id, true).await?;
|
board.board_hal.pump(plant_id, true).await?;
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ pub struct PlantState {
|
|||||||
pub sensor_a_firmware_build_minutes: Option<u32>,
|
pub sensor_a_firmware_build_minutes: Option<u32>,
|
||||||
/// Last known firmware build timestamp for sensor B.
|
/// Last known firmware build timestamp for sensor B.
|
||||||
pub sensor_b_firmware_build_minutes: Option<u32>,
|
pub sensor_b_firmware_build_minutes: Option<u32>,
|
||||||
|
/// Last time fertilizer was applied (Unix timestamp in seconds).
|
||||||
|
pub last_fertilizer_time: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_range_moisture(
|
fn map_range_moisture(
|
||||||
@@ -162,6 +164,7 @@ impl PlantState {
|
|||||||
|
|
||||||
let previous_pump = board.board_hal.get_esp().last_pump_time(plant_id);
|
let previous_pump = board.board_hal.get_esp().last_pump_time(plant_id);
|
||||||
let consecutive_pump_count = board.board_hal.get_esp().consecutive_pump_count(plant_id);
|
let consecutive_pump_count = board.board_hal.get_esp().consecutive_pump_count(plant_id);
|
||||||
|
let last_fertilizer_time = board.board_hal.get_esp().last_fertilizer_time(plant_id);
|
||||||
let (a_builds, b_builds) = board.board_hal.get_sensor_build_minutes();
|
let (a_builds, b_builds) = board.board_hal.get_sensor_build_minutes();
|
||||||
let state = Self {
|
let state = Self {
|
||||||
sensor_a,
|
sensor_a,
|
||||||
@@ -172,6 +175,7 @@ impl PlantState {
|
|||||||
},
|
},
|
||||||
sensor_a_firmware_build_minutes: a_builds[plant_id],
|
sensor_a_firmware_build_minutes: a_builds[plant_id],
|
||||||
sensor_b_firmware_build_minutes: b_builds[plant_id],
|
sensor_b_firmware_build_minutes: b_builds[plant_id],
|
||||||
|
last_fertilizer_time,
|
||||||
};
|
};
|
||||||
if state.is_err() {
|
if state.is_err() {
|
||||||
let _ = board.board_hal.fault(plant_id, true).await;
|
let _ = board.board_hal.fault(plant_id, true).await;
|
||||||
@@ -296,6 +300,7 @@ impl PlantState {
|
|||||||
},
|
},
|
||||||
sensor_a_firmware_build_minutes: self.sensor_a_firmware_build_minutes,
|
sensor_a_firmware_build_minutes: self.sensor_a_firmware_build_minutes,
|
||||||
sensor_b_firmware_build_minutes: self.sensor_b_firmware_build_minutes,
|
sensor_b_firmware_build_minutes: self.sensor_b_firmware_build_minutes,
|
||||||
|
last_fertilizer_time: self.last_fertilizer_time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,4 +333,6 @@ pub struct PlantInfo<'a> {
|
|||||||
sensor_a_firmware_build_minutes: Option<u32>,
|
sensor_a_firmware_build_minutes: Option<u32>,
|
||||||
/// firmware build timestamp of sensor B (minutes since Unix epoch); None if unknown
|
/// firmware build timestamp of sensor B (minutes since Unix epoch); None if unknown
|
||||||
sensor_b_firmware_build_minutes: Option<u32>,
|
sensor_b_firmware_build_minutes: Option<u32>,
|
||||||
|
/// last time when fertilizer was applied
|
||||||
|
last_fertilizer_time: i64,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ use crate::webserver::get_log::{get_live_log, get_log};
|
|||||||
use crate::webserver::get_static::{serve_bundle, serve_favicon, serve_index};
|
use crate::webserver::get_static::{serve_bundle, serve_favicon, serve_index};
|
||||||
use crate::webserver::ota::ota_operations;
|
use crate::webserver::ota::ota_operations;
|
||||||
use crate::webserver::post_json::{
|
use crate::webserver::post_json::{
|
||||||
board_test, can_power, detect_sensors, night_lamp_test, pump_test, set_config, wifi_scan,
|
board_test, can_power, detect_sensors, fertilizer_pump_test, night_lamp_test, pump_test,
|
||||||
write_time,
|
set_config, wifi_scan, write_time,
|
||||||
};
|
};
|
||||||
use crate::{bail, BOARD_ACCESS};
|
use crate::{bail, BOARD_ACCESS};
|
||||||
use alloc::borrow::ToOwned;
|
use alloc::borrow::ToOwned;
|
||||||
@@ -116,6 +116,7 @@ impl Handler for HTTPRequestRouter {
|
|||||||
"/pumptest" => Some(pump_test(conn).await),
|
"/pumptest" => Some(pump_test(conn).await),
|
||||||
"/can_power" => Some(can_power(conn).await),
|
"/can_power" => Some(can_power(conn).await),
|
||||||
"/lamptest" => Some(night_lamp_test(conn).await),
|
"/lamptest" => Some(night_lamp_test(conn).await),
|
||||||
|
"/fertilizerpumptest" => Some(fertilizer_pump_test(conn).await),
|
||||||
"/boardtest" => Some(board_test().await),
|
"/boardtest" => Some(board_test().await),
|
||||||
"/detect_sensors" => Some(detect_sensors(conn).await),
|
"/detect_sensors" => Some(detect_sensors(conn).await),
|
||||||
"/reboot" => {
|
"/reboot" => {
|
||||||
|
|||||||
@@ -102,6 +102,19 @@ where
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn fertilizer_pump_test<T, const N: usize>(
|
||||||
|
_request: &mut Connection<'_, T, N>,
|
||||||
|
) -> FatResult<Option<String>>
|
||||||
|
where
|
||||||
|
T: Read + Write,
|
||||||
|
{
|
||||||
|
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||||
|
board.board_hal.extra2(true).await?;
|
||||||
|
embassy_time::Timer::after_millis(1000).await;
|
||||||
|
board.board_hal.extra2(false).await?;
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) async fn write_time<T, const N: usize>(
|
pub(crate) async fn write_time<T, const N: usize>(
|
||||||
request: &mut Connection<'_, T, N>,
|
request: &mut Connection<'_, T, N>,
|
||||||
) -> FatResult<Option<String>>
|
) -> FatResult<Option<String>>
|
||||||
|
|||||||
@@ -128,6 +128,8 @@ export interface PlantConfig {
|
|||||||
min_moisture: number,
|
min_moisture: number,
|
||||||
pump_time_s: number,
|
pump_time_s: number,
|
||||||
pump_cooldown_min: number,
|
pump_cooldown_min: number,
|
||||||
|
fertilizer_s: number,
|
||||||
|
fertilizer_cooldown_min: number,
|
||||||
pump_hour_start: number,
|
pump_hour_start: number,
|
||||||
pump_hour_end: number,
|
pump_hour_end: number,
|
||||||
pump_limit_ml: number,
|
pump_limit_ml: number,
|
||||||
|
|||||||
@@ -22,3 +22,8 @@
|
|||||||
<div class="boardkey">Pump corrosion protection (weekly)</div>
|
<div class="boardkey">Pump corrosion protection (weekly)</div>
|
||||||
<input type="checkbox" id="hardware_pump_corrosion_protection">
|
<input type="checkbox" id="hardware_pump_corrosion_protection">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="subtitle">Fertilizer Pump:</div>
|
||||||
|
<div class="flexcontainer">
|
||||||
|
<button class="subtitle" id="fertilizer_pump_test">Test Fertilizer Pump</button>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export class HardwareConfigView {
|
|||||||
private readonly hardware_board_value: HTMLSelectElement;
|
private readonly hardware_board_value: HTMLSelectElement;
|
||||||
private readonly hardware_battery_value: HTMLSelectElement;
|
private readonly hardware_battery_value: HTMLSelectElement;
|
||||||
private readonly hardware_pump_corrosion_protection: HTMLInputElement;
|
private readonly hardware_pump_corrosion_protection: HTMLInputElement;
|
||||||
|
private readonly fertilizer_pump_test: HTMLButtonElement;
|
||||||
constructor(controller:Controller){
|
constructor(controller:Controller){
|
||||||
(document.getElementById("hardwareview") as HTMLElement).innerHTML = require('./hardware.html') as string;
|
(document.getElementById("hardwareview") as HTMLElement).innerHTML = require('./hardware.html') as string;
|
||||||
|
|
||||||
@@ -33,6 +34,11 @@ export class HardwareConfigView {
|
|||||||
|
|
||||||
this.hardware_pump_corrosion_protection = document.getElementById("hardware_pump_corrosion_protection") as HTMLInputElement;
|
this.hardware_pump_corrosion_protection = document.getElementById("hardware_pump_corrosion_protection") as HTMLInputElement;
|
||||||
this.hardware_pump_corrosion_protection.onchange = controller.configChanged
|
this.hardware_pump_corrosion_protection.onchange = controller.configChanged
|
||||||
|
|
||||||
|
this.fertilizer_pump_test = document.getElementById("fertilizer_pump_test") as HTMLButtonElement;
|
||||||
|
this.fertilizer_pump_test.onclick = () => {
|
||||||
|
controller.testFertilizerPump();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setConfig(hardware: BoardHardware) {
|
setConfig(hardware: BoardHardware) {
|
||||||
|
|||||||
@@ -304,6 +304,12 @@ export class Controller {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testFertilizerPump() {
|
||||||
|
fetch(PUBLIC_URL + "/fertilizerpumptest", {
|
||||||
|
method: "POST"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
testPlant(plantId: number) {
|
testPlant(plantId: number) {
|
||||||
let counter = 0
|
let counter = 0
|
||||||
let limit = 30
|
let limit = 30
|
||||||
|
|||||||
@@ -78,6 +78,16 @@
|
|||||||
<input class="plantvalue" id="plant_${plantId}_pump_cooldown_min" type="number" min="0" max="600"
|
<input class="plantvalue" id="plant_${plantId}_pump_cooldown_min" type="number" min="0" max="600"
|
||||||
placeholder="30">
|
placeholder="30">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flexcontainer plantPumpEnabledOnly_${plantId}">
|
||||||
|
<div class="plantkey">Fertilizer (s):</div>
|
||||||
|
<input class="plantvalue" id="plant_${plantId}_fertilizer_s" type="number" min="0" max="60"
|
||||||
|
placeholder="0">
|
||||||
|
</div>
|
||||||
|
<div class="flexcontainer plantPumpEnabledOnly_${plantId}">
|
||||||
|
<div class="plantkey">Fertilizer Cooldown (m):</div>
|
||||||
|
<input class="plantvalue" id="plant_${plantId}_fertilizer_cooldown_min" type="number" min="0" max="20160"
|
||||||
|
placeholder="1440">
|
||||||
|
</div>
|
||||||
<div class="flexcontainer plantPumpEnabledOnly_${plantId}">
|
<div class="flexcontainer plantPumpEnabledOnly_${plantId}">
|
||||||
<div class="plantkey">"Pump Hour Start":</div>
|
<div class="plantkey">"Pump Hour Start":</div>
|
||||||
<select class="plantvalue" id="plant_${plantId}_pump_hour_start">10</select>
|
<select class="plantvalue" id="plant_${plantId}_pump_hour_start">10</select>
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ export class PlantView {
|
|||||||
private readonly minMoisture: HTMLInputElement;
|
private readonly minMoisture: HTMLInputElement;
|
||||||
private readonly pumpTimeS: HTMLInputElement;
|
private readonly pumpTimeS: HTMLInputElement;
|
||||||
private readonly pumpCooldown: HTMLInputElement;
|
private readonly pumpCooldown: HTMLInputElement;
|
||||||
|
private readonly fertilizerS: HTMLInputElement;
|
||||||
|
private readonly fertilizerCooldownMin: HTMLInputElement;
|
||||||
private readonly pumpHourStart: HTMLSelectElement;
|
private readonly pumpHourStart: HTMLSelectElement;
|
||||||
private readonly pumpHourEnd: HTMLSelectElement;
|
private readonly pumpHourEnd: HTMLSelectElement;
|
||||||
private readonly sensorAInstalled: HTMLInputElement;
|
private readonly sensorAInstalled: HTMLInputElement;
|
||||||
@@ -180,6 +182,16 @@ export class PlantView {
|
|||||||
controller.configChanged()
|
controller.configChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.fertilizerS = document.getElementById("plant_" + plantId + "_fertilizer_s") as HTMLInputElement;
|
||||||
|
this.fertilizerS.onchange = function () {
|
||||||
|
controller.configChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fertilizerCooldownMin = document.getElementById("plant_" + plantId + "_fertilizer_cooldown_min") as HTMLInputElement;
|
||||||
|
this.fertilizerCooldownMin.onchange = function () {
|
||||||
|
controller.configChanged()
|
||||||
|
}
|
||||||
|
|
||||||
this.pumpHourStart = document.getElementById("plant_" + plantId + "_pump_hour_start") as HTMLSelectElement;
|
this.pumpHourStart = document.getElementById("plant_" + plantId + "_pump_hour_start") as HTMLSelectElement;
|
||||||
this.pumpHourStart.onchange = function () {
|
this.pumpHourStart.onchange = function () {
|
||||||
controller.configChanged()
|
controller.configChanged()
|
||||||
@@ -328,6 +340,8 @@ export class PlantView {
|
|||||||
this.minMoisture.value = plantConfig.min_moisture?.toString() || "";
|
this.minMoisture.value = plantConfig.min_moisture?.toString() || "";
|
||||||
this.pumpTimeS.value = plantConfig.pump_time_s.toString();
|
this.pumpTimeS.value = plantConfig.pump_time_s.toString();
|
||||||
this.pumpCooldown.value = plantConfig.pump_cooldown_min.toString();
|
this.pumpCooldown.value = plantConfig.pump_cooldown_min.toString();
|
||||||
|
this.fertilizerS.value = plantConfig.fertilizer_s?.toString() || "0";
|
||||||
|
this.fertilizerCooldownMin.value = plantConfig.fertilizer_cooldown_min?.toString() || "1440";
|
||||||
this.pumpHourStart.value = plantConfig.pump_hour_start.toString();
|
this.pumpHourStart.value = plantConfig.pump_hour_start.toString();
|
||||||
this.pumpHourEnd.value = plantConfig.pump_hour_end.toString();
|
this.pumpHourEnd.value = plantConfig.pump_hour_end.toString();
|
||||||
this.sensorBInstalled.checked = plantConfig.sensor_b;
|
this.sensorBInstalled.checked = plantConfig.sensor_b;
|
||||||
@@ -355,6 +369,8 @@ export class PlantView {
|
|||||||
pump_time_s: this.pumpTimeS.valueAsNumber,
|
pump_time_s: this.pumpTimeS.valueAsNumber,
|
||||||
pump_limit_ml: 5000,
|
pump_limit_ml: 5000,
|
||||||
pump_cooldown_min: this.pumpCooldown.valueAsNumber,
|
pump_cooldown_min: this.pumpCooldown.valueAsNumber,
|
||||||
|
fertilizer_s: this.fertilizerS.valueAsNumber || 0,
|
||||||
|
fertilizer_cooldown_min: this.fertilizerCooldownMin.valueAsNumber || 1440,
|
||||||
pump_hour_start: +this.pumpHourStart.value,
|
pump_hour_start: +this.pumpHourStart.value,
|
||||||
pump_hour_end: +this.pumpHourEnd.value,
|
pump_hour_end: +this.pumpHourEnd.value,
|
||||||
sensor_b: this.sensorBInstalled.checked,
|
sensor_b: this.sensorBInstalled.checked,
|
||||||
|
|||||||
Reference in New Issue
Block a user