main stuff for adding new output is done. for i2c i have not idea atm what i need.

This commit is contained in:
Marcus 2024-10-26 22:10:39 +02:00
parent b7d21ca868
commit 40d0175564
6 changed files with 158 additions and 52 deletions

View file

@ -133,7 +133,8 @@ void setup() {
Webserver_Init(); Webserver_Init();
Serial.printf(":: [SETUP] Usable Pins: %d\n", GPIOindex_length); Serial.printf(":: [SETUP] Usable Pins: %d\n", GPIOindex_length);
for(byte i = 0; i < GPIOindex_length; i++) { for(byte i = 0; i < GPIOindex_length; i++) {
Serial.printf(":: [SETUP] Pin Index: %d, GPIO: %d, Notes: %d\n", i, GPIOindex[i].gpio, GPIOindex[i].note); Serial.printf(":: [SETUP] Pin Index: %d, GPIO: %d, Notes: ", i, GPIOindex[i].gpio);
Serial.println(GPIO_Index_note_descr[GPIOindex[i].note]);
} }
} }

View file

@ -77,7 +77,7 @@ char INPUT_ONLY_descr[] = "IN_ONLY";
char NO_PWM_descr[] = "NO_PWM"; char NO_PWM_descr[] = "NO_PWM";
char HIGH_BOOT_descr[] = "B_HIGH"; char HIGH_BOOT_descr[] = "B_HIGH";
const char * GPIO_Index_note[] = { const char * GPIO_Index_note_descr[] = {
NULL, // 0 - no note NULL, // 0 - no note
BOOTFAILS_LOW_descr, // 1 BOOTFAILS_LOW_descr, // 1
BOOTFAILS_HIGH_descr, // 2 BOOTFAILS_HIGH_descr, // 2
@ -87,11 +87,61 @@ const char * GPIO_Index_note[] = {
HIGH_BOOT_descr, // 6 HIGH_BOOT_descr, // 6
}; };
/*
* Output Type
*/
// 0 is unconfigured
const byte Output_Type_total = 4;
const byte OUTPUT_TYPE_GPIO = 1; const byte OUTPUT_TYPE_GPIO = 1;
const byte OUTPUT_TYPE_I2C = 2; const byte OUTPUT_TYPE_I2C = 2;
const byte OUTPUT_TYPE_WEB = 3; const byte OUTPUT_TYPE_WEB = 3;
char OUTPUT_TYPE_GPIO_descr[] = "GPIO";
char OUTPUT_TYPE_I2C_descr[] = "I2C";
char OUTPUT_TYPE_WEB_descr[] = "Webcall";
const char * Output_Type_descr[] = {
NULL, // 0 - no description because 0 means unconfigured
OUTPUT_TYPE_GPIO_descr,
OUTPUT_TYPE_I2C_descr,
OUTPUT_TYPE_WEB_descr,
};
/*
* Output Device
*/
// 0 is unconfigured
const byte Output_Device_total = 7;
const byte OUTPUT_DEVICE_LIGHT = 1;
const byte OUTPUT_DEVICE_FAN = 2;
const byte OUTPUT_DEVICE_PUMP = 3;
const byte OUTPUT_DEVICE_HUMIDIFIER = 4;
const byte OUTPUT_DEVICE_DEHUMIDIFIER = 5;
const byte OUTPUT_DEVICE_HEATING = 6;
char OUTPUT_DEVICE_LIGHT_descr[] = "Light";
char OUTPUT_DEVICE_FAN_descr[] = "Fan";
char OUTPUT_DEVICE_PUMP_descr[] = "Pump";
char OUTPUT_DEVICE_HUMIDIFIER_descr[] = "Humidifier";
char OUTPUT_DEVICE_DEHUMIDIFIER_descr[] = "Dehumidifier";
char OUTPUT_DEVICE_HEATING_descr[] = "Heating";
const char * Output_Device_descr[] = {
NULL, // 0 - no description because 0 means unconfigured
OUTPUT_DEVICE_LIGHT_descr,
OUTPUT_DEVICE_FAN_descr,
OUTPUT_DEVICE_PUMP_descr,
OUTPUT_DEVICE_HUMIDIFIER_descr,
OUTPUT_DEVICE_DEHUMIDIFIER_descr,
OUTPUT_DEVICE_HEATING_descr,
};
struct GPIO_Index { struct GPIO_Index {
const byte gpio; const byte gpio;
const byte note; const byte note;
@ -146,9 +196,9 @@ struct Config_System_Output {
* - gpio_invert: invert gpio output * - gpio_invert: invert gpio output
* - gpio_pwm: enable pwm for output * - gpio_pwm: enable pwm for output
* - i2c: * - i2c:
* - web_host: ip to smart plug (tasmota e.g.) * - webcall_host: ip to smart plug (tasmota e.g.)
* - web_req_on: GET request path to turn ON * - webcall_path_on: GET request path to turn ON
* - web_req_off: GET request path to turn ON * - webcall_path_off: GET request path to turn OFF
* *
*/ */
@ -160,9 +210,9 @@ struct Config_System_Output {
bool gpio_invert[Max_Outputs]; bool gpio_invert[Max_Outputs];
bool gpio_pwm[Max_Outputs]; bool gpio_pwm[Max_Outputs];
char i2c[Max_Outputs][8]; char i2c[Max_Outputs][8];
char web_host[Max_Outputs][32]; char webcall_host[Max_Outputs][32];
char web_req_on[Max_Outputs][32]; char webcall_path_on[Max_Outputs][32];
char web_req_off[Max_Outputs][32]; char webcall_path_off[Max_Outputs][32];
}; };
/* main System struct */ /* main System struct */

View file

@ -221,9 +221,9 @@ bool LoadConfig() {
// i2c // i2c
strlcpy(config.system.output.i2c[i], objSystemOutput["i2c"][i], sizeof(config.system.output.i2c[i])); strlcpy(config.system.output.i2c[i], objSystemOutput["i2c"][i], sizeof(config.system.output.i2c[i]));
// web // web
strlcpy(config.system.output.web_host[i], objSystemOutput["web_host"][i], sizeof(config.system.output.web_host[i])); strlcpy(config.system.output.webcall_host[i], objSystemOutput["webcall_host"][i], sizeof(config.system.output.webcall_host[i]));
strlcpy(config.system.output.web_req_on[i], objSystemOutput["web_req_on"][i], sizeof(config.system.output.web_req_on[i])); strlcpy(config.system.output.webcall_path_on[i], objSystemOutput["webcall_path_on"][i], sizeof(config.system.output.webcall_path_on[i]));
strlcpy(config.system.output.web_req_off[i], objSystemOutput["web_req_off"][i], sizeof(config.system.output.web_req_off[i])); strlcpy(config.system.output.webcall_path_off[i], objSystemOutput["webcall_path_off"][i], sizeof(config.system.output.webcall_path_off[i]));
} }
} }
@ -301,9 +301,9 @@ bool SaveConfig(bool writeToSerial = false) {
// i2c // i2c
objSystemOutput["i2c"][i] = config.system.output.i2c[i]; objSystemOutput["i2c"][i] = config.system.output.i2c[i];
// web // web
objSystemOutput["web_host"][i] = config.system.output.web_host[i]; objSystemOutput["webcall_host"][i] = config.system.output.webcall_host[i];
objSystemOutput["web_req_on"][i] = config.system.output.web_req_on[i]; objSystemOutput["webcall_path_on"][i] = config.system.output.webcall_path_on[i];
objSystemOutput["web_req_off"][i] = config.system.output.web_req_off[i]; objSystemOutput["webcall_path_off"][i] = config.system.output.webcall_path_off[i];
} }
} }

