Compare commits
No commits in common. "main" and "firmware_v0.1.0" have entirely different histories.
main
...
firmware_v
19 changed files with 257 additions and 8852 deletions
24
.gitmodules
vendored
24
.gitmodules
vendored
|
@ -1,24 +0,0 @@
|
||||||
[submodule "Arduino/CanGrow/Adafruit-GFX-Library"]
|
|
||||||
path = Arduino/CanGrow/Adafruit-GFX-Library
|
|
||||||
url = https://github.com/adafruit/Adafruit-GFX-Library
|
|
||||||
[submodule "Arduino/CanGrow/lib/Adafruit-GFX-Library"]
|
|
||||||
path = Arduino/CanGrow/lib/Adafruit-GFX-Library
|
|
||||||
url = https://github.com/adafruit/Adafruit-GFX-Library
|
|
||||||
[submodule "Arduino/CanGrow/lib/Adafruit_SSD1306"]
|
|
||||||
path = Arduino/CanGrow/lib/Adafruit_SSD1306
|
|
||||||
url = https://github.com/adafruit/Adafruit_SSD1306
|
|
||||||
[submodule "Arduino/CanGrow/lib/Adafruit_BME280_Library"]
|
|
||||||
path = Arduino/CanGrow/lib/Adafruit_BME280_Library
|
|
||||||
url = https://github.com/adafruit/Adafruit_BME280_Library/
|
|
||||||
[submodule "Arduino/CanGrow/lib/NTPClient"]
|
|
||||||
path = Arduino/CanGrow/lib/NTPClient
|
|
||||||
url = https://github.com/arduino-libraries/NTPClient
|
|
||||||
[submodule "Arduino/CanGrow/lib/Time"]
|
|
||||||
path = Arduino/CanGrow/lib/Time
|
|
||||||
url = https://github.com/PaulStoffregen/Time
|
|
||||||
[submodule "Arduino/CanGrow/lib/Adafruit_SHT31"]
|
|
||||||
path = Arduino/CanGrow/lib/Adafruit_SHT31
|
|
||||||
url = https://github.com/adafruit/Adafruit_SHT31/
|
|
||||||
[submodule "Arduino/CanGrow/lib/Adafruit_Sensor"]
|
|
||||||
path = Arduino/CanGrow/lib/Adafruit_Sensor
|
|
||||||
url = https://github.com/adafruit/Adafruit_Sensor
|
|
|
@ -3,13 +3,12 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Includes
|
* Includes
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Libraries internal (Arduino Core / ESP)
|
// Libraries
|
||||||
// https://github.com/arduino/ArduinoCore-avr/tree/master/libraries/SPI
|
// https://github.com/arduino/ArduinoCore-avr/tree/master/libraries/SPI
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
// https://github.com/arduino/ArduinoCore-avr/tree/master/libraries/Wire
|
// https://github.com/arduino/ArduinoCore-avr/tree/master/libraries/Wire
|
||||||
|
@ -23,40 +22,32 @@
|
||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
// OTA update
|
// OTA update
|
||||||
#include <ESP8266HTTPUpdateServer.h>
|
#include <ESP8266HTTPUpdateServer.h>
|
||||||
|
|
||||||
// Libraries external
|
|
||||||
// https://github.com/adafruit/Adafruit-GFX-Library
|
// https://github.com/adafruit/Adafruit-GFX-Library
|
||||||
//include "lib/Adafruit-GFX-Library/Adafruit_GFX.h"
|
|
||||||
#include <Adafruit_GFX.h>
|
#include <Adafruit_GFX.h>
|
||||||
// https://github.com/adafruit/Adafruit_SSD1306
|
// https://github.com/adafruit/Adafruit_SSD1306
|
||||||
//include "lib/Adafruit_SSD1306/Adafruit_SSD1306.h"
|
|
||||||
#include <Adafruit_SSD1306.h>
|
#include <Adafruit_SSD1306.h>
|
||||||
// https://github.com/adafruit/Adafruit_Sensor
|
// https://github.com/adafruit/Adafruit_BME280_Library/
|
||||||
// include "lib/Adafruit_Sensor/Adafruit_Sensor.h"
|
|
||||||
#include <Adafruit_Sensor.h>
|
#include <Adafruit_Sensor.h>
|
||||||
// https://github.com/adafruit/Adafruit_BME280_Library
|
|
||||||
//include "lib/Adafruit_BME280_Library/Adafruit_BME280.h"
|
|
||||||
#include <Adafruit_BME280.h>
|
#include <Adafruit_BME280.h>
|
||||||
// https://github.com/adafruit/Adafruit_SHT31/
|
|
||||||
//#include "lib/Adafruit_SHT31/Adafruit_SHT31.h"
|
|
||||||
#include <Adafruit_SHT31.h>
|
|
||||||
// https://github.com/bblanchon/ArduinoJson
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
#include "lib/ArduinoJson/ArduinoJson-v7.2.1.h"
|
#include <ArduinoJson.h>
|
||||||
// https://github.com/arduino-libraries/NTPClient
|
// https://github.com/arduino-libraries/NTPClient
|
||||||
//#include "lib/NTPClient/NTPClient.h"
|
|
||||||
#include <NTPClient.h>
|
#include <NTPClient.h>
|
||||||
// https://github.com/PaulStoffregen/Time
|
// https://github.com/PaulStoffregen/Time
|
||||||
//#include "lib/Time/TimeLib.h"
|
|
||||||
#include <TimeLib.h>
|
#include <TimeLib.h>
|
||||||
|
|
||||||
// DHT support dropped
|
// DHT support dropped
|
||||||
// https://github.com/adafruit/DHT-sensor-library
|
// https://github.com/adafruit/DHT-sensor-library
|
||||||
// #include "DHT.h"
|
// #include "DHT.h"
|
||||||
|
// SHT30/31
|
||||||
|
// https://github.com/adafruit/Adafruit_SHT31/
|
||||||
|
#include "Adafruit_SHT31.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CanGrow header files
|
* CanGrow header files
|
||||||
*/
|
*/
|
||||||
#include "CanGrow_Version.h"
|
|
||||||
#include "CanGrow_PinAssignments.h"
|
#include "CanGrow_PinAssignments.h"
|
||||||
#include "CanGrow_Init.h"
|
#include "CanGrow_Init.h"
|
||||||
#include "CanGrow_Logo.h"
|
#include "CanGrow_Logo.h"
|
||||||
|
@ -66,7 +57,6 @@
|
||||||
#include "CanGrow_WebFunctions.h"
|
#include "CanGrow_WebFunctions.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup
|
* Setup
|
||||||
*
|
*
|
||||||
|
@ -136,39 +126,25 @@ void setup() {
|
||||||
// dht.begin(); //TODO: Do only, when configured
|
// dht.begin(); //TODO: Do only, when configured
|
||||||
|
|
||||||
// initialise BME280
|
// initialise BME280
|
||||||
// dirty way of supporting multiple addresses, DRY? :p
|
Serial.println(":: initialise BME280 sensor ::");
|
||||||
Serial.println(":: initialise BME280 sensor, address 0x76 ::");
|
|
||||||
// ToDo: let the user configure somewhere the ID of the BME280 sensor
|
// ToDo: let the user configure somewhere the ID of the BME280 sensor
|
||||||
if(!bme_0x76.begin(0x76)) {
|
if(!bme.begin(0x76)) {
|
||||||
Serial.println("!! Cannot find BME280 on I2C bus at address 0x76. Please check connection or ID");
|
Serial.println("!! Cannot find BME280 on I2C bus. Please check connection or ID");
|
||||||
}
|
|
||||||
Serial.println(":: initialise BME280 sensor, address 0x77 ::");
|
|
||||||
// ToDo: let the user configure somewhere the ID of the BME280 sensor
|
|
||||||
if(!bme_0x77.begin(0x77)) {
|
|
||||||
Serial.println("!! Cannot find BME280 on I2C bus at address 0x77. Please check connection or ID");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialise SHT31
|
// initialise SHT31
|
||||||
Serial.println(":: initialise SHT31 sensor, address 0x44 ::");
|
Serial.println(":: initialise SHT31 sensor ::");
|
||||||
if (! sht31_0x44.begin(0x44)) { // Set to 0x45 for alternate i2c addr
|
if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
|
||||||
Serial.println("!! Cannot find SHT31 on I2C bus at address 0x45. Please check connection or ID");
|
Serial.println("Couldn't find SHT31");
|
||||||
}
|
|
||||||
Serial.println(":: initialise SHT31 sensor, address 0x45 ::");
|
|
||||||
if (! sht31_0x45.begin(0x45)) { // Set to 0x45 for alternate i2c addr
|
|
||||||
Serial.println("!! Cannot find SHT31 on I2C bus at address 0x45. Please check connection or ID");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.print(":: SHT31 (0x44) heater enable state ::");
|
Serial.print("SHT31 Heater Enabled State: ");
|
||||||
if (sht31_0x44.isHeaterEnabled())
|
if (sht31.isHeaterEnabled())
|
||||||
Serial.println("ENABLED");
|
Serial.println("ENABLED");
|
||||||
else
|
else
|
||||||
Serial.println("DISABLED");
|
Serial.println("DISABLED");
|
||||||
|
|
||||||
Serial.print(":: SHT31 (0x45) heater enable state ::");
|
|
||||||
if (sht31_0x45.isHeaterEnabled())
|
|
||||||
Serial.println("ENABLED");
|
|
||||||
else
|
|
||||||
Serial.println("DISABLED");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,9 +218,12 @@ void setup() {
|
||||||
// we do this here because otherwise on inverted
|
// we do this here because otherwise on inverted
|
||||||
// boards like CanGrow PCB v0.6 it would be turned on
|
// boards like CanGrow PCB v0.6 it would be turned on
|
||||||
if(configured == true) {
|
if(configured == true) {
|
||||||
initOutputs();
|
pinMode(PinLED, OUTPUT);
|
||||||
|
pinMode(PinPUMP, OUTPUT);
|
||||||
|
pinMode(PinFAN, OUTPUT);
|
||||||
|
// set PWM frequency
|
||||||
|
analogWriteFreq(PWMFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,9 +249,6 @@ void loop() {
|
||||||
// refresh all sensor values
|
// refresh all sensor values
|
||||||
refreshSensors();
|
refreshSensors();
|
||||||
|
|
||||||
// calculate VPD - https://www.grower.ch/forum/threads/diy-grow-controller-cangrow-projektvorstellung.163654/page-4#post-4294197
|
|
||||||
valVPD = (((100 - valHumidity) / 100) * (610.7 * (pow(10, (7.5 * valTemperature / (237.3 + valTemperature))))))/1000;
|
|
||||||
|
|
||||||
// calculate acutal DayOfGrow
|
// calculate acutal DayOfGrow
|
||||||
DayOfGrow = int(ceil(float((timeClient.getEpochTime() - GrowStart) / 60 / 60 / 24)));
|
DayOfGrow = int(ceil(float((timeClient.getEpochTime() - GrowStart) / 60 / 60 / 24)));
|
||||||
// decide if we are in Veg or Bloom phase of grow
|
// decide if we are in Veg or Bloom phase of grow
|
||||||
|
|
|
@ -186,24 +186,6 @@ input[type=text], input[type=date], input[type=number], input[type=password], se
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* VPD colors */
|
|
||||||
|
|
||||||
.vpd_danger1 {
|
|
||||||
color: #1a6c9c;
|
|
||||||
}
|
|
||||||
.vpd_earlyveg {
|
|
||||||
color: #22ab9c;
|
|
||||||
}
|
|
||||||
.vpd_lateveg {
|
|
||||||
color: #9cc55b;
|
|
||||||
}
|
|
||||||
.vpd_latebloom {
|
|
||||||
color: #9cc55b;
|
|
||||||
}
|
|
||||||
.vpd_danger2 {
|
|
||||||
color: #1a6c9c;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -470,7 +452,7 @@ const char HTMLgauge[] PROGMEM = R"EOF(
|
||||||
|
|
||||||
<div class='gaugeWrapper'>
|
<div class='gaugeWrapper'>
|
||||||
<div class='gauge gauge--liveupdate spacer' id='gaugeTemperature' style='float:left; margin-right: 10px;'>
|
<div class='gauge gauge--liveupdate spacer' id='gaugeTemperature' style='float:left; margin-right: 10px;'>
|
||||||
<div class='gaugeLabel'>🌡️ Temperature</div>
|
<div class='gaugeLabel'>Temperature</div>
|
||||||
<div class='gauge__container'>
|
<div class='gauge__container'>
|
||||||
<div class='gauge__background'></div>
|
<div class='gauge__background'></div>
|
||||||
<div class='gauge__center'></div>
|
<div class='gauge__center'></div>
|
||||||
|
@ -485,7 +467,7 @@ const char HTMLgauge[] PROGMEM = R"EOF(
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='gauge gauge--liveupdate spacer' id='gaugeHumidity' style='float:left; margin-right: 10px;'>
|
<div class='gauge gauge--liveupdate spacer' id='gaugeHumidity' style='float:left; margin-right: 10px;'>
|
||||||
<div class='gaugeLabel'>☁️ Humidity</div>
|
<div class='gaugeLabel'>Humidity</div>
|
||||||
<div class='gauge__container'>
|
<div class='gauge__container'>
|
||||||
<div class='gauge__background'></div>
|
<div class='gauge__background'></div>
|
||||||
<div class='gauge__center'></div>
|
<div class='gauge__center'></div>
|
||||||
|
@ -500,7 +482,7 @@ const char HTMLgauge[] PROGMEM = R"EOF(
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='gauge gauge--liveupdate' id='gaugeSoilmoisture' style='float:left;'>
|
<div class='gauge gauge--liveupdate' id='gaugeSoilmoisture' style='float:left;'>
|
||||||
<div class='gaugeLabel'>🪴 Soilmoisture</div>
|
<div class='gaugeLabel'>Soilmoisture</div>
|
||||||
<div class='gauge__container'>
|
<div class='gauge__container'>
|
||||||
<div class='gauge__background'></div>
|
<div class='gauge__background'></div>
|
||||||
<div class='gauge__center'></div>
|
<div class='gauge__center'></div>
|
||||||
|
@ -545,7 +527,7 @@ const char HTMLsystemSubNav[] PROGMEM = R"EOF(
|
||||||
</ul>
|
</ul>
|
||||||
)EOF";
|
)EOF";
|
||||||
|
|
||||||
const char JSsoilmoisture[] PROGMEM = R"EOF(
|
const char JSsoilmoistureTypeSelect[] PROGMEM = R"EOF(
|
||||||
<script>
|
<script>
|
||||||
function MoistureSensorType() {
|
function MoistureSensorType() {
|
||||||
let selVal = document.getElementById('SelMoistureSensor_Type').value;
|
let selVal = document.getElementById('SelMoistureSensor_Type').value;
|
||||||
|
@ -571,30 +553,5 @@ const char JSsoilmoisture[] PROGMEM = R"EOF(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadJSON(callback) {
|
|
||||||
var xobj = new XMLHttpRequest();
|
|
||||||
xobj.overrideMimeType("application/json");
|
|
||||||
xobj.open('GET', '/api/sensors', true);
|
|
||||||
xobj.onreadystatechange = function() {
|
|
||||||
if (xobj.readyState == 4 && xobj.status == "200") {
|
|
||||||
callback(xobj.responseText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xobj.send(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function SoilmoistureRefresh() {
|
|
||||||
loadJSON(function(response) {
|
|
||||||
json = JSON.parse(response);
|
|
||||||
document.getElementById('iSoilmoistureRaw').textContent = json.soilmoistureRaw;
|
|
||||||
console.log(json.soilmoistureRaw);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
)EOF";
|
)EOF";
|
||||||
|
|
||||||
const char HTMLsoilmoistureCalibrateText[] PROGMEM = R"EOF(<p class='helpbox'> <b>Calibration</b><br>
|
|
||||||
Put your soilmoisture sensor into dry soil and hit Refresh.<br>
|
|
||||||
Adjust the value of '<i>Soilmoisture dry</i>' if needed according to the reading.<br>
|
|
||||||
Repeat this with wet soil for '<i>Soilmoisture wet</i>'.</p>)EOF";
|
|
||||||
|
|
|
@ -20,20 +20,12 @@ const bool APhidden = false;
|
||||||
|
|
||||||
// valSoilmoisture - contains the value of getSoilmoisture()
|
// valSoilmoisture - contains the value of getSoilmoisture()
|
||||||
unsigned short valSoilmoisture;
|
unsigned short valSoilmoisture;
|
||||||
// helper variable for pump control with soilmoisture
|
|
||||||
// average of last readings
|
|
||||||
unsigned short valSoilmoistureAvg = 0;
|
|
||||||
unsigned short valSoilmoistureAvg_tmp = 0;
|
|
||||||
byte valSoilmoistureAvg_count = 0;
|
|
||||||
short valSoilmoistureRaw;
|
|
||||||
|
|
||||||
// valTemperature - contains the value of getTemperature()
|
// valTemperature - contains the value of getTemperature()
|
||||||
float valTemperature;
|
float valTemperature;
|
||||||
// valTemperature - contains the value of getHumidity()
|
// valTemperature - contains the value of getHumidity()
|
||||||
float valHumidity;
|
float valHumidity;
|
||||||
// valWaterlevel - contains the value of getWaterlevel()
|
// valWaterlevel - contains the value of getWaterlevel()
|
||||||
byte valWaterlevel;
|
byte valWaterlevel;
|
||||||
|
|
||||||
// do we need a restart? (e.g. after wifi settings change)
|
// do we need a restart? (e.g. after wifi settings change)
|
||||||
bool NeedRestart;
|
bool NeedRestart;
|
||||||
bool FirstRun;
|
bool FirstRun;
|
||||||
|
@ -42,13 +34,6 @@ byte ScreenToDisplay = 0;
|
||||||
// how many seconds actual screen got displayed
|
// how many seconds actual screen got displayed
|
||||||
byte ScreenIterationPassed = 0;
|
byte ScreenIterationPassed = 0;
|
||||||
|
|
||||||
// VPD value - https://www.grower.ch/forum/threads/diy-grow-controller-cangrow-projektvorstellung.163654/page-4#post-4294197
|
|
||||||
float valVPD;
|
|
||||||
|
|
||||||
// DayNight -
|
|
||||||
// true Day , false night
|
|
||||||
bool DayNight;
|
|
||||||
|
|
||||||
bool MaintenanceMode = false;
|
bool MaintenanceMode = false;
|
||||||
unsigned long MaintenanceStarted = 0;
|
unsigned long MaintenanceStarted = 0;
|
||||||
|
|
||||||
|
@ -57,7 +42,12 @@ unsigned long MaintenanceStarted = 0;
|
||||||
byte PumpOnTimePassed = 0;
|
byte PumpOnTimePassed = 0;
|
||||||
bool PumpOnManual = false;
|
bool PumpOnManual = false;
|
||||||
|
|
||||||
|
// helper variable for pump control with soilmoisture
|
||||||
|
// average of last readings
|
||||||
|
unsigned short valSoilmoistureAvg = 0;
|
||||||
|
unsigned short valSoilmoistureAvg_tmp = 0;
|
||||||
|
byte valSoilmoistureAvg_count = 0;
|
||||||
|
//unsigned short
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* millis timer
|
* millis timer
|
||||||
|
|
|
@ -12,17 +12,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SEALEVELPRESSURE_HPA (1013.25)
|
#define SEALEVELPRESSURE_HPA (1013.25)
|
||||||
// dirty way of having multiple addresses configurable
|
Adafruit_BME280 bme;
|
||||||
Adafruit_BME280 bme_0x76;
|
|
||||||
Adafruit_BME280 bme_0x77;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SHT30/31 Stuff
|
* SHT30/31 Stuff
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Adafruit_SHT31 sht31_0x44 = Adafruit_SHT31();
|
bool enableHeater = false;
|
||||||
Adafruit_SHT31 sht31_0x45 = Adafruit_SHT31();
|
Adafruit_SHT31 sht31 = Adafruit_SHT31();
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Chirp functions
|
* Chirp functions
|
||||||
|
@ -104,11 +103,9 @@ float getTemperature(byte tempSensor) {
|
||||||
/*
|
/*
|
||||||
* tempSensor
|
* tempSensor
|
||||||
* ==========
|
* ==========
|
||||||
* 1 : BME280 0x76 temp sensor
|
* 1 : DHT11 temp sensor
|
||||||
* 2 : BME280 0x77 temp sensor
|
* 2 : chirp I2C temp sensor
|
||||||
* 3 : SHT31 0x44 temp sensor
|
* 3 : SHT31
|
||||||
* 4 : SHT31 0x45 temp sensor
|
|
||||||
* 5 : Chirp I2C 0x20 temp sensor
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float temperature = 0;
|
float temperature = 0;
|
||||||
|
@ -116,23 +113,18 @@ float getTemperature(byte tempSensor) {
|
||||||
switch(tempSensor) {
|
switch(tempSensor) {
|
||||||
case 1:
|
case 1:
|
||||||
// read temperature from BME280
|
// read temperature from BME280
|
||||||
temperature = bme_0x76.readTemperature();
|
temperature = bme.readTemperature();
|
||||||
|
// read temperature from DHT11
|
||||||
|
// dht support dropped
|
||||||
|
// temperature = dht.readTemperature();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// read temperature from BME280
|
// read temperature from chrip I2C
|
||||||
temperature = bme_0x77.readTemperature();
|
temperature = readI2CRegister16bit(0x20, 5) * 0.10 ;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// read temp from SHT31
|
// read temp from SHT31
|
||||||
temperature = sht31_0x44.readTemperature();
|
temperature = sht31.readTemperature();
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
// read temp from SHT31
|
|
||||||
temperature = sht31_0x45.readTemperature();
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// read temperature from chrip I2C
|
|
||||||
temperature = readI2CRegister16bit(0x20, 5) * 0.10 ;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// if sensor type is not recognized, return 99
|
// if sensor type is not recognized, return 99
|
||||||
|
@ -146,26 +138,18 @@ float getHumidity(byte HumSensor) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sensors:
|
* sensors:
|
||||||
* 1 : BME280 0x76 humidity sensor
|
* 1: BME280
|
||||||
* 2 : BME280 0x77 humidity sensor
|
* 2: SHT31
|
||||||
* 3 : SHT31 0x44 humidity sensor
|
|
||||||
* 4 : SHT31 0x45 humidity sensor
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
float humidity;
|
float humidity;
|
||||||
|
|
||||||
switch(HumSensor) {
|
switch(HumSensor) {
|
||||||
case 1:
|
case 1:
|
||||||
humidity = bme_0x76.readHumidity();
|
humidity = bme.readHumidity();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
humidity = bme_0x77.readHumidity();
|
humidity = sht31.readHumidity();
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
humidity = sht31_0x44.readHumidity();
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
humidity = sht31_0x45.readHumidity();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
humidity = 0.0;
|
humidity = 0.0;
|
||||||
|
@ -203,7 +187,7 @@ int getSoilmoisture(byte moistureSensor, bool returnRAW = false) {
|
||||||
|
|
||||||
digitalWrite(PINsoilmoisture, HIGH);
|
digitalWrite(PINsoilmoisture, HIGH);
|
||||||
// wait a bit to let the circuit stabilize
|
// wait a bit to let the circuit stabilize
|
||||||
//delay(50);
|
delay(50);
|
||||||
|
|
||||||
// get analog input value
|
// get analog input value
|
||||||
// get values 10 times and get the middle for more precise data
|
// get values 10 times and get the middle for more precise data
|
||||||
|
|
|
@ -114,7 +114,7 @@ bool loadEEPROM() {
|
||||||
* 249 HumiditySensor_Type (1 byte)
|
* 249 HumiditySensor_Type (1 byte)
|
||||||
* 250 PWMFrequency (2 byte)
|
* 250 PWMFrequency (2 byte)
|
||||||
* 252 DisplayScreenDuration (1 byte)
|
* 252 DisplayScreenDuration (1 byte)
|
||||||
* 253 ...
|
* 253
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -551,15 +551,10 @@ void controlLED() {
|
||||||
setOutput(1, PinLEDPWM);
|
setOutput(1, PinLEDPWM);
|
||||||
}
|
}
|
||||||
|
|
||||||
// its daytime
|
|
||||||
DayNight = true;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//Serial.println("good night time");
|
//Serial.println("good night time");
|
||||||
// turn off
|
// turn off
|
||||||
setOutput(1, 0);
|
setOutput(1, 0);
|
||||||
// nighttime
|
|
||||||
DayNight = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,7 +562,6 @@ void refreshSensors() {
|
||||||
byte soilmoistureAvgSampleCount = 5;
|
byte soilmoistureAvgSampleCount = 5;
|
||||||
|
|
||||||
valSoilmoisture = getSoilmoisture(MoistureSensor_Type);
|
valSoilmoisture = getSoilmoisture(MoistureSensor_Type);
|
||||||
valSoilmoistureRaw = getSoilmoisture(MoistureSensor_Type, true);
|
|
||||||
valHumidity = getHumidity(HumiditySensor_Type);
|
valHumidity = getHumidity(HumiditySensor_Type);
|
||||||
valTemperature = getTemperature(TemperatureSensor_Type);
|
valTemperature = getTemperature(TemperatureSensor_Type);
|
||||||
valWaterlevel = getWaterlevel();
|
valWaterlevel = getWaterlevel();
|
||||||
|
@ -736,7 +730,6 @@ void controlPUMP() {
|
||||||
PumpOnManual = false;
|
PumpOnManual = false;
|
||||||
setOutput(3, 0);
|
setOutput(3, 0);
|
||||||
//digitalWrite(PinPUMP, LOW);
|
//digitalWrite(PinPUMP, LOW);
|
||||||
PumpLastOn = timeClient.getEpochTime();
|
|
||||||
EEPROM.put(237, PumpLastOn);
|
EEPROM.put(237, PumpLastOn);
|
||||||
EEPROM.commit(); //write to EEPROM
|
EEPROM.commit(); //write to EEPROM
|
||||||
PumpOnTimePassed = 0;
|
PumpOnTimePassed = 0;
|
||||||
|
@ -831,13 +824,3 @@ void controlFAN() {
|
||||||
setOutput(4, PinFAN2PWM);
|
setOutput(4, PinFAN2PWM);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initOutputs() {
|
|
||||||
pinMode(PinLED, OUTPUT);
|
|
||||||
pinMode(PinPUMP, OUTPUT);
|
|
||||||
pinMode(PinFAN, OUTPUT);
|
|
||||||
// set PWM frequency
|
|
||||||
analogWriteFreq(PWMFrequency);
|
|
||||||
for(byte i = 1; i <= 4; i++) {
|
|
||||||
setOutput(i, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
/*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CANGROW_VER "0.1.4"
|
|
||||||
// CANGROW_BUILD default dummy value if not set as Compiler Flag
|
|
||||||
#ifndef CANGROW_BUILD
|
|
||||||
#define CANGROW_BUILD "1a2b3c4-0000000000000"
|
|
||||||
#endif
|
|
|
@ -78,7 +78,7 @@ String returnHTMLheader(String MenuEntry = "") {
|
||||||
// status icons and info
|
// status icons and info
|
||||||
if(MaintenanceMode == true) {
|
if(MaintenanceMode == true) {
|
||||||
// status icons
|
// status icons
|
||||||
header += " | ⛅ ";
|
header += " | ⏸️ ";
|
||||||
header += MaintenanceDuration - ((millis() - MaintenanceStarted) / 1000);
|
header += MaintenanceDuration - ((millis() - MaintenanceStarted) / 1000);
|
||||||
header += "s";
|
header += "s";
|
||||||
}
|
}
|
||||||
|
@ -210,51 +210,31 @@ void Syslogout() {
|
||||||
void SysMaintenance() {
|
void SysMaintenance() {
|
||||||
String body = returnHTMLheader();
|
String body = returnHTMLheader();
|
||||||
|
|
||||||
// when requesting to handle Dimming
|
|
||||||
if( (webserver.hasArg("DimmOn")) || (webserver.hasArg("DimmOff")) ) {
|
|
||||||
// check first if PWM is disabled / relais is used
|
|
||||||
if(UseLEDrelais == false) {
|
|
||||||
// if not, do it
|
|
||||||
if( (webserver.hasArg("DimmOn")) ) {
|
if( (webserver.hasArg("DimmOn")) ) {
|
||||||
MaintenanceMode = true;
|
MaintenanceMode = true;
|
||||||
MaintenanceStarted = millis();
|
MaintenanceStarted = millis();
|
||||||
body += "<div class='infomsg'>⛅ Dimm LED ON for ";
|
body += "<div class='infomsg'>⏸️ Dimm LED On for ";
|
||||||
body += MaintenanceDuration;
|
body += MaintenanceDuration;
|
||||||
body += "s</div>";
|
body += "s</div>";
|
||||||
} else if( (webserver.hasArg("DimmOff")) ) {
|
} else if (webserver.hasArg("DimmOff")){
|
||||||
MaintenanceMode = false;
|
MaintenanceMode = false;
|
||||||
body += "<div class='infomsg'>⏹️ Dimm LED OFF</div>";
|
body += "<div class='infomsg'>⏸️ Dimm LED Off</div>";
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// otherwise nice error
|
|
||||||
body += "<div class='warnmsg'>⛅ Cannot dimm LED, <i>Use relais for LED (disable PWM)</i> is set to <i>Yes</i> in 🔆 Grow settings</div>";
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if(webserver.hasArg("PumpOnManual")) {
|
} else if(webserver.hasArg("PumpOnManual")) {
|
||||||
if(UsePump > 0) {
|
|
||||||
PumpOnManual = true;
|
PumpOnManual = true;
|
||||||
body += "<div class='infomsg'>💧 Pump manual activated for ";
|
body += "<div class='infomsg'>💧 Pump manual activated for ";
|
||||||
body += PumpOnTime;
|
body += PumpOnTime;
|
||||||
body += "s</div>";
|
body += "s</div>";
|
||||||
} else {
|
|
||||||
body += "<div class='warnmsg'>💧 Cannot activate, <i>Pump mode</i> is set to <i>Off</i> in 🔆 Grow settings</div>";
|
|
||||||
}
|
|
||||||
} else if(webserver.hasArg("PumpOffManual")) {
|
|
||||||
// stooop
|
|
||||||
setOutput(3, 0);
|
|
||||||
PumpOnManual = false;
|
|
||||||
PumpOnTimePassed = 0;
|
|
||||||
body += "<div class='infomsg'>💧 Pump manual stopped</div>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
body += "<h2>🧰 Maintenance</h2>";
|
body += "<h2>🧰 Maintenance</h2>";
|
||||||
|
|
||||||
body += "Dimm LED <a class='button' href='/system/maintenance?DimmOn=1'>⛅ On</a> <a class='button' href='/system/maintenance?DimmOff=1'>⏹️ Off</a><br><br><br>";
|
body += "Dimm LED <a class='button' href='/system/maintenance?DimmOn=1'>On</a> <a class='button' href='/system/maintenance?DimmOff=1'>Off</a><br><br><br>";
|
||||||
body += "Pump manual <a class='button' href='/system/maintenance?PumpOnManual=1'>💧 Activate for ";
|
body += "Pump manual <a class='button' href='/system/maintenance?PumpOnManual=1'>Activate for ";
|
||||||
body += PumpOnTime;
|
body += PumpOnTime;
|
||||||
body += "s</a> ";
|
body += "s</a><br>";
|
||||||
body += "<a class='button' href='/system/maintenance?PumpOffManual=1'>🛑 Stop manual</a><br>";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
body += FPSTR(HTMLfooter);
|
body += FPSTR(HTMLfooter);
|
||||||
|
@ -379,68 +359,25 @@ void WEBroot() {
|
||||||
body += "'></a>\n<br>\n";
|
body += "'></a>\n<br>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
body += "<b>Grow started: 🗓️</b> ";
|
body += "<b>Grow started:</b> ";
|
||||||
body += returnStrDateFromEpoch(GrowStart);
|
body += returnStrDateFromEpoch(GrowStart);
|
||||||
body += "<br>\n";
|
body += "<br>\n";
|
||||||
body += "<b>Harvest date (est.): 🍂 </b> ";
|
|
||||||
body += returnStrDateFromEpoch(GrowStart + (60 * 60 * 24 * (DaysVeg + DaysBloom) ) );
|
|
||||||
body += "<br>\n";
|
|
||||||
body += "<b>Day of Grow:</b> ";
|
body += "<b>Day of Grow:</b> ";
|
||||||
if(DayNight == true) {
|
|
||||||
body += " 🌞 ";
|
|
||||||
} else {
|
|
||||||
body += " 🌚 ";
|
|
||||||
}
|
|
||||||
body += DayOfGrow;
|
body += DayOfGrow;
|
||||||
body += "<br>\n";
|
body += "<br>\n";
|
||||||
body += "<b>Grow status:</b> ";
|
body += "<b>Grow status:</b> ";
|
||||||
switch(growState()) {
|
switch(growState()) {
|
||||||
case 1:
|
case 1:
|
||||||
body += "🌱 Vegetation<br>\n";
|
body += "🌱 vegetation<br>\n";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
body += "🌼 Bloom (";
|
body += "🌼 bloom<br>\n";
|
||||||
body += DayOfGrow - DaysVeg;
|
|
||||||
body += ")<br>\n";
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
body += "🍂 Harvest (";
|
body += "🍂 harvest\n";
|
||||||
body += DayOfGrow - (DaysVeg + DaysBloom);
|
|
||||||
body += ")<br>\n";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VPD
|
|
||||||
body += "<b>VPD (est.): ";
|
|
||||||
// apply text color to the value according to this chart
|
|
||||||
if(valVPD < 0) {
|
|
||||||
body += "⚠️ <span class=''>";
|
|
||||||
body += valVPD;
|
|
||||||
body += "</span></b> (Danger! Check for disease!)";
|
|
||||||
} else if(valVPD < 0.4 ) {
|
|
||||||
body += "⚠️ <span class='vpd_danger1'>";
|
|
||||||
body += valVPD;
|
|
||||||
body += "</span></b> (Danger! Under transpiration!)";
|
|
||||||
} else if(valVPD < 0.8 ) {
|
|
||||||
body += "🍃 <span class='vpd_earlyveg'>";
|
|
||||||
body += valVPD;
|
|
||||||
body += "</span></b> (Early vegetation)";
|
|
||||||
} else if(valVPD < 1.2 ) {
|
|
||||||
body += "🍃 <span class='vpd_lateveg'>";
|
|
||||||
body += valVPD;
|
|
||||||
body += "</span></b> (Late vegetation)";
|
|
||||||
} else if(valVPD < 1.6 ) {
|
|
||||||
body += "🍃 <span class='vpd_latebloom'>";
|
|
||||||
body += valVPD;
|
|
||||||
body += "</span></b> (Late bloom)";
|
|
||||||
} else if(valVPD > 1.6 ) {
|
|
||||||
body += "⚠️ <span class='vpd_danger2'>";
|
|
||||||
body += valVPD;
|
|
||||||
body += "</span></b> (Danger - over transpiration!)";
|
|
||||||
}
|
|
||||||
body += "<br>\n";
|
|
||||||
|
|
||||||
|
|
||||||
if(UsePump > 0) {
|
if(UsePump > 0) {
|
||||||
body += "<b>Pump water level:</b> ";
|
body += "<b>Pump water level:</b> ";
|
||||||
switch(getWaterlevel()) {
|
switch(getWaterlevel()) {
|
||||||
|
@ -460,8 +397,7 @@ void WEBroot() {
|
||||||
body += "<b>Growlight brightness:</b> ";
|
body += "<b>Growlight brightness:</b> ";
|
||||||
body += ((PinLEDPWM * 100) / 255);
|
body += ((PinLEDPWM * 100) / 255);
|
||||||
body += " %<br>\n";
|
body += " %<br>\n";
|
||||||
|
body += "<br>\n";
|
||||||
|
|
||||||
//~ body += "<form method='post' action='/switch'>\n";
|
//~ body += "<form method='post' action='/switch'>\n";
|
||||||
//~ body += "<b>MOSFET:</b> <select id='output' name='output' >\n";
|
//~ body += "<b>MOSFET:</b> <select id='output' name='output' >\n";
|
||||||
//~ body += "<option disabled value='' selected hidden>---</option>\n";
|
//~ body += "<option disabled value='' selected hidden>---</option>\n";
|
||||||
|
@ -480,7 +416,7 @@ void WEBroot() {
|
||||||
|
|
||||||
//~ body += "<input type='submit' value='Save'>\n";
|
//~ body += "<input type='submit' value='Save'>\n";
|
||||||
//~ body += "</form><br>\n";
|
//~ body += "</form><br>\n";
|
||||||
body += "<br><a class='button' href='/system/maintenance'>🧰 Maintenance</a>";
|
body += "<a class='button' href='/system/maintenance'>🧰 Maintenance</a>";
|
||||||
|
|
||||||
|
|
||||||
body += FPSTR(HTMLfooter);
|
body += FPSTR(HTMLfooter);
|
||||||
|
@ -531,35 +467,32 @@ void WEBgrowSettings() {
|
||||||
body+= "' required><br>\n";
|
body+= "' required><br>\n";
|
||||||
|
|
||||||
|
|
||||||
|
// the input field, which calls javascript convertDateToEpoch() to write data to transmit to id GrowStart
|
||||||
|
body += "Grow start date: <input type='date' id='GrowStart_sel' onChange='convertDateToEpoch(\"GrowStart_sel\", \"GrowStart\");' value='";
|
||||||
|
body += returnStrDateFromEpoch(GrowStart);
|
||||||
|
body += "' required><br>\n";
|
||||||
|
|
||||||
body += "<input type='hidden' id='GrowStart' name='GrowStart' value='";
|
body += "<input type='hidden' id='GrowStart' name='GrowStart' value='";
|
||||||
body += GrowStart;
|
body += GrowStart;
|
||||||
body+= "' required>\n";
|
body+= "' required>\n";
|
||||||
|
|
||||||
// the input field, which calls javascript convertDateToEpoch() to write data to transmit to id GrowStart
|
|
||||||
body += "Grow start date: <input type='date' id='GrowStart_sel' onChange='convertDateToEpoch(\"GrowStart_sel\", \"GrowStart\");' value='";
|
|
||||||
body += returnStrDateFromEpoch(GrowStart);
|
|
||||||
body += "' required><br><br>\n";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
body += "<b>Grow duration</b><br>";
|
|
||||||
body += "Vegetation duration: <input class='inputShort' type='number' name='DaysVeg' min='0' max='255' value='";
|
body += "Vegetation duration: <input class='inputShort' type='number' name='DaysVeg' min='0' max='255' value='";
|
||||||
body += DaysVeg;
|
body += DaysVeg;
|
||||||
body+= "' required> Days<br>\n";
|
body+= "' required>days<br>\n";
|
||||||
|
|
||||||
body += "Bloom duration: <input class='inputShort' type='number' name='DaysBloom' min='0' max='255' value='";
|
body += "Bloom duration: <input class='inputShort' type='number' name='DaysBloom' min='0' max='255' value='";
|
||||||
body += DaysBloom;
|
body += DaysBloom;
|
||||||
body+= "' required> Days<br><br>\n";
|
body+= "' required> days<br>\n";
|
||||||
|
|
||||||
|
body += "Time LED ON vegetation: <input class='inputShort' type='number' name='LighthoursVeg' min='0' max='255' value='";
|
||||||
body += "<b>Light configuration</b><br>";
|
|
||||||
body += "LED ON vegetation: <input class='inputShort' type='number' name='LighthoursVeg' min='0' max='255' value='";
|
|
||||||
body += LighthoursVeg;
|
body += LighthoursVeg;
|
||||||
body+= "' required> Hours<br>\n";
|
body+= "' required> hours<br>\n";
|
||||||
|
|
||||||
body += "LED ON bloom: <input class='inputShort' type='number' name='LighthoursBloom' min='0' max='255' value='";
|
body += "Time LED ON bloom: <input class='inputShort' type='number' name='LighthoursBloom' min='0' max='255' value='";
|
||||||
body += LighthoursBloom;
|
body += LighthoursBloom;
|
||||||
body+= "' required> Hours<br>\n";
|
body+= "' required> hours<br>\n";
|
||||||
|
|
||||||
body += "Sunrise: <input class='inputShort' type='number' name='SunriseHour' min='0' max='23' value='";
|
body += "Sunrise: <input class='inputShort' type='number' name='SunriseHour' min='0' max='23' value='";
|
||||||
body += SunriseHour;
|
body += SunriseHour;
|
||||||
|
@ -588,9 +521,7 @@ void WEBgrowSettings() {
|
||||||
body += "<option value='0'" + returnStrSelected(PinLEDPWM, 0) + ">Off</option>\n";
|
body += "<option value='0'" + returnStrSelected(PinLEDPWM, 0) + ">Off</option>\n";
|
||||||
body += "</select><br>\n";
|
body += "</select><br>\n";
|
||||||
}
|
}
|
||||||
body += "<br>";
|
|
||||||
|
|
||||||
body += "<b>Fan configuration</b><br>";
|
|
||||||
if(UseFANrelais == false) {
|
if(UseFANrelais == false) {
|
||||||
body += "FAN1 speed: <input type='range' id='PinFANPWM' name='PinFANPWM' min='0' max='255' value='";
|
body += "FAN1 speed: <input type='range' id='PinFANPWM' name='PinFANPWM' min='0' max='255' value='";
|
||||||
body += PinFANPWM;
|
body += PinFANPWM;
|
||||||
|
@ -604,42 +535,20 @@ void WEBgrowSettings() {
|
||||||
|
|
||||||
body += "FAN2 speed: <input type='range' id='PinFAN2PWM' name='PinFAN2PWM' min='0' max='255' value='";
|
body += "FAN2 speed: <input type='range' id='PinFAN2PWM' name='PinFAN2PWM' min='0' max='255' value='";
|
||||||
body += PinFAN2PWM;
|
body += PinFAN2PWM;
|
||||||
body += "'/> %<br><br>\n";
|
body += "'/> %<br>\n";
|
||||||
|
|
||||||
|
|
||||||
body += "<b>Pump configuration</b><br>";
|
|
||||||
|
|
||||||
// PumpMode byte
|
|
||||||
body += "Pump mode: <select id='UsePump' name='UsePump' required>\n";
|
|
||||||
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
|
||||||
body += "<option value='0'" + returnStrSelected(UsePump, 0) + ">Off</option>\n";
|
|
||||||
body += "<option value='1'" + returnStrSelected(UsePump, 1) + ">1</option>\n";
|
|
||||||
body += "<option value='2'" + returnStrSelected(UsePump, 2) + ">2</option>\n";
|
|
||||||
body += "<option value='3'" + returnStrSelected(UsePump, 3) + ">3</option>\n";
|
|
||||||
body += "</select><br><p class='helpbox'><b>1:</b> Water every few days.<br> \
|
|
||||||
<b>2:</b> Water if the soil moisture falls below <i>Soilmoisture low</i> value<br> \
|
|
||||||
<b>3:</b> Water every few days if the soil moisture falls below <i>Soilmoisture low</i> value.</p>\n";
|
|
||||||
|
|
||||||
// TODO ugly. can this done be better?
|
|
||||||
// PumpOnTime int
|
|
||||||
body += "Pump ON time: <input class='inputShort' type='number' name='PumpOnTime' min='0' max='255' value='";
|
|
||||||
body += PumpOnTime;
|
|
||||||
body += "' required> Seconds<br>\n";
|
|
||||||
|
|
||||||
// SoilmoistureLow byte
|
|
||||||
body += "Soilmoisture low: <input class='inputShort' type='number' name='SoilmoistureLow' min='0' value='";
|
|
||||||
body += SoilmoistureLow;
|
|
||||||
body += "' required> %<br>\n";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
body += "Pump interval vegetation: every <input class='inputShort' type='number' name='PumpIntervalVeg' min='0' max='255' value='";
|
body += "Pump interval vegetation: every <input class='inputShort' type='number' name='PumpIntervalVeg' min='0' max='255' value='";
|
||||||
body += PumpIntervalVeg;
|
body += PumpIntervalVeg;
|
||||||
body += "' required> Days<br>\n";
|
body += "' required ";
|
||||||
|
if( (UsePump != 1) && UsePump != 3) { body += "readonly"; }
|
||||||
|
body += "> days<br>\n";
|
||||||
|
|
||||||
body += "Pump interval bloom: every <input class='inputShort' type='number' name='PumpIntervalBloom' min='0' max='255' value='";
|
body += "Pump interval bloom: every <input class='inputShort' type='number' name='PumpIntervalBloom' min='0' max='255' value='";
|
||||||
body += PumpIntervalBloom;
|
body += PumpIntervalBloom;
|
||||||
body += "' required> Days<br><br>\n";
|
body += "' required ";
|
||||||
|
if((UsePump != 1) && (UsePump != 3)) { body += "readonly"; }
|
||||||
|
body += "> days<br>\n";
|
||||||
|
|
||||||
|
|
||||||
body += "<input type='submit' value='💾 Save settings'>\n";
|
body += "<input type='submit' value='💾 Save settings'>\n";
|
||||||
|
@ -677,31 +586,60 @@ void WEBsystemSettings() {
|
||||||
// form starts
|
// form starts
|
||||||
body += "<form method='post' action='/systemSettings/save'>\n";
|
body += "<form method='post' action='/systemSettings/save'>\n";
|
||||||
|
|
||||||
body += "<b>Output configuration</b><br>";
|
// UseFan bool
|
||||||
|
//~ body += "Fan mode: <select id='UseFan' name='UseFan' required>\n";
|
||||||
|
//~ if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
|
//~ body += "<option value='1'" + returnStrSelected(UseFan, 0) + ">Off</option>\n";
|
||||||
|
//~ body += "<option value='1'" + returnStrSelected(UseFan, 1) + ">Use</option>\n";
|
||||||
|
//~ body += "<option value='0'" + returnStrSelected(UseFan, 2) + ">Do not use</option>\n";
|
||||||
|
//~ body += "</select><br>\n";
|
||||||
|
|
||||||
|
/*
|
||||||
|
// UsePump bool
|
||||||
|
body += "Use PUMP: <select id='UsePump' name='UsePump' required>\n";
|
||||||
|
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
|
body += "<option value='1'" + returnStrSelected(UsePump, 1) + ">Yes</option>\n";
|
||||||
|
body += "<option value='0'" + returnStrSelected(UsePump, 0) + ">No</option>\n";
|
||||||
|
body += "</select><br>\n";
|
||||||
|
*/
|
||||||
|
|
||||||
// OutputInvert bool
|
// OutputInvert bool
|
||||||
body += "Invert Outputs: <select id='OutputInvert' name='OutputInvert' required>\n";
|
body += "Invert Outputs: <select id='OutputInvert' name='OutputInvert' required>\n";
|
||||||
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
body += "<option value='0'" + returnStrSelected(OutputInvert, 0) + ">No</option>\n";
|
|
||||||
body += "<option value='1'" + returnStrSelected(OutputInvert, 1) + ">Yes</option>\n";
|
body += "<option value='1'" + returnStrSelected(OutputInvert, 1) + ">Yes</option>\n";
|
||||||
|
body += "<option value='0'" + returnStrSelected(OutputInvert, 0) + ">No</option>\n";
|
||||||
body += "</select><br>\n";
|
body += "</select><br>\n";
|
||||||
body += "<p class='helpbox'>When using CanGrow PCB v0.6, set to <b>Yes</b></p>\n";
|
|
||||||
|
// PumpMode byte
|
||||||
|
body += "Pump mode: <select id='UsePump' name='UsePump' required>\n";
|
||||||
|
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
|
body += "<option value='0'" + returnStrSelected(UsePump, 0) + ">Off</option>\n";
|
||||||
|
body += "<option value='1'" + returnStrSelected(UsePump, 1) + ">1</option>\n";
|
||||||
|
body += "<option value='2'" + returnStrSelected(UsePump, 2) + ">2</option>\n";
|
||||||
|
body += "<option value='3'" + returnStrSelected(UsePump, 3) + ">3</option>\n";
|
||||||
|
body += "</select><br><p class='helpbox'><b>1:</b> Water every few days.<br> \
|
||||||
|
<b>2:</b> Water if the soil moisture falls below <i>Soilmoisture low</i> value<br> \
|
||||||
|
<b>3:</b> Water every few days if the soil moisture falls below <i>Soilmoisture low</i> value.</p>\n";
|
||||||
|
|
||||||
// UseLEDrelais bool
|
// UseLEDrelais bool
|
||||||
body += "Use relais for LED (disable PWM): <select id='UseLEDrelais' name='UseLEDrelais' required>\n";
|
body += "Use relais for LED (disable PWM): <select id='UseLEDrelais' name='UseLEDrelais' required>\n";
|
||||||
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
body += "<option value='0'" + returnStrSelected(UseLEDrelais, 0) + ">No</option>\n";
|
|
||||||
body += "<option value='1'" + returnStrSelected(UseLEDrelais, 1) + ">Yes</option>\n";
|
body += "<option value='1'" + returnStrSelected(UseLEDrelais, 1) + ">Yes</option>\n";
|
||||||
|
body += "<option value='0'" + returnStrSelected(UseLEDrelais, 0) + ">No</option>\n";
|
||||||
body += "</select><br>\n";
|
body += "</select><br>\n";
|
||||||
|
|
||||||
// UseFANrelais bool
|
// UseFANrelais bool
|
||||||
body += "Use relais for FAN1 (disable PWM): <select id='UseFANrelais' name='UseFANrelais' required>\n";
|
body += "Use relais for FAN (disable PWM): <select id='UseFANrelais' name='UseFANrelais' required>\n";
|
||||||
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
body += "<option value='0'" + returnStrSelected(UseFANrelais, 0) + ">No</option>\n";
|
|
||||||
body += "<option value='1'" + returnStrSelected(UseFANrelais, 1) + ">Yes</option>\n";
|
body += "<option value='1'" + returnStrSelected(UseFANrelais, 1) + ">Yes</option>\n";
|
||||||
body += "</select><br><br>\n";
|
body += "<option value='0'" + returnStrSelected(UseFANrelais, 0) + ">No</option>\n";
|
||||||
|
body += "</select><br>\n";
|
||||||
|
|
||||||
|
// TODO ugly. can this done be better?
|
||||||
body += "<b>Sensor configuration</b><br>";
|
// PumpOnTime int
|
||||||
|
body += "Pump ON time: <input class='inputShort' type='number' name='PumpOnTime' min='0' max='255' value='";
|
||||||
|
body += PumpOnTime;
|
||||||
|
body += "' required> Seconds<br>\n";
|
||||||
|
|
||||||
// MoistureSensor_Type byte
|
// MoistureSensor_Type byte
|
||||||
body += "Soilmoisture sensor: <select id='SelMoistureSensor_Type' name='MoistureSensor_Type' onchange='MoistureSensorType();' required>\n";
|
body += "Soilmoisture sensor: <select id='SelMoistureSensor_Type' name='MoistureSensor_Type' onchange='MoistureSensorType();' required>\n";
|
||||||
|
@ -709,33 +647,31 @@ void WEBsystemSettings() {
|
||||||
body += "<option disabled value='' selected hidden>---</option>\n";
|
body += "<option disabled value='' selected hidden>---</option>\n";
|
||||||
}
|
}
|
||||||
body += "<option value='1'" + returnStrSelected(MoistureSensor_Type, 1) + ">Analog capacitive</option>\n";
|
body += "<option value='1'" + returnStrSelected(MoistureSensor_Type, 1) + ">Analog capacitive</option>\n";
|
||||||
body += "<option value='2'" + returnStrSelected(MoistureSensor_Type, 2) + ">I2C Chirp (0x20)</option>\n";
|
body += "<option value='2'" + returnStrSelected(MoistureSensor_Type, 2) + ">I2C Chirp</option>\n";
|
||||||
body += "</select><br>\n";
|
body += "</select><br>\n";
|
||||||
|
|
||||||
// SoilmoistureDry byte
|
// SoilmoistureLow byte
|
||||||
body += "Soilmoisture dry: <input type='number' id='iSoilmoistureDry' name='SoilmoistureDry' min='0' value='";
|
body += "Soilmoisture low: <input class='inputShort' type='number' name='SoilmoistureLow' min='0' value='";
|
||||||
body += SoilmoistureDry;
|
body += SoilmoistureLow;
|
||||||
body += "' required><br>\n";
|
body += "' required> %<br>\n";
|
||||||
|
|
||||||
// SoilmoistureWet byte
|
// SoilmoistureWet byte
|
||||||
body += "Soilmoisture wet: <input type='number' id='iSoilmoistureWet' name='SoilmoistureWet' min='0' value='";
|
body += "Soilmoisture wet: <input type='number' id='iSoilmoistureWet' name='SoilmoistureWet' min='0' value='";
|
||||||
body += SoilmoistureWet;
|
body += SoilmoistureWet;
|
||||||
body += "' required><br>\n";
|
body += "' required>\n";
|
||||||
|
body += "<p class='helpbox'><b>Analog capacitive:</b> <i>160</i><br> \
|
||||||
|
<b>I2C Chirp:</b> <i>485</i></p>";
|
||||||
|
|
||||||
|
// SoilmoistureDry byte
|
||||||
|
body += "Soilmoisture dry: <input type='number' id='iSoilmoistureDry' name='SoilmoistureDry' min='0' value='";
|
||||||
|
body += SoilmoistureDry;
|
||||||
|
body += "' required>\n";
|
||||||
|
body += "<p class='helpbox'><b>Analog capacitive:</b> <i>360</i><br> \
|
||||||
|
<b>I2C Chirp:</b> <i>250</i></p>";
|
||||||
|
|
||||||
if(configured == true) {
|
|
||||||
// refresh valSoilmoistureRaw to ensure we have fresh data
|
|
||||||
refreshSensors();
|
|
||||||
body += "Soilmoisture raw reading: <i><span id='iSoilmoistureRaw'>";
|
|
||||||
body += valSoilmoistureRaw;
|
|
||||||
body += "</span></i> <input type='button' class='button' value='🔃 Refresh' style='padding: 3px;' onclick='SoilmoistureRefresh();'><br>\n";
|
|
||||||
body += FPSTR(HTMLsoilmoistureCalibrateText);
|
|
||||||
} else {
|
|
||||||
body += "<p class='helpbox'> <b>Calibration</b><br> \
|
|
||||||
You have to save settings first before you can calibrate the soilmoisture sensor.<p>";
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoistureSensor_Type Javascript
|
// MoistureSensor_Type Javascript
|
||||||
body += FPSTR(JSsoilmoisture);
|
body += FPSTR(JSsoilmoistureTypeSelect);
|
||||||
|
|
||||||
|
|
||||||
// TemperatureSensor_Type byte
|
// TemperatureSensor_Type byte
|
||||||
|
@ -743,11 +679,9 @@ void WEBsystemSettings() {
|
||||||
if(configured == false) {
|
if(configured == false) {
|
||||||
body += "<option disabled value='' selected hidden>---</option>\n";
|
body += "<option disabled value='' selected hidden>---</option>\n";
|
||||||
}
|
}
|
||||||
body += "<option value='1'" + returnStrSelected(TemperatureSensor_Type, 1) + ">I2C BME280 (0x76)</option>\n";
|
body += "<option value='1'" + returnStrSelected(TemperatureSensor_Type, 1) + ">I2C BME280</option>\n";
|
||||||
body += "<option value='2'" + returnStrSelected(TemperatureSensor_Type, 2) + ">I2C BME280 (0x77)</option>\n";
|
body += "<option value='2'" + returnStrSelected(TemperatureSensor_Type, 2) + ">I2C Chirp</option>\n";
|
||||||
body += "<option value='3'" + returnStrSelected(TemperatureSensor_Type, 3) + ">I2C SHT31 (0x44)</option>\n";
|
body += "<option value='3'" + returnStrSelected(TemperatureSensor_Type, 3) + ">I2C SHT31</option>\n";
|
||||||
body += "<option value='4'" + returnStrSelected(TemperatureSensor_Type, 4) + ">I2C SHT31 (0x45)</option>\n";
|
|
||||||
body += "<option value='5'" + returnStrSelected(TemperatureSensor_Type, 5) + ">I2C Chirp (0x20)</option>\n";
|
|
||||||
body += "</select><br>\n";
|
body += "</select><br>\n";
|
||||||
|
|
||||||
// HumiditySensor_Type byte
|
// HumiditySensor_Type byte
|
||||||
|
@ -755,18 +689,12 @@ void WEBsystemSettings() {
|
||||||
if(configured == false) {
|
if(configured == false) {
|
||||||
body += "<option disabled value='' selected hidden>---</option>\n";
|
body += "<option disabled value='' selected hidden>---</option>\n";
|
||||||
}
|
}
|
||||||
body += "<option value='1'" + returnStrSelected(HumiditySensor_Type, 1) + ">I2C BME280 (0x76)</option>\n";
|
body += "<option value='1'" + returnStrSelected(HumiditySensor_Type, 1) + ">I2C BME280</option>\n";
|
||||||
body += "<option value='2'" + returnStrSelected(HumiditySensor_Type, 2) + ">I2C BME280 (0x77)</option>\n";
|
body += "<option value='2'" + returnStrSelected(HumiditySensor_Type, 2) + ">I2C SHT31</option>\n";
|
||||||
body += "<option value='3'" + returnStrSelected(HumiditySensor_Type, 3) + ">I2C SHT31 (0x44)</option>\n";
|
body += "</select><br>\n";
|
||||||
body += "<option value='4'" + returnStrSelected(HumiditySensor_Type, 4) + ">I2C SHT31 (0x45)</option>\n";
|
|
||||||
body += "</select><br><br>\n";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
body += "<b>General configuration</b><br>";
|
|
||||||
|
|
||||||
// NtpOffset int
|
// NtpOffset int
|
||||||
body += "NTP offset/UTC timezone: <input class='inputShort' type='number' name='NtpOffset' min='-12' max='14' value='";
|
body += "NTP offset: <input class='inputShort' type='number' name='NtpOffset' min='-12' max='14' value='";
|
||||||
body += NtpOffset;
|
body += NtpOffset;
|
||||||
body+= "' required> Hours<br>\n";
|
body+= "' required> Hours<br>\n";
|
||||||
|
|
||||||
|
@ -782,12 +710,12 @@ void WEBsystemSettings() {
|
||||||
// DisplayScreenDuration byte
|
// DisplayScreenDuration byte
|
||||||
body += "Display rotation interval: <input class='inputShort' type='number' name='DisplayScreenDuration' min='0' max='255' value='";
|
body += "Display rotation interval: <input class='inputShort' type='number' name='DisplayScreenDuration' min='0' max='255' value='";
|
||||||
body += DisplayScreenDuration;
|
body += DisplayScreenDuration;
|
||||||
body += "' required> Seconds<br>\n";
|
body += "' required> s<br>\n";
|
||||||
body += "<p class='helpbox'><b>0</b> will always show sensor value screen</p>";
|
body += "<p class='helpbox'><b>0</b> will always show sensor value screen</p>";
|
||||||
|
|
||||||
body += "ESP32-Cam IP (optional): <input type='text' name='Esp32CamIP' maxlength='16' value='";
|
body += "ESP32-Cam IP (optional): <input type='text' name='Esp32CamIP' maxlength='16' value='";
|
||||||
body += Esp32CamIP;
|
body += Esp32CamIP;
|
||||||
body += "' ><br><br>\n";
|
body += "' ><br>\n";
|
||||||
|
|
||||||
|
|
||||||
body += "<input type='submit' value='💾 Save settings'>\n";
|
body += "<input type='submit' value='💾 Save settings'>\n";
|
||||||
|
@ -856,7 +784,7 @@ void WEBwifiSettings() {
|
||||||
body += "IP: <input type='text' name='WIFIip'><br>\n";
|
body += "IP: <input type='text' name='WIFIip'><br>\n";
|
||||||
body += "Subnet mask: <input type='text' name='WIFInetmask'><br>\n";
|
body += "Subnet mask: <input type='text' name='WIFInetmask'><br>\n";
|
||||||
body += "Gateway: <input type='text' name='WIFIgateway'><br>\n";
|
body += "Gateway: <input type='text' name='WIFIgateway'><br>\n";
|
||||||
body += "DNS: <input type='text' name='WIFIdns'><br><br>\n";
|
body += "DNS: <input type='text' name='WIFIdns'><br>\n";
|
||||||
body += "<input type='submit' value='💾 Save settings'>\n";
|
body += "<input type='submit' value='💾 Save settings'>\n";
|
||||||
body += "</form>\n";
|
body += "</form>\n";
|
||||||
body += FPSTR(HTMLfooter);
|
body += FPSTR(HTMLfooter);
|
||||||
|
@ -896,11 +824,6 @@ void POSTgrowSettings() {
|
||||||
SunriseMinute = webserver.arg("SunriseMinute").toInt();
|
SunriseMinute = webserver.arg("SunriseMinute").toInt();
|
||||||
SunFade = webserver.arg("SunFade").toInt();
|
SunFade = webserver.arg("SunFade").toInt();
|
||||||
SunFadeDuration = webserver.arg("SunFadeDuration").toInt();
|
SunFadeDuration = webserver.arg("SunFadeDuration").toInt();
|
||||||
|
|
||||||
UsePump = webserver.arg("UsePump").toInt();
|
|
||||||
PumpOnTime = webserver.arg("PumpOnTime").toInt();
|
|
||||||
SoilmoistureLow = webserver.arg("SoilmoistureLow").toInt();
|
|
||||||
|
|
||||||
PumpIntervalVeg = webserver.arg("PumpIntervalVeg").toInt();
|
PumpIntervalVeg = webserver.arg("PumpIntervalVeg").toInt();
|
||||||
PumpIntervalBloom = webserver.arg("PumpIntervalBloom").toInt();
|
PumpIntervalBloom = webserver.arg("PumpIntervalBloom").toInt();
|
||||||
|
|
||||||
|
@ -928,15 +851,6 @@ void POSTgrowSettings() {
|
||||||
EEPROM.put(248, PinFAN2PWM);
|
EEPROM.put(248, PinFAN2PWM);
|
||||||
EEPROM.put(217, SunFade);
|
EEPROM.put(217, SunFade);
|
||||||
EEPROM.put(218, SunFadeDuration);
|
EEPROM.put(218, SunFadeDuration);
|
||||||
|
|
||||||
// size is 1 byte
|
|
||||||
EEPROM.put(163, UsePump);
|
|
||||||
// size is 1 byte
|
|
||||||
EEPROM.put(164, PumpOnTime);
|
|
||||||
// size is 1 byte
|
|
||||||
EEPROM.put(166, SoilmoistureLow);
|
|
||||||
|
|
||||||
|
|
||||||
// size is 1 byte
|
// size is 1 byte
|
||||||
EEPROM.put(241, PumpIntervalVeg);
|
EEPROM.put(241, PumpIntervalVeg);
|
||||||
// size is 1 byte
|
// size is 1 byte
|
||||||
|
@ -974,20 +888,6 @@ void POSTgrowSettings() {
|
||||||
Serial.print("PinFAN2PWM: ");
|
Serial.print("PinFAN2PWM: ");
|
||||||
Serial.println(PinFAN2PWM);
|
Serial.println(PinFAN2PWM);
|
||||||
|
|
||||||
Serial.print("UsePump: ");
|
|
||||||
Serial.println(UsePump);
|
|
||||||
Serial.print("PumpOnTime: ");
|
|
||||||
Serial.println(PumpOnTime);
|
|
||||||
Serial.print("SoilmoistureLow: ");
|
|
||||||
Serial.println(SoilmoistureLow);
|
|
||||||
|
|
||||||
Serial.print("PumpIntervalVeg: ");
|
|
||||||
Serial.println(PumpIntervalVeg);
|
|
||||||
Serial.print("PumpIntervalBloom: ");
|
|
||||||
Serial.println(PumpIntervalBloom);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
webserver.sendHeader("Location", String("/growSettings?success"), true);
|
webserver.sendHeader("Location", String("/growSettings?success"), true);
|
||||||
webserver.send(302, "text/plain", "growSettings/save: success!\n");
|
webserver.send(302, "text/plain", "growSettings/save: success!\n");
|
||||||
}
|
}
|
||||||
|
@ -1001,8 +901,9 @@ void POSTsystemSettings() {
|
||||||
|
|
||||||
NtpOffset = webserver.arg("NtpOffset").toInt();
|
NtpOffset = webserver.arg("NtpOffset").toInt();
|
||||||
MoistureSensor_Type = webserver.arg("MoistureSensor_Type").toInt();
|
MoistureSensor_Type = webserver.arg("MoistureSensor_Type").toInt();
|
||||||
|
SoilmoistureLow = webserver.arg("SoilmoistureLow").toInt();
|
||||||
|
UsePump = webserver.arg("UsePump").toInt();
|
||||||
|
PumpOnTime = webserver.arg("PumpOnTime").toInt();
|
||||||
UseFan = webserver.arg("UseFan").toInt();
|
UseFan = webserver.arg("UseFan").toInt();
|
||||||
UseLEDrelais = webserver.arg("UseLEDrelais").toInt();
|
UseLEDrelais = webserver.arg("UseLEDrelais").toInt();
|
||||||
UseFANrelais = webserver.arg("UseFANrelais").toInt();
|
UseFANrelais = webserver.arg("UseFANrelais").toInt();
|
||||||
|
@ -1020,17 +921,23 @@ void POSTsystemSettings() {
|
||||||
// when configured is false, set it to true and ensure outputs are set
|
// when configured is false, set it to true and ensure outputs are set
|
||||||
if(configured == false) {
|
if(configured == false) {
|
||||||
configured = true;
|
configured = true;
|
||||||
initOutputs();
|
pinMode(PinLED, OUTPUT);
|
||||||
|
pinMode(PinPUMP, OUTPUT);
|
||||||
|
pinMode(PinFAN, OUTPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// size is 1 byte
|
// size is 1 byte
|
||||||
EEPROM.put(161, configured);
|
EEPROM.put(161, configured);
|
||||||
// size is 1 byte
|
// size is 1 byte
|
||||||
EEPROM.put(162, UseFan);
|
EEPROM.put(162, UseFan);
|
||||||
|
// size is 1 byte
|
||||||
|
EEPROM.put(163, UsePump);
|
||||||
|
// size is 1 byte
|
||||||
|
EEPROM.put(164, PumpOnTime);
|
||||||
// size is 1 byte
|
// size is 1 byte
|
||||||
EEPROM.put(165, MoistureSensor_Type);
|
EEPROM.put(165, MoistureSensor_Type);
|
||||||
|
// size is 1 byte
|
||||||
|
EEPROM.put(166, SoilmoistureLow);
|
||||||
// size is 2 byte
|
// size is 2 byte
|
||||||
EEPROM.put(167, NtpOffset);
|
EEPROM.put(167, NtpOffset);
|
||||||
// size is 1 byte
|
// size is 1 byte
|
||||||
|
@ -1084,10 +991,14 @@ void POSTsystemSettings() {
|
||||||
Serial.println(configured);
|
Serial.println(configured);
|
||||||
Serial.print("UseFan: ");
|
Serial.print("UseFan: ");
|
||||||
Serial.println(UseFan);
|
Serial.println(UseFan);
|
||||||
|
Serial.print("UsePump: ");
|
||||||
|
Serial.println(UsePump);
|
||||||
|
Serial.print("PumpOnTime: ");
|
||||||
|
Serial.println(PumpOnTime);
|
||||||
Serial.print("MoistureSensor_Type: ");
|
Serial.print("MoistureSensor_Type: ");
|
||||||
Serial.println(MoistureSensor_Type);
|
Serial.println(MoistureSensor_Type);
|
||||||
|
Serial.print("SoilmoistureLow: ");
|
||||||
|
Serial.println(SoilmoistureLow);
|
||||||
Serial.print("NtpOffset: ");
|
Serial.print("NtpOffset: ");
|
||||||
Serial.println(NtpOffset);
|
Serial.println(NtpOffset);
|
||||||
Serial.print("UseLEDrelais: ");
|
Serial.print("UseLEDrelais: ");
|
||||||
|
@ -1235,11 +1146,9 @@ void APIgetSensors() {
|
||||||
|
|
||||||
jsonSensors["soilmoisture"] = valSoilmoisture;
|
jsonSensors["soilmoisture"] = valSoilmoisture;
|
||||||
jsonSensors["soilmoistureAvg"] = valSoilmoistureAvg;
|
jsonSensors["soilmoistureAvg"] = valSoilmoistureAvg;
|
||||||
jsonSensors["soilmoistureRaw"] = valSoilmoistureRaw;
|
|
||||||
jsonSensors["temperature"] = valTemperature;
|
jsonSensors["temperature"] = valTemperature;
|
||||||
jsonSensors["humidity"] = valHumidity;
|
jsonSensors["humidity"] = valHumidity;
|
||||||
jsonSensors["waterlevel"] = valWaterlevel;
|
jsonSensors["waterlevel"] = valWaterlevel;
|
||||||
jsonSensors["vpd"] = valVPD;
|
|
||||||
|
|
||||||
String body;
|
String body;
|
||||||
serializeJsonPretty(jsonSensors, body);
|
serializeJsonPretty(jsonSensors, body);
|
||||||
|
@ -1255,21 +1164,9 @@ void APIgetDebug() {
|
||||||
JsonObject objRuntime = jsonDebug["runtime"].add<JsonObject>();
|
JsonObject objRuntime = jsonDebug["runtime"].add<JsonObject>();
|
||||||
objRuntime["PumpOnTimePassed"] = PumpOnTimePassed;
|
objRuntime["PumpOnTimePassed"] = PumpOnTimePassed;
|
||||||
objRuntime["PumpOnManual"] = PumpOnManual;
|
objRuntime["PumpOnManual"] = PumpOnManual;
|
||||||
objRuntime["valTemperature"] = valTemperature;
|
|
||||||
objRuntime["valHumidity"] = valHumidity;
|
|
||||||
objRuntime["valSoilmoisture"] = valSoilmoisture;
|
|
||||||
objRuntime["valSoilmoistureRaw"] = valSoilmoistureRaw;
|
|
||||||
objRuntime["valSoilmoistureAvg"] = valSoilmoistureAvg;
|
objRuntime["valSoilmoistureAvg"] = valSoilmoistureAvg;
|
||||||
objRuntime["valSoilmoistureAvg_tmp"] = valSoilmoistureAvg_tmp;
|
objRuntime["valSoilmoistureAvg_tmp"] = valSoilmoistureAvg_tmp;
|
||||||
objRuntime["valSoilmoistureAvg_count"] = valSoilmoistureAvg_count;
|
objRuntime["valSoilmoistureAvg_count"] = valSoilmoistureAvg_count;
|
||||||
objRuntime["NeedRestart"] = NeedRestart;
|
|
||||||
objRuntime["FirstRun"] = FirstRun;
|
|
||||||
objRuntime["ScreenToDisplay"] = ScreenToDisplay;
|
|
||||||
objRuntime["ScreenIterationPassed"] = ScreenIterationPassed;
|
|
||||||
objRuntime["DayNight"] = DayNight;
|
|
||||||
objRuntime["MaintenanceMode"] = MaintenanceMode;
|
|
||||||
objRuntime["MaintenanceStarted"] = MaintenanceStarted;
|
|
||||||
|
|
||||||
|
|
||||||
// WiFi
|
// WiFi
|
||||||
JsonObject objWiFi = jsonDebug["wifi"].add<JsonObject>();
|
JsonObject objWiFi = jsonDebug["wifi"].add<JsonObject>();
|
||||||
|
@ -1294,13 +1191,6 @@ void APIgetDebug() {
|
||||||
objSystem["MaintenanceDuration"] = MaintenanceDuration;
|
objSystem["MaintenanceDuration"] = MaintenanceDuration;
|
||||||
objSystem["PumpOnTime"] = PumpOnTime;
|
objSystem["PumpOnTime"] = PumpOnTime;
|
||||||
objSystem["PumpLastOn"] = PumpLastOn;
|
objSystem["PumpLastOn"] = PumpLastOn;
|
||||||
objSystem["OutputInvert"] = OutputInvert;
|
|
||||||
objSystem["SoilmoistureWet"] = SoilmoistureWet;
|
|
||||||
objSystem["SoilmoistureDry"] = SoilmoistureDry;
|
|
||||||
objSystem["HumiditySensor_Type"] = HumiditySensor_Type;
|
|
||||||
objSystem["PWMFrequency"] = PWMFrequency;
|
|
||||||
objSystem["DisplayScreenDuration"] = DisplayScreenDuration;
|
|
||||||
objSystem["Esp32CamIP"] = Esp32CamIP;
|
|
||||||
|
|
||||||
// Grow
|
// Grow
|
||||||
JsonObject objGrow = jsonDebug["grow"].add<JsonObject>();
|
JsonObject objGrow = jsonDebug["grow"].add<JsonObject>();
|
||||||
|
@ -1317,42 +1207,25 @@ void APIgetDebug() {
|
||||||
objGrow["SunFadeDuration"] = SunFadeDuration;
|
objGrow["SunFadeDuration"] = SunFadeDuration;
|
||||||
objGrow["PinLEDPWM"] = PinLEDPWM;
|
objGrow["PinLEDPWM"] = PinLEDPWM;
|
||||||
objGrow["PinFANPWM"] = PinFANPWM;
|
objGrow["PinFANPWM"] = PinFANPWM;
|
||||||
objGrow["PinFAN2PWM"] = PinFAN2PWM;
|
|
||||||
objGrow["DayOfGrow"] = DayOfGrow;
|
objGrow["DayOfGrow"] = DayOfGrow;
|
||||||
objGrow["PumpIntervalVeg"] = PumpIntervalVeg;
|
objGrow["PumpIntervalVeg"] = PumpIntervalVeg;
|
||||||
objGrow["PumpIntervalBloom"] = PumpIntervalBloom;
|
objGrow["PumpIntervalBloom"] = PumpIntervalBloom;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Sensors
|
// Sensors
|
||||||
JsonObject objSensors = jsonDebug["sensors"].add<JsonObject>();
|
JsonObject objSensors = jsonDebug["sensors"].add<JsonObject>();
|
||||||
|
|
||||||
// Chirp
|
// Chirp
|
||||||
objSensors["chirp"]["temperature"] = getTemperature(5);
|
objSensors["chirp"]["temperature"] = getTemperature(2);
|
||||||
objSensors["chirp"]["soilmoisture"] = getSoilmoisture(2);
|
objSensors["chirp"]["soilmoisture"] = getSoilmoisture(2);
|
||||||
objSensors["chirp"]["soilmoistureRAW"] = getSoilmoisture(2, true);
|
objSensors["chirp"]["soilmoistureRAW"] = getSoilmoisture(2, true);
|
||||||
objSensors["chirp"]["light"] = getLightchirp();
|
objSensors["chirp"]["light"] = getLightchirp();
|
||||||
|
|
||||||
// BME280 0x76
|
// BME280
|
||||||
objSensors["bme280_0x76"]["temperature"] = getTemperature(1);
|
objSensors["bme280"]["temperature"] = getTemperature(1);
|
||||||
objSensors["bme280_0x76"]["humidity"] = getHumidity(1);
|
objSensors["bme280"]["humidity"] = getHumidity(1);
|
||||||
//objSensors["bme280_0x76"]["preassure"] = bme.readPressure() / 100.0F;
|
objSensors["bme280"]["preassure"] = bme.readPressure() / 100.0F;
|
||||||
//objSensors["bme280_0x76"]["appAltitude"] = bme.readAltitude(SEALEVELPRESSURE_HPA);
|
objSensors["bme280"]["appAltitude"] = bme.readAltitude(SEALEVELPRESSURE_HPA);
|
||||||
|
|
||||||
// BME280 0x77
|
|
||||||
objSensors["bme280_0x77"]["temperature"] = getTemperature(2);
|
|
||||||
objSensors["bme280_0x77"]["humidity"] = getHumidity(2);
|
|
||||||
//objSensors["bme280_0x77"]["preassure"] = bme.readPressure() / 100.0F;
|
|
||||||
//objSensors["bme280_0x77"]["appAltitude"] = bme.readAltitude(SEALEVELPRESSURE_HPA);
|
|
||||||
|
|
||||||
// SHT31 0x44
|
|
||||||
objSensors["sht31_0x44"]["temperature"] = getTemperature(3);
|
|
||||||
objSensors["sht31_0x44"]["humidity"] = getHumidity(3);
|
|
||||||
|
|
||||||
// SHT31 0x45
|
|
||||||
objSensors["sht31_0x45"]["temperature"] = getTemperature(4);
|
|
||||||
objSensors["sht31_0x45"]["humidity"] = getHumidity(4);
|
|
||||||
|
|
||||||
// Analog
|
// Analog
|
||||||
objSensors["analog"]["soilmoisture"] = getSoilmoisture(1);
|
objSensors["analog"]["soilmoisture"] = getSoilmoisture(1);
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 372 KiB After Width: | Height: | Size: 291 KiB |
|
@ -1 +0,0 @@
|
||||||
Subproject commit d4720987895bc49bdb38beb9d3e288de8bd59078
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 9412f3d1a2e334a3415d79df706dad02925488aa
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 5e34a20df62371150f7cb10330919e9393b884b1
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 78d6a130b2045a8b7b76616da81603796757ed47
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 7b2473b6b24ae340f41685b5f5b2b90ad896db04
|
|
File diff suppressed because it is too large
Load diff
|
@ -1 +0,0 @@
|
||||||
Subproject commit 61684d4516839b579b81105be3447499c1417908
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit a18e50dcea4ee17285d732d39e7bc559482d1d3d
|
|
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
test -z $TTY && TTY="/dev/ttyUSB0"
|
test -z $TTY && TTY="/dev/ttyUSB0"
|
||||||
test -z $IP && IP="192.168.4.20"
|
test -z $IP && IP="192.168.4.20"
|
||||||
|
test -z $VER && VER="0.1.0"
|
||||||
VER="$(grep "define CANGROW_VER" Arduino/CanGrow/CanGrow_Version.h | cut -d \" -f2 |sed -e 's/\"//g')"
|
|
||||||
BUILD="$(git rev-parse --short HEAD)-$(date '+%Y%m%d%H%M%S')"
|
BUILD="$(git rev-parse --short HEAD)-$(date '+%Y%m%d%H%M%S')"
|
||||||
|
|
||||||
ACLI="$HOME/.local/bin/arduino-cli"
|
ACLI="$HOME/.local/bin/arduino-cli"
|
||||||
|
@ -75,8 +74,7 @@ case $1 in
|
||||||
check_acli
|
check_acli
|
||||||
echo ":: Building firmware $VER $BUILD, target dir: $(pwd)/build/"
|
echo ":: Building firmware $VER $BUILD, target dir: $(pwd)/build/"
|
||||||
test -d build || mkdir build
|
test -d build || mkdir build
|
||||||
${ACLI_CMD} --no-color compile -b ${BOARD} "Arduino/CanGrow/CanGrow.ino" --build-property "build.extra_flags=-DCANGROW_BUILD=\"${BUILD}\"" --output-dir build/ || exit 1
|
${ACLI_CMD} --no-color compile -b ${BOARD} "Arduino/CanGrow/CanGrow.ino" --build-property "build.extra_flags=-DCANGROW_VER=\"${VER}\" -DCANGROW_BUILD=\"${BUILD}\"" --output-dir build/ || exit 1
|
||||||
#${ACLI_CMD} --no-color compile -b ${BOARD} "Arduino/CanGrow/CanGrow.ino" --build-property "build.extra_flags=-DCANGROW_VER=\"${VER}\" -DCANGROW_BUILD=\"${BUILD}\"" --output-dir build/ || exit 1
|
|
||||||
cp build/CanGrow.ino.bin build/CanGrow_v${VER}_${BUILD}.bin
|
cp build/CanGrow.ino.bin build/CanGrow_v${VER}_${BUILD}.bin
|
||||||
;;
|
;;
|
||||||
u|upload)
|
u|upload)
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset='UTF-8'>
|
<meta charset='UTF-8'>
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
||||||
<title>CanGrow - Amnesia Haze</title>
|
<title>CanGrow - Ruderalis Indica</title>
|
||||||
|
|
||||||
<link rel='icon' href='data:;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAABcElEQVQ4y42TzU/bQBDFf7Nx1qGuAYVgQSuo2khBggPhyIH//9AiJAQ9tEeLqCKiUD6sxF52OMSEBCdW57aa9968fTsr3V5XWVLPO6sANNL7ZRAMNeU6Ea4T1UEI6pr55kcAwhpMrYOpk2/r/yEQmKWkIonf+TZVgex4Fw0bIEtIAALF3gbZ8U5VwKa3PJ18JT9IpiLvyflBwuhLG5veVUM0/0aoCONPa2hQjWZ8uEVeupJnXSBwO8YOH8iTeAKc2Q4Xt2C1VZL93F7MjbK/bxDnp5Zn7b+So+9pdQ+K/Q5qJlrRj5Ts6DM+rK7Ih7Mr3HaM7jYQVZqXQ6Tb6yqBYdTfomhHiFfUyMI3f+01/z7RHNzTGDyWGThP63SA2d8EEfIkrgQpzmOvH0AV+3M4zegNpUwagAYG8Yp4BS0nl4Kz5Mpf0JXJMby6w/66Aa+M+9uE53/Iexsggq4ESOYWC0jmsBfX8xdXhcJjL4cLc3kBl8uJGQ/CrpAAAAAASUVORK5CYII='>
|
<link rel='icon' href='data:;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAABcElEQVQ4y42TzU/bQBDFf7Nx1qGuAYVgQSuo2khBggPhyIH//9AiJAQ9tEeLqCKiUD6sxF52OMSEBCdW57aa9968fTsr3V5XWVLPO6sANNL7ZRAMNeU6Ea4T1UEI6pr55kcAwhpMrYOpk2/r/yEQmKWkIonf+TZVgex4Fw0bIEtIAALF3gbZ8U5VwKa3PJ18JT9IpiLvyflBwuhLG5veVUM0/0aoCONPa2hQjWZ8uEVeupJnXSBwO8YOH8iTeAKc2Q4Xt2C1VZL93F7MjbK/bxDnp5Zn7b+So+9pdQ+K/Q5qJlrRj5Ts6DM+rK7Ih7Mr3HaM7jYQVZqXQ6Tb6yqBYdTfomhHiFfUyMI3f+01/z7RHNzTGDyWGThP63SA2d8EEfIkrgQpzmOvH0AV+3M4zegNpUwagAYG8Yp4BS0nl4Kz5Mpf0JXJMby6w/66Aa+M+9uE53/Iexsggq4ESOYWC0jmsBfX8xdXhcJjL4cLc3kBl8uJGQ/CrpAAAAAASUVORK5CYII='>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
color: #cae0d0;
|
color: #cae0d0;
|
||||||
background-color: #1d211e;
|
background-color: #1d211e;
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
font-family: helvetica;
|
||||||
}
|
}
|
||||||
|
|
||||||
.center {
|
.center {
|
||||||
|
@ -19,12 +19,6 @@ body {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.centered {
|
|
||||||
display: block;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4, h5 {
|
h1, h2, h3, h4, h5 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
@ -59,12 +53,6 @@ a:active {
|
||||||
width: 42px;
|
width: 42px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.helpbox {
|
|
||||||
font-size: 0.8em;
|
|
||||||
margin-left: 15px;
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
.nav {
|
.nav {
|
||||||
background: #333;
|
background: #333;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -75,27 +63,9 @@ a:active {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subnav {
|
|
||||||
text-align: center;
|
|
||||||
display: table;
|
|
||||||
margin: auto;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 0;
|
|
||||||
position: relative;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav li {
|
.nav li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subnav li {
|
|
||||||
background: #026b45;
|
|
||||||
list-style: none;
|
|
||||||
border-radius: 3px;
|
|
||||||
margin-bottom: 3px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav li:first-of-type {
|
.nav li:first-of-type {
|
||||||
|
@ -103,7 +73,7 @@ a:active {
|
||||||
border-top-left-radius: 3px;
|
border-top-left-radius: 3px;
|
||||||
border-bottom-left-radius: 3px;
|
border-bottom-left-radius: 3px;
|
||||||
}
|
}
|
||||||
.nav li a, .nav span, .subnav li a, .subnav span, .button, .button:link, input[type=button], input[type=submit], input[type=reset] {
|
.nav li a , .nav span, .button, .button:link, input[type=button], input[type=submit], input[type=reset] {
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
display: block;
|
display: block;
|
||||||
font-family: 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
|
font-family: 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
|
||||||
|
@ -113,13 +83,13 @@ a:active {
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav li a:hover, .subnav li a:hover, .activeMenu, .button:link:hover, .button:visited:hover, input[type=button]:hover, input[type=submit]:hover, input[type=reset]:hover {
|
.nav li a:hover , .activeMenu, .button:link:hover, .button:visited:hover, input[type=button]:hover, input[type=submit]:hover, input[type=reset]:hover {
|
||||||
background: #04AA6D;
|
background: #04AA6D;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav li a:active, .subnav li a:active {
|
.nav li a:active {
|
||||||
background: #026b45;
|
background: #026b45;
|
||||||
color: #cae0d0;
|
color: #cae0d0;
|
||||||
}
|
}
|
||||||
|
@ -155,151 +125,73 @@ input[type=text], input[type=date], input[type=number], input[type=password], se
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 1820px) {
|
@media only screen and (min-width: 1280px) {
|
||||||
.center, .nav {
|
.center, .nav {
|
||||||
width: 60%; min-width: 420px;
|
width: 60%; min-width: 420px;
|
||||||
}
|
}
|
||||||
.subnav li {
|
|
||||||
display: '';
|
|
||||||
margin-bottom: 3px;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 640px) {
|
|
||||||
.subnav li {
|
|
||||||
display: inline-block;
|
|
||||||
margin-bottom: 3px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* VPD colors */
|
|
||||||
|
|
||||||
.vpd_danger1 {
|
|
||||||
color: #1a6c9c;
|
|
||||||
}
|
|
||||||
.vpd_earlyveg {
|
|
||||||
color: #22ab9c;
|
|
||||||
}
|
|
||||||
.vpd_lateveg {
|
|
||||||
color: #9cc55b;
|
|
||||||
}
|
|
||||||
.vpd_latebloom {
|
|
||||||
color: #9cc55b;
|
|
||||||
}
|
|
||||||
.vpd_danger2 {
|
|
||||||
color: #1a6c9c;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<ul class='nav'><li><a href='/'>🌱 Amnesiaaaa Haze</a></li>
|
<ul class='nav'><li><a href='/'>🌱 Ruderalis Indica</a></li>
|
||||||
<li><a href='/growSettings' >🔆 Grow settings</a></li>
|
<li><a href='/growSettings' >🔆 Grow settings</a></li>
|
||||||
<li><a href='/systemSettings' class='activeMenu'>⚙ System settings</a></li>
|
<li><a href='/systemSettings' class='activeMenu'>⚙ System settings</a></li>
|
||||||
<li><a href='/wifiSettings' >📡 WiFi settings</a></li>
|
<li><a href='/wifiSettings' >📡 WiFi settings</a></li>
|
||||||
<li><a href='/help' >❓ Help</a></li>
|
<li><a href='/help' >❓ Help</a></li>
|
||||||
<li><span class='MenuTime'>00:23:10</span></li>
|
<li><span class='MenuTime'>00:03:39</span></li>
|
||||||
<li><a href='https://git.la10cy.net/DeltaLima/CanGrow' target='_blank'>CanGrow v0.1.3-dev</a></li>
|
<li><a href='https://git.la10cy.net/DeltaLima/CanGrow' target='_blank'>CanGrow v0.1</a></li>
|
||||||
</ul><div class='center'><h2>⚙ System settings</h2>
|
</ul><div class='center'><h2>⚙ System settings</h2><p>here you can set which features and sensors you use<br></p><form method='post' action='/systemSettings/save'>
|
||||||
<ul class='subnav'>
|
<table>
|
||||||
<li><a href='/system/update'>🔄 Firmware update</a></li>
|
<tr>
|
||||||
<li><a href='/system/restart' >🔁 CanGrow restart</a></li>
|
<td>Use FAN: </td>
|
||||||
<li><a href='/system/wipe' >💣 Factory reset</a></li>
|
<td>
|
||||||
</ul>
|
<select id='UseFan' name='UseFan' required>
|
||||||
<p>here you can set which features and sensors you use<br></p><form method='post' action='/systemSettings/save'>
|
|
||||||
<b>Output configuration</b><br>Invert Outputs: <select id='OutputInvert' name='OutputInvert' required>
|
|
||||||
<option value='0'>No</option>
|
|
||||||
<option value='1' selected >Yes</option>
|
<option value='1' selected >Yes</option>
|
||||||
</select><br>
|
<option value='0'>No</option>
|
||||||
<p class='helpbox'>When using CanGrow PCB v0.6, set to <b>Yes</b></p>
|
</select>
|
||||||
Use relais for LED (disable PWM): <select id='UseLEDrelais' name='UseLEDrelais' required>
|
</td>
|
||||||
<option value='0' selected >No</option>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Use PUMP: </td>
|
||||||
|
<td><select id='UsePump' name='UsePump' required>
|
||||||
|
<option value='1' selected >Yes</option>
|
||||||
|
<option value='0'>No</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Use relais for LED:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select id='UseLEDrelais' name='UseLEDrelais' required>
|
||||||
<option value='1'>Yes</option>
|
<option value='1'>Yes</option>
|
||||||
</select><br>
|
<option value='0' selected >No</option>
|
||||||
Use relais for FAN1 (disable PWM): <select id='UseFANrelais' name='UseFANrelais' required>
|
</select>
|
||||||
<option value='0'>No</option>
|
</td>
|
||||||
<option value='1' selected >Yes</option>
|
</tr>
|
||||||
</select><br><br>
|
<tr>
|
||||||
<b>Sensor configuration</b><br>Soilmoisture sensor: <select id='SelMoistureSensor_Type' name='MoistureSensor_Type' onchange='MoistureSensorType();' required>
|
<td></td>Use relais for FAN: </td>
|
||||||
|
<select id='UseFANrelais' name='UseFANrelais' required>
|
||||||
|
<option value='1'>Yes</option>
|
||||||
|
<option value='0' selected >No</option>
|
||||||
|
</select>
|
||||||
|
</tr>
|
||||||
|
PUMP ON time: <input class='inputShort' type='number' name='PumpOnTime' min='0' max='255' value='3' required> Seconds<br>
|
||||||
|
Soilmoisture sensor: <select id='MoistureSensor_Type' name='MoistureSensor_Type' required>
|
||||||
<option value='1' selected >Analog capacitive</option>
|
<option value='1' selected >Analog capacitive</option>
|
||||||
<option value='2'>I2C Chirp (0x20)</option>
|
<option value='2'>I2C chirp</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
Soilmoisture dry: <input type='number' id='iSoilmoistureDry' name='SoilmoistureDry' min='0' value='360' required><br>
|
Soilmoisture low: <input class='inputShort' type='number' name='SoilmoistureLow' min='0' value='20' required> %<br>
|
||||||
Soilmoisture wet: <input type='number' id='iSoilmoistureWet' name='SoilmoistureWet' min='0' value='160' required><br>
|
|
||||||
Soilmoisture raw reading: <i><span id='iSoilmoistureRaw'>123</span></i> <input type='button' class='button' value='🔃 Refresh' style='padding: 3px;' onclick='SoilmoistureRefresh();'>
|
|
||||||
<p class='helpbox'>
|
|
||||||
<b>Calibration</b><br>
|
|
||||||
Put your soilmoisture sensor into dry soil and hit Refresh.<br>
|
|
||||||
Adjust the value of 'Soilmoisture dry' if needed according to the reading.<br>
|
|
||||||
Repeat this with wet soil for 'Soilmoisture wet'.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
function loadJSON(callback) {
|
|
||||||
var xobj = new XMLHttpRequest();
|
|
||||||
xobj.overrideMimeType("application/json");
|
|
||||||
xobj.open('GET', '/api/sensors', true);
|
|
||||||
xobj.onreadystatechange = function() {
|
|
||||||
if (xobj.readyState == 4 && xobj.status == "200") {
|
|
||||||
callback(xobj.responseText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xobj.send(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function SoilmoistureRefresh() {
|
|
||||||
loadJSON(function(response) {
|
|
||||||
json = JSON.parse(response);
|
|
||||||
document.getElementById('iSoilmoistureRaw').textContent = json.soilmoistureRaw;
|
|
||||||
console.log(json.soilmoistureRaw);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function MoistureSensorType() {
|
|
||||||
let selVal = document.getElementById('SelMoistureSensor_Type').value;
|
|
||||||
let wet = document.getElementById('iSoilmoistureWet');
|
|
||||||
let dry = document.getElementById('iSoilmoistureDry');
|
|
||||||
switch(selVal) {
|
|
||||||
case '1':
|
|
||||||
wet.value = 160;
|
|
||||||
dry.value = 360;
|
|
||||||
console.log(selVal);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '2':
|
|
||||||
wet.value = 485;
|
|
||||||
dry.value = 250;
|
|
||||||
console.log(selVal);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
wet.value = 0;
|
|
||||||
dry.value = 0;
|
|
||||||
console.log(selVal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
Temperature sensor: <select id='TemperatureSensor_Type' name='TemperatureSensor_Type' required>
|
Temperature sensor: <select id='TemperatureSensor_Type' name='TemperatureSensor_Type' required>
|
||||||
<option value='1' selected >I2C BME280 (0x76)</option>
|
<option value='1' selected >DHT11/22</option>
|
||||||
<option value='2'>I2C BME280 (0x77)</option>
|
<option value='2'>I2C chirp</option>
|
||||||
<option value='3'>I2C SHT31 (0x44)</option>
|
|
||||||
<option value='4'>I2C SHT31 (0x45)</option>
|
|
||||||
<option value='5'>I2C Chirp (0x20)</option>
|
|
||||||
</select><br>
|
</select><br>
|
||||||
Humidity sensor: <select id='HumiditySensor_Type' name='HumiditySensor_Type' required>
|
NTP offset: <input class='inputShort' type='number' name='NtpOffset' min='-12' max='14' value='2' required> Hours<br>
|
||||||
<option value='1' selected >I2C BME280 (0x76)</option>
|
|
||||||
<option value='2'>I2C BME280 (0x77)</option>
|
|
||||||
<option value='3'>I2C SHT31 (0x44)</option>
|
|
||||||
<option value='4'>I2C SHT31 (0x45)</option>
|
|
||||||
</select><br><br>
|
|
||||||
<b>General configuration</b><br>NTP offset/UTC timezone: <input class='inputShort' type='number' name='NtpOffset' min='-12' max='14' value='1' required> Hours<br>
|
|
||||||
Maintenance Duration: <input class='inputShort' type='number' name='MaintenanceDuration' min='0' max='900' value='300' required> Seconds<br>
|
Maintenance Duration: <input class='inputShort' type='number' name='MaintenanceDuration' min='0' max='900' value='300' required> Seconds<br>
|
||||||
PWM Frequency: <input type='number' name='PWMFrequency' min='0' max='20000' value='13370' required> Hz<br>
|
<input type='submit' value='Save'>
|
||||||
Display rotation interval: <input class='inputShort' type='number' name='DisplayScreenDuration' min='0' max='255' value='3' required> Seconds<br>
|
|
||||||
<p class='helpbox'><b>0</b> will always show sensor value screen</p>ESP32-Cam IP (optional): <input type='text' name='Esp32CamIP' maxlength='16' value='' ><br><br>
|
</table>
|
||||||
<input type='submit' value='💾 Save settings'>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue