From c8247268cccb7e0998d4171cddb7c084b9d6be39 Mon Sep 17 00:00:00 2001 From: Marcus Date: Sat, 26 Oct 2024 16:54:39 +0200 Subject: [PATCH] implement checks if gpio is free when adding new output --- Arduino/CanGrow/CanGrow.ino | 38 +----------- Arduino/CanGrow/include/CanGrow.h | 22 ++++--- Arduino/CanGrow/include/CanGrow_Core.h | 59 ++++++++++++++++++- Arduino/CanGrow/include/CanGrow_LittleFS.h | 26 ++++---- .../CanGrow/include/Webserver/Page_system.h | 53 ++++++++++++----- .../include/Webserver/Page_system_HTML.h | 17 ++++-- 6 files changed, 140 insertions(+), 75 deletions(-) diff --git a/Arduino/CanGrow/CanGrow.ino b/Arduino/CanGrow/CanGrow.ino index cafc769..798c6bd 100644 --- a/Arduino/CanGrow/CanGrow.ino +++ b/Arduino/CanGrow/CanGrow.ino @@ -149,43 +149,7 @@ void loop() { if((digitalRead(PinWIPE) != PinWIPE_default) && (alrdySaved == false)) { - Serial.println(":: [LOOP] PinWIPE is triggered, saving config.json and set config.system.httpLogSerial to true"); - config.system.httpLogSerial = true; - - // testing output save stuff - - Serial.println(":: [LOOP] save output 0"); - byte i = 0; - config.system.output.type[i] = 1; - config.system.output.device[i] = 1; - strlcpy(config.system.output.name[i], "bla", sizeof("bla")); - config.system.output.gpio[i] = 3; - config.system.output.gpio_invert[i] = false; - config.system.output.gpio_pwm[i] = false; - strlcpy(config.system.output.i2c[i], "0x3", sizeof("0x3")); - - for(byte j=0; j < 4 ; j++) { - config.system.output.ip[i][j] = j + 3; - } - strlcpy(config.system.output.ip_path[i], "/asd?foo=lol", sizeof("/asd?foo=lol")); - config.system.output.enabled[i] = true; - - Serial.println(":: [LOOP] save output 1"); - i = 1; - config.system.output.type[i] = 2; - config.system.output.device[i] = 3; - strlcpy(config.system.output.name[i], "lol", sizeof("lol")); - config.system.output.gpio[i] = 5; - config.system.output.gpio_invert[i] = true; - config.system.output.gpio_pwm[i] = true; - strlcpy(config.system.output.i2c[i], "0x69", sizeof("0x69")); - - for(byte j=0; j < 4 ; j++) { - config.system.output.ip[i][j] = j + 23; - } - strlcpy(config.system.output.ip_path[i], "/toggle_switch?on=true", sizeof("/toggle_switch?on=true")); - config.system.output.enabled[i] = true; - + Serial.println(":: [LOOP] PinWIPE is triggered"); // save config to littlefs as json SaveConfig(); // only print json to serial diff --git a/Arduino/CanGrow/include/CanGrow.h b/Arduino/CanGrow/include/CanGrow.h index 3947b34..9eb890b 100644 --- a/Arduino/CanGrow/include/CanGrow.h +++ b/Arduino/CanGrow/include/CanGrow.h @@ -70,6 +70,10 @@ const byte INPUT_ONLY = 4; const byte NO_PWM = 5; const byte HIGH_BOOT = 6; +const byte OUTPUT_TYPE_GPIO = 1; +const byte OUTPUT_TYPE_I2C = 2; +const byte OUTPUT_TYPE_WEB = 3; + struct GPIO_Index { const byte gpio; const byte note; @@ -110,7 +114,7 @@ struct Config_System_Output { * - output_type: output type like GPIO, I2C, URL * 1 - GPIO * 2 - I2C - * 3 - URL + * 3 - Web * - device: what this output is connected to * 1 - Light * 2 - Fan @@ -118,25 +122,29 @@ struct Config_System_Output { * 4 - Humudifier * 5 - Dehumidifier * 6 - Heating + * - name: name of output + * - enabled: enable output * - gpio: which gpio is used * - gpio_invert: invert gpio output * - gpio_pwm: enable pwm for output * - i2c: - * - ip: ip to smart plug (tasmota e.g.) - * - ip_path: uri path - * - enabled: enable output + * - web_host: ip to smart plug (tasmota e.g.) + * - web_req_on: GET request path to turn ON + * - web_req_off: GET request path to turn ON + * */ byte type[Max_Outputs]; byte device[Max_Outputs]; char name[Max_Outputs][32]; + bool enabled[Max_Outputs]; byte gpio[Max_Outputs]; bool gpio_invert[Max_Outputs]; bool gpio_pwm[Max_Outputs]; char i2c[Max_Outputs][8]; - byte ip[Max_Outputs][4]; - char ip_path[Max_Outputs][32]; - bool enabled[Max_Outputs]; + char web_host[Max_Outputs][32]; + char web_req_on[Max_Outputs][32]; + char web_req_off[Max_Outputs][32]; }; /* main System struct */ diff --git a/Arduino/CanGrow/include/CanGrow_Core.h b/Arduino/CanGrow/include/CanGrow_Core.h index 10a69cd..7a0782f 100644 --- a/Arduino/CanGrow/include/CanGrow_Core.h +++ b/Arduino/CanGrow/include/CanGrow_Core.h @@ -30,7 +30,7 @@ // blink fast with the built in LED in an infinite loop void Restart() { - Serial.println(":: [Restart] got triggered, restarting in 2 seconds"); + Serial.println(":: [Core:Restart] got triggered, restarting in 2 seconds"); byte i = 0; while(i <= 16) { if(i % 2) { @@ -55,3 +55,60 @@ char* IP2Char(IPAddress ipaddr){ sprintf(buffer, "%d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3] ); return buffer; } + +byte Give_Free_OutputId() { + byte outputId_free; + for(byte i=0; i < Max_Outputs; i++) { + if(config.system.output.type[i] > 0) { + // here i define that 255 stands for "no more free outputs" + outputId_free = 255; + } else { + outputId_free = i; + break; + } + } + #ifndef DEBUG + Serial.printf("DB [Core:Give_Free_OutputId] next free output id: %d\n", outputId_free); + #endif + return outputId_free; +} + +//bool Check_OutputId_Used(byte outputId) { + +//} + +// checks if GPIO is already in use by output or sensor +bool Check_GPIOindex_Used(byte gpio) { + bool used; + #ifndef DEBUG + Serial.printf("DB [Core:Check_GPIOindex_Used] check GPIO: %d\n", gpio); + #endif + // go through each outputid + for(byte i=0; i < Max_Outputs; i++) { + #ifndef DEBUG + //Serial.printf("DB [Core:Check_GPIOindex_Used] OutputId: %d , type: %d\n", i, config.system.output.type[i]); + #endif + // check if output type is gpio + if(config.system.output.type[i] == OUTPUT_TYPE_GPIO) { + #ifndef DEBUG + Serial.printf("DB [Core:Check_GPIOindex_Used] OutputId: %d is GPIO (type %d)\n", i, config.system.output.type[i]); + #endif + // check if gpio id is already in use + if(config.system.output.gpio[i] == gpio) { + #ifndef DEBUG + Serial.printf("DB [Core:Check_GPIOindex_Used] output.gpio[%d](%d) == GPIO %d\n", i, config.system.output.gpio[i], gpio); + #endif + used = true; + break; + } else { + used = false; + } + } + } + #ifndef DEBUG + Serial.printf("DB [Core:Check_GPIOindex_Used] GPIO: %d, used: %d\n", gpio, used); + #endif + // check sensors + + return used; +} diff --git a/Arduino/CanGrow/include/CanGrow_LittleFS.h b/Arduino/CanGrow/include/CanGrow_LittleFS.h index e1daaee..4f54291 100644 --- a/Arduino/CanGrow/include/CanGrow_LittleFS.h +++ b/Arduino/CanGrow/include/CanGrow_LittleFS.h @@ -213,15 +213,17 @@ bool LoadConfig() { config.system.output.type[i] = objSystemOutput["type"][i]; config.system.output.device[i] = objSystemOutput["device"][i]; strlcpy(config.system.output.name[i], objSystemOutput["name"][i], sizeof(config.system.output.name[i])); + config.system.output.enabled[i] = objSystemOutput["enabled"][i]; + // gpio config.system.output.gpio[i] = objSystemOutput["gpio"][i]; config.system.output.gpio_invert[i] = objSystemOutput["gpio_invert"][i]; config.system.output.gpio_pwm[i] = objSystemOutput["gpio_pwm"][i]; + // i2c strlcpy(config.system.output.i2c[i], objSystemOutput["i2c"][i], sizeof(config.system.output.i2c[i])); - for(byte j=0; j < 4 ; j++) { - config.system.output.ip[i][j] = objSystemOutput["ip"][i][j]; - } - strlcpy(config.system.output.ip_path[i], objSystemOutput["ip_path"][i], sizeof(config.system.output.ip_path[i])); - config.system.output.enabled[i] = objSystemOutput["enabled"][i]; + // web + strlcpy(config.system.output.web_host[i], objSystemOutput["web_host"][i], sizeof(config.system.output.web_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.web_req_off[i], objSystemOutput["web_req_off"][i], sizeof(config.system.output.web_req_off[i])); } } @@ -291,16 +293,18 @@ bool SaveConfig(bool writeToSerial = false) { objSystemOutput["type"][i] = config.system.output.type[i]; objSystemOutput["device"][i] = config.system.output.device[i]; objSystemOutput["name"][i] = config.system.output.name[i]; + objSystemOutput["enabled"][i] = config.system.output.enabled[i]; + // gpio objSystemOutput["gpio"][i] = config.system.output.gpio[i]; objSystemOutput["gpio_invert"][i] = config.system.output.gpio_invert[i]; objSystemOutput["gpio_pwm"][i] = config.system.output.gpio_pwm[i]; + // i2c objSystemOutput["i2c"][i] = config.system.output.i2c[i]; - - for(byte j=0; j < 4 ; j++) { - objSystemOutput["ip"][i][j] = config.system.output.ip[i][j]; - } - objSystemOutput["ip_path"][i] = config.system.output.ip_path[i]; - objSystemOutput["enabled"][i] = config.system.output.enabled[i]; + // web + objSystemOutput["web_host"][i] = config.system.output.web_host[i]; + objSystemOutput["web_req_on"][i] = config.system.output.web_req_on[i]; + objSystemOutput["web_req_off"][i] = config.system.output.web_req_off[i]; + } } diff --git a/Arduino/CanGrow/include/Webserver/Page_system.h b/Arduino/CanGrow/include/Webserver/Page_system.h index acbbff0..4514fa4 100644 --- a/Arduino/CanGrow/include/Webserver/Page_system.h +++ b/Arduino/CanGrow/include/Webserver/Page_system.h @@ -365,26 +365,20 @@ String Proc_WebPage_system_output_add(const String& var) { return Proc_WebPage_system_SUBNAV(var, 1); } else if(var == "OUTPUT_ID") { // we check which id is free. A free ID as type == 0 - byte freeOutputId; - - for(byte i=0; i < Max_Outputs; i++) { - if(config.system.output.type[i] > 0) { - // here i define that 255 stands for "not available" - freeOutputId = 255; - } else { - freeOutputId = i; - break; - } - } - Serial.printf("DB [Webserver:system:output:add(Proc)] next free output id: %d\n", freeOutputId); - return String(freeOutputId); + return String(Give_Free_OutputId()); } else if(var == "GPIO_INDEX") { String gpioIndex_html; for(byte i = 0; i < GPIOindex_length; i++) { gpioIndex_html += ""; @@ -444,6 +442,7 @@ void WebPage_system_output_add(AsyncWebServerRequest *request) { if(request->method() == HTTP_POST) { Serial.println(":: [Webserver:system:output:add] [POST] hello"); byte outputId; + byte outputType; if(request->hasParam("outputId", true)) { const AsyncWebParameter* p_outputId = request->getParam("outputId", true); Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_outputId->name().c_str(), p_outputId->value().c_str()); @@ -453,7 +452,11 @@ void WebPage_system_output_add(AsyncWebServerRequest *request) { if(request->hasParam("type", true)) { const AsyncWebParameter* p_type = request->getParam("type", true); Serial.printf(":: [Webserver:system] POST[%s]: %s\n", p_type->name().c_str(), p_type->value().c_str()); + // put info config struct config.system.output.type[outputId] = p_type->value().toInt(); + + // remember the value in own var to work later with here + outputType = p_type->value().toInt(); } if(request->hasParam("device", true)) { @@ -474,6 +477,28 @@ void WebPage_system_output_add(AsyncWebServerRequest *request) { config.system.output.enabled[outputId] = p_enabled->value().toInt(); } + // only fill gpio values if type is GPIO + if(outputType == 1) { + if(request->hasParam("gpio", true)) { + 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)) { + 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()); + config.system.output.gpio_pwm[outputId] = p_gpio_pwm->value().toInt(); + } + + if(request->hasParam("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()); + config.system.output.gpio_invert[outputId] = p_gpio_invert->value().toInt(); + } + } + + SaveConfig(); AsyncWebServerResponse *response = request->beginChunkedResponse("text/html", Chunk_system_output_add_HTML, Proc_WebPage_system_output_add_POST); diff --git a/Arduino/CanGrow/include/Webserver/Page_system_HTML.h b/Arduino/CanGrow/include/Webserver/Page_system_HTML.h index 91c1c89..46e2198 100644 --- a/Arduino/CanGrow/include/Webserver/Page_system_HTML.h +++ b/Arduino/CanGrow/include/Webserver/Page_system_HTML.h @@ -202,7 +202,14 @@ const char* Page_system_output_add_HTML PROGMEM = R"(%HEADER%
+ + GPIO invert:
+
@@ -213,14 +220,14 @@ const char* Page_system_output_add_HTML PROGMEM = R"(%HEADER%