View file

@ -64,6 +64,7 @@ h3 {
td { td {
text-align: left; text-align: left;
vertical-align: middle; vertical-align: middle;
border-bottom: 1px solid #262B27;
} }
a:link, a:visited { a:link, a:visited {

View file

@ -312,9 +312,9 @@ String Proc_WebPage_system_output(const String& var) {
output_tr_td += "</td><td>"; output_tr_td += "</td><td>";
output_tr_td += config.system.output.name[i]; output_tr_td += config.system.output.name[i];
output_tr_td += "</td><td>"; output_tr_td += "</td><td>";
output_tr_td += config.system.output.type[i]; output_tr_td += Output_Type_descr[config.system.output.type[i]];
output_tr_td += "</td><td>"; output_tr_td += "</td><td>";
output_tr_td += config.system.output.device[i]; output_tr_td += Output_Device_descr[config.system.output.device[i]];
output_tr_td += "</td><td>"; output_tr_td += "</td><td>";
output_tr_td += config.system.output.enabled[i]; output_tr_td += config.system.output.enabled[i];
output_tr_td += "</td><td><a href='#"; output_tr_td += "</td><td><a href='#";
@ -367,6 +367,33 @@ String Proc_WebPage_system_output_add(const String& var) {
// we check which id is free. A free ID as type == 0 // we check which id is free. A free ID as type == 0
return String(Give_Free_OutputId()); return String(Give_Free_OutputId());
/* OUTPUT_TYPE */
} else if(var == "OUTPUT_TYPE") {
String outputType_html;
// go through all available Output Devices, skip 0 because it means unconfigured
for(byte i = 1; i < Output_Type_total; i++) {
outputType_html += "<option value='";
outputType_html += i;
outputType_html += "'>";
outputType_html += Output_Type_descr[i];
outputType_html += "</option>";
}
return outputType_html;
/* OUTPUT_DEVICE */
} else if(var == "OUTPUT_DEVICE") {
String outputDevice_html;
// go through all available Output Devices, skip 0 because it means unconfigured
for(byte i = 1; i < Output_Device_total; i++) {
outputDevice_html += "<option value='";
outputDevice_html += i;
outputDevice_html += "'>";
outputDevice_html += Output_Device_descr[i];
outputDevice_html += "</option>";
}
return outputDevice_html;
/* GPIO_INDEX */
} else if(var == "GPIO_INDEX") { } else if(var == "GPIO_INDEX") {
String gpioIndex_html; String gpioIndex_html;
// iterate through through all available GPIOs in index // iterate through through all available GPIOs in index
@ -385,7 +412,7 @@ String Proc_WebPage_system_output_add(const String& var) {
//add gpio note if there is some //add gpio note if there is some
//if(GPIOindex[i].note > 0) { //if(GPIOindex[i].note > 0) {
gpioIndex_html += " "; gpioIndex_html += " ";
gpioIndex_html += GPIO_Index_note[GPIOindex[i].note]; gpioIndex_html += GPIO_Index_note_descr[GPIOindex[i].note];
// disable output incompatible gpio // disable output incompatible gpio
if(GPIOindex[i].note == INPUT_ONLY) { if(GPIOindex[i].note == INPUT_ONLY) {
@ -472,25 +499,59 @@ void WebPage_system_output_add(AsyncWebServerRequest *request) {
config.system.output.enabled[outputId] = p_enabled->value().toInt(); config.system.output.enabled[outputId] = p_enabled->value().toInt();
} }
// only fill gpio values if type is GPIO // only fill the type related config vars
if(outputType == 1) { switch(outputType) {
if(request->hasParam("gpio", true)) { // GPIO
const AsyncWebParameter* p_gpio = request->getParam("gpio", true); case 1:
Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_gpio->name().c_str(), p_gpio->value().c_str()); if(request->hasParam("gpio", true)) {
config.system.output.gpio[outputId] = p_gpio->value().toInt(); const AsyncWebParameter* p_gpio = request->getParam("gpio", true);
} Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_gpio->name().c_str(), p_gpio->value().c_str());
config.system.output.gpio[outputId] = p_gpio->value().toInt();
}
if(request->hasParam("gpio_pwm", true)) { if(request->hasParam("gpio_pwm", true)) {
const AsyncWebParameter* p_gpio_pwm = request->getParam("gpio_pwm", true); const AsyncWebParameter* p_gpio_pwm = request->getParam("gpio_pwm", true);
Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_gpio_pwm->name().c_str(), p_gpio_pwm->value().c_str()); Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_gpio_pwm->name().c_str(), p_gpio_pwm->value().c_str());
config.system.output.gpio_pwm[outputId] = p_gpio_pwm->value().toInt(); config.system.output.gpio_pwm[outputId] = p_gpio_pwm->value().toInt();
} }
if(request->hasParam("gpio_invert", true)) { if(request->hasParam("gpio_invert", true)) {
const AsyncWebParameter* p_gpio_invert = request->getParam("gpio_invert", true); const AsyncWebParameter* p_gpio_invert = request->getParam("gpio_invert", true);
Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_gpio_invert->name().c_str(), p_gpio_invert->value().c_str()); Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_gpio_invert->name().c_str(), p_gpio_invert->value().c_str());
config.system.output.gpio_invert[outputId] = p_gpio_invert->value().toInt(); config.system.output.gpio_invert[outputId] = p_gpio_invert->value().toInt();
} }
break;
// I2C
case 2:
if(request->hasParam("i2c", true)) {
const AsyncWebParameter* p_i2c = request->getParam("i2c", true);
Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_i2c->name().c_str(), p_i2c->value().c_str());
strlcpy(config.system.output.i2c[outputId], p_i2c->value().c_str(), sizeof(config.system.output.i2c[outputId]));
}
break;
// Webcall
case 3:
if(request->hasParam("webcall_host", true)) {
const AsyncWebParameter* p_webcall_host = request->getParam("webcall_host", true);
Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_webcall_host->name().c_str(), p_webcall_host->value().c_str());
strlcpy(config.system.output.webcall_host[outputId], p_webcall_host->value().c_str(), sizeof(config.system.output.webcall_host[outputId]));
}
if(request->hasParam("webcall_path_on", true)) {
const AsyncWebParameter* p_webcall_path_on = request->getParam("webcall_path_on", true);
Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_webcall_path_on->name().c_str(), p_webcall_path_on->value().c_str());
strlcpy(config.system.output.webcall_path_on[outputId], p_webcall_path_on->value().c_str(), sizeof(config.system.output.webcall_path_on[outputId]));
}
if(request->hasParam("webcall_path_off", true)) {
const AsyncWebParameter* p_webcall_path_off = request->getParam("webcall_path_off", true);
Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_webcall_path_off->name().c_str(), p_webcall_path_off->value().c_str());
strlcpy(config.system.output.webcall_path_off[outputId], p_webcall_path_off->value().c_str(), sizeof(config.system.output.webcall_path_off[outputId]));
}
break;
default: break;
} }

