refactor: unify moisture handling, update config structure, and add peer dependencies
This commit is contained in:
8
Software/MainBoard/.idea/.gitignore
generated
vendored
Normal file
8
Software/MainBoard/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
11
Software/MainBoard/.idea/MainBoard.iml
generated
Normal file
11
Software/MainBoard/.idea/MainBoard.iml
generated
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="EMPTY_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/rust/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/rust/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
8
Software/MainBoard/.idea/modules.xml
generated
Normal file
8
Software/MainBoard/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/MainBoard.iml" filepath="$PROJECT_DIR$/.idea/MainBoard.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
7
Software/MainBoard/.idea/vcs.xml
generated
Normal file
7
Software/MainBoard/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/../../website/themes/blowfish" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
172
Software/MainBoard/d1.json
Normal file
172
Software/MainBoard/d1.json
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
{
|
||||||
|
"hardware": {
|
||||||
|
"board": "V4",
|
||||||
|
"battery": "Disabled"
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"max_wait": 10000,
|
||||||
|
"ap_ssid": "PlantCtrl Init",
|
||||||
|
"ssid": "private",
|
||||||
|
"password": "wertertzu",
|
||||||
|
"mqtt_url": "",
|
||||||
|
"mqtt_user": null,
|
||||||
|
"mqtt_password": null,
|
||||||
|
"base_topic": ""
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"tank_allow_pumping_if_sensor_error": true,
|
||||||
|
"tank_empty_percent": 5,
|
||||||
|
"tank_full_percent": 95,
|
||||||
|
"tank_sensor_enabled": false,
|
||||||
|
"tank_useable_ml": 50000,
|
||||||
|
"tank_warn_percent": 40,
|
||||||
|
"ml_per_pulse": 0
|
||||||
|
},
|
||||||
|
"night_lamp": {
|
||||||
|
"night_lamp_hour_start": 19,
|
||||||
|
"night_lamp_hour_end": 2,
|
||||||
|
"night_lamp_only_when_dark": true,
|
||||||
|
"enabled": true,
|
||||||
|
"low_soc_cutoff": 30,
|
||||||
|
"low_soc_restore": 50
|
||||||
|
},
|
||||||
|
"plants": [
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_b": false,
|
||||||
|
"sensor_a": true,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_b": false,
|
||||||
|
"sensor_a": true,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_b": false,
|
||||||
|
"sensor_a": true,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_b": false,
|
||||||
|
"sensor_a": true,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_b": false,
|
||||||
|
"sensor_a": true,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_b": false,
|
||||||
|
"sensor_a": true,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_b": false,
|
||||||
|
"sensor_a": true,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_b": false,
|
||||||
|
"sensor_a": true,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timezone": "Europe/Berlin"
|
||||||
|
}
|
||||||
180
Software/MainBoard/d2.json
Normal file
180
Software/MainBoard/d2.json
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
{
|
||||||
|
"hardware": {
|
||||||
|
"board": "V4",
|
||||||
|
"battery": "Disabled"
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"ap_ssid": "PlantCtrl Init",
|
||||||
|
"ssid": "private",
|
||||||
|
"password": "wertertzu",
|
||||||
|
"mqtt_url": "",
|
||||||
|
"base_topic": "",
|
||||||
|
"mqtt_user": null,
|
||||||
|
"mqtt_password": null,
|
||||||
|
"max_wait": 10000
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"tank_sensor_enabled": false,
|
||||||
|
"tank_allow_pumping_if_sensor_error": true,
|
||||||
|
"tank_useable_ml": 50000,
|
||||||
|
"tank_warn_percent": 40,
|
||||||
|
"tank_empty_percent": 5,
|
||||||
|
"tank_full_percent": 95,
|
||||||
|
"ml_per_pulse": 0.0
|
||||||
|
},
|
||||||
|
"night_lamp": {
|
||||||
|
"enabled": true,
|
||||||
|
"night_lamp_hour_start": 19,
|
||||||
|
"night_lamp_hour_end": 2,
|
||||||
|
"night_lamp_only_when_dark": true,
|
||||||
|
"low_soc_cutoff": 30,
|
||||||
|
"low_soc_restore": 50
|
||||||
|
},
|
||||||
|
"plants": [
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_limit_ml": 5000,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_a": true,
|
||||||
|
"sensor_b": false,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_limit_ml": 5000,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_a": true,
|
||||||
|
"sensor_b": false,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_limit_ml": 5000,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_a": true,
|
||||||
|
"sensor_b": false,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_limit_ml": 5000,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_a": true,
|
||||||
|
"sensor_b": false,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_limit_ml": 5000,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_a": true,
|
||||||
|
"sensor_b": false,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_limit_ml": 5000,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_a": true,
|
||||||
|
"sensor_b": false,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_limit_ml": 5000,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_a": true,
|
||||||
|
"sensor_b": false,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "Off",
|
||||||
|
"target_moisture": 40,
|
||||||
|
"min_moisture": 30,
|
||||||
|
"pump_time_s": 30,
|
||||||
|
"pump_limit_ml": 5000,
|
||||||
|
"pump_cooldown_min": 60,
|
||||||
|
"pump_hour_start": 9,
|
||||||
|
"pump_hour_end": 20,
|
||||||
|
"sensor_a": true,
|
||||||
|
"sensor_b": false,
|
||||||
|
"max_consecutive_pump_count": 10,
|
||||||
|
"moisture_sensor_min_frequency": null,
|
||||||
|
"moisture_sensor_max_frequency": null,
|
||||||
|
"min_pump_current_ma": 10,
|
||||||
|
"max_pump_current_ma": 3000,
|
||||||
|
"ignore_current_error": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timezone": "Europe/Berlin"
|
||||||
|
}
|
||||||
@@ -151,6 +151,8 @@ heapless = { version = "0.7.17", features = ["serde"] }
|
|||||||
mcutie = { version = "0.3.0", default-features = false, features = ["log", "homeassistant"] }
|
mcutie = { version = "0.3.0", default-features = false, features = ["log", "homeassistant"] }
|
||||||
nb = "1.1.0"
|
nb = "1.1.0"
|
||||||
embedded-can = "0.4.1"
|
embedded-can = "0.4.1"
|
||||||
|
no-panic = "0.1.35"
|
||||||
|
dont_panic = "0.1.0"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
rm ./src/webserver/index.html.gz
|
rm ./src/webserver/index.html.gz
|
||||||
rm ./src/webserver/bundle.js.gz
|
rm ./src/webserver/bundle.js.gz
|
||||||
|
rm ./src_webpack/index.html.gz
|
||||||
|
rm ./src_webpack/bundle.js.gz
|
||||||
|
rm ./src_webpack/index.html
|
||||||
|
rm ./src_webpack/bundle.js
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
pushd ./src_webpack/
|
pushd ./src_webpack/
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ pub struct PlantControllerConfig {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct PlantConfig {
|
pub struct PlantConfig {
|
||||||
pub mode: PlantWateringMode,
|
pub mode: PlantWateringMode,
|
||||||
pub target_moisture: f32,
|
pub target_moisture: u8,
|
||||||
pub min_moisture: f32,
|
pub min_moisture: u8,
|
||||||
pub pump_time_s: u16,
|
pub pump_time_s: u16,
|
||||||
pub pump_limit_ml: u16,
|
pub pump_limit_ml: u16,
|
||||||
pub pump_cooldown_min: u16,
|
pub pump_cooldown_min: u16,
|
||||||
@@ -125,8 +125,8 @@ pub struct PlantConfig {
|
|||||||
pub sensor_a: bool,
|
pub sensor_a: bool,
|
||||||
pub sensor_b: bool,
|
pub sensor_b: bool,
|
||||||
pub max_consecutive_pump_count: u8,
|
pub max_consecutive_pump_count: u8,
|
||||||
pub moisture_sensor_min_frequency: Option<f32>, // Optional min frequency
|
pub moisture_sensor_min_frequency: Option<u16>, // Optional min frequency
|
||||||
pub moisture_sensor_max_frequency: Option<f32>, // Optional max frequency
|
pub moisture_sensor_max_frequency: Option<u16>, // Optional max frequency
|
||||||
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,
|
||||||
@@ -136,8 +136,8 @@ impl Default for PlantConfig {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
mode: PlantWateringMode::Off,
|
mode: PlantWateringMode::Off,
|
||||||
target_moisture: 40.,
|
target_moisture: 40,
|
||||||
min_moisture: 30.,
|
min_moisture: 30,
|
||||||
pump_time_s: 30,
|
pump_time_s: 30,
|
||||||
pump_limit_ml: 5000,
|
pump_limit_ml: 5000,
|
||||||
pump_cooldown_min: 60,
|
pump_cooldown_min: 60,
|
||||||
|
|||||||
@@ -316,3 +316,4 @@ impl From<sntpc::Error> for FatError {
|
|||||||
FatError::SNTPError { error: value }
|
FatError::SNTPError { error: value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ macro_rules! mk_static {
|
|||||||
($t:ty,$val:expr) => {{
|
($t:ty,$val:expr) => {{
|
||||||
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
||||||
#[deny(unused_attributes)]
|
#[deny(unused_attributes)]
|
||||||
let x = STATIC_CELL.uninit().write(($val));
|
let x = STATIC_CELL.uninit().write($val);
|
||||||
x
|
x
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ macro_rules! mk_static {
|
|||||||
($t:ty,$val:expr) => {{
|
($t:ty,$val:expr) => {{
|
||||||
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
||||||
#[deny(unused_attributes)]
|
#[deny(unused_attributes)]
|
||||||
let x = STATIC_CELL.uninit().write(($val));
|
let x = STATIC_CELL.uninit().write($val);
|
||||||
x
|
x
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
use crate::bail;
|
use crate::bail;
|
||||||
use crate::fat_error::{ContextExt, FatError, FatResult};
|
use crate::fat_error::{ContextExt, FatResult};
|
||||||
use crate::hal::Box;
|
use crate::hal::Box;
|
||||||
use crate::hal::{DetectionResult, Moistures, Sensor};
|
use crate::hal::{DetectionResult, Moistures, Sensor};
|
||||||
use crate::log::{LogMessage, LOG_ACCESS};
|
use crate::log::{LogMessage, LOG_ACCESS};
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bincode::config;
|
|
||||||
use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET};
|
use canapi::id::{classify, plant_id, MessageKind, IDENTIFY_CMD_OFFSET};
|
||||||
use canapi::SensorSlot;
|
use canapi::SensorSlot;
|
||||||
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_time::{Duration, Instant, Timer, WithTimeout};
|
use embassy_time::{Duration, Timer, WithTimeout};
|
||||||
use embedded_can::{Frame, Id};
|
use embedded_can::{Frame, Id};
|
||||||
use esp_hal::gpio::Output;
|
use esp_hal::gpio::Output;
|
||||||
use esp_hal::i2c::master::I2c;
|
use esp_hal::i2c::master::I2c;
|
||||||
@@ -86,7 +85,7 @@ impl SensorInteraction for SensorImpl {
|
|||||||
} => {
|
} => {
|
||||||
can_power.set_high();
|
can_power.set_high();
|
||||||
let config = twai_config.take().expect("twai config not set");
|
let config = twai_config.take().expect("twai config not set");
|
||||||
let mut twai = config.start();
|
let mut twai = config.into_async().start();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let rec = twai.receive();
|
let rec = twai.receive();
|
||||||
@@ -100,15 +99,17 @@ impl SensorInteraction for SensorImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Timer::after_millis(10).await;
|
Timer::after_millis(10).await;
|
||||||
let can = Self::inner_can(&mut twai).await;
|
|
||||||
|
let mut moistures = Moistures::default();
|
||||||
|
let _ = Self::wait_for_can_measurements(&mut twai, &mut moistures).with_timeout(Duration::from_millis(5000)).await;
|
||||||
|
|
||||||
|
|
||||||
can_power.set_low();
|
can_power.set_low();
|
||||||
|
|
||||||
let config = twai.stop();
|
let config = twai.stop().into_blocking();
|
||||||
twai_config.replace(config);
|
twai_config.replace(config);
|
||||||
|
|
||||||
let value = can?;
|
Ok(moistures)
|
||||||
Ok(value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,9 +161,8 @@ impl SensorImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result = DetectionResult::default();
|
let mut moistures = Moistures::default();
|
||||||
// Wait for messages to arrive
|
let _ = Self::wait_for_can_measurements(&mut as_async, &mut moistures)
|
||||||
let _ = Self::wait_for_can_measurements(&mut as_async, &mut result)
|
|
||||||
.with_timeout(Duration::from_millis(5000))
|
.with_timeout(Duration::from_millis(5000))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -170,6 +170,8 @@ impl SensorImpl {
|
|||||||
can_power.set_low();
|
can_power.set_low();
|
||||||
twai_config.replace(config);
|
twai_config.replace(config);
|
||||||
|
|
||||||
|
let result= moistures.into();
|
||||||
|
|
||||||
info!("Autodetection result: {result:?}");
|
info!("Autodetection result: {result:?}");
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
@@ -178,8 +180,9 @@ impl SensorImpl {
|
|||||||
|
|
||||||
async fn wait_for_can_measurements(
|
async fn wait_for_can_measurements(
|
||||||
as_async: &mut Twai<'_, Async>,
|
as_async: &mut Twai<'_, Async>,
|
||||||
result: &mut DetectionResult,
|
moistures: &mut Moistures,
|
||||||
) {
|
) -> FatResult<()> {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match as_async.receive_async().await {
|
match as_async.receive_async().await {
|
||||||
Ok(can_frame) => match can_frame.id() {
|
Ok(can_frame) => match can_frame.id() {
|
||||||
@@ -196,12 +199,14 @@ impl SensorImpl {
|
|||||||
if msg.0 == MessageKind::MoistureData {
|
if msg.0 == MessageKind::MoistureData {
|
||||||
let plant = msg.1 as usize;
|
let plant = msg.1 as usize;
|
||||||
let sensor = msg.2;
|
let sensor = msg.2;
|
||||||
|
let data = can_frame.data();
|
||||||
|
|
||||||
match sensor {
|
match sensor {
|
||||||
SensorSlot::A => {
|
SensorSlot::A => {
|
||||||
result.plant[plant].sensor_a = true;
|
moistures.sensor_a_hz[plant] = data[0] as f32;
|
||||||
}
|
}
|
||||||
SensorSlot::B => {
|
SensorSlot::B => {
|
||||||
result.plant[plant].sensor_b = true;
|
moistures.sensor_b_hz[plant] = data[0] as f32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,7 +219,6 @@ impl SensorImpl {
|
|||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Error receiving CAN message: {err:?}");
|
error!("Error receiving CAN message: {err:?}");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,31 +306,17 @@ impl SensorImpl {
|
|||||||
let median = results[mid];
|
let median = results[mid];
|
||||||
Ok(median)
|
Ok(median)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn inner_can(twai: &mut Twai<'static, Blocking>) -> FatResult<Moistures> {
|
|
||||||
config::standard();
|
|
||||||
|
|
||||||
let timeout = Instant::now()
|
|
||||||
.checked_add(embassy_time::Duration::from_millis(100))
|
|
||||||
.context("Timeout")?;
|
|
||||||
loop {
|
|
||||||
let answer = twai.receive();
|
|
||||||
match answer {
|
|
||||||
Ok(answer) => {
|
|
||||||
info!("Received CAN message: {answer:?}");
|
|
||||||
}
|
|
||||||
Err(error) => match error {
|
|
||||||
nb::Error::Other(error) => {
|
|
||||||
return Err(FatError::CanBusError { error });
|
|
||||||
}
|
|
||||||
nb::Error::WouldBlock => {
|
|
||||||
if Instant::now() > timeout {
|
|
||||||
bail!("Timeout waiting for CAN answer");
|
|
||||||
}
|
|
||||||
Timer::after_millis(10).await;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Moistures> for DetectionResult {
|
||||||
|
fn from(value: Moistures) -> Self {
|
||||||
|
let mut result = DetectionResult::default();
|
||||||
|
for (plant, sensor) in value.sensor_a_hz.iter().enumerate() {
|
||||||
|
result.plant[plant].sensor_a = *sensor > 1.0_f32;
|
||||||
|
}
|
||||||
|
for (plant, sensor) in value.sensor_b_hz.iter().enumerate() {
|
||||||
|
result.plant[plant].sensor_b = *sensor > 1.0_f32;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ use deranged::RangedU8;
|
|||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::mutex::Mutex;
|
use embassy_sync::mutex::Mutex;
|
||||||
use esp_hal::Persistable;
|
use esp_hal::Persistable;
|
||||||
use log::info;
|
use log::{info, warn};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use strum_macros::IntoStaticStr;
|
use strum_macros::IntoStaticStr;
|
||||||
use unit_enum::UnitEnum;
|
use unit_enum::UnitEnum;
|
||||||
@@ -159,24 +159,41 @@ impl LogArray {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn limit_length<const LIMIT: usize>(input: &str, target: &mut heapless::String<LIMIT>) {
|
fn limit_length<const LIMIT: usize>(input: &str, target: &mut heapless::String<LIMIT>) {
|
||||||
for char in input.chars() {
|
for char in input.chars() {
|
||||||
match target.push(char) {
|
match target.push(char) {
|
||||||
Ok(_) => {} //continue adding chars
|
Ok(_) => {} //continue adding chars
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
//clear space for two asci chars
|
//clear space for two asci chars
|
||||||
|
info!("pushing char {char} to limit {LIMIT} current value {target} input {input}");
|
||||||
while target.len() + 2 >= LIMIT {
|
while target.len() + 2 >= LIMIT {
|
||||||
target.pop().unwrap();
|
target.pop();
|
||||||
}
|
}
|
||||||
//add .. to shortened strings
|
//add .. to shortened strings
|
||||||
target.push('.').unwrap();
|
match target.push('.'){
|
||||||
target.push('.').unwrap();
|
Ok(_) => {}
|
||||||
|
Err(_) => {
|
||||||
|
warn!("Error pushin . to limit {LIMIT} current value {target} input {input}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match target.push('.'){
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(_) => {
|
||||||
|
warn!("Error pushin . to limit {LIMIT} current value {target} input {input}")
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while target.len() < LIMIT {
|
while target.len() < LIMIT {
|
||||||
target.push(' ').unwrap();
|
match target.push(' ') {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(_) => {
|
||||||
|
warn!("Error pushing space to limit {LIMIT} current value {target} input {input}")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -832,7 +832,7 @@ macro_rules! mk_static {
|
|||||||
($t:ty,$val:expr) => {{
|
($t:ty,$val:expr) => {{
|
||||||
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
||||||
#[deny(unused_attributes)]
|
#[deny(unused_attributes)]
|
||||||
let x = STATIC_CELL.uninit().write(($val));
|
let x = STATIC_CELL.uninit().write($val);
|
||||||
x
|
x
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,8 +120,8 @@ impl PlantState {
|
|||||||
let raw = moistures.sensor_a_hz[plant_id];
|
let raw = moistures.sensor_a_hz[plant_id];
|
||||||
match map_range_moisture(
|
match map_range_moisture(
|
||||||
raw,
|
raw,
|
||||||
board.board_hal.get_config().plants[plant_id].moisture_sensor_min_frequency,
|
board.board_hal.get_config().plants[plant_id].moisture_sensor_min_frequency.map(|a| a as f32),
|
||||||
board.board_hal.get_config().plants[plant_id].moisture_sensor_max_frequency,
|
board.board_hal.get_config().plants[plant_id].moisture_sensor_max_frequency.map(|b| b as f32),
|
||||||
) {
|
) {
|
||||||
Ok(moisture_percent) => MoistureSensorState::MoistureValue {
|
Ok(moisture_percent) => MoistureSensorState::MoistureValue {
|
||||||
raw_hz: raw,
|
raw_hz: raw,
|
||||||
@@ -137,8 +137,8 @@ impl PlantState {
|
|||||||
let raw = moistures.sensor_b_hz[plant_id];
|
let raw = moistures.sensor_b_hz[plant_id];
|
||||||
match map_range_moisture(
|
match map_range_moisture(
|
||||||
raw,
|
raw,
|
||||||
board.board_hal.get_config().plants[plant_id].moisture_sensor_min_frequency,
|
board.board_hal.get_config().plants[plant_id].moisture_sensor_min_frequency.map(|a| a as f32),
|
||||||
board.board_hal.get_config().plants[plant_id].moisture_sensor_max_frequency,
|
board.board_hal.get_config().plants[plant_id].moisture_sensor_max_frequency.map(|b| b as f32)
|
||||||
) {
|
) {
|
||||||
Ok(moisture_percent) => MoistureSensorState::MoistureValue {
|
Ok(moisture_percent) => MoistureSensorState::MoistureValue {
|
||||||
raw_hz: raw,
|
raw_hz: raw,
|
||||||
@@ -186,7 +186,7 @@ impl PlantState {
|
|||||||
pub fn plant_moisture(
|
pub fn plant_moisture(
|
||||||
&self,
|
&self,
|
||||||
) -> (
|
) -> (
|
||||||
Option<f32>,
|
Option<u8>,
|
||||||
(Option<&MoistureSensorError>, Option<&MoistureSensorError>),
|
(Option<&MoistureSensorError>, Option<&MoistureSensorError>),
|
||||||
) {
|
) {
|
||||||
match (
|
match (
|
||||||
@@ -194,10 +194,10 @@ impl PlantState {
|
|||||||
self.sensor_b.moisture_percent(),
|
self.sensor_b.moisture_percent(),
|
||||||
) {
|
) {
|
||||||
(Some(moisture_a), Some(moisture_b)) => {
|
(Some(moisture_a), Some(moisture_b)) => {
|
||||||
(Some((moisture_a + moisture_b) / 2.), (None, None))
|
(Some(((moisture_a + moisture_b) / 2.) as u8), (None, None))
|
||||||
}
|
}
|
||||||
(Some(moisture_percent), _) => (Some(moisture_percent), (None, self.sensor_b.is_err())),
|
(Some(moisture_percent), _) => (Some(moisture_percent as u8), (None, self.sensor_b.is_err())),
|
||||||
(_, Some(moisture_percent)) => (Some(moisture_percent), (self.sensor_a.is_err(), None)),
|
(_, Some(moisture_percent)) => (Some(moisture_percent as u8), (self.sensor_a.is_err(), None)),
|
||||||
_ => (None, (self.sensor_a.is_err(), self.sensor_b.is_err())),
|
_ => (None, (self.sensor_a.is_err(), self.sensor_b.is_err())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -707,6 +707,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -731,6 +732,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"fast-uri": "^3.0.1",
|
"fast-uri": "^3.0.1",
|
||||||
@@ -957,6 +959,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.8.3",
|
"baseline-browser-mapping": "^2.8.3",
|
||||||
"caniuse-lite": "^1.0.30001741",
|
"caniuse-lite": "^1.0.30001741",
|
||||||
@@ -2274,6 +2277,7 @@
|
|||||||
"integrity": "sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==",
|
"integrity": "sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/html-minifier-terser": "^6.0.0",
|
"@types/html-minifier-terser": "^6.0.0",
|
||||||
"html-minifier-terser": "^6.0.2",
|
"html-minifier-terser": "^6.0.2",
|
||||||
@@ -3380,6 +3384,7 @@
|
|||||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
"fast-json-stable-stringify": "^2.0.0",
|
"fast-json-stable-stringify": "^2.0.0",
|
||||||
@@ -4338,7 +4343,8 @@
|
|||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "0BSD"
|
"license": "0BSD",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/type-is": {
|
"node_modules/type-is": {
|
||||||
"version": "1.6.18",
|
"version": "1.6.18",
|
||||||
@@ -4360,6 +4366,7 @@
|
|||||||
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
|
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -4508,6 +4515,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.3.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.3.tgz",
|
||||||
"integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==",
|
"integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/eslint-scope": "^3.7.7",
|
"@types/eslint-scope": "^3.7.7",
|
||||||
"@types/estree": "^1.0.8",
|
"@types/estree": "^1.0.8",
|
||||||
@@ -4557,6 +4565,7 @@
|
|||||||
"integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
|
"integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discoveryjs/json-ext": "^0.5.0",
|
"@discoveryjs/json-ext": "^0.5.0",
|
||||||
"@webpack-cli/configtest": "^2.1.1",
|
"@webpack-cli/configtest": "^2.1.1",
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ export interface PlantConfig {
|
|||||||
pump_cooldown_min: number,
|
pump_cooldown_min: number,
|
||||||
pump_hour_start: number,
|
pump_hour_start: number,
|
||||||
pump_hour_end: number,
|
pump_hour_end: number,
|
||||||
|
pump_limit_ml: number,
|
||||||
sensor_a: boolean,
|
sensor_a: boolean,
|
||||||
sensor_b: boolean,
|
sensor_b: boolean,
|
||||||
max_consecutive_pump_count: number,
|
max_consecutive_pump_count: number,
|
||||||
|
|||||||
@@ -296,6 +296,7 @@ export class Controller {
|
|||||||
configChanged() {
|
configChanged() {
|
||||||
const current = controller.getConfig();
|
const current = controller.getConfig();
|
||||||
var pretty = JSON.stringify(current, undefined, 0);
|
var pretty = JSON.stringify(current, undefined, 0);
|
||||||
|
|
||||||
controller.submitView.setJson(pretty);
|
controller.submitView.setJson(pretty);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
Mode:
|
Mode:
|
||||||
</div>
|
</div>
|
||||||
<select class="plantvalue" id="plant_${plantId}_mode">
|
<select class="plantvalue" id="plant_${plantId}_mode">
|
||||||
<option value="OFF">Off</option>
|
<option value="Off">Off</option>
|
||||||
<option value="TargetMoisture">Target</option>
|
<option value="TargetMoisture">Target</option>
|
||||||
<option value="MinMoisture">Min Moisture</option>
|
<option value="MinMoisture">Min Moisture</option>
|
||||||
<option value="TimerOnly">Timer</option>
|
<option value="TimerOnly">Timer</option>
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ export class PlantView {
|
|||||||
|
|
||||||
console.log("updateVisibility plantConfig: " + plantConfig.mode)
|
console.log("updateVisibility plantConfig: " + plantConfig.mode)
|
||||||
let showSensor = plantConfig.sensor_a || plantConfig.sensor_b
|
let showSensor = plantConfig.sensor_a || plantConfig.sensor_b
|
||||||
let showPump = plantConfig.mode !== "OFF"
|
let showPump = plantConfig.mode !== "Off"
|
||||||
let showTarget = plantConfig.mode === "TargetMoisture"
|
let showTarget = plantConfig.mode === "TargetMoisture"
|
||||||
let showMin = plantConfig.mode === "MinMoisture"
|
let showMin = plantConfig.mode === "MinMoisture"
|
||||||
|
|
||||||
@@ -299,6 +299,7 @@ export class PlantView {
|
|||||||
target_moisture: this.targetMoisture.valueAsNumber,
|
target_moisture: this.targetMoisture.valueAsNumber,
|
||||||
min_moisture: this.minMoisture.valueAsNumber,
|
min_moisture: this.minMoisture.valueAsNumber,
|
||||||
pump_time_s: this.pumpTimeS.valueAsNumber,
|
pump_time_s: this.pumpTimeS.valueAsNumber,
|
||||||
|
pump_limit_ml: 5000,
|
||||||
pump_cooldown_min: this.pumpCooldown.valueAsNumber,
|
pump_cooldown_min: this.pumpCooldown.valueAsNumber,
|
||||||
pump_hour_start: +this.pumpHourStart.value,
|
pump_hour_start: +this.pumpHourStart.value,
|
||||||
pump_hour_end: +this.pumpHourEnd.value,
|
pump_hour_end: +this.pumpHourEnd.value,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ console.log("Dev server is " + isDevServer);
|
|||||||
var host;
|
var host;
|
||||||
if (isDevServer) {
|
if (isDevServer) {
|
||||||
//ensure no trailing /
|
//ensure no trailing /
|
||||||
host = 'http://10.23.44.186';
|
host = 'http://192.168.1.105';
|
||||||
} else {
|
} else {
|
||||||
host = '';
|
host = '';
|
||||||
}
|
}
|
||||||
|
|||||||
8
Software/Shared/canapi/.idea/.gitignore
generated
vendored
Normal file
8
Software/Shared/canapi/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
11
Software/Shared/canapi/.idea/canapi.iml
generated
Normal file
11
Software/Shared/canapi/.idea/canapi.iml
generated
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="EMPTY_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
8
Software/Shared/canapi/.idea/modules.xml
generated
Normal file
8
Software/Shared/canapi/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/canapi.iml" filepath="$PROJECT_DIR$/.idea/canapi.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
7
Software/Shared/canapi/.idea/vcs.xml
generated
Normal file
7
Software/Shared/canapi/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/../../../website/themes/blowfish" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Reference in New Issue
Block a user