adust pcb to new 3.3 software improvements
This commit is contained in:
parent
58b63fc8ee
commit
1927449c1d
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"board": {
|
||||
"active_layer": 1,
|
||||
"active_layer": 0,
|
||||
"active_layer_preset": "",
|
||||
"auto_track_width": false,
|
||||
"hidden_netclasses": [],
|
||||
@ -68,7 +68,7 @@
|
||||
39,
|
||||
40
|
||||
],
|
||||
"visible_layers": "ffc7fff_ffffffff",
|
||||
"visible_layers": "ffc35ba_ffffffff",
|
||||
"zone_display_mode": 1
|
||||
},
|
||||
"git": {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,11 +10,7 @@ use chrono_tz::{Europe::Berlin, Tz};
|
||||
use config::Mode;
|
||||
use esp_idf_hal::delay::Delay;
|
||||
use esp_idf_sys::{
|
||||
esp_deep_sleep, esp_ota_get_app_partition_count, esp_ota_get_running_partition,
|
||||
esp_ota_get_state_partition, 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, esp_restart, vTaskDelay, CONFIG_FREERTOS_HZ,
|
||||
esp_deep_sleep, esp_ota_get_app_partition_count, esp_ota_get_running_partition, esp_ota_get_state_partition, 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, esp_restart, esp_sleep_enable_ext1_wakeup, esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW, vTaskDelay, CONFIG_FREERTOS_HZ
|
||||
};
|
||||
use log::error;
|
||||
use once_cell::sync::Lazy;
|
||||
@ -126,16 +122,6 @@ struct PlantStateMQTT<'a> {
|
||||
last_pump: &'a str,
|
||||
next_pump: &'a str,
|
||||
}
|
||||
#[derive(Serialize)]
|
||||
struct BatteryState<'a> {
|
||||
voltage_milli_volt: &'a str,
|
||||
current_milli_ampere: &'a str,
|
||||
cycle_count: &'a str,
|
||||
design_milli_ampere: &'a str,
|
||||
remaining_milli_ampere: &'a str,
|
||||
state_of_charge: &'a str,
|
||||
state_of_health: &'a str,
|
||||
}
|
||||
|
||||
fn safe_main() -> anyhow::Result<()> {
|
||||
// It is necessary to call this function once. Otherwise some patches to the runtime
|
||||
@ -155,11 +141,12 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
|
||||
log::info!("Startup Rust");
|
||||
|
||||
let git_hash = env!("VERGEN_GIT_DESCRIBE");
|
||||
let build_timestamp = env!("VERGEN_BUILD_TIMESTAMP");
|
||||
let mut to_config = false;
|
||||
|
||||
let version = get_version();
|
||||
println!(
|
||||
"Version useing git has {} build on {}",
|
||||
git_hash, build_timestamp
|
||||
version.git_hash, version.build_time
|
||||
);
|
||||
|
||||
let count = unsafe { esp_ota_get_app_partition_count() };
|
||||
@ -192,6 +179,7 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
println!("Board hal init");
|
||||
let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap();
|
||||
board.general_fault(false);
|
||||
|
||||
println!("Mounting filesystem");
|
||||
board.mount_file_system()?;
|
||||
let free_space = board.file_system_size()?;
|
||||
@ -232,8 +220,18 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
|
||||
println!("cur is {}", cur);
|
||||
|
||||
let mut to_config = false;
|
||||
if board.is_mode_override() {
|
||||
if board.get_restart_to_conf() {
|
||||
println!("config mode software override");
|
||||
for _i in 0..2 {
|
||||
board.general_fault(true);
|
||||
Delay::new_default().delay_ms(100);
|
||||
board.general_fault(false);
|
||||
Delay::new_default().delay_ms(100);
|
||||
}
|
||||
to_config = true;
|
||||
board.general_fault(true);
|
||||
board.set_restart_to_conf(false);
|
||||
} else if board.is_mode_override() {
|
||||
board.general_fault(true);
|
||||
println!("config mode override is pressed, waiting 5s");
|
||||
for _i in 0..5 {
|
||||
@ -244,12 +242,16 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
if board.is_mode_override() {
|
||||
board.general_fault(true);
|
||||
to_config = true;
|
||||
} else {
|
||||
board.general_fault(false);
|
||||
}
|
||||
} else {
|
||||
println!("No config override start detected");
|
||||
}
|
||||
|
||||
|
||||
let config: PlantControllerConfig;
|
||||
match board.get_config() {
|
||||
Ok(valid) => {
|
||||
@ -293,7 +295,7 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
board.general_fault(true);
|
||||
}
|
||||
}
|
||||
if (config.network.mqtt_url.is_some()) {
|
||||
if config.network.mqtt_url.is_some() {
|
||||
match board.mqtt(&config) {
|
||||
Ok(_) => {
|
||||
println!("Mqtt connection ready");
|
||||
@ -338,8 +340,12 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
if mqtt {
|
||||
let ip_string = ip_address.unwrap_or("N/A".to_owned());
|
||||
let _ = board.mqtt_publish(&config, "/firmware/address", ip_string.as_bytes());
|
||||
let _ = board.mqtt_publish(&config, "/firmware/githash", git_hash.as_bytes());
|
||||
let _ = board.mqtt_publish(&config, "/firmware/buildtime", build_timestamp.as_bytes());
|
||||
let _ = board.mqtt_publish(&config, "/firmware/githash", version.git_hash.as_bytes());
|
||||
let _ = board.mqtt_publish(
|
||||
&config,
|
||||
"/firmware/buildtime",
|
||||
version.build_time.as_bytes(),
|
||||
);
|
||||
let _ = board.mqtt_publish(
|
||||
&config,
|
||||
"/firmware/last_online",
|
||||
@ -425,6 +431,7 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
);
|
||||
|
||||
let stay_alive_mqtt = STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
let stay_alive = stay_alive_mqtt;
|
||||
println!("Check stay alive, current state is {}", stay_alive);
|
||||
|
||||
@ -550,23 +557,17 @@ fn safe_main() -> anyhow::Result<()> {
|
||||
let _webserver = httpd(reboot_now.clone());
|
||||
wait_infinity(WaitType::MqttConfig, reboot_now.clone());
|
||||
}
|
||||
|
||||
unsafe { esp_deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64) };
|
||||
unsafe {
|
||||
esp_sleep_enable_ext1_wakeup(0b10u64, esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW);
|
||||
esp_deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64)
|
||||
};
|
||||
}
|
||||
|
||||
fn publish_battery_state(
|
||||
board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>,
|
||||
config: &PlantControllerConfig,
|
||||
) {
|
||||
let bat = BatteryState {
|
||||
voltage_milli_volt: &to_string(&board.voltage_milli_volt()),
|
||||
current_milli_ampere: &to_string(&board.average_current_milli_ampere()),
|
||||
cycle_count: &to_string(&board.cycle_count()),
|
||||
design_milli_ampere: &to_string(&board.design_milli_ampere_hour()),
|
||||
remaining_milli_ampere: &to_string(&board.remaining_milli_ampere_hour()),
|
||||
state_of_charge: &to_string(&board.state_charge_percent()),
|
||||
state_of_health: &to_string(&board.state_health_percent()),
|
||||
};
|
||||
let bat = board.get_battery_state();
|
||||
match serde_json::to_string(&bat) {
|
||||
Ok(state) => {
|
||||
let _ = board.mqtt_publish(&config, "/battery", state.as_bytes());
|
||||
@ -1005,7 +1006,7 @@ fn sensor_to_string(value: &Option<u8>, error: &Option<SensorError>, enabled: bo
|
||||
};
|
||||
}
|
||||
|
||||
fn to_string<T: Display>(value: &Result<T>) -> String {
|
||||
fn to_string<T: Display>(value: Result<T>) -> String {
|
||||
return match value {
|
||||
Ok(v) => v.to_string(),
|
||||
Err(err) => {
|
||||
@ -1054,3 +1055,19 @@ fn in_time_range(cur: &DateTime<Tz>, start: u8, end: u8) -> bool {
|
||||
return curhour > start || curhour < end;
|
||||
}
|
||||
}
|
||||
|
||||
fn get_version() -> VersionInfo {
|
||||
let branch = env!("VERGEN_GIT_BRANCH").to_owned();
|
||||
let hash = &env!("VERGEN_GIT_SHA")[0..8];
|
||||
|
||||
return VersionInfo {
|
||||
git_hash: (branch + "@" + hash),
|
||||
build_time: env!("VERGEN_BUILD_TIMESTAMP").to_owned(),
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
struct VersionInfo {
|
||||
git_hash: String,
|
||||
build_time: String,
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ use esp_idf_sys::{esp, esp_spiffs_check, gpio_hold_dis, gpio_hold_en, vTaskDelay
|
||||
use one_wire_bus::OneWire;
|
||||
|
||||
use crate::config::{self, PlantControllerConfig};
|
||||
use crate::{plant_hal, STAY_ALIVE};
|
||||
use crate::{plant_hal, to_string, STAY_ALIVE};
|
||||
|
||||
//Only support for 8 right now!
|
||||
pub const PLANT_COUNT: usize = 8;
|
||||
@ -117,6 +117,9 @@ static mut CONSECUTIVE_WATERING_PLANT: [u32; PLANT_COUNT] = [0; PLANT_COUNT];
|
||||
#[link_section = ".rtc.data"]
|
||||
static mut LOW_VOLTAGE_DETECTED: bool = false;
|
||||
|
||||
#[link_section = ".rtc.data"]
|
||||
static mut RESTART_TO_CONF: bool = false;
|
||||
|
||||
pub struct FileSystemSizeInfo {
|
||||
pub total_size: usize,
|
||||
pub used_size: usize,
|
||||
@ -180,7 +183,33 @@ pub struct FileList {
|
||||
iter_error: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct BatteryState {
|
||||
voltage_milli_volt: String,
|
||||
current_milli_ampere: String,
|
||||
cycle_count: String,
|
||||
design_milli_ampere: String,
|
||||
remaining_milli_ampere: String,
|
||||
state_of_charge: String,
|
||||
state_of_health: String,
|
||||
temperature: String,
|
||||
}
|
||||
|
||||
impl PlantCtrlBoard<'_> {
|
||||
pub fn get_battery_state(&mut self) -> BatteryState {
|
||||
let bat = BatteryState {
|
||||
voltage_milli_volt: to_string(self.voltage_milli_volt()),
|
||||
current_milli_ampere: to_string(self.average_current_milli_ampere()),
|
||||
cycle_count: to_string(self.cycle_count()),
|
||||
design_milli_ampere: to_string(self.design_milli_ampere_hour()),
|
||||
remaining_milli_ampere: to_string(self.remaining_milli_ampere_hour()),
|
||||
state_of_charge: to_string(self.state_charge_percent()),
|
||||
state_of_health: to_string(self.state_health_percent()),
|
||||
temperature: to_string(self.bat_temperature()),
|
||||
};
|
||||
return bat;
|
||||
}
|
||||
|
||||
pub fn list_files(&self, filename: &str) -> FileList {
|
||||
let storage = CString::new(SPIFFS_PARTITION_NAME).unwrap();
|
||||
let error = unsafe {
|
||||
@ -956,6 +985,16 @@ impl PlantCtrlBoard<'_> {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_restart_to_conf(&mut self) -> bool {
|
||||
return unsafe { RESTART_TO_CONF };
|
||||
}
|
||||
|
||||
pub fn set_restart_to_conf(&mut self, to_conf: bool) {
|
||||
unsafe {
|
||||
RESTART_TO_CONF = to_conf;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn state_charge_percent(&mut self) -> Result<u8> {
|
||||
match self.battery_driver.state_of_charge() {
|
||||
OkStd(r) => Ok(r),
|
||||
@ -1012,6 +1051,13 @@ impl PlantCtrlBoard<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bat_temperature(&mut self) -> Result<u16> {
|
||||
match self.battery_driver.temperature() {
|
||||
OkStd(r) => Ok(r as u16),
|
||||
Err(err) => bail!("Error reading Temperature {:?}", err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flash_bq34_z100(&mut self, line: &str, dryrun: bool) -> Result<()> {
|
||||
match self.battery_driver.write_flash_stream_i2c(line, dryrun) {
|
||||
OkStd(r) => Ok(r),
|
||||
@ -1193,32 +1239,60 @@ impl PlantHal {
|
||||
ms4.set_high()?;
|
||||
|
||||
//init,reset rtc memory depending on cause
|
||||
let mut init_rtc_store: bool = false;
|
||||
let mut to_config_mode: bool = false;
|
||||
let reasons = ResetReason::get();
|
||||
let reset_store = match reasons {
|
||||
ResetReason::Software => false,
|
||||
ResetReason::ExternalPin => false,
|
||||
ResetReason::Watchdog => true,
|
||||
ResetReason::Sdio => true,
|
||||
ResetReason::Panic => true,
|
||||
ResetReason::InterruptWatchdog => true,
|
||||
ResetReason::PowerOn => true,
|
||||
ResetReason::Unknown => true,
|
||||
ResetReason::Brownout => true,
|
||||
ResetReason::TaskWatchdog => true,
|
||||
ResetReason::DeepSleep => false,
|
||||
ResetReason::USBPeripheral => true,
|
||||
ResetReason::JTAG => true,
|
||||
match reasons {
|
||||
ResetReason::Software => {},
|
||||
ResetReason::ExternalPin => {},
|
||||
ResetReason::Watchdog => {
|
||||
init_rtc_store = true;
|
||||
},
|
||||
ResetReason::Sdio => {
|
||||
init_rtc_store = true
|
||||
},
|
||||
ResetReason::Panic => {
|
||||
init_rtc_store = true
|
||||
},
|
||||
ResetReason::InterruptWatchdog => {
|
||||
init_rtc_store = true
|
||||
},
|
||||
ResetReason::PowerOn => {
|
||||
init_rtc_store = true
|
||||
},
|
||||
ResetReason::Unknown => {
|
||||
init_rtc_store = true
|
||||
},
|
||||
ResetReason::Brownout => {
|
||||
init_rtc_store = true
|
||||
},
|
||||
ResetReason::TaskWatchdog => {
|
||||
init_rtc_store = true
|
||||
},
|
||||
ResetReason::DeepSleep => {},
|
||||
ResetReason::USBPeripheral => {
|
||||
init_rtc_store = true;
|
||||
to_config_mode = true;
|
||||
},
|
||||
ResetReason::JTAG => {
|
||||
init_rtc_store = true
|
||||
},
|
||||
};
|
||||
if reset_store {
|
||||
println!("Clear and reinit RTC store");
|
||||
println!("Reset due to {:?} requires rtc clear {} and force config mode {}", reasons, init_rtc_store, to_config_mode);
|
||||
if init_rtc_store {
|
||||
unsafe {
|
||||
LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
|
||||
CONSECUTIVE_WATERING_PLANT = [0; PLANT_COUNT];
|
||||
LOW_VOLTAGE_DETECTED = false;
|
||||
RESTART_TO_CONF = to_config_mode;
|
||||
};
|
||||
} else {
|
||||
println!("Keeping RTC store");
|
||||
unsafe {
|
||||
if to_config_mode{
|
||||
RESTART_TO_CONF = true;
|
||||
}
|
||||
println!("Current restart to conf mode{:?}", RESTART_TO_CONF);
|
||||
|
||||
println!(
|
||||
"Current low voltage detection is {:?}",
|
||||
LOW_VOLTAGE_DETECTED
|
||||
|
2050
rust/src/webserver/bootstrap-grid.css
vendored
Normal file
2050
rust/src/webserver/bootstrap-grid.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,9 @@ use std::{
|
||||
sync::{atomic::AtomicBool, Arc},
|
||||
};
|
||||
|
||||
use crate::{espota::OtaUpdate, map_range_moisture, plant_hal::FileInfo, BOARD_ACCESS};
|
||||
use crate::{
|
||||
espota::OtaUpdate, get_version, map_range_moisture, plant_hal::FileInfo, BOARD_ACCESS,
|
||||
};
|
||||
use anyhow::bail;
|
||||
use chrono::DateTime;
|
||||
use core::result::Result::Ok;
|
||||
@ -29,12 +31,6 @@ struct FileList {
|
||||
file: Vec<FileInfo>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
struct VersionInfo<'a> {
|
||||
git_hash: &'a str,
|
||||
build_time: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
struct LoadData<'a> {
|
||||
rtc: &'a str,
|
||||
@ -158,17 +154,19 @@ fn set_config(
|
||||
anyhow::Ok(Some("saved".to_owned()))
|
||||
}
|
||||
|
||||
fn get_version(
|
||||
fn get_battery_state(
|
||||
_request: &mut Request<&mut EspHttpConnection>,
|
||||
) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||
let branch = env!("VERGEN_GIT_BRANCH").to_owned();
|
||||
let hash = &env!("VERGEN_GIT_SHA")[0..8];
|
||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||
let battery_state = board.get_battery_state();
|
||||
let battery_json = serde_json::to_string(&battery_state)?;
|
||||
anyhow::Ok(Some(battery_json))
|
||||
}
|
||||
|
||||
let version_info: VersionInfo<'_> = VersionInfo {
|
||||
git_hash: &(branch + "@" + hash),
|
||||
build_time: env!("VERGEN_BUILD_TIMESTAMP"),
|
||||
};
|
||||
anyhow::Ok(Some(serde_json::to_string(&version_info)?))
|
||||
fn get_version_web(
|
||||
_request: &mut Request<&mut EspHttpConnection>,
|
||||
) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||
anyhow::Ok(Some(serde_json::to_string(&get_version())?))
|
||||
}
|
||||
|
||||
fn pump_test(
|
||||
@ -296,10 +294,14 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
||||
Box::new(EspHttpServer::new(&server_config).unwrap());
|
||||
server
|
||||
.fn_handler("/version", Method::Get, |request| {
|
||||
handle_error_to500(request, get_version)
|
||||
handle_error_to500(request, get_version_web)
|
||||
})
|
||||
.unwrap();
|
||||
server
|
||||
.fn_handler("/battery", Method::Get, |request| {
|
||||
handle_error_to500(request, get_battery_state)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
server
|
||||
.fn_handler("/time", Method::Get, |request| {
|
||||
handle_error_to500(request, get_data)
|
||||
@ -522,7 +524,7 @@ fn cors_response(
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let headers = [
|
||||
("Access-Control-Allow-Origin", "*"),
|
||||
("Access-Control-Allow-Headers", "*")
|
||||
("Access-Control-Allow-Headers", "*"),
|
||||
];
|
||||
let mut response = request.into_response(status, None, &headers)?;
|
||||
response.write(body.as_bytes())?;
|
||||
|
241
rust/src_webpack/package-lock.json
generated
241
rust/src_webpack/package-lock.json
generated
@ -5,11 +5,10 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"copy-webpack-plugin": "^12.0.2",
|
||||
"source-map-loader": "^4.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"copy-webpack-plugin": "^12.0.2",
|
||||
"css-loader": "^7.1.2",
|
||||
"html-webpack-harddisk-plugin": "^2.0.0",
|
||||
"html-webpack-plugin": "^5.6.3",
|
||||
"raw-loader": "^4.0.2",
|
||||
@ -155,7 +154,6 @@
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "2.0.5",
|
||||
@ -169,7 +167,6 @@
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
@ -179,7 +176,6 @@
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.scandir": "2.1.5",
|
||||
@ -193,7 +189,6 @@
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
|
||||
"integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@ -698,7 +693,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
|
||||
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ajv": "^8.0.0"
|
||||
@ -716,7 +710,6 @@
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
@ -733,7 +726,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ajv-keywords": {
|
||||
@ -894,7 +886,6 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
@ -1222,7 +1213,6 @@
|
||||
"version": "12.0.2",
|
||||
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz",
|
||||
"integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-glob": "^3.3.2",
|
||||
@ -1247,7 +1237,6 @@
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
@ -1264,7 +1253,6 @@
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
|
||||
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3"
|
||||
@ -1277,7 +1265,6 @@
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
@ -1290,14 +1277,12 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/copy-webpack-plugin/node_modules/schema-utils": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
|
||||
"integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
|
||||
"dev": true,
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
|
||||
"integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
@ -1306,7 +1291,7 @@
|
||||
"ajv-keywords": "^5.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.13.0"
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@ -1334,42 +1319,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/css-loader": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz",
|
||||
"integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"icss-utils": "^5.1.0",
|
||||
"postcss": "^8.4.33",
|
||||
"postcss-modules-extract-imports": "^3.1.0",
|
||||
"postcss-modules-local-by-default": "^4.0.5",
|
||||
"postcss-modules-scope": "^3.2.0",
|
||||
"postcss-modules-values": "^4.0.0",
|
||||
"postcss-value-parser": "^4.2.0",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@rspack/core": "0.x || 1.x",
|
||||
"webpack": "^5.27.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@rspack/core": {
|
||||
"optional": true
|
||||
},
|
||||
"webpack": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/css-select": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
|
||||
@ -1400,19 +1349,6 @@
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
},
|
||||
"node_modules/cssesc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"cssesc": "bin/cssesc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
@ -1833,7 +1769,6 @@
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
||||
"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
@ -1855,7 +1790,6 @@
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
|
||||
"integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/fastest-levenshtein": {
|
||||
@ -1871,7 +1805,6 @@
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
|
||||
"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
@ -1894,7 +1827,6 @@
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@ -2017,7 +1949,6 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
@ -2036,7 +1967,6 @@
|
||||
"version": "14.0.2",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz",
|
||||
"integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sindresorhus/merge-streams": "^2.1.0",
|
||||
@ -2404,24 +2334,10 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/icss-utils": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
|
||||
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >= 14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
@ -2517,7 +2433,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@ -2527,7 +2442,6 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
@ -2572,7 +2486,6 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@ -2814,7 +2727,6 @@
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
@ -2834,7 +2746,6 @@
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
@ -2903,25 +2814,6 @@
|
||||
"multicast-dns": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
|
||||
@ -2968,7 +2860,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@ -3170,7 +3061,6 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz",
|
||||
"integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@ -3189,7 +3079,6 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
@ -3209,119 +3098,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.49",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
|
||||
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-modules-extract-imports": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz",
|
||||
"integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >= 14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-modules-local-by-default": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz",
|
||||
"integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"icss-utils": "^5.0.0",
|
||||
"postcss-selector-parser": "^7.0.0",
|
||||
"postcss-value-parser": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >= 14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-modules-scope": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
|
||||
"integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"postcss-selector-parser": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >= 14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-modules-values": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
|
||||
"integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"icss-utils": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >= 14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-selector-parser": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz",
|
||||
"integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-value-parser": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pretty-error": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
|
||||
@ -3392,7 +3168,6 @@
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -3545,7 +3320,6 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@ -3610,7 +3384,6 @@
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"iojs": ">=1.0.0",
|
||||
@ -3634,7 +3407,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -3959,7 +3731,6 @@
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
|
||||
"integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
@ -4262,7 +4033,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
@ -4361,7 +4131,6 @@
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
|
||||
"integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
@ -10,6 +10,7 @@
|
||||
"webpack-dev-server": "^5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"copy-webpack-plugin": "^12.0.2",
|
||||
"source-map-loader": "^4.0.1"
|
||||
}
|
||||
}
|
||||
|
@ -66,3 +66,14 @@ interface VersionInfo {
|
||||
git_hash: string,
|
||||
build_time: string
|
||||
}
|
||||
|
||||
interface BatteryState {
|
||||
temperature: string
|
||||
voltage_milli_volt: string,
|
||||
current_milli_ampere: string,
|
||||
cycle_count: string,
|
||||
design_milli_ampere: string,
|
||||
remaining_milli_ampere: string,
|
||||
state_of_charge: string,
|
||||
state_of_health: string
|
||||
}
|
46
rust/src_webpack/src/batteryview.html
Normal file
46
rust/src_webpack/src/batteryview.html
Normal file
@ -0,0 +1,46 @@
|
||||
<div class="container col-sm-6 col-md-5" style="border-style: solid; border-width: 1px; padding: 8px; margin: 8px;" >
|
||||
<div class="row">
|
||||
<div class="col-7">
|
||||
</div>
|
||||
<div class="col-7" style="text-align: center; font-weight: bold;">
|
||||
Time:
|
||||
</div>
|
||||
<div style="display: block; right: 8px; position: absolute;">
|
||||
<input id="battery_auto_refresh" type="checkbox">⟳
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="col-7">V:</span>
|
||||
<div class="col-5" id="battery_voltage_milli_volt" style="text-wrap: nowrap"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-7">mA:</span>
|
||||
<div class="col-5" id="battery_current_milli_ampere" style="text-wrap: nowrap"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-7">Cycles:</span>
|
||||
<div class="col-5" id="battery_cycle_count" style="text-wrap: nowrap"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-7">design mA:</span>
|
||||
<div class="col-5" id="battery_design_milli_ampere" style="text-wrap: nowrap"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-7">remaining mA:</span>
|
||||
<div class="col-5" id="battery_remaining_milli_ampere" style="text-wrap: nowrap"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-7">charge %:</span>
|
||||
<div class="col-5" id="battery_state_of_charge" style="text-wrap: nowrap"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-7">health %:</span>
|
||||
<div class="col-5" id="battery_state_of_health" style="text-wrap: nowrap"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-7">Temp °C:</span>
|
||||
<div class="col-5" id="battery_temperature" style="text-wrap: nowrap"></div>
|
||||
</div>
|
||||
</div>
|
69
rust/src_webpack/src/batteryview.ts
Normal file
69
rust/src_webpack/src/batteryview.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { Controller } from "./main";
|
||||
|
||||
export class BatteryView{
|
||||
voltage_milli_volt: HTMLSpanElement;
|
||||
current_milli_ampere: HTMLSpanElement;
|
||||
cycle_count: HTMLSpanElement;
|
||||
design_milli_ampere: HTMLSpanElement;
|
||||
remaining_milli_ampere: HTMLSpanElement;
|
||||
state_of_charge: HTMLSpanElement;
|
||||
state_of_health: HTMLSpanElement;
|
||||
temperature: HTMLSpanElement;
|
||||
auto_refresh: HTMLInputElement;
|
||||
timer: NodeJS.Timeout | undefined;
|
||||
controller: Controller;
|
||||
|
||||
constructor (controller:Controller) {
|
||||
(document.getElementById("batteryview") as HTMLElement).innerHTML = require("./batteryview.html")
|
||||
this.voltage_milli_volt = document.getElementById("battery_voltage_milli_volt") as HTMLSpanElement;
|
||||
this.current_milli_ampere = document.getElementById("battery_current_milli_ampere") as HTMLSpanElement;
|
||||
this.cycle_count = document.getElementById("battery_cycle_count") as HTMLSpanElement;
|
||||
this.design_milli_ampere = document.getElementById("battery_design_milli_ampere") as HTMLSpanElement;
|
||||
this.remaining_milli_ampere = document.getElementById("battery_remaining_milli_ampere") as HTMLSpanElement;
|
||||
this.state_of_charge = document.getElementById("battery_state_of_charge") as HTMLSpanElement;
|
||||
this.state_of_health = document.getElementById("battery_state_of_health") as HTMLSpanElement;
|
||||
this.temperature = document.getElementById("battery_temperature") as HTMLSpanElement;
|
||||
this.auto_refresh = document.getElementById("battery_auto_refresh") as HTMLInputElement;
|
||||
|
||||
this.controller = controller
|
||||
this.auto_refresh.onchange = () => {
|
||||
if(this.timer){
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
if(this.auto_refresh.checked){
|
||||
controller.updateBatteryData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update(batterystate: BatteryState|null){
|
||||
if (batterystate == null) {
|
||||
this.voltage_milli_volt.innerText = "N/A"
|
||||
this.current_milli_ampere.innerText = "N/A"
|
||||
this.cycle_count.innerText = "N/A"
|
||||
this.design_milli_ampere.innerText = "N/A"
|
||||
this.remaining_milli_ampere.innerText = "N/A"
|
||||
this.state_of_charge.innerText = "N/A"
|
||||
this.state_of_health.innerText = "N/A"
|
||||
this.temperature.innerText = "N/A"
|
||||
} else {
|
||||
this.voltage_milli_volt.innerText = String(+batterystate.voltage_milli_volt/1000)
|
||||
this.current_milli_ampere.innerText = batterystate.current_milli_ampere
|
||||
this.cycle_count.innerText = batterystate.cycle_count
|
||||
this.design_milli_ampere.innerText = batterystate.design_milli_ampere
|
||||
this.remaining_milli_ampere.innerText = batterystate.remaining_milli_ampere
|
||||
this.state_of_charge.innerText = batterystate.state_of_charge
|
||||
this.state_of_health.innerText = batterystate.state_of_health
|
||||
this.temperature.innerText = String(+batterystate.temperature / 100)
|
||||
}
|
||||
|
||||
|
||||
if(this.auto_refresh.checked){
|
||||
this.timer = setTimeout(this.controller.updateBatteryData, 1000);
|
||||
} else {
|
||||
if(this.timer){
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
<div class="container-xxl">
|
||||
<link rel="stylesheet" href="bootstrap-grid.css">
|
||||
<style>
|
||||
.progressPane{
|
||||
@ -66,70 +65,30 @@
|
||||
</style>
|
||||
|
||||
|
||||
<div id="progressPane" class="progressPane">
|
||||
<div class="progressPaneCenter">
|
||||
<div id="progressPaneBar" class="progress" data-label="50% Complete">
|
||||
<span id="progressPaneSpan" class="value" style="width:100%;"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container-xxl">
|
||||
<input type="button" id="test" value="Test">
|
||||
<h2>Current Firmware</h2>
|
||||
<div>
|
||||
<div id="firmware_buildtime">Buildtime loading</div>
|
||||
<div id="firmware_githash">Build githash loading</div>
|
||||
|
||||
<div id="firmwareview">
|
||||
|
||||
</div>
|
||||
|
||||
<h2>firmeware OTA v3</h2>
|
||||
|
||||
<form id="upload_form" method="post">
|
||||
<input type="file" name="file1" id="firmware_file"><br>
|
||||
<progress id="firmware_progressBar" value="0" max="100" style="width:300px;"></progress>
|
||||
<h3 id="firmware_status"></h3>
|
||||
<h3 id="firmware_answer"></h3>
|
||||
<p id="firmware_loaded_n_total"></p>
|
||||
</form>
|
||||
|
||||
<div id="timeview">
|
||||
</div>
|
||||
|
||||
<div id="network_view">
|
||||
</div>
|
||||
|
||||
<div id="tankview"></div>
|
||||
<div id="batteryview"></div>
|
||||
|
||||
|
||||
<h2>config</h2>
|
||||
|
||||
<div id="configform">
|
||||
<h3>Tank:</h3>
|
||||
<div>
|
||||
<input type="checkbox" id="tank_sensor_enabled">
|
||||
Enable Tank Sensor
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" id="tank_allow_pumping_if_sensor_error">
|
||||
Allow Pumping if Sensor Error
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<input type="number" min="2" max="500000" id="tank_useable_ml">
|
||||
Tank Size mL
|
||||
</div>
|
||||
<div>
|
||||
<input type="number" min="1" max="500000" id="tank_warn_percent">
|
||||
Tank Warn Percent (mapped in relation to empty and full)
|
||||
</div>
|
||||
<div>
|
||||
<input type="number" min="0" max="100" id="tank_empty_percent">
|
||||
Tank Empty Percent (% max move)
|
||||
</div>
|
||||
<div>
|
||||
<input type="number" min="0" max="100" id="tank_full_percent">
|
||||
Tank Full Percent (% max move)
|
||||
</div>
|
||||
|
||||
<h3>Light:</h3>
|
||||
<input type="checkbox" id="night_lamp_enabled" checked="false"> Enable Nightlight
|
||||
<div>
|
||||
@ -155,3 +114,11 @@
|
||||
<textarea id="json" cols=50 rows=10></textarea>
|
||||
<script src="bundle.js"></script>
|
||||
</div>
|
||||
|
||||
<div id="progressPane" class="progressPane">
|
||||
<div class="progressPaneCenter">
|
||||
<div id="progressPaneBar" class="progress" data-label="50% Complete">
|
||||
<span id="progressPaneSpan" class="value" style="width:100%;"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -9,10 +9,11 @@ import { TimeView } from "./timeview";
|
||||
import { PlantView, PlantViews } from "./plant";
|
||||
import { NetworkConfigView } from "./network";
|
||||
import { NightLampView } from "./nightmode";
|
||||
import { TankConfigView } from "./tanks";
|
||||
import { TankConfigView } from "./tankview";
|
||||
import { SubmitView } from "./submitView";
|
||||
import { ProgressView } from "./progress";
|
||||
import { OTAView } from "./ota";
|
||||
import { BatteryView } from "./batteryview";
|
||||
|
||||
export class Controller {
|
||||
updateRTCData() {
|
||||
@ -27,6 +28,18 @@ export class Controller {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
updateBatteryData() {
|
||||
fetch(PUBLIC_URL + "/battery")
|
||||
.then(response => response.json())
|
||||
.then(json => json as BatteryState)
|
||||
.then(battery => {
|
||||
controller.batteryView.update(battery)
|
||||
})
|
||||
.catch(error => {
|
||||
controller.batteryView.update(null)
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
uploadNewFirmware(file: File) {
|
||||
var current = 0;
|
||||
var max = 100;
|
||||
@ -226,11 +239,13 @@ export class Controller {
|
||||
readonly submitView: SubmitView;
|
||||
readonly firmWareView : OTAView;
|
||||
readonly progressview: ProgressView;
|
||||
readonly batteryView: BatteryView;
|
||||
constructor() {
|
||||
this.timeView = new TimeView(this)
|
||||
this.plantViews = new PlantViews(this)
|
||||
this.networkView = new NetworkConfigView(this, PUBLIC_URL)
|
||||
this.tankView = new TankConfigView(this)
|
||||
this.batteryView = new BatteryView(this)
|
||||
this.nightLampView = new NightLampView(this)
|
||||
this.submitView = new SubmitView(this)
|
||||
this.firmWareView = new OTAView(this)
|
||||
@ -239,6 +254,8 @@ export class Controller {
|
||||
}
|
||||
const controller = new Controller();
|
||||
controller.updateRTCData();
|
||||
controller.updateBatteryData();
|
||||
controller.downloadConfig();
|
||||
controller.measure_moisture();
|
||||
n controller.measure_moisture();
|
||||
controller.version();
|
||||
|
||||
|
22
rust/src_webpack/src/ota.html
Normal file
22
rust/src_webpack/src/ota.html
Normal file
@ -0,0 +1,22 @@
|
||||
<div class="container col-12 col-sm-7 col-md-7" style="border-width: 1px; border-style: solid; padding: 8px; margin: 8px;">
|
||||
<div class="row">
|
||||
<div class="col-12" style="text-align: center; font-weight: bold;">
|
||||
Current Firmware
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<span>Buildtime:</span>
|
||||
<span id="firmware_buildtime" style="text-wrap: nowrap"></span>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<span>Buildhash:</span>
|
||||
<span id="firmware_githash" style="text-wrap: nowrap"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<form class="col-12" id="upload_form" method="post">
|
||||
<input type="file" name="file1" id="firmware_file"><br>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -6,6 +6,8 @@ export class OTAView {
|
||||
firmware_githash: HTMLDivElement;
|
||||
|
||||
constructor(controller: Controller) {
|
||||
(document.getElementById("firmwareview") as HTMLElement).innerHTML = require("./ota.html")
|
||||
|
||||
this.firmware_buildtime = document.getElementById("firmware_buildtime") as HTMLDivElement;
|
||||
this.firmware_githash = document.getElementById("firmware_githash") as HTMLDivElement;
|
||||
|
||||
|
@ -1,35 +1,59 @@
|
||||
<h4 id="plant_${plantId}_header">Plant ${plantId}</h4>
|
||||
<div>
|
||||
<button id="plant_${plantId}_test">Test</button>
|
||||
<div class="container" style="border-style: solid; border-width: 1px; margin: 8px; padding: 8px;">
|
||||
<span class="row col-12" style="font-weight: bold; display: block; text-align: center;" id="plant_${plantId}_header">Plant ${plantId}</span>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-1"></div>
|
||||
<button class="col-10" id="plant_${plantId}_test">Test</button>
|
||||
<div class="col-1"></div>
|
||||
</div>
|
||||
<div>
|
||||
Current:
|
||||
<br>
|
||||
Sensor A:<span id="plant_${plantId}_moisture_a">loading</span>
|
||||
<br>
|
||||
Sensor b:<span id="plant_${plantId}_moisture_b">loading</span>
|
||||
<div class="row">
|
||||
<div class="col-12">Live:</div>
|
||||
</div>
|
||||
Mode: <select id="plant_${plantId}_mode">
|
||||
<div class="row">
|
||||
<div class="col-7">Sensor A:</div>
|
||||
<span class="col-4" id="plant_${plantId}_moisture_a">loading</span>
|
||||
<div class="col-7">Sensor B:</div>
|
||||
<span class="col-4" id="plant_${plantId}_moisture_b">loading</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-7">
|
||||
Mode:
|
||||
</div>
|
||||
<select class="col-4" id="plant_${plantId}_mode">
|
||||
<option value="OFF">Off</option>
|
||||
<option value="TargetMoisture">Target Moisture</option>
|
||||
<option value="TimerOnly">Timer Only</option>
|
||||
<option value="TargetMoisture">Target</option>
|
||||
<option value="TimerOnly">Timer</option>
|
||||
</select>
|
||||
|
||||
<div>
|
||||
Target Moisture: <input id="plant_${plantId}_target_moisture" type="number" min="0" max="100" placeholder="0">
|
||||
<br>
|
||||
Pump Time (s): <input id="plant_${plantId}_pump_time_s" type="number" min="0" max="600" placeholder="30">
|
||||
<br>
|
||||
Pump Cooldown (m): <input id="plant_${plantId}_pump_cooldown_min" type="number" min="0" max="600" placeholder="30">
|
||||
<br>
|
||||
"Pump Hour Start": <select id="plant_${plantId}_pump_hour_start">10</select>
|
||||
<br>
|
||||
"Pump Hour End": <select id="plant_${plantId}_pump_hour_end">19</select>
|
||||
<br>
|
||||
Sensor B installed: <input id="plant_${plantId}_sensor_b" type="checkbox">
|
||||
<br>
|
||||
Max Consecutive Pump Count: <input id="plant_${plantId}_max_consecutive_pump_count" type="number" min="1", max="50", placeholder="10">
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-7">Target Moisture:</div>
|
||||
<input class="col-4" id="plant_${plantId}_target_moisture" type="number" min="0" max="100" placeholder="0">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-7">Pump Time (s):</div>
|
||||
<input class="col-4" id="plant_${plantId}_pump_time_s" type="number" min="0" max="600" placeholder="30">
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-7">Pump Cooldown (m):</div>
|
||||
<input class="col-4" id="plant_${plantId}_pump_cooldown_min" type="number" min="0" max="600" placeholder="30">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-7">"Pump Hour Start":</div>
|
||||
<select class="col-4" id="plant_${plantId}_pump_hour_start">10</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-7">"Pump Hour End":</div>
|
||||
<select class="col-4" id="plant_${plantId}_pump_hour_end">19</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-7">Sensor B installed:</div>
|
||||
<input class="col-4" id="plant_${plantId}_sensor_b" type="checkbox">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-7">Max Consecutive Pump Count:</div>
|
||||
<input class="col-4" id="plant_${plantId}_max_consecutive_pump_count" type="number" min="1", max="50", placeholder="10">
|
||||
</div>
|
||||
|
||||
</div>
|
@ -135,7 +135,6 @@ export class PlantView {
|
||||
this.maxConsecutivePumpCount.onchange = function(){
|
||||
controller.configChanged()
|
||||
}
|
||||
console.log(this)
|
||||
}
|
||||
|
||||
update(a: number, b: number) {
|
||||
|
27
rust/src_webpack/src/tankview.html
Normal file
27
rust/src_webpack/src/tankview.html
Normal file
@ -0,0 +1,27 @@
|
||||
<h3>Tank:</h3>
|
||||
<div>
|
||||
<input type="checkbox" id="tank_sensor_enabled">
|
||||
Enable Tank Sensor
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" id="tank_allow_pumping_if_sensor_error">
|
||||
Allow Pumping if Sensor Error
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<input type="number" min="2" max="500000" id="tank_useable_ml">
|
||||
Tank Size mL
|
||||
</div>
|
||||
<div>
|
||||
<input type="number" min="1" max="500000" id="tank_warn_percent">
|
||||
Tank Warn Percent (mapped in relation to empty and full)
|
||||
</div>
|
||||
<div>
|
||||
<input type="number" min="0" max="100" id="tank_empty_percent">
|
||||
Tank Empty Percent (% max move)
|
||||
</div>
|
||||
<div>
|
||||
<input type="number" min="0" max="100" id="tank_full_percent">
|
||||
Tank Full Percent (% max move)
|
||||
</div>
|
@ -9,6 +9,9 @@ export class TankConfigView {
|
||||
private readonly tank_allow_pumping_if_sensor_error: HTMLInputElement;
|
||||
|
||||
constructor(controller:Controller){
|
||||
(document.getElementById("tankview") as HTMLElement).innerHTML = require("./tankview.html")
|
||||
|
||||
|
||||
this.tank_useable_ml = document.getElementById("tank_useable_ml") as HTMLInputElement;
|
||||
this.tank_useable_ml.onchange = controller.configChanged
|
||||
this.tank_empty_percent = document.getElementById("tank_empty_percent") as HTMLInputElement;
|
@ -1,7 +1,28 @@
|
||||
<h2>Time</h2>
|
||||
AutoRefresh:<input id="timeview_auto_refresh" type="checkbox">
|
||||
<div id="timeview_esp_time">Esp time</div>
|
||||
<div id="timeview_rtc_time">Rtc time</div>
|
||||
<div id="timeview_browser_time">Rtc time</div>
|
||||
<div></div>
|
||||
<div class="container col-sm-6 col-md-5" style="border-style: solid; border-width: 1px; padding: 8px; margin: 8px;" >
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
</div>
|
||||
<div class="col-4" style="text-align: center; font-weight: bold;">
|
||||
Time:
|
||||
</div>
|
||||
<div style="display: block; right: 8px; position: absolute;">
|
||||
<input id="timeview_auto_refresh" type="checkbox">⟳
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="col-2">MCU:</span>
|
||||
<div class="col-9" id="timeview_esp_time" style="text-wrap: nowrap">Esp time</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-2">RTC:</span>
|
||||
<div class="col-9" id="timeview_rtc_time" style="text-wrap: nowrap">Rtc time</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col-2">Local:</span>
|
||||
<div class="col-9" id="timeview_browser_time" style="text-wrap: nowrap">Local time</div>
|
||||
</div>
|
||||
|
||||
<button id="timeview_time_upload">Store Browser time into esp and rtc</button>
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@ const isDevServer = process.env.WEBPACK_SERVE;
|
||||
console.log("Dev server is " + isDevServer);
|
||||
var host;
|
||||
if (isDevServer){
|
||||
host = 'http://192.168.1.172';
|
||||
host = 'http://192.168.0.103';
|
||||
} else {
|
||||
host = '';
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user