View file

@ -165,20 +165,13 @@ const char* Page_system_output_add_HTML PROGMEM = R"(%HEADER%
<u>Type</u>:<br> <u>Type</u>:<br>
<select id='type_sel' name='type' onchange="showSelect('type_sel', 'type_', 'hidden');" required> <select id='type_sel' name='type' onchange="showSelect('type_sel', 'type_', 'hidden');" required>
<option disabled value='' selected hidden>---</option> <option disabled value='' selected hidden>---</option>
<option value='1'>GPIO</option> %OUTPUT_TYPE%
<option value='2'>I2C</option>
<option value='3'>URL</option>
</select><br> </select><br>
<u>Device</u>:<br> <u>Device</u>:<br>
<select name='device' required> <select name='device' required>
<option disabled value='' selected hidden>---</option> <option disabled value='' selected hidden>---</option>
<option value='1'>Light</option> %OUTPUT_DEVICE%
<option value='2'>Fan</option>
<option value='3'>Pump</option>
<option value='3'>Humidifier</option>
<option value='3'>Dehumidifier</option>
<option value='3'>Heating</option>
</select><br> </select><br>
<u>Name</u>:<br> <u>Name</u>:<br>
@ -220,14 +213,14 @@ const char* Page_system_output_add_HTML PROGMEM = R"(%HEADER%
</div> </div>
<div class='hidden' id='type_3'> <div class='hidden' id='type_3'>
<u>Web</u>:<br> <u>Webcall host</u>:<br>
<input type='text' name='web_host' maxlength='32' value='' ><br> <input type='text' name='webcall_host' maxlength='32' value='' ><br>
<u>URI on</u>:<br> <u>Webcall path 'on'</u>:<br>
<input type='text' name='web_req_on' maxlength='32' value='' ><br> <input type='text' name='webcall_path_on' maxlength='32' value='' ><br>
<u>URI off</u>:<br> <u>Webcall path 'off'</u>:<br>
<input type='text' name='web_req_off' maxlength='32' value='' ><br> <input type='text' name='webcall_path_off' maxlength='32' value='' ><br>
</div> </div>
<br> <br>