From a215932f872daa6052d0ae32925dbfb2bddcbe44 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Mon, 6 May 2019 17:05:55 +0200 Subject: [PATCH 001/128] atlas Sensor for pH an Redox (ORP) added --- src/_P036_FrameOLED.ino | 89 +++++--- src/_P214_Atlas_EZO_pH.ino | 445 ++++++++++++++++++++++++++++++++++++ src/_P222_Atlas_EZO_ORP.ino | 361 +++++++++++++++++++++++++++++ 3 files changed, 866 insertions(+), 29 deletions(-) create mode 100644 src/_P214_Atlas_EZO_pH.ino create mode 100644 src/_P222_Atlas_EZO_ORP.ino diff --git a/src/_P036_FrameOLED.ino b/src/_P036_FrameOLED.ino index 36937fcfb..5d48cca1f 100644 --- a/src/_P036_FrameOLED.ino +++ b/src/_P036_FrameOLED.ino @@ -25,6 +25,9 @@ #define P36_CONTRAST_MED 0xCF #define P36_CONTRAST_HIGH 0xFF +#define P36_SIZE_128X32 32 +#define P36_SIZE_128X64 64 + #include "SSD1306.h" #include "SH1106Wire.h" @@ -170,6 +173,16 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string) optionValues6[2] = P36_CONTRAST_HIGH; addFormSelector(F("Contrast"), F("p036_contrast"), 3, options6, optionValues6, choice6); + // size 64 or 128 + byte choice7 = PCONFIG(7); + String options7[2]; + options7[0] = F("128x32"); + options7[1] = F("128x64"); + int optionValues7[2]; + optionValues7[0] = P36_SIZE_128X32; + optionValues7[1] = P36_SIZE_128X64; + addFormSelector(F("Screen Size"), F("p036_screen_size"), 2, options7, optionValues7, choice7); + success = true; break; } @@ -188,6 +201,7 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string) PCONFIG(4) = getFormItemInt(F("p036_timer")); PCONFIG(5) = getFormItemInt(F("p036_controller")); PCONFIG(6) = getFormItemInt(F("p036_contrast")); + PCONFIG(7) = getFormItemInt(F("p036_screen_size")); String error; char P036_deviceTemplate[P36_Nlines][P36_Nchars]; @@ -224,7 +238,12 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string) uint8_t OLED_address = PCONFIG(0); if (PCONFIG(5) == 1) { - display = new SSD1306Wire(OLED_address, Settings.Pin_i2c_sda, Settings.Pin_i2c_scl); + if(PCONFIG(7) == P36_SIZE_128X32) { + digitalWrite(16, HIGH); + display = new SSD1306Wire(OLED_address, Settings.Pin_i2c_sda, Settings.Pin_i2c_scl, 128, 32); + } else { + display = new SSD1306Wire(OLED_address, Settings.Pin_i2c_sda, Settings.Pin_i2c_scl, 128, 64); + } } else { display = new SH1106Wire(OLED_address, Settings.Pin_i2c_sda, Settings.Pin_i2c_scl); } @@ -381,12 +400,14 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string) // Update display display_header(); - display_indicator(currentFrameToDisplay, nrFramesToDisplay); + if(PCONFIG(7) != P36_SIZE_128X32) { + display_indicator(currentFrameToDisplay, nrFramesToDisplay); + } // display_indicator(frameCounter, NFrames); display->display(); int scrollspeed = PCONFIG(3); - display_scroll(oldString, newString, linesPerFrame, scrollspeed); + display_scroll(oldString, newString, linesPerFrame, scrollspeed, PCONFIG(7)); success = true; break; @@ -578,7 +599,7 @@ void display_indicator(int iframe, int frameCount) { } } -void display_scroll(String outString[], String inString[], int nlines, int scrollspeed) +void display_scroll(String outString[], String inString[], int nlines, int scrollspeed, int screenSize) { // outString contains the outgoing strings in this frame @@ -587,34 +608,40 @@ void display_scroll(String outString[], String inString[], int nlines, int scrol int ypos[4]; // ypos contains the heights of the various lines - this depends on the font and the number of lines - if (nlines == 1) - { - display->setFont(ArialMT_Plain_24); - ypos[0] = 20; - } - - if (nlines == 2) - { + if(screenSize == P36_SIZE_128X32) { + nlines = 1; display->setFont(ArialMT_Plain_16); ypos[0] = 15; - ypos[1] = 34; - } + } else { + if (nlines == 1) + { + display->setFont(ArialMT_Plain_24); + ypos[0] = 20; + } - if (nlines == 3) - { - display->setFont(Dialog_plain_12); - ypos[0] = 13; - ypos[1] = 25; - ypos[2] = 37; - } + if (nlines == 2) + { + display->setFont(ArialMT_Plain_16); + ypos[0] = 15; + ypos[1] = 34; + } - if (nlines == 4) - { - display->setFont(ArialMT_Plain_10); - ypos[0] = 12; - ypos[1] = 22; - ypos[2] = 32; - ypos[3] = 42; + if (nlines == 3) + { + display->setFont(Dialog_plain_12); + ypos[0] = 13; + ypos[1] = 25; + ypos[2] = 37; + } + + if (nlines == 4) + { + display->setFont(ArialMT_Plain_10); + ypos[0] = 12; + ypos[1] = 22; + ypos[2] = 32; + ypos[3] = 42; + } } display->setTextAlignment(TEXT_ALIGN_CENTER); @@ -626,7 +653,11 @@ void display_scroll(String outString[], String inString[], int nlines, int scrol display->setColor(BLACK); // We allow 12 pixels at the top because otherwise the wifi indicator gets too squashed!! - display->fillRect(0, 12, 128, 42); // scrolling window is 44 pixels high - ie 64 less margin of 10 at top and bottom + if(screenSize == P36_SIZE_128X32) { + display->fillRect(0, 15, 128, 32); + } else { + display->fillRect(0, 12, 128, 42); // scrolling window is 44 pixels high - ie 64 less margin of 10 at top and bottom + } display->setColor(WHITE); // Now draw the strings diff --git a/src/_P214_Atlas_EZO_pH.ino b/src/_P214_Atlas_EZO_pH.ino new file mode 100644 index 000000000..99f441f5d --- /dev/null +++ b/src/_P214_Atlas_EZO_pH.ino @@ -0,0 +1,445 @@ +//######################################################################## +//################## Plugin 214 : Atlas Scientific EZO Ph sensor ######## +//######################################################################## + +// datasheet at https://www.atlas-scientific.com/_files/_datasheets/_circuit/pH_EZO_datasheet.pdf +// works only in i2c mode + +#define PLUGIN_214 +#define PLUGIN_ID_214 214 +#define PLUGIN_NAME_214 "Environment - Atlas Scientific pH EZO [TESTING]" +#define PLUGIN_VALUENAME1_214 "pH" +#define PLUGIN_VALUENAME2_214 "Voltage" + +boolean Plugin_214_init = false; + +boolean Plugin_214(byte function, struct EventStruct *event, String& string) +{ + boolean success = false; + + switch (function) + { + case PLUGIN_DEVICE_ADD: + { + Device[++deviceCount].Number = PLUGIN_ID_214; + Device[deviceCount].Type = DEVICE_TYPE_I2C; + Device[deviceCount].VType = SENSOR_TYPE_SINGLE; + Device[deviceCount].Ports = 0; + Device[deviceCount].PullUpOption = false; + Device[deviceCount].InverseLogicOption = false; + Device[deviceCount].FormulaOption = true; + Device[deviceCount].ValueCount = 2; + Device[deviceCount].SendDataOption = true; + Device[deviceCount].TimerOption = true; + Device[deviceCount].GlobalSyncOption = true; + break; + } + + case PLUGIN_GET_DEVICENAME: + { + string = F(PLUGIN_NAME_214); + break; + } + + case PLUGIN_GET_DEVICEVALUENAMES: + { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_214)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_214)); + break; + } + + case PLUGIN_WEBFORM_LOAD: + { + #define _P214_ATLASEZO_I2C_NB_OPTIONS 4 + byte I2Cchoice = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; + int optionValues[_P214_ATLASEZO_I2C_NB_OPTIONS] = { 0x63, 0x64, 0x65, 0x66 }; + addFormSelectorI2C(F("plugin_214_i2c"), _P214_ATLASEZO_I2C_NB_OPTIONS, optionValues, I2Cchoice); + + addFormSubHeader(F("General")); + + char sensordata[32]; + bool info; + info = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"i",sensordata); + + if (info) { + String boardInfo(sensordata); + + addHtml(F("Board type : ")); + int pos1 = boardInfo.indexOf(','); + int pos2 = boardInfo.lastIndexOf(','); + addHtml(boardInfo.substring(pos1+1,pos2)); + if (boardInfo.substring(pos1+1,pos2) != "pH"){ + addHtml(F(" WARNING : Board type should be 'pH', check your i2c Address ? ")); + } + addHtml(F("Board version :")); + addHtml(boardInfo.substring(pos2+1)); + addHtml(F("")); + + addHtml(F("")); + + } else { + addHtml(F("Unable to send command to device")); + success = false; + break; + } + + addFormCheckBox(F("Status LED"),F("Plugin_214_status_led"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]); + + char statussensordata[32]; + bool status; + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",statussensordata); + + if (status) { + String boardStatus(statussensordata); + + addHtml(F("Board restart code: ")); + int pos1 = boardStatus.indexOf(','); + int pos2 = boardStatus.lastIndexOf(','); + switch ((char)boardStatus.substring(pos1+1,pos2)[0]) + { + case 'P': + { + addHtml(F("powered off")); + break; + } + case 'S': + { + addHtml(F("software reset")); + break; + } + case 'B': + { + addHtml(F("brown out")); + break; + } + case 'W': + { + addHtml(F("watch dog")); + break; + } + case 'U': + default: + { + addHtml(F("unknown")); + break; + } + } + + addHtml(F("Board voltage :")); + addHtml(boardStatus.substring(pos2+1)); + addHtml(F(" V")); + + addHtml(F("")); + + } else { + addHtml(F("Unable to send status command to device")); + success = false; + break; + } + + addFormSubHeader(F("Calibration")); + + int nb_calibration_points = -1; + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0], "Cal,?",sensordata); + + if (status){ + if (strncmp(sensordata,"?Cal,",5)){ + char tmp[2]; + tmp[0] = sensordata[5]; + tmp[1] = '\0', + nb_calibration_points = atoi(tmp); + } + } + + addRowLabel(F("Middle")); + addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_M' step='0.01"),Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1],1,14); + if (nb_calibration_points > 0) { + addHtml(F(" OK")); + } else { + addHtml(F(" Not yet calibrated")); + } + addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_M"), false); + addHtml(F("\n\n")); + + addRowLabel(F("Low")); + addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_L' step='0.01"), Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2],1,14); + if (nb_calibration_points > 1) { + addHtml(F(" OK")); + } else { + addHtml(F(" Not yet calibrated")); + } + addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_L"), false); + addHtml(F("\n\n")); + + addHtml(F("High")); + addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_H' step='0.01"), Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3],1,14); + if (nb_calibration_points > 2) { + addHtml(F(" OK")); + } else { + addHtml(F(" Not yet calibrated")); + } + addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_H"), false); + addHtml(F("\n\n")); + + if (nb_calibration_points > 1){ + char sensordata[32]; + char cmd[8] = "Slope,?"; + bool status; + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd,sensordata); + + if (status){ + String slopeAnswer("Answer to 'Slope' command : "); + slopeAnswer += sensordata; + addFormNote(slopeAnswer); + } + } + + addFormSubHeader(F("Temperature compensation")); + char deviceTemperatureTemplate[40]; + LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); + addFormTextBox(F("Temperature "), F("Plugin_214_temperature_template"), deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); + addFormNote(F("You can use a formulae (and idealy refer to a temp sensor). ")); + float value; + char strValue[5]; + String deviceTemperatureTemplateString(deviceTemperatureTemplate); + String pooltempString(parseTemplate(deviceTemperatureTemplateString, 40)); + addHtml(F("
")); + if (Calculate(pooltempString.c_str(),&value) == CALCULATE_OK ){ + addHtml(F("Actual value : ")); + dtostrf(value,5,2,strValue); + addHtml(strValue); + } else { + addHtml(F("(It seems I can't parse your formulae)")); + } + + addHtml(F("
")); + + success = true; + break; + } + + case PLUGIN_WEBFORM_SAVE: + { + Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_214_i2c")); + + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_214_sensorVersion")); + + char sensordata[32]; + if (isFormItemChecked(F("Plugin_214_status_led"))) { + _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,1",sensordata); + } else { + _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,0",sensordata); + } + Settings.TaskDevicePluginConfig[event->TaskIndex][1] = isFormItemChecked(F("Plugin_214_status_led")); + + + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("Plugin_214_ref_cal_M")); + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2] = getFormItemFloat(F("Plugin_214_ref_cal_L")); + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3] = getFormItemFloat(F("Plugin_214_ref_cal_H")); + + String cmd ("Cal,"); + bool triggerCalibrate = false; + if (isFormItemChecked("Plugin_214_enable_cal_M")) { + cmd += "mid,"; + cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]; + triggerCalibrate = true; + } else if (isFormItemChecked("Plugin_214_enable_cal_L")){ + cmd += "low,"; + cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2]; + triggerCalibrate = true; + } else if (isFormItemChecked("Plugin_214_enable_cal_H")){ + cmd += "high,"; + cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3]; + triggerCalibrate = true; + } + if (triggerCalibrate){ + char sensordata[32]; + _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd.c_str(),sensordata); + } + + char deviceTemperatureTemplate[40]; + String tmpString = WebServer.arg(F("Plugin_214_temperature_template")); + strncpy(deviceTemperatureTemplate, tmpString.c_str(), sizeof(deviceTemperatureTemplate)-1); + deviceTemperatureTemplate[sizeof(deviceTemperatureTemplate)-1]=0; //be sure that our string ends with a \0 + + SaveCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); + + Plugin_214_init = false; + success = true; + break; + } + + case PLUGIN_INIT: + { + Plugin_214_init = true; + } + + case PLUGIN_READ: + { + char sensordata[32]; + bool status; + + //first set the temperature of reading + char deviceTemperatureTemplate[40]; + LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); + + String deviceTemperatureTemplateString(deviceTemperatureTemplate); + String pooltempString(parseTemplate(deviceTemperatureTemplateString, 40)); + //String setTemperature("T,"); + String setTemperature("RT,"); + float temperatureReading; + if (Calculate(pooltempString.c_str(),&temperatureReading) == CALCULATE_OK ){ + setTemperature += temperatureReading; + } else { + success = false; + break; + } + + //ok, now we can read the pH value with Temperature compensation + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],setTemperature.c_str(),sensordata); + + //ok, now we can read the pH value + //status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"r",sensordata); + + //we read the voltagedata char statussensordata[32]; + char voltagedata[32]; + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",voltagedata); + + + if (status){ + String sensorString(sensordata); + String voltage(voltagedata); + int pos = voltage.lastIndexOf(','); + UserVar[event->BaseVarIndex] = sensorString.toFloat(); + UserVar[event->BaseVarIndex + 1] = voltage.substring(pos+1).toFloat(); + } + else { + UserVar[event->BaseVarIndex] = -1; + UserVar[event->BaseVarIndex + 1] = -1; + } + + //go to sleep + //status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Sleep",sensordata); + + success = true; + break; + } + case PLUGIN_WRITE: + { + //TODO : do something more usefull ... + + String tmpString = string; + int argIndex = tmpString.indexOf(','); + if (argIndex) + tmpString = tmpString.substring(0, argIndex); + if (tmpString.equalsIgnoreCase(F("ATLASCMD"))) + { + success = true; + argIndex = string.lastIndexOf(','); + tmpString = string.substring(argIndex + 1); + if (tmpString.equalsIgnoreCase(F("CalMid"))){ + String log("Asking for Mid calibration "); + addLog(LOG_LEVEL_INFO, log); + } + else if (tmpString.equalsIgnoreCase(F("CalLow"))){ + String log("Asking for Low calibration "); + addLog(LOG_LEVEL_INFO, log); + } + else if (tmpString.equalsIgnoreCase(F("CalHigh"))){ + String log("Asking for High calibration "); + addLog(LOG_LEVEL_INFO, log); + } + } + break; + } + } + return success; +} + +// Call this function with two char arrays, one containing the command +// The other containing an allocatted char array for answer +// Returns true on success, false otherwise + +bool _P214_send_I2C_command(uint8_t I2Caddress,const char * cmd, char* sensordata) { + uint16_t sensor_bytes_received = 0; + + byte error; + byte i2c_response_code = 0; + byte in_char = 0; + + Serial.println(cmd); + Wire.beginTransmission(I2Caddress); + Wire.write(cmd); + error = Wire.endTransmission(); + + if (error != 0) { + return false; + } + + //don't read answer if we want to go to sleep + if (strncmp(cmd,"Sleep",5) == 0) { + return true; + } + + i2c_response_code = 254; + while (i2c_response_code == 254) { // in case the cammand takes longer to process, we keep looping here until we get a success or an error + + if ( + ( (cmd[0] == 'r' || cmd[0] == 'R') && cmd[1] == '\0' ) + || + ( ( strncmp(cmd,"cal",3) || strncmp(cmd,"Cal",3) ) && !strncmp(cmd,"Cal,?",5) ) + ) + { + delay(900); + } + else { + delay(300); + } + + Wire.requestFrom(I2Caddress, (uint8_t) 32); //call the circuit and request 32 bytes (this is more then we need). + i2c_response_code = Wire.read(); //read response code + + while (Wire.available()) { //read response + in_char = Wire.read(); + + if (in_char == 0) { //if we receive a null caracter, we're done + while (Wire.available()) { //purge the data line if needed + Wire.read(); + } + + break; //exit the while loop. + } + else { + sensordata[sensor_bytes_received] = in_char; //load this byte into our array. + sensor_bytes_received++; + } + } + sensordata[sensor_bytes_received] = '\0'; + + switch (i2c_response_code) { + case 1: + Serial.print( F("< success, answer = ")); + Serial.println(sensordata); + break; + + case 2: + Serial.println( F("< command failed")); + return false; + + case 254: + Serial.println( F("< command pending")); + break; + + case 255: + Serial.println( F("< no data")); + return false; + } + } + + Serial.println(sensordata); + return true; +} diff --git a/src/_P222_Atlas_EZO_ORP.ino b/src/_P222_Atlas_EZO_ORP.ino new file mode 100644 index 000000000..edec85177 --- /dev/null +++ b/src/_P222_Atlas_EZO_ORP.ino @@ -0,0 +1,361 @@ +//######################################################################## +//################## Plugin 222 : Atlas Scientific EZO ORP sensor ######## +//######################################################################## + +// datasheet at https://www.atlas-scientific.com/_files/_datasheets/_circuit/ORP_EZO_datasheet.pdf +// works only in i2c mode + +#define PLUGIN_222 +#define PLUGIN_ID_222 222 +#define PLUGIN_NAME_222 "Environment - Atlas Scientific ORP EZO [TESTING]" +#define PLUGIN_VALUENAME1_222 "ORP" +#define PLUGIN_VALUENAME2_222 "Voltage" + +boolean Plugin_222_init = false; + +boolean Plugin_222(byte function, struct EventStruct *event, String& string) +{ + boolean success = false; + + switch (function) + { + case PLUGIN_DEVICE_ADD: + { + Device[++deviceCount].Number = PLUGIN_ID_222; + Device[deviceCount].Type = DEVICE_TYPE_I2C; + Device[deviceCount].VType = SENSOR_TYPE_SINGLE; + Device[deviceCount].Ports = 0; + Device[deviceCount].PullUpOption = false; + Device[deviceCount].InverseLogicOption = false; + Device[deviceCount].FormulaOption = true; + Device[deviceCount].ValueCount = 2; + Device[deviceCount].SendDataOption = true; + Device[deviceCount].TimerOption = true; + Device[deviceCount].GlobalSyncOption = true; + break; + } + + case PLUGIN_GET_DEVICENAME: + { + string = F(PLUGIN_NAME_222); + break; + } + + case PLUGIN_GET_DEVICEVALUENAMES: + { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_222)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_222)); + break; + } + + case PLUGIN_WEBFORM_LOAD: + { + #define _P222_ATLASEZO_I2C_NB_OPTIONS 4 + byte I2Cchoice = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; + int optionValues[_P222_ATLASEZO_I2C_NB_OPTIONS] = { 0x62, 0x63, 0x64, 0x65 }; + addFormSelectorI2C(F("plugin_222_i2c"), _P222_ATLASEZO_I2C_NB_OPTIONS, optionValues, I2Cchoice); + + addFormSubHeader(F("General")); + + char sensordata[32]; + bool info; + info = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"i",sensordata); + + if (info) { + String boardInfo(sensordata); + + addHtml(F("Board type : ")); + int pos1 = boardInfo.indexOf(','); + int pos2 = boardInfo.lastIndexOf(','); + addHtml(boardInfo.substring(pos1+1,pos2)); + if (boardInfo.substring(pos1+1,pos2) != "ORP"){ + addHtml(F(" WARNING : Board type should be 'ORP', check your i2c Address ? ")); + } + addHtml(F("Board version :")); + addHtml(boardInfo.substring(pos2+1)); + addHtml(F("")); + + addHtml(F("")); + + } else { + addHtml(F("Unable to send command to device")); + success = false; + break; + } + + addFormCheckBox(F("Status LED"),F("Plugin_222_status_led"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]); + + char statussensordata[32]; + bool status; + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",statussensordata); + + if (status) { + String boardStatus(statussensordata); + + addHtml(F("Board restart code: ")); + int pos1 = boardStatus.indexOf(','); + int pos2 = boardStatus.lastIndexOf(','); + switch ((char)boardStatus.substring(pos1+1,pos2)[0]) + { + case 'P': + { + addHtml(F("powered off")); + break; + } + case 'S': + { + addHtml(F("software reset")); + break; + } + case 'B': + { + addHtml(F("brown out")); + break; + } + case 'W': + { + addHtml(F("watch dog")); + break; + } + case 'U': + default: + { + addHtml(F("unknown")); + break; + } + } + + addHtml(F("Board voltage :")); + addHtml(boardStatus.substring(pos2+1)); + addHtml(F(" V")); + + addHtml(F("")); + + } else { + addHtml(F("Unable to send status command to device")); + success = false; + break; + } + + addFormSubHeader(F("Calibration")); + + int nb_calibration_points = -1; + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0], "Cal,?",sensordata); + + if (status){ + if (strncmp(sensordata,"?Cal,",5)){ + char tmp[2]; + tmp[0] = sensordata[5]; + tmp[1] = '\0', + nb_calibration_points = atoi(tmp); + } + } + + addRowLabel(F("ORP Calibration")); + addFormNumericBox(F("Ref ORP"),F("Plugin_222_ref_cal_M' step='1"),Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1],0,1500); + if (nb_calibration_points > 0) { + addHtml(F(" OK")); + } else { + addHtml(F(" Not yet calibrated")); + } + addFormCheckBox(F("Enable"),F("Plugin_222_enable_cal_M"), false); + + if (nb_calibration_points > 1){ + char sensordata[32]; + char cmd[8] = "Slope,?"; + bool status; + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd,sensordata); + + if (status){ + String slopeAnswer("Answer to 'Slope' command : "); + slopeAnswer += sensordata; + addFormNote(slopeAnswer); + } + } + + addHtml(F("")); + + success = true; + break; + } + + case PLUGIN_WEBFORM_SAVE: + { + Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_222_i2c")); + + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_222_sensorVersion")); + + char sensordata[32]; + if (isFormItemChecked(F("Plugin_222_status_led"))) { + _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,1",sensordata); + } else { + _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,0",sensordata); + } + Settings.TaskDevicePluginConfig[event->TaskIndex][1] = isFormItemChecked(F("Plugin_222_status_led")); + + + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("Plugin_222_ref_cal_M")); + + String cmd ("Cal,"); + bool triggerCalibrate = false; + if (isFormItemChecked("Plugin_222_enable_cal_M")) { + cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]; + triggerCalibrate = true; + } + if (triggerCalibrate){ + char sensordata[32]; + _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd.c_str(),sensordata); + } + + Plugin_222_init = false; + success = true; + break; + } + + case PLUGIN_INIT: + { + Plugin_222_init = true; + } + + case PLUGIN_READ: + { + char sensordata[32]; + bool status; + + //ok, now we can read the ORP value + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"R",sensordata); + + //we read the voltagedata char statussensordata[32]; + char voltagedata[32]; + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",voltagedata); + + if (status){ + String sensorString(sensordata); + String voltage(voltagedata); + int pos = voltage.lastIndexOf(','); + UserVar[event->BaseVarIndex] = sensorString.toFloat(); + UserVar[event->BaseVarIndex + 1] = voltage.substring(pos+1).toFloat(); + } + else { + UserVar[event->BaseVarIndex] = -1; + UserVar[event->BaseVarIndex + 1] = -1; + } + + //go to sleep + //status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Sleep",sensordata); + + success = true; + break; + } + case PLUGIN_WRITE: + { + //TODO : do something more usefull ... + + String tmpString = string; + int argIndex = tmpString.indexOf(','); + if (argIndex) + tmpString = tmpString.substring(0, argIndex); + if (tmpString.equalsIgnoreCase(F("ATLASCMD"))) + { + success = true; + argIndex = string.lastIndexOf(','); + tmpString = string.substring(argIndex + 1); + if (tmpString.equalsIgnoreCase(F("CalMid"))){ + String log("Asking for calibration "); + addLog(LOG_LEVEL_INFO, log); + } + } + break; + } + } + return success; +} + +// Call this function with two char arrays, one containing the command +// The other containing an allocatted char array for answer +// Returns true on success, false otherwise + +bool _P222_send_I2C_command(uint8_t I2Caddress,const char * cmd, char* sensordata) { + uint16_t sensor_bytes_received = 0; + + byte error; + byte i2c_response_code = 0; + byte in_char = 0; + + Serial.println(cmd); + Wire.beginTransmission(I2Caddress); + Wire.write(cmd); + error = Wire.endTransmission(); + + if (error != 0) { + Serial.println(error); + return false; + } + + //don't read answer if we want to go to sleep + if (strncmp(cmd,"Sleep",5) == 0) { + return true; + } + + i2c_response_code = 254; + while (i2c_response_code == 254) { // in case the cammand takes longer to process, we keep looping here until we get a success or an error + + if ( + ( (cmd[0] == 'r' || cmd[0] == 'R') && cmd[1] == '\0' ) + || + ( ( strncmp(cmd,"cal",3) || strncmp(cmd,"Cal",3) ) && !strncmp(cmd,"Cal,?",5) ) + ) + { + delay(900); + } + else { + delay(300); + } + + Wire.requestFrom(I2Caddress, (uint8_t) 32); //call the circuit and request 32 bytes (this is more then we need). + i2c_response_code = Wire.read(); //read response code + + while (Wire.available()) { //read response + in_char = Wire.read(); + + if (in_char == 0) { //if we receive a null caracter, we're done + while (Wire.available()) { //purge the data line if needed + Wire.read(); + } + + break; //exit the while loop. + } + else { + sensordata[sensor_bytes_received] = in_char; //load this byte into our array. + sensor_bytes_received++; + } + } + sensordata[sensor_bytes_received] = '\0'; + + switch (i2c_response_code) { + case 1: + Serial.print( F("< success, answer = ")); + Serial.println(sensordata); + break; + + case 2: + Serial.println( F("< command failed")); + return false; + + case 254: + Serial.println( F("< command pending")); + break; + + case 255: + Serial.println( F("< no data")); + return false; + } + } + + Serial.println(sensordata); + return true; +} From ed895998238cfb0c7844238928c670f4d3a48810 Mon Sep 17 00:00:00 2001 From: denisfrench Date: Sun, 12 Apr 2020 21:31:27 +1000 Subject: [PATCH 002/128] [MQTT] Connect message honors LWT settings (#3006) --- src/Controller.ino | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Controller.ino b/src/Controller.ino index 652746f39..d460ee868 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -246,17 +246,17 @@ bool MQTTConnect(controllerIndex_t controller_idx) log += subscribeTo; addLog(LOG_LEVEL_INFO, log); - if (MQTTclient.publish(LWTTopic.c_str(), LWTMessageConnect.c_str(), 1)) { - updateMQTTclient_connected(); - statusLED(true); - mqtt_reconnect_count = 0; + updateMQTTclient_connected(); + statusLED(true); + mqtt_reconnect_count = 0; - // call all installed controller to publish autodiscover data - if (MQTTclient_should_reconnect) { CPluginCall(CPlugin::Function::CPLUGIN_GOT_CONNECTED, 0); } - MQTTclient_should_reconnect = false; - return true; // end loop if succesfull - } - return false; + // call all installed controller to publish autodiscover data + if (MQTTclient_should_reconnect) { CPluginCall(CPlugin::Function::CPLUGIN_GOT_CONNECTED, 0); } + MQTTclient_should_reconnect = false; + + if (ControllerSettings.mqtt_sendLWT()) { MQTTclient.publish(LWTTopic.c_str(), LWTMessageConnect.c_str(), willRetain); } + + return true; } String getMQTTclientID(const ControllerSettingsStruct& ControllerSettings) { From 03aad0e44e75fdd42a2d14eeaf572a9f996ff623 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zimon Date: Sun, 12 Apr 2020 12:14:26 +0000 Subject: [PATCH 003/128] rfid events update for P008/P017/P040, plus send event after log line. --- src/_P008_RFID.ino | 39 ++++++++++++++++++++++++++++++++------- src/_P017_PN532.ino | 44 +++++++++++++++++++++++++++++++++++--------- src/_P040_ID12.ino | 5 +++-- 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/_P008_RFID.ino b/src/_P008_RFID.ino index 8ceda3f2e..0f9045214 100644 --- a/src/_P008_RFID.ino +++ b/src/_P008_RFID.ino @@ -73,6 +73,19 @@ boolean Plugin_008(byte function, struct EventStruct *event, String& string) break; } + case PLUGIN_TIMER_IN: + { + if (Plugin_008_init) { + // Reset card id on timeout + UserVar[event->BaseVarIndex] = 0; + UserVar[event->BaseVarIndex + 1] = 0; + addLog(LOG_LEVEL_INFO, F("RFID : Removed Tag")); + sendData(event); + success = true; + } + break; + } + case PLUGIN_ONCE_A_SECOND: { if (Plugin_008_init) @@ -83,8 +96,6 @@ boolean Plugin_008(byte function, struct EventStruct *event, String& string) { // a number of keys were pressed and finished by # Plugin_008_keyBuffer = Plugin_008_keyBuffer >> 4; // Strip # - UserVar[event->BaseVarIndex] = (Plugin_008_keyBuffer & 0xFFFF); - UserVar[event->BaseVarIndex + 1] = ((Plugin_008_keyBuffer >> 16) & 0xFFFF); } else if (Plugin_008_bitCount == Plugin_008_WiegandSize) { @@ -94,8 +105,6 @@ boolean Plugin_008(byte function, struct EventStruct *event, String& string) Plugin_008_keyBuffer &= 0xFFFFFF; else Plugin_008_keyBuffer &= 0xFFFFFFFF; - UserVar[event->BaseVarIndex] = (Plugin_008_keyBuffer & 0xFFFF); - UserVar[event->BaseVarIndex + 1] = ((Plugin_008_keyBuffer >> 16) & 0xFFFF); } else { @@ -113,10 +122,24 @@ boolean Plugin_008(byte function, struct EventStruct *event, String& string) } break; } + + unsigned long old_key = ((uint32_t) UserVar[event->BaseVarIndex]) | ((uint32_t) UserVar[event->BaseVarIndex + 1])<<16; + bool new_key = false; + + if (old_key != Plugin_008_keyBuffer) { + UserVar[event->BaseVarIndex] = (Plugin_008_keyBuffer & 0xFFFF); + UserVar[event->BaseVarIndex + 1] = ((Plugin_008_keyBuffer >> 16) & 0xFFFF); + new_key = true; + } if (loglevelActiveFor(LOG_LEVEL_INFO)) { - // write log - String log = F("RFID : Tag: "); + // write log + String log = F("RFID : "); + if (new_key) { + log += F("New Tag: "); + } else { + log += F("Old Tag: "); + } log += (unsigned long) Plugin_008_keyBuffer; log += F(" Bits: "); log += Plugin_008_bitCount; @@ -126,7 +149,9 @@ boolean Plugin_008(byte function, struct EventStruct *event, String& string) Plugin_008_keyBuffer = 0; Plugin_008_bitCount = 0; Plugin_008_timeoutCount = 0; - sendData(event); + + if (new_key) sendData(event); + setPluginTaskTimer(500, event->TaskIndex, event->Par1); } } break; diff --git a/src/_P017_PN532.ino b/src/_P017_PN532.ino index e67ef4ad5..6756f1836 100644 --- a/src/_P017_PN532.ino +++ b/src/_P017_PN532.ino @@ -92,6 +92,17 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string) break; } + case PLUGIN_TIMER_IN: + { + // Reset card id on timeout + UserVar[event->BaseVarIndex] = 0; + UserVar[event->BaseVarIndex + 1] = 0; + addLog(LOG_LEVEL_INFO, F("RFID : Removed Tag")); + sendData(event); + success = true; + break; + } + case PLUGIN_TEN_PER_SECOND: { static unsigned long tempcounter = 0; @@ -134,15 +145,30 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string) key <<= 8; key += uid[i]; } - UserVar[event->BaseVarIndex] = (key & 0xFFFF); - UserVar[event->BaseVarIndex + 1] = ((key >> 16) & 0xFFFF); - String log = F("PN532: Tag: "); - log += key; - tempcounter++; - log += ' '; - log += tempcounter; - addLog(LOG_LEVEL_INFO, log); - sendData(event); + unsigned long old_key = ((uint32_t) UserVar[event->BaseVarIndex]) | ((uint32_t) UserVar[event->BaseVarIndex + 1])<<16; + bool new_key = false; + if (old_key != key) { + UserVar[event->BaseVarIndex] = (key & 0xFFFF); + UserVar[event->BaseVarIndex + 1] = ((key >> 16) & 0xFFFF); + new_key = true; + } + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("PN532: "); + if (new_key) { + log += F("New Tag: "); + } else { + log += F("Old Tag: "); + } + log += key; + tempcounter++; + log += ' '; + log += tempcounter; + addLog(LOG_LEVEL_INFO, log); + } + + if (new_key) sendData(event); + setPluginTaskTimer(500, event->TaskIndex, event->Par1); } } break; diff --git a/src/_P040_ID12.ino b/src/_P040_ID12.ino index b4c67b7ae..ea966cb48 100644 --- a/src/_P040_ID12.ino +++ b/src/_P040_ID12.ino @@ -139,12 +139,11 @@ boolean Plugin_040(byte function, struct EventStruct *event, String& string) unsigned long key = 0, old_key = 0; old_key = ((uint32_t) UserVar[event->BaseVarIndex]) | ((uint32_t) UserVar[event->BaseVarIndex + 1])<<16; for (byte i = 1; i < 5; i++) key = key | (((unsigned long) code[i] << ((4 - i) * 8))); - bool new_key = false; + bool new_key = false; if (old_key != key) { UserVar[event->BaseVarIndex] = (key & 0xFFFF); UserVar[event->BaseVarIndex + 1] = ((key >> 16) & 0xFFFF); new_key = true; - sendData(event); } if (loglevelActiveFor(LOG_LEVEL_INFO)) { @@ -157,6 +156,8 @@ boolean Plugin_040(byte function, struct EventStruct *event, String& string) log += key; addLog(LOG_LEVEL_INFO, log); } + + if (new_key) sendData(event); setPluginTaskTimer(500, event->TaskIndex, event->Par1); } } From 137f4e4e37b88d9bbf43b6b3cbb04e12908eac26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Sun, 22 Mar 2020 13:45:51 +0100 Subject: [PATCH 004/128] Initial Ethernet support --- platformio_esp32_envs.ini | 2 +- src/ESPEasy.ino | 4 ++++ src/ESPEasyWiFiEvent.cpp | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index e1d8aecc4..fff572e5e 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -29,7 +29,7 @@ build_flags = ${mqtt_flags.build_flags} [env:custom_ESP32_4M316k] extends = esp32_common platform = ${esp32_common.platform} -build_flags = ${esp32_common.build_flags} -DPLUGIN_BUILD_CUSTOM +build_flags = ${esp32_common.build_flags} -DPLUGIN_BUILD_CUSTOM -DHAS_ETHERNET board = esp32dev extra_scripts = ${esp32_common.extra_scripts} pre:pre_custom_esp32.py diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index d5df04936..055296462 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -1,6 +1,9 @@ #include +#ifdef HAS_ETHERNET + #include +#endif #ifdef CONTINUOUS_INTEGRATION #pragma GCC diagnostic error "-Wall" #else @@ -369,6 +372,7 @@ void setup() rulesProcessing(event); // TD-er: Process events in the setup() now. } + ETH.begin(); WiFiConnectRelaxed(); setWebserverRunning(true); diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index e8ac039e3..4a8ee84ab 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -99,6 +99,18 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { case SYSTEM_EVENT_SCAN_DONE: processedScanDone = false; break; +#ifdef HAS_ETHERNET + case SYSTEM_EVENT_ETH_START: + break; + case SYSTEM_EVENT_ETH_CONNECTED: + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + break; + case SYSTEM_EVENT_ETH_STOP: + break; + case SYSTEM_EVENT_ETH_GOT_IP: + break; +#endif default: break; } From 14d91ccf10730808f970c7a5a4702966cfd9e0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Sun, 22 Mar 2020 17:01:10 +0100 Subject: [PATCH 005/128] Added displaying Ethernet parameter in sysinfo and root page --- src/ESPEasy.ino | 7 +++-- src/ESPEasyEth.ino | 35 +++++++++++++++++++++++++ src/StringProvider.ino | 49 +++++++++++++++++++++++++++++++++++ src/StringProviderTypes.h | 13 +++++++++- src/WebServer_RootPage.ino | 5 ++++ src/WebServer_SysInfoPage.ino | 17 ++++++++++++ 6 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 src/ESPEasyEth.ino diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index 055296462..20df7794a 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -1,9 +1,6 @@ #include -#ifdef HAS_ETHERNET - #include -#endif #ifdef CONTINUOUS_INTEGRATION #pragma GCC diagnostic error "-Wall" #else @@ -372,8 +369,10 @@ void setup() rulesProcessing(event); // TD-er: Process events in the setup() now. } - ETH.begin(); WiFiConnectRelaxed(); +#ifdef HAS_ETHERNET + ETHConnectRelaxed(); +#endif setWebserverRunning(true); diff --git a/src/ESPEasyEth.ino b/src/ESPEasyEth.ino new file mode 100644 index 000000000..20502b83b --- /dev/null +++ b/src/ESPEasyEth.ino @@ -0,0 +1,35 @@ + +#ifdef HAS_ETHERNET + #define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT + #define ETH_PHY_POWER 12 + #include + + +String EthGetHostname() +{ + String hostnameToReturn(Settings.getHostname()); + hostnameToReturn.replace(" ", "-"); + hostnameToReturn.replace("_", "-"); // See RFC952 + return hostnameToReturn; +} + +bool prepareEth() { + char hostname[40]; + safe_strncpy(hostname, EthGetHostname(), sizeof(hostname)); + ETH.setHostname(hostname); + return true; +} + +void ETHConnectRelaxed() { + // if (!ethConnectAttemptNeeded) { + // return; // already connected or connect attempt in progress need to disconnect first + // } + if (!prepareEth()) { + // Dead code for now... + addLog(LOG_LEVEL_ERROR, F("ETH : Could not prepare ETH!")); + return; + } + ETH.begin(); +} + +#endif \ No newline at end of file diff --git a/src/StringProvider.ino b/src/StringProvider.ino index c5f541c8d..c9097bde1 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -97,6 +97,18 @@ String getLabel(LabelType::Enum label) { case LabelType::MAX_OTA_SKETCH_SIZE: return F("Max. OTA Sketch Size"); case LabelType::OTA_2STEP: return F("OTA 2-step Needed"); case LabelType::OTA_POSSIBLE: return F("OTA possible"); +#ifdef HAS_ETHERNET + case LabelType::ETH_IP_ADDRESS: return F("Eth IP Address"); + case LabelType::ETH_IP_SUBNET: return F("Eth IP Subnet"); + case LabelType::ETH_IP_ADDRESS_SUBNET: return F("Eth IP / Subnet"); + case LabelType::ETH_IP_GATEWAY: return F("Eth Gateway"); + case LabelType::ETH_IP_DNS: return F("Eth DNS"); + case LabelType::ETH_MAC: return F("Eth MAC"); + case LabelType::ETH_DUPLEX: return F("Eth Mode"); + case LabelType::ETH_SPEED: return F("Eth Speed"); + case LabelType::ETH_STATE: return F("Eth State"); + case LabelType::ETH_SPEED_STATE: return F("Eth State"); +#endif } return F("MissingString"); @@ -201,11 +213,48 @@ String getValue(LabelType::Enum label) { case LabelType::MAX_OTA_SKETCH_SIZE: break; case LabelType::OTA_2STEP: break; case LabelType::OTA_POSSIBLE: break; +#ifdef HAS_ETHERNET + case LabelType::ETH_IP_ADDRESS: return ETH.localIP().toString(); + case LabelType::ETH_IP_SUBNET: return ETH.subnetMask().toString(); + case LabelType::ETH_IP_ADDRESS_SUBNET: return String(getValue(LabelType::ETH_IP_ADDRESS) + F(" / ") + getValue(LabelType::ETH_IP_SUBNET)); + case LabelType::ETH_IP_GATEWAY: return ETH.gatewayIP().toString(); + case LabelType::ETH_IP_DNS: return ETH.dnsIP().toString(); + case LabelType::ETH_MAC: return ETH.macAddress(); + case LabelType::ETH_DUPLEX: return ETH.fullDuplex() ? F("Full Duplex") : F("Half Duplex"); + case LabelType::ETH_SPEED: return getEthSpeed(); + case LabelType::ETH_STATE: return ETH.linkUp() ? F("Link Up") : F("Link Down"); + case LabelType::ETH_SPEED_STATE: return getEthLinkSpeedState(); +#endif } return F("MissingString"); } +#ifdef HAS_ETHERNET +String getEthSpeed() { + String result; + result.reserve(7); + result += ETH.linkSpeed(); + result += F("Mbps"); + return result; +} + +String getEthLinkSpeedState() { + String result; + result.reserve(29); + if (ETH.linkUp()) { + result += getValue(LabelType::ETH_STATE); + result += ' '; + result += getValue(LabelType::ETH_DUPLEX); + result += ' '; + result += getEthSpeed(); + } else { + result = getValue(LabelType::ETH_STATE); + } + return result; +} +#endif + String getExtendedValue(LabelType::Enum label) { switch (label) { diff --git a/src/StringProviderTypes.h b/src/StringProviderTypes.h index 01c839cd3..bfbb2ae61 100644 --- a/src/StringProviderTypes.h +++ b/src/StringProviderTypes.h @@ -97,7 +97,18 @@ enum Enum : short { MAX_OTA_SKETCH_SIZE, OTA_2STEP, OTA_POSSIBLE, - +#ifdef HAS_ETHERNET + ETH_IP_ADDRESS, + ETH_IP_SUBNET, + ETH_IP_ADDRESS_SUBNET, + ETH_IP_GATEWAY, + ETH_IP_DNS, + ETH_MAC, + ETH_DUPLEX, + ETH_SPEED, + ETH_STATE, + ETH_SPEED_STATE, +#endif }; }; diff --git a/src/WebServer_RootPage.ino b/src/WebServer_RootPage.ino index 150e9230a..3e87cd8cc 100644 --- a/src/WebServer_RootPage.ino +++ b/src/WebServer_RootPage.ino @@ -120,6 +120,11 @@ void handle_root() { addHtml(html); } +#ifdef HAS_ETHERNET + addRowLabelValue(LabelType::ETH_SPEED_STATE); + addRowLabelValue(LabelType::ETH_IP_ADDRESS); +#endif + #ifdef FEATURE_MDNS { addRowLabel(getLabel(LabelType::M_DNS)); diff --git a/src/WebServer_SysInfoPage.ino b/src/WebServer_SysInfoPage.ino index 41c0c36a0..893482bd5 100644 --- a/src/WebServer_SysInfoPage.ino +++ b/src/WebServer_SysInfoPage.ino @@ -218,6 +218,10 @@ void handle_sysinfo() { handle_sysinfo_Network(); +#ifdef HAS_ETHERNET + handle_sysinfo_Ethernet(); +#endif + handle_sysinfo_WiFiSettings(); handle_sysinfo_Firmware(); @@ -311,6 +315,19 @@ void handle_sysinfo_basicInfo() { addRowLabelValue(LabelType::SW_WD_COUNT); } +#ifdef HAS_ETHERNET +void handle_sysinfo_Ethernet() { + addTableSeparator(F("Ethernet"), 2, 3); + addRowLabelValue(LabelType::ETH_STATE); + addRowLabelValue(LabelType::ETH_SPEED); + addRowLabelValue(LabelType::ETH_DUPLEX); + addRowLabelValue(LabelType::ETH_MAC); + addRowLabelValue(LabelType::ETH_IP_ADDRESS_SUBNET); + addRowLabelValue(LabelType::ETH_IP_GATEWAY); + addRowLabelValue(LabelType::ETH_IP_DNS); +} +#endif + void handle_sysinfo_Network() { addTableSeparator(F("Network"), 2, 3, F("Wifi")); From b4f01b4b5ac699978c6722161577ec4bb3c7bf8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Sun, 22 Mar 2020 22:39:39 +0100 Subject: [PATCH 006/128] Added configuration of Eth Phy via Hardware settings web page --- src/ESPEasyEth.ino | 71 ++++++++++++++++++++++++---- src/ESPEasy_checks.ino | 2 +- src/WebServer_HardwarePage.ino | 25 ++++++++++ src/src/DataStructs/SettingsStruct.h | 8 ++++ 4 files changed, 97 insertions(+), 9 deletions(-) diff --git a/src/ESPEasyEth.ino b/src/ESPEasyEth.ino index 20502b83b..2173e1145 100644 --- a/src/ESPEasyEth.ino +++ b/src/ESPEasyEth.ino @@ -1,9 +1,9 @@ #ifdef HAS_ETHERNET - #define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT - #define ETH_PHY_POWER 12 - #include - + // #define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT + // #define ETH_PHY_POWER 12 + #include "ETH.h" + #include String EthGetHostname() { @@ -13,23 +13,78 @@ String EthGetHostname() return hostnameToReturn; } +bool checkSettings() { + bool result = true; + if (Settings.ETH_Phy_Type != 0 && Settings.ETH_Phy_Type != 1) + result = false; + if (Settings.ETH_Clock_Mode > 3) + result = false; + if (Settings.ETH_Pin_mdc > MAX_GPIO) + result = false; + if (Settings.ETH_Pin_mdio > MAX_GPIO) + result = false; + if (Settings.ETH_Pin_power > MAX_GPIO) + result = false; + return result; +} + bool prepareEth() { - char hostname[40]; - safe_strncpy(hostname, EthGetHostname(), sizeof(hostname)); - ETH.setHostname(hostname); + if (!checkSettings()) + { + addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!")); + return false; + } + ETH.setHostname(EthGetHostname().c_str()); return true; } +String getDebugClockModeStr() +{ + switch (Settings.ETH_Clock_Mode) + { + case 0: return F("ETH_CLOCK_GPIO0_IN"); + case 1: return F("ETH_CLOCK_GPIO0_OUT"); + case 2: return F("ETH_CLOCK_GPIO16_OUT"); + case 3: return F("ETH_CLOCK_GPIO17_OUT"); + default: return F("ETH_CLOCK_ERR"); + } +} + +void printSettings() +{ + String settingsDebugLog; + settingsDebugLog.reserve(115); + settingsDebugLog += F("ETH: PHY Type: "); + settingsDebugLog += Settings.ETH_Phy_Type == 0 ? F("ETH_PHY_LAN8720") : F("ETH_PHY_TLK110"); + settingsDebugLog += F(" PHY Addr: "); + settingsDebugLog += Settings.ETH_Phy_Addr; + settingsDebugLog += F(" Eth Clock mode: "); + settingsDebugLog += getDebugClockModeStr(); + settingsDebugLog += F(" MDC Pin: "); + settingsDebugLog += String(Settings.ETH_Pin_mdc); + settingsDebugLog += F(" MIO Pin: "); + settingsDebugLog += String(Settings.ETH_Pin_mdio); + settingsDebugLog += F(" Power Pin: "); + settingsDebugLog += String(Settings.ETH_Pin_power); + addLog(LOG_LEVEL_INFO, settingsDebugLog); +} + void ETHConnectRelaxed() { // if (!ethConnectAttemptNeeded) { // return; // already connected or connect attempt in progress need to disconnect first // } + printSettings(); if (!prepareEth()) { // Dead code for now... addLog(LOG_LEVEL_ERROR, F("ETH : Could not prepare ETH!")); return; } - ETH.begin(); + ETH.begin(Settings.ETH_Phy_Addr, + Settings.ETH_Pin_power, + Settings.ETH_Pin_mdc, + Settings.ETH_Pin_mdio, + (eth_phy_type_t)Settings.ETH_Phy_Type, + (eth_clock_mode_t)Settings.ETH_Clock_Mode); } #endif \ No newline at end of file diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index be00efd91..5de4f950c 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -34,7 +34,7 @@ template constexpr size_t offsetOf(U T::*member) void run_compiletime_checks() { check_size(); check_size(); - const unsigned int SettingsStructSize = (248 + 82 * TASKS_MAX); + const unsigned int SettingsStructSize = (256 + 82 * TASKS_MAX); check_size(); check_size(); check_size(); diff --git a/src/WebServer_HardwarePage.ino b/src/WebServer_HardwarePage.ino index 14ba03f6f..4926b7874 100644 --- a/src/WebServer_HardwarePage.ino +++ b/src/WebServer_HardwarePage.ino @@ -21,6 +21,14 @@ void handle_hardware() { Settings.I2C_clockSpeed = getFormItemInt(F("pi2csp"), DEFAULT_I2C_CLOCK_SPEED); Settings.InitSPI = isFormItemChecked(F("initspi")); // SPI Init Settings.Pin_sd_cs = getFormItemInt(F("sd")); +#ifdef HAS_ETHERNET + Settings.ETH_Phy_Addr = getFormItemInt(F("ethphy")); + Settings.ETH_Pin_mdc = getFormItemInt(F("ethmdc")); + Settings.ETH_Pin_mdio = getFormItemInt(F("ethmdio")); + Settings.ETH_Pin_power = getFormItemInt(F("ethpower")); + Settings.ETH_Phy_Type = getFormItemInt(F("ethtype")); + Settings.ETH_Clock_Mode = getFormItemInt(F("ethclock")); +#endif int gpio = 0; // FIXME TD-er: Max of 17 is a limit in the Settings.PinBootStates array @@ -75,6 +83,23 @@ void handle_hardware() { #ifdef FEATURE_SD addFormPinSelect(formatGpioName_output("SD Card CS"), "sd", Settings.Pin_sd_cs); #endif // ifdef FEATURE_SD +#ifdef HAS_ETHERNET + addFormSubHeader(F("Ethernet")); + addRowLabel_tr_id(F("Ethernet PHY type"), "ethtype"); + String ethPhyTypes[2] = { F("LAN8710"), F("TLK110") }; + addSelector("ethtype", 2, ethPhyTypes, NULL, NULL, Settings.ETH_Phy_Type, false, true); + addFormNumericBox(F("Ethernet PHY Address"), "ethphy", Settings.ETH_Phy_Addr, 0, 255); + addFormNote(F("I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)")); + addFormPinSelect(formatGpioName_output("Ethernet MDC pin"), "ethmdc", Settings.ETH_Pin_mdc); + addFormPinSelect(formatGpioName_input("Ethernet MIO pin"), "ethmdio", Settings.ETH_Pin_mdio); + addFormPinSelect(formatGpioName_output("Ethernet Power pin"), "ethpower", Settings.ETH_Pin_power); + addRowLabel_tr_id(F("Ethernet Clock"), "ethclock"); + String ethClockOptions[4] = { F("External crystal oscillator"), + F("50MHz APLL Output on GPIO0"), + F("50MHz APLL Output on GPIO16"), + F("50MHz APLL Inverted Output on GPIO17") }; + addSelector("ethclock", 4, ethClockOptions, NULL, NULL, Settings.ETH_Clock_Mode, false, true); +#endif // ifdef HAS_ETHERNET addFormSubHeader(F("GPIO boot states")); int gpio = 0; diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index acec419a7..d8e63ca73 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -177,6 +177,14 @@ class SettingsStruct_tmpl // Try to extend settings to make the checksum 4-byte aligned. // uint8_t ProgmemMd5[16]; // crc of the binary that last saved the struct to file. // uint8_t md5[16]; +#ifdef HAS_ETHERNET + uint8_t ETH_Phy_Addr; + int8_t ETH_Pin_mdc; + int8_t ETH_Pin_mdio; + int8_t ETH_Pin_power; + int8_t ETH_Phy_Type; + uint8_t ETH_Clock_Mode; +#endif }; /* From c7b9f3f55e118dacfaf3e331f2c2ac8782df35da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Mon, 23 Mar 2020 11:11:07 +0100 Subject: [PATCH 007/128] Added Olimex ESP32-PoE board to DeviceModel and default settings --- src/ESPEasy-Globals.h | 19 +++++++++++++++++++ src/ESPEasy_checks.ino | 6 +++++- src/Hardware.ino | 3 +++ src/Misc.ino | 9 +++++++++ src/src/DataStructs/DeviceModel.h | 1 + src/src/DataStructs/ESPEasyDefaults.h | 21 +++++++++++++++++++++ src/src/DataStructs/SettingsStruct.cpp | 8 ++++++++ 7 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/ESPEasy-Globals.h b/src/ESPEasy-Globals.h index f7dbdda74..f9625739e 100644 --- a/src/ESPEasy-Globals.h +++ b/src/ESPEasy-Globals.h @@ -422,6 +422,17 @@ struct GpioFactorySettingsStruct { i2c_sda = -1; // GPIO4 conflicts with relay control. i2c_scl = -1; // GPIO5 conflicts with SW input break; + case DeviceMode_Olimex_ESP32_PoE: + button[0] = 34; // DUT1 Button + relais[0] = -1; // No LED's or relays on board + status_led = -1; + i2c_sda = 4; + i2c_scl = 5; + #ifdef HAS_ETHERNET + eth_power = 12; + eth_clock_mode = 3; + #endif + break; // case DeviceModel_default: break; default: break; @@ -433,6 +444,14 @@ struct GpioFactorySettingsStruct { int8_t status_led = DEFAULT_PIN_STATUS_LED; int8_t i2c_sda = DEFAULT_PIN_I2C_SDA; int8_t i2c_scl = DEFAULT_PIN_I2C_SCL; +#ifdef HAS_ETHERNET + int8_t eth_phyaddr = DEFAULT_ETH_PHY_ADDR; + int8_t eth_phytype = DEFAULT_ETH_PHY_TYPE; + int8_t eth_mdc = DEFAULT_ETH_PIN_MDC; + int8_t eth_mdio = DEFAULT_ETH_PIN_MDIO; + int8_t eth_power = DEFAULT_ETH_PIN_POWER; + int8_t eth_clock_mode = DEFAULT_ETH_CLOCK_MODE; +#endif }; void addPredefinedPlugins(const GpioFactorySettingsStruct& gpio_settings); diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index 5de4f950c..aa6c5613f 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -34,7 +34,11 @@ template constexpr size_t offsetOf(U T::*member) void run_compiletime_checks() { check_size(); check_size(); +#ifdef HAS_ETHERNET const unsigned int SettingsStructSize = (256 + 82 * TASKS_MAX); +#else + const unsigned int SettingsStructSize = (248 + 82 * TASKS_MAX); +#endif check_size(); check_size(); check_size(); @@ -54,7 +58,7 @@ void run_compiletime_checks() { check_size(); check_size(); check_size(); - check_size(); + check_size(); #if defined(USE_NON_STANDARD_24_TASKS) && defined(ESP8266) static_assert(TASKS_MAX == 24, "TASKS_MAX invalid size"); #endif diff --git a/src/Hardware.ino b/src/Hardware.ino index e06b9b451..1aed68d5c 100644 --- a/src/Hardware.ino +++ b/src/Hardware.ino @@ -166,6 +166,7 @@ String getDeviceModelBrandString(DeviceModel model) { case DeviceModel_Sonoff_POW: case DeviceModel_Sonoff_POWr2: return F("Sonoff"); case DeviceModel_Shelly1: return F("Shelly"); + case DeviceMode_Olimex_ESP32_PoE: return F("Olimex"); // case DeviceModel_default: default: return ""; @@ -189,6 +190,7 @@ String getDeviceModelString(DeviceModel model) { case DeviceModel_Sonoff_POW: result += F(" POW"); break; case DeviceModel_Sonoff_POWr2: result += F(" POW-r2"); break; case DeviceModel_Shelly1: result += '1'; break; + case DeviceMode_Olimex_ESP32_PoE: result += F(" ESP32-PoE"); break; // case DeviceModel_default: default: result += F("default"); @@ -211,6 +213,7 @@ bool modelMatchingFlashSize(DeviceModel model) { case DeviceModel_Sonoff_POW: case DeviceModel_Sonoff_POWr2: return size_MB == 4; case DeviceModel_Shelly1: return size_MB == 2; + case DeviceMode_Olimex_ESP32_PoE:return size_MB == 4; // case DeviceModel_default: default: return true; diff --git a/src/Misc.ino b/src/Misc.ino index d4dc6666f..4a683dc53 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -1208,6 +1208,15 @@ void ResetFactory() Settings.UseSerial = DEFAULT_USE_SERIAL; Settings.BaudRate = DEFAULT_SERIAL_BAUD; +#ifdef HAS_ETHERNET + Settings.ETH_Phy_Addr = gpio_settings.eth_phyaddr; + Settings.ETH_Pin_mdc = gpio_settings.eth_mdc; + Settings.ETH_Pin_mdio = gpio_settings.eth_mdio; + Settings.ETH_Pin_power = gpio_settings.eth_power; + Settings.ETH_Phy_Type = gpio_settings.eth_phytype; + Settings.ETH_Clock_Mode = gpio_settings.eth_clock_mode; +#endif + /* Settings.GlobalSync = DEFAULT_USE_GLOBAL_SYNC; diff --git a/src/src/DataStructs/DeviceModel.h b/src/src/DataStructs/DeviceModel.h index dca830c92..4fd4cf830 100644 --- a/src/src/DataStructs/DeviceModel.h +++ b/src/src/DataStructs/DeviceModel.h @@ -18,6 +18,7 @@ enum DeviceModel { DeviceModel_Sonoff_POW, DeviceModel_Sonoff_POWr2, DeviceModel_Shelly1, + DeviceMode_Olimex_ESP32_PoE, DeviceModel_MAX }; diff --git a/src/src/DataStructs/ESPEasyDefaults.h b/src/src/DataStructs/ESPEasyDefaults.h index b2597308f..999a328dc 100644 --- a/src/src/DataStructs/ESPEasyDefaults.h +++ b/src/src/DataStructs/ESPEasyDefaults.h @@ -168,6 +168,27 @@ #define DEFAULT_PIN_STATUS_LED_INVERSED true #endif +#ifdef HAS_ETHERNET +#ifndef DEFAULT_ETH_PHY_ADDR +#define DEFAULT_ETH_PHY_ADDR 0 +#endif +#ifndef DEFAULT_ETH_PHY_TYPE +#define DEFAULT_ETH_PHY_TYPE 0 +#endif +#ifndef DEFAULT_ETH_PIN_MDC +#define DEFAULT_ETH_PIN_MDC 23 +#endif +#ifndef DEFAULT_ETH_PIN_MDIO +#define DEFAULT_ETH_PIN_MDIO 18 +#endif +#ifndef DEFAULT_ETH_PIN_POWER +#define DEFAULT_ETH_PIN_POWER -1 +#endif +#ifndef DEFAULT_ETH_CLOCK_MODE +#define DEFAULT_ETH_CLOCK_MODE 3 +#endif +#endif + // --- Advanced Settings --------------------------------------------------------------------------------- diff --git a/src/src/DataStructs/SettingsStruct.cpp b/src/src/DataStructs/SettingsStruct.cpp index 5ef1bc683..1faf47b15 100644 --- a/src/src/DataStructs/SettingsStruct.cpp +++ b/src/src/DataStructs/SettingsStruct.cpp @@ -206,6 +206,14 @@ void SettingsStruct_tmpl::clearMisc() { Pin_i2c_scl = -1; Pin_status_led = -1; Pin_sd_cs = -1; +#ifdef HAS_ETHERNET + ETH_Phy_Addr = 0; + ETH_Pin_mdc = -1; + ETH_Pin_mdio = -1; + ETH_Pin_power = -1; + ETH_Phy_Type = 0; + ETH_Clock_Mode = 0; +#endif for (byte i = 0; i < 17; ++i) { PinBootStates[i] = 0; } BaudRate = 0; From dffd7ebfc1da7f081de49a3efce666db5973934d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Mon, 23 Mar 2020 12:33:08 +0100 Subject: [PATCH 008/128] Increased BUILD number to 20107 --- src/ESPEasyStorage.ino | 10 ++++++++++ src/ESPEasy_buildinfo.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ESPEasyStorage.ino b/src/ESPEasyStorage.ino index 700e60898..b90ec34e6 100644 --- a/src/ESPEasyStorage.ino +++ b/src/ESPEasyStorage.ino @@ -178,6 +178,16 @@ String BuildFixes() } #endif // USES_MQTT } +#ifdef HAS_ETHERNET + if (Settings.Build < 20107) { + Settings.ETH_Phy_Addr = DEFAULT_ETH_PHY_ADDR; + Settings.ETH_Pin_mdc = DEFAULT_ETH_PIN_MDC; + Settings.ETH_Pin_mdio = DEFAULT_ETH_PIN_MDIO; + Settings.ETH_Pin_power = DEFAULT_ETH_PIN_POWER; + Settings.ETH_Phy_Type = DEFAULT_ETH_PHY_TYPE; + Settings.ETH_Clock_Mode = DEFAULT_ETH_CLOCK_MODE; + } +#endif Settings.Build = BUILD; return SaveSettings(); diff --git a/src/ESPEasy_buildinfo.h b/src/ESPEasy_buildinfo.h index d87055c12..b6647320a 100644 --- a/src/ESPEasy_buildinfo.h +++ b/src/ESPEasy_buildinfo.h @@ -20,7 +20,7 @@ #endif // if defined(ESP32) -#define BUILD 20106 // git version e.g. "20103" can be read as "2.1.03" (stored in int16_t) +#define BUILD 20107 // git version e.g. "20103" can be read as "2.1.03" (stored in int16_t) #if defined(ESP8266) # define BUILD_NOTES " - Mega" #endif // if defined(ESP8266) From 5f15e98e5a93d7c9e6f2baa5d3222702663ebad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Mon, 23 Mar 2020 12:50:55 +0100 Subject: [PATCH 009/128] Fix build on devices without Ethernet. Forget to adjust size of GpioFactorySettingsStruct. --- src/ESPEasy_checks.ino | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index aa6c5613f..c3432d664 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -58,7 +58,12 @@ void run_compiletime_checks() { check_size(); check_size(); check_size(); - check_size(); +#ifdef HAS_ETHERNET + const unsigned int GpioFactorySettingsStructSize = 17; +#else + const unsigned int GpioFactorySettingsStructSize = 11; +#endif + check_size(); #if defined(USE_NON_STANDARD_24_TASKS) && defined(ESP8266) static_assert(TASKS_MAX == 24, "TASKS_MAX invalid size"); #endif From 9314523c22ee4e96f9b682bd6ec1a287e3f7c27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Mon, 23 Mar 2020 13:20:55 +0100 Subject: [PATCH 010/128] Remove ifdefs for Ethernet in settings --- src/ESPEasy-Globals.h | 4 - src/ESPEasyEth_ProcessEvent.ino | 426 ++++++++++++++++++++++++++ src/ESPEasyStorage.ino | 2 - src/ESPEasy_checks.ino | 11 +- src/Misc.ino | 2 - src/src/DataStructs/ESPEasyDefaults.h | 2 - src/src/DataStructs/SettingsStruct.h | 2 - 7 files changed, 427 insertions(+), 22 deletions(-) create mode 100644 src/ESPEasyEth_ProcessEvent.ino diff --git a/src/ESPEasy-Globals.h b/src/ESPEasy-Globals.h index f9625739e..109000964 100644 --- a/src/ESPEasy-Globals.h +++ b/src/ESPEasy-Globals.h @@ -428,10 +428,8 @@ struct GpioFactorySettingsStruct { status_led = -1; i2c_sda = 4; i2c_scl = 5; - #ifdef HAS_ETHERNET eth_power = 12; eth_clock_mode = 3; - #endif break; // case DeviceModel_default: break; @@ -444,14 +442,12 @@ struct GpioFactorySettingsStruct { int8_t status_led = DEFAULT_PIN_STATUS_LED; int8_t i2c_sda = DEFAULT_PIN_I2C_SDA; int8_t i2c_scl = DEFAULT_PIN_I2C_SCL; -#ifdef HAS_ETHERNET int8_t eth_phyaddr = DEFAULT_ETH_PHY_ADDR; int8_t eth_phytype = DEFAULT_ETH_PHY_TYPE; int8_t eth_mdc = DEFAULT_ETH_PIN_MDC; int8_t eth_mdio = DEFAULT_ETH_PIN_MDIO; int8_t eth_power = DEFAULT_ETH_PIN_POWER; int8_t eth_clock_mode = DEFAULT_ETH_CLOCK_MODE; -#endif }; void addPredefinedPlugins(const GpioFactorySettingsStruct& gpio_settings); diff --git a/src/ESPEasyEth_ProcessEvent.ino b/src/ESPEasyEth_ProcessEvent.ino new file mode 100644 index 000000000..3ed601e46 --- /dev/null +++ b/src/ESPEasyEth_ProcessEvent.ino @@ -0,0 +1,426 @@ +#include "src/Globals/ESPEasyWiFiEvent.h" + +/* +bool unprocessedWifiEvents() { + if (processedConnect && processedDisconnect && processedGotIP && processedDHCPTimeout) + { + return false; + } + return true; +} + +// ******************************************************************************** +// Called from the loop() to make sure events are processed as soon as possible. +// These functions are called from Setup() or Loop() and thus may call delay() or yield() +// ******************************************************************************** +void handle_unprocessedWiFiEvents() +{ + if (WiFi.status() == WL_DISCONNECTED) { + delay(100); + } + + if ((wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) || unprocessedWifiEvents()) { + // WiFi connection is not yet available, so introduce some extra delays to + // help the background tasks managing wifi connections + delay(1); + + if (wifiConnectAttemptNeeded) { + WiFiConnectRelaxed(); + } + + // Process disconnect events before connect events. + if (!processedDisconnect) { + #ifndef BUILD_NO_DEBUG + addLog(LOG_LEVEL_DEBUG, F("WIFI : Entering processDisconnect()")); + #endif // ifndef BUILD_NO_DEBUG + processDisconnect(); + } + + if (!processedConnect) { + #ifndef BUILD_NO_DEBUG + addLog(LOG_LEVEL_DEBUG, F("WIFI : Entering processConnect()")); + #endif // ifndef BUILD_NO_DEBUG + processConnect(); + } + + if (!processedGotIP) { + #ifndef BUILD_NO_DEBUG + addLog(LOG_LEVEL_DEBUG, F("WIFI : Entering processGotIP()")); + #endif // ifndef BUILD_NO_DEBUG + processGotIP(); + } + + if (!processedDHCPTimeout) { + #ifndef BUILD_NO_DEBUG + addLog(LOG_LEVEL_DEBUG, F("WIFI : DHCP timeout, Calling disconnect()")); + #endif // ifndef BUILD_NO_DEBUG + processedDHCPTimeout = true; + processDisconnect(); + } + + if (wifiStatus & ESPEASY_WIFI_CONNECTED) { + // The actual connection has been made, no need to wait for IP to release this semaphore. + wifiConnectInProgress = false; + } + + if ((wifiStatus & ESPEASY_WIFI_GOT_IP) && (wifiStatus & ESPEASY_WIFI_CONNECTED) && WiFi.isConnected()) { + markWiFi_services_initialized(); + } + } else if (!WiFiConnected()) { + // Somehow the WiFi has entered a limbo state. + // FIXME TD-er: This may happen on WiFi config with AP_STA mode active. + // addLog(LOG_LEVEL_ERROR, F("Wifi status out sync")); + // resetWiFi(); + if (loglevelActiveFor(LOG_LEVEL_ERROR)) { + String wifilog = F("WIFI : Wifi status out sync WiFi.status() = "); + wifilog += String(WiFi.status()); + + addLog(LOG_LEVEL_ERROR, wifilog); + } + } + + if (wifiStatus == ESPEASY_WIFI_DISCONNECTED) { + #ifndef BUILD_NO_DEBUG + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { + String wifilog = F("WIFI : Disconnected: WiFi.status() = "); + wifilog += String(WiFi.status()); + + addLog(LOG_LEVEL_DEBUG, wifilog); + } + #endif // ifndef BUILD_NO_DEBUG + + // While connecting to WiFi make sure the device has ample time to do so + delay(10); + } + + if (!processedDisconnectAPmode) { processDisconnectAPmode(); } + + if (!processedConnectAPmode) { processConnectAPmode(); } + + if (timerAPoff != 0) { processDisableAPmode(); } + + if (!processedScanDone) { processScanDone(); } + + if (wifi_connect_attempt > 0) { + // We only want to clear this counter if the connection is currently stable. + if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) { + if (timePassedSince(lastConnectMoment) > WIFI_CONNECTION_CONSIDERED_STABLE) { + // Connection considered stable + wifi_connect_attempt = 0; + + if (!WiFi.getAutoConnect()) { + WiFi.setAutoConnect(true); + } + } else { + if (WiFi.getAutoConnect()) { + WiFi.setAutoConnect(false); + } + } + } + } +} + +// ******************************************************************************** +// Functions to process the data gathered from the events. +// These functions are called from Setup() or Loop() and thus may call delay() or yield() +// ******************************************************************************** +void processDisconnect() { + if (processedDisconnect) { return; } + processedDisconnect = true; + wifiStatus = ESPEASY_WIFI_DISCONNECTED; +// setWebserverRunning(false); + delay(100); // FIXME TD-er: See https://github.com/letscontrolit/ESPEasy/issues/1987#issuecomment-451644424 + + if (Settings.UseRules) { + eventQueue.add(F("WiFi#Disconnected")); + } + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("WIFI : Disconnected! Reason: '"); + log += getLastDisconnectReason(); + log += '\''; + + if (lastConnectedDuration > 0) { + log += F(" Connected for "); + log += format_msec_duration(lastConnectedDuration); + } + addLog(LOG_LEVEL_INFO, log); + } + + if (Settings.WiFiRestart_connection_lost()) { + setWifiMode(WIFI_OFF); + delay(100); + } + logConnectionStatus(); +} + +void processConnect() { + if (processedConnect) { return; } + processedConnect = true; + wifiStatus |= ESPEASY_WIFI_CONNECTED; + delay(100); // FIXME TD-er: See https://github.com/letscontrolit/ESPEasy/issues/1987#issuecomment-451644424 + ++wifi_reconnects; + + if (wifiStatus < ESPEASY_WIFI_CONNECTED) { return; } + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + const long connect_duration = timeDiff(last_wifi_connect_attempt_moment, lastConnectMoment); + String log = F("WIFI : Connected! AP: "); + log += WiFi.SSID(); + log += " ("; + log += WiFi.BSSIDstr(); + log += F(") Ch: "); + log += RTC.lastWiFiChannel; + + if ((connect_duration > 0) && (connect_duration < 30000)) { + // Just log times when they make sense. + log += F(" Duration: "); + log += connect_duration; + log += F(" ms"); + } + addLog(LOG_LEVEL_INFO, log); + } + + if (Settings.UseRules) { + if (bssid_changed) { + eventQueue.add(F("WiFi#ChangedAccesspoint")); + } + + if (channel_changed) { + eventQueue.add(F("WiFi#ChangedWiFichannel")); + } + } + + if (useStaticIP()) { + markGotIP(); // in static IP config the got IP event is never fired. + } + saveToRTC(); + + logConnectionStatus(); +} + +void processGotIP() { + if (processedGotIP) { + return; + } + IPAddress ip = WiFi.localIP(); + + if (!useStaticIP()) { + if ((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)) { + return; + } + } + processedGotIP = true; + wifiStatus |= ESPEASY_WIFI_GOT_IP; + const IPAddress gw = WiFi.gatewayIP(); + const IPAddress subnet = WiFi.subnetMask(); + const long dhcp_duration = timeDiff(lastConnectMoment, lastGetIPmoment); + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("WIFI : "); + + if (useStaticIP()) { + log += F("Static IP: "); + } else { + log += F("DHCP IP: "); + } + log += formatIP(ip); + log += " ("; + log += WifiGetHostname(); + log += F(") GW: "); + log += formatIP(gw); + log += F(" SN: "); + log += formatIP(subnet); + + if ((dhcp_duration > 0) && (dhcp_duration < 30000)) { + // Just log times when they make sense. + log += F(" duration: "); + log += dhcp_duration; + log += F(" ms"); + } + addLog(LOG_LEVEL_INFO, log); + } + + // Might not work in core 2.5.0 + // See https://github.com/esp8266/Arduino/issues/5839 + if ((Settings.IP_Octet != 0) && (Settings.IP_Octet != 255)) + { + ip[3] = Settings.IP_Octet; + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("IP : Fixed IP octet:"); + log += formatIP(ip); + addLog(LOG_LEVEL_INFO, log); + } + WiFi.config(ip, gw, subnet); + } + + // First try to get the time, since that may be used in logs + if (node_time.systemTimePresent()) { + node_time.initTime(); + } +#ifdef USES_MQTT + mqtt_reconnect_count = 0; + MQTTclient_should_reconnect = true; + timermqtt_interval = 100; + setIntervalTimer(TIMER_MQTT); +#endif // USES_MQTT + sendGratuitousARP_now(); + + if (Settings.UseRules) + { + eventQueue.add(F("WiFi#Connected")); + } + statusLED(true); + + // WiFi.scanDelete(); + + if (wifiSetup) { + // Wifi setup was active, Apparently these settings work. + wifiSetup = false; + SaveSettings(); + } + logConnectionStatus(); +} + +// A client disconnected from the AP on this node. +void processDisconnectAPmode() { + if (processedDisconnectAPmode) { return; } + processedDisconnectAPmode = true; + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + const int nrStationsConnected = WiFi.softAPgetStationNum(); + String log = F("AP Mode: Client disconnected: "); + log += formatMAC(lastMacDisconnectedAPmode); + log += F(" Connected devices: "); + log += nrStationsConnected; + addLog(LOG_LEVEL_INFO, log); + } +} + +// Client connects to AP on this node +void processConnectAPmode() { + if (processedConnectAPmode) { return; } + processedConnectAPmode = true; + // Extend timer to switch off AP. + timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION; + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("AP Mode: Client connected: "); + log += formatMAC(lastMacConnectedAPmode); + log += F(" Connected devices: "); + log += WiFi.softAPgetStationNum(); + addLog(LOG_LEVEL_INFO, log); + } + setWebserverRunning(true); + + // Start DNS, only used if the ESP has no valid WiFi config + // It will reply with it's own address on all DNS requests + // (captive portal concept) + if (!dnsServerActive) { + dnsServerActive = true; + dnsServer.start(DNS_PORT, "*", apIP); + } +} + +// Switch of AP mode when timeout reached and no client connected anymore. +void processDisableAPmode() { + if (timerAPoff == 0) { return; } + + if (WifiIsAP(WiFi.getMode())) { + // disable AP after timeout and no clients connected. + if (timeOutReached(timerAPoff) && (WiFi.softAPgetStationNum() == 0)) { + setAP(false); + } + } + + if (!WifiIsAP(WiFi.getMode())) { + timerAPoff = 0; + } +} + +void processScanDone() { + if (processedScanDone) { return; } + + // Better act on the scan done event, as it may get triggered for normal wifi begin calls. + int8_t scanCompleteStatus = WiFi.scanComplete(); + switch (scanCompleteStatus) { + case 0: // Nothing (yet) found + if (timePassedSince(lastGetScanMoment) > 5000) { + processedScanDone = true; + } + return; + case -1: // WIFI_SCAN_RUNNING + return; + case -2: // WIFI_SCAN_FAILED + addLog(LOG_LEVEL_ERROR, F("WiFi : Scan failed")); + processedScanDone = true; + return; + } + + lastGetScanMoment = millis(); + processedScanDone = true; + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("WIFI : Scan finished, found: "); + log += scanCompleteStatus; + addLog(LOG_LEVEL_INFO, log); + } + + int bestScanID = -1; + int32_t bestRssi = -1000; + uint8_t bestWiFiSettings = RTC.lastWiFiSettingsIndex; + + if (selectValidWiFiSettings() && scanCompleteStatus > 0) { + const uint8_t startWiFiSettings = RTC.lastWiFiSettingsIndex; + bool done = false; + while (!done) { + String ssid_to_check = getLastWiFiSettingsSSID(); + for (int i = 0; i < scanCompleteStatus; ++i) { + if (WiFi.SSID(i) == ssid_to_check) { + int32_t rssi = WiFi.RSSI(i); + + if (bestRssi < rssi) { + bestRssi = rssi; + bestScanID = i; + bestWiFiSettings = RTC.lastWiFiSettingsIndex; + } + } + } + + // Select the next WiFi settings. + // RTC.lastWiFiSettingsIndex may be updated. + if (!selectNextWiFiSettings()) { + done = true; + } + if (startWiFiSettings == RTC.lastWiFiSettingsIndex) { + done = true; + } + } + + if (bestScanID >= 0) { + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("WIFI : Selected: "); + log += formatScanResult(bestScanID, " "); + addLog(LOG_LEVEL_INFO, log); + } + RTC.lastWiFiSettingsIndex = bestWiFiSettings; + uint8_t *scanbssid = WiFi.BSSID(bestScanID); + + if (scanbssid) { + for (int i = 0; i < 6; ++i) { + RTC.lastBSSID[i] = *(scanbssid + i); + } + } + } + } +} + + +void markWiFi_services_initialized() { + wifiStatus = ESPEASY_WIFI_SERVICES_INITIALIZED; + wifiConnectInProgress = false; + setWebserverRunning(true); +} +*/ \ No newline at end of file diff --git a/src/ESPEasyStorage.ino b/src/ESPEasyStorage.ino index b90ec34e6..2bc92cc1e 100644 --- a/src/ESPEasyStorage.ino +++ b/src/ESPEasyStorage.ino @@ -178,7 +178,6 @@ String BuildFixes() } #endif // USES_MQTT } -#ifdef HAS_ETHERNET if (Settings.Build < 20107) { Settings.ETH_Phy_Addr = DEFAULT_ETH_PHY_ADDR; Settings.ETH_Pin_mdc = DEFAULT_ETH_PIN_MDC; @@ -187,7 +186,6 @@ String BuildFixes() Settings.ETH_Phy_Type = DEFAULT_ETH_PHY_TYPE; Settings.ETH_Clock_Mode = DEFAULT_ETH_CLOCK_MODE; } -#endif Settings.Build = BUILD; return SaveSettings(); diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index c3432d664..0761d9e61 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -34,11 +34,7 @@ template constexpr size_t offsetOf(U T::*member) void run_compiletime_checks() { check_size(); check_size(); -#ifdef HAS_ETHERNET const unsigned int SettingsStructSize = (256 + 82 * TASKS_MAX); -#else - const unsigned int SettingsStructSize = (248 + 82 * TASKS_MAX); -#endif check_size(); check_size(); check_size(); @@ -58,12 +54,7 @@ void run_compiletime_checks() { check_size(); check_size(); check_size(); -#ifdef HAS_ETHERNET - const unsigned int GpioFactorySettingsStructSize = 17; -#else - const unsigned int GpioFactorySettingsStructSize = 11; -#endif - check_size(); + check_size(); #if defined(USE_NON_STANDARD_24_TASKS) && defined(ESP8266) static_assert(TASKS_MAX == 24, "TASKS_MAX invalid size"); #endif diff --git a/src/Misc.ino b/src/Misc.ino index 4a683dc53..d81d24952 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -1208,14 +1208,12 @@ void ResetFactory() Settings.UseSerial = DEFAULT_USE_SERIAL; Settings.BaudRate = DEFAULT_SERIAL_BAUD; -#ifdef HAS_ETHERNET Settings.ETH_Phy_Addr = gpio_settings.eth_phyaddr; Settings.ETH_Pin_mdc = gpio_settings.eth_mdc; Settings.ETH_Pin_mdio = gpio_settings.eth_mdio; Settings.ETH_Pin_power = gpio_settings.eth_power; Settings.ETH_Phy_Type = gpio_settings.eth_phytype; Settings.ETH_Clock_Mode = gpio_settings.eth_clock_mode; -#endif /* Settings.GlobalSync = DEFAULT_USE_GLOBAL_SYNC; diff --git a/src/src/DataStructs/ESPEasyDefaults.h b/src/src/DataStructs/ESPEasyDefaults.h index 999a328dc..688b5e6da 100644 --- a/src/src/DataStructs/ESPEasyDefaults.h +++ b/src/src/DataStructs/ESPEasyDefaults.h @@ -168,7 +168,6 @@ #define DEFAULT_PIN_STATUS_LED_INVERSED true #endif -#ifdef HAS_ETHERNET #ifndef DEFAULT_ETH_PHY_ADDR #define DEFAULT_ETH_PHY_ADDR 0 #endif @@ -187,7 +186,6 @@ #ifndef DEFAULT_ETH_CLOCK_MODE #define DEFAULT_ETH_CLOCK_MODE 3 #endif -#endif diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index d8e63ca73..ae9d27f00 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -177,14 +177,12 @@ class SettingsStruct_tmpl // Try to extend settings to make the checksum 4-byte aligned. // uint8_t ProgmemMd5[16]; // crc of the binary that last saved the struct to file. // uint8_t md5[16]; -#ifdef HAS_ETHERNET uint8_t ETH_Phy_Addr; int8_t ETH_Pin_mdc; int8_t ETH_Pin_mdio; int8_t ETH_Pin_power; int8_t ETH_Phy_Type; uint8_t ETH_Clock_Mode; -#endif }; /* From 7584ce6cc9ed45a925fdc0d30a1cef9d6f7930f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Mon, 23 Mar 2020 23:19:48 +0100 Subject: [PATCH 011/128] Renamed functions in ESPEasyEth, added eth* prefix --- src/ESPEasyEth.ino | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/ESPEasyEth.ino b/src/ESPEasyEth.ino index 2173e1145..8016d32ae 100644 --- a/src/ESPEasyEth.ino +++ b/src/ESPEasyEth.ino @@ -1,19 +1,16 @@ #ifdef HAS_ETHERNET - // #define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT - // #define ETH_PHY_POWER 12 - #include "ETH.h" - #include -String EthGetHostname() -{ +#include "ETH.h" + +String ethGetHostname() { String hostnameToReturn(Settings.getHostname()); hostnameToReturn.replace(" ", "-"); hostnameToReturn.replace("_", "-"); // See RFC952 return hostnameToReturn; } -bool checkSettings() { +bool ethCheckSettings() { bool result = true; if (Settings.ETH_Phy_Type != 0 && Settings.ETH_Phy_Type != 1) result = false; @@ -28,18 +25,17 @@ bool checkSettings() { return result; } -bool prepareEth() { - if (!checkSettings()) +bool ethPrepare() { + if (!ethCheckSettings()) { addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!")); return false; } - ETH.setHostname(EthGetHostname().c_str()); + ETH.setHostname(ethGetHostname().c_str()); return true; } -String getDebugClockModeStr() -{ +String ethGetDebugClockModeStr() { switch (Settings.ETH_Clock_Mode) { case 0: return F("ETH_CLOCK_GPIO0_IN"); @@ -50,8 +46,7 @@ String getDebugClockModeStr() } } -void printSettings() -{ +void ethPrintSettings() { String settingsDebugLog; settingsDebugLog.reserve(115); settingsDebugLog += F("ETH: PHY Type: "); @@ -59,7 +54,7 @@ void printSettings() settingsDebugLog += F(" PHY Addr: "); settingsDebugLog += Settings.ETH_Phy_Addr; settingsDebugLog += F(" Eth Clock mode: "); - settingsDebugLog += getDebugClockModeStr(); + settingsDebugLog += ethGetDebugClockModeStr(); settingsDebugLog += F(" MDC Pin: "); settingsDebugLog += String(Settings.ETH_Pin_mdc); settingsDebugLog += F(" MIO Pin: "); @@ -70,11 +65,8 @@ void printSettings() } void ETHConnectRelaxed() { - // if (!ethConnectAttemptNeeded) { - // return; // already connected or connect attempt in progress need to disconnect first - // } - printSettings(); - if (!prepareEth()) { + ethPrintSettings(); + if (!ethPrepare()) { // Dead code for now... addLog(LOG_LEVEL_ERROR, F("ETH : Could not prepare ETH!")); return; From 6137da89f00d8053d92c11bc15f31ea3cd7085c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Tue, 24 Mar 2020 09:40:34 +0100 Subject: [PATCH 012/128] Moved WifiGetHostname into more generic createRFCCompliantHostname --- src/ESPEasyEth.ino | 9 +-------- src/ESPEasyWifi.ino | 14 +------------- src/ESPEasyWifi_ProcessEvent.ino | 2 +- src/Networking.ino | 10 ++++++++++ 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/ESPEasyEth.ino b/src/ESPEasyEth.ino index 8016d32ae..de595e0d0 100644 --- a/src/ESPEasyEth.ino +++ b/src/ESPEasyEth.ino @@ -3,13 +3,6 @@ #include "ETH.h" -String ethGetHostname() { - String hostnameToReturn(Settings.getHostname()); - hostnameToReturn.replace(" ", "-"); - hostnameToReturn.replace("_", "-"); // See RFC952 - return hostnameToReturn; -} - bool ethCheckSettings() { bool result = true; if (Settings.ETH_Phy_Type != 0 && Settings.ETH_Phy_Type != 1) @@ -31,7 +24,7 @@ bool ethPrepare() { addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!")); return false; } - ETH.setHostname(ethGetHostname().c_str()); + ETH.setHostname(createRFCCompliantHostname(Settings.getHostname()).c_str()); return true; } diff --git a/src/ESPEasyWifi.ino b/src/ESPEasyWifi.ino index 9eec41d8d..4d6f56538 100644 --- a/src/ESPEasyWifi.ino +++ b/src/ESPEasyWifi.ino @@ -203,7 +203,7 @@ bool prepareWiFi() { } setSTA(true); char hostname[40]; - safe_strncpy(hostname, WifiGetHostname().c_str(), sizeof(hostname)); + safe_strncpy(hostname, createRFCCompliantHostname(WifiGetAPssid()).c_str(), sizeof(hostname)); #if defined(ESP8266) wifi_station_set_hostname(hostname); @@ -514,18 +514,6 @@ String WifiGetAPssid() return Settings.getHostname(); } -// ******************************************************************************** -// Determine hostname: basically WifiGetAPssid with spaces changed to - -// ******************************************************************************** -String WifiGetHostname() -{ - String hostname(WifiGetAPssid()); - - hostname.replace(" ", "-"); - hostname.replace("_", "-"); // See RFC952 - return hostname; -} - bool useStaticIP() { return Settings.IP[0] != 0 && Settings.IP[0] != 255; } diff --git a/src/ESPEasyWifi_ProcessEvent.ino b/src/ESPEasyWifi_ProcessEvent.ino index 3f8e563d5..ee7ff8d55 100644 --- a/src/ESPEasyWifi_ProcessEvent.ino +++ b/src/ESPEasyWifi_ProcessEvent.ino @@ -246,7 +246,7 @@ void processGotIP() { } log += formatIP(ip); log += " ("; - log += WifiGetHostname(); + log += createRFCCompliantHostname(WifiGetAPssid()); log += F(") GW: "); log += formatIP(gw); log += F(" SN: "); diff --git a/src/Networking.ino b/src/Networking.ino index 8284f7a9f..16ee2fc47 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -1002,6 +1002,16 @@ String splitURL(const String& fullURL, String& host, uint16_t& port, String& fil return fullURL.substring(endhost); } +// Create hostname with - instead of spaces +String createRFCCompliantHostname(String oldString) +{ + String result(oldString); + + result.replace(" ", "-"); + result.replace("_", "-"); // See RFC952 + return result; +} + #ifdef USE_SETTINGS_ARCHIVE // Download a file from a given URL and save to a local file named "file_save" From da1039e7f29cf10aae26a246d54457c9eda7fef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Obrembski?= Date: Mon, 13 Apr 2020 15:04:11 +0200 Subject: [PATCH 013/128] Added basic implementation of Ethernet Static IP --- src/ESPEasyEth.ino | 29 ++++++++++++++++++++++++++ src/ESPEasy_checks.ino | 2 +- src/WebServer_ConfigPage.ino | 22 +++++++++++++++++++ src/src/DataStructs/SettingsStruct.cpp | 6 ++++-- src/src/DataStructs/SettingsStruct.h | 4 ++++ 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/ESPEasyEth.ino b/src/ESPEasyEth.ino index de595e0d0..9bc430272 100644 --- a/src/ESPEasyEth.ino +++ b/src/ESPEasyEth.ino @@ -3,6 +3,33 @@ #include "ETH.h" +bool ethUseStaticIP() { + return Settings.ETH_IP[0] != 0 && Settings.ETH_IP[3] != 255; +} + +void ethSetupStaticIPconfig() { + //setUseStaticIP(useStaticIP()); + + if (!ethUseStaticIP()) { return; } + const IPAddress ip = Settings.ETH_IP; + const IPAddress gw = Settings.ETH_Gateway; + const IPAddress subnet = Settings.ETH_Subnet; + const IPAddress dns = Settings.ETH_DNS; + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("ETH IP : Static IP : "); + log += formatIP(ip); + log += F(" GW: "); + log += formatIP(gw); + log += F(" SN: "); + log += formatIP(subnet); + log += F(" DNS: "); + log += formatIP(dns); + addLog(LOG_LEVEL_INFO, log); + } + ETH.config(ip, gw, subnet, dns); +} + bool ethCheckSettings() { bool result = true; if (Settings.ETH_Phy_Type != 0 && Settings.ETH_Phy_Type != 1) @@ -25,6 +52,8 @@ bool ethPrepare() { return false; } ETH.setHostname(createRFCCompliantHostname(Settings.getHostname()).c_str()); + ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); + ethSetupStaticIPconfig(); return true; } diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index 0761d9e61..df01c948b 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -34,7 +34,7 @@ template constexpr size_t offsetOf(U T::*member) void run_compiletime_checks() { check_size(); check_size(); - const unsigned int SettingsStructSize = (256 + 82 * TASKS_MAX); + const unsigned int SettingsStructSize = (272 + 82 * TASKS_MAX); check_size(); check_size(); check_size(); diff --git a/src/WebServer_ConfigPage.ino b/src/WebServer_ConfigPage.ino index 66a380430..471ab92ff 100644 --- a/src/WebServer_ConfigPage.ino +++ b/src/WebServer_ConfigPage.ino @@ -28,6 +28,12 @@ void handle_config() { String espgateway = web_server.arg(F("espgateway")); String espsubnet = web_server.arg(F("espsubnet")); String espdns = web_server.arg(F("espdns")); +#ifdef HAS_ETHERNET + String espethip = web_server.arg(F("espethip")); + String espethgateway = web_server.arg(F("espethgateway")); + String espethsubnet = web_server.arg(F("espethsubnet")); + String espethdns = web_server.arg(F("espethdns")); +#endif Settings.Unit = getFormItemInt(F("unit"), Settings.Unit); // String apkey = web_server.arg(F("apkey")); @@ -96,6 +102,12 @@ void handle_config() { str2ip(espgateway, Settings.Gateway); str2ip(espsubnet, Settings.Subnet); str2ip(espdns, Settings.DNS); +#ifdef HAS_ETHERNET + str2ip(espethip, Settings.ETH_IP); + str2ip(espethgateway, Settings.ETH_Gateway); + str2ip(espethsubnet, Settings.ETH_Subnet); + str2ip(espethdns, Settings.ETH_DNS); +#endif addHtmlError(SaveSettings()); } @@ -145,6 +157,16 @@ void handle_config() { addFormIPBox(F("ESP DNS"), F("espdns"), Settings.DNS); addFormNote(F("Leave empty for DHCP")); +#ifdef HAS_ETHERNET + addFormSubHeader(F("Ethernet IP Settings")); + + addFormIPBox(F("ESP Ethernet IP"), F("espethip"), Settings.ETH_IP); + addFormIPBox(F("ESP Ethernet GW"), F("espethgateway"), Settings.ETH_Gateway); + addFormIPBox(F("ESP Ethernet Subnetmask"), F("espethsubnet"), Settings.ETH_Subnet); + addFormIPBox(F("ESP Ethernet DNS"), F("espethdns"), Settings.ETH_DNS); + addFormNote(F("Leave empty for DHCP")); +#endif + addFormSubHeader(F("Sleep Mode")); diff --git a/src/src/DataStructs/SettingsStruct.cpp b/src/src/DataStructs/SettingsStruct.cpp index 1faf47b15..3358c60e2 100644 --- a/src/src/DataStructs/SettingsStruct.cpp +++ b/src/src/DataStructs/SettingsStruct.cpp @@ -139,6 +139,10 @@ void SettingsStruct_tmpl::clearNetworkSettings() { Gateway[i] = 0; Subnet[i] = 0; DNS[i] = 0; + ETH_IP[i] = 0; + ETH_Gateway[i] = 0; + ETH_Subnet[i] = 0; + ETH_DNS[i] = 0; } } @@ -206,14 +210,12 @@ void SettingsStruct_tmpl::clearMisc() { Pin_i2c_scl = -1; Pin_status_led = -1; Pin_sd_cs = -1; -#ifdef HAS_ETHERNET ETH_Phy_Addr = 0; ETH_Pin_mdc = -1; ETH_Pin_mdio = -1; ETH_Pin_power = -1; ETH_Phy_Type = 0; ETH_Clock_Mode = 0; -#endif for (byte i = 0; i < 17; ++i) { PinBootStates[i] = 0; } BaudRate = 0; diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index ae9d27f00..db57944e5 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -183,6 +183,10 @@ class SettingsStruct_tmpl int8_t ETH_Pin_power; int8_t ETH_Phy_Type; uint8_t ETH_Clock_Mode; + byte ETH_IP[4]; + byte ETH_Gateway[4]; + byte ETH_Subnet[4]; + byte ETH_DNS[4]; }; /* From 5c4952c57507020b89b526da89d9e708068d38ee Mon Sep 17 00:00:00 2001 From: Bartlomiej Zimon Date: Tue, 14 Apr 2020 16:30:15 +0000 Subject: [PATCH 014/128] PN532: remove hardcoded scl/sda pins reading and use hardware configuration instead --- src/_P017_PN532.ino | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/_P017_PN532.ino b/src/_P017_PN532.ino index 6756f1836..53928a1c6 100644 --- a/src/_P017_PN532.ino +++ b/src/_P017_PN532.ino @@ -71,7 +71,7 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string) case PLUGIN_WEBFORM_LOAD: { // FIXME TD-er: Why is this using pin3 and not pin1? And why isn't this using the normal pin selection functions? - addFormPinSelect(F("Reset Pin"), F("taskdevicepin3"), CONFIG_PIN3); + addFormPinSelect(F("Reset Pin"), F("taskdevicepin3"), CONFIG_PIN3); success = true; break; } @@ -112,7 +112,9 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string) counter++; if (counter == 3 ) { - if (digitalRead(4) == 0 || digitalRead(5) == 0) + // TODO: is it needed? + if (Settings.Pin_i2c_sda >= 0 && Settings.Pin_i2c_scl>= 0 + && (digitalRead(Settings.Pin_i2c_sda)==0 || digitalRead(Settings.Pin_i2c_scl)==0)) { addLog(LOG_LEVEL_ERROR, F("PN532: BUS error")); Plugin_017_Init(CONFIG_PIN3); From f133c2b759e92b744c30560220c457a9cee74483 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zimon Date: Tue, 14 Apr 2020 19:40:28 +0000 Subject: [PATCH 015/128] PN532: update comment --- src/_P017_PN532.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_P017_PN532.ino b/src/_P017_PN532.ino index 53928a1c6..402df7c5e 100644 --- a/src/_P017_PN532.ino +++ b/src/_P017_PN532.ino @@ -112,7 +112,7 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string) counter++; if (counter == 3 ) { - // TODO: is it needed? + // TODO: Clock stretching issue https://github.com/esp8266/Arduino/issues/1541 if (Settings.Pin_i2c_sda >= 0 && Settings.Pin_i2c_scl>= 0 && (digitalRead(Settings.Pin_i2c_sda)==0 || digitalRead(Settings.Pin_i2c_scl)==0)) { From 7238f7c23bde06178ee002cc190462c7256d392c Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Wed, 15 Apr 2020 14:23:54 +0200 Subject: [PATCH 016/128] [MQTT] Process publish LWT connect message asynchronous If publish of LWT connect message fails during connect, retry later. The connect state should not depend on it. --- src/Controller.ino | 119 ++++++++++++++++++++++++++++----------- src/src/Globals/MQTT.cpp | 7 ++- src/src/Globals/MQTT.h | 1 + 3 files changed, 91 insertions(+), 36 deletions(-) diff --git a/src/Controller.ino b/src/Controller.ino index d460ee868..3b4818cae 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -67,7 +67,8 @@ void sendData(struct EventStruct *event) bool validUserVar(struct EventStruct *event) { const deviceIndex_t DeviceIndex = getDeviceIndex_from_TaskIndex(event->TaskIndex); - if (!validDeviceIndex(DeviceIndex)) return false; + + if (!validDeviceIndex(DeviceIndex)) { return false; } switch (Device[DeviceIndex].VType) { case SENSOR_TYPE_LONG: return true; @@ -177,34 +178,13 @@ bool MQTTConnect(controllerIndex_t controller_idx) // MQTT needs a unique clientname to subscribe to broker String clientid = getMQTTclientID(ControllerSettings); - String LWTTopic = ControllerSettings.MQTTLwtTopic; - - if (LWTTopic.length() == 0) - { - LWTTopic = ControllerSettings.Subscribe; - LWTTopic += F("/LWT"); - } - LWTTopic.replace(F("/#"), F("/status")); - parseSystemVariables(LWTTopic, false); - - String LWTMessageConnect = ControllerSettings.LWTMessageConnect; - - if (LWTMessageConnect.length() == 0) { - LWTMessageConnect = F(DEFAULT_MQTT_LWT_CONNECT_MESSAGE); - } - parseSystemVariables(LWTMessageConnect, false); - - String LWTMessageDisconnect = ControllerSettings.LWTMessageDisconnect; - - if (LWTMessageDisconnect.length() == 0) { - LWTMessageDisconnect = F(DEFAULT_MQTT_LWT_DISCONNECT_MESSAGE); - } - parseSystemVariables(LWTMessageDisconnect, false); - - bool MQTTresult = false; - uint8_t willQos = 0; - bool willRetain = ControllerSettings.mqtt_willRetain() && ControllerSettings.mqtt_sendLWT(); - bool cleanSession = ControllerSettings.mqtt_cleanSession(); // As suggested here: https://github.com/knolleary/pubsubclient/issues/458#issuecomment-493875150 + String LWTTopic = getLWT_topic(ControllerSettings); + String LWTMessageDisconnect = getLWT_messageDisconnect(ControllerSettings); + bool MQTTresult = false; + uint8_t willQos = 0; + bool willRetain = ControllerSettings.mqtt_willRetain() && ControllerSettings.mqtt_sendLWT(); + bool cleanSession = ControllerSettings.mqtt_cleanSession(); // As suggested here: + // https://github.com/knolleary/pubsubclient/issues/458#issuecomment-493875150 if (hasControllerCredentialsSet(controller_idx, ControllerSettings)) { MQTTresult = @@ -229,8 +209,9 @@ bool MQTTConnect(controllerIndex_t controller_idx) delay(0); - byte controller_number = Settings.Protocol[controller_idx]; + byte controller_number = Settings.Protocol[controller_idx]; count_connection_results(MQTTresult, F("MQTT : Broker "), controller_number, ControllerSettings); + if (!MQTTresult) { MQTTclient.disconnect(); updateMQTTclient_connected(); @@ -254,13 +235,20 @@ bool MQTTConnect(controllerIndex_t controller_idx) if (MQTTclient_should_reconnect) { CPluginCall(CPlugin::Function::CPLUGIN_GOT_CONNECTED, 0); } MQTTclient_should_reconnect = false; - if (ControllerSettings.mqtt_sendLWT()) { MQTTclient.publish(LWTTopic.c_str(), LWTMessageConnect.c_str(), willRetain); } + if (ControllerSettings.mqtt_sendLWT()) { + String LWTMessageConnect = getLWT_messageConnect(ControllerSettings); + + if (!MQTTclient.publish(LWTTopic.c_str(), LWTMessageConnect.c_str(), willRetain)) { + MQTTclient_must_send_LWT_connected = true; + } + } return true; } String getMQTTclientID(const ControllerSettingsStruct& ControllerSettings) { String clientid = ControllerSettings.ClientID; + if (clientid.length() == 0) { // Try to generate some default clientid = F(CONTROLLER_DEFAULT_CLIENTID); @@ -289,6 +277,7 @@ bool MQTTCheck(controllerIndex_t controller_idx) return false; } protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(controller_idx); + if (!validProtocolIndex(ProtocolIndex)) { return false; } @@ -299,15 +288,79 @@ bool MQTTCheck(controllerIndex_t controller_idx) { if (MQTTclient_should_reconnect) { addLog(LOG_LEVEL_ERROR, F("MQTT : Intentional reconnect")); - } + } return MQTTConnect(controller_idx); } + + if (MQTTclient_must_send_LWT_connected) { + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(controller_idx, ControllerSettings); + + if (ControllerSettings.mqtt_sendLWT()) { + String LWTTopic = getLWT_topic(ControllerSettings); + String LWTMessageConnect = getLWT_messageConnect(ControllerSettings); + bool willRetain = ControllerSettings.mqtt_willRetain(); + + if (MQTTclient.publish(LWTTopic.c_str(), LWTMessageConnect.c_str(), willRetain)) { + MQTTclient_must_send_LWT_connected = false; + } + } else { + MQTTclient_must_send_LWT_connected = false; + } + } } // When no MQTT protocol is enabled, all is fine. return true; } -#endif //USES_MQTT + + +String getLWT_topic(const ControllerSettingsStruct& ControllerSettings) { + String LWTTopic; + + if (ControllerSettings.mqtt_sendLWT()) { + LWTTopic = ControllerSettings.MQTTLwtTopic; + + if (LWTTopic.length() == 0) + { + LWTTopic = ControllerSettings.Subscribe; + LWTTopic += F("/LWT"); + } + LWTTopic.replace(F("/#"), F("/status")); + parseSystemVariables(LWTTopic, false); + } + return LWTTopic; +} + +String getLWT_messageConnect(const ControllerSettingsStruct& ControllerSettings) { + String LWTMessageConnect; + + if (ControllerSettings.mqtt_sendLWT()) { + LWTMessageConnect = ControllerSettings.LWTMessageConnect; + + if (LWTMessageConnect.length() == 0) { + LWTMessageConnect = F(DEFAULT_MQTT_LWT_CONNECT_MESSAGE); + } + parseSystemVariables(LWTMessageConnect, false); + } + return LWTMessageConnect; +} + +String getLWT_messageDisconnect(const ControllerSettingsStruct& ControllerSettings) { + String LWTMessageDisconnect; + + if (ControllerSettings.mqtt_sendLWT()) { + LWTMessageDisconnect = ControllerSettings.LWTMessageDisconnect; + + if (LWTMessageDisconnect.length() == 0) { + LWTMessageDisconnect = F(DEFAULT_MQTT_LWT_DISCONNECT_MESSAGE); + } + parseSystemVariables(LWTMessageDisconnect, false); + } + return LWTMessageDisconnect; +} + +#endif // USES_MQTT /*********************************************************************************************\ * Send status info to request source diff --git a/src/src/Globals/MQTT.cpp b/src/src/Globals/MQTT.cpp index 6043f6b7a..e79a16c21 100644 --- a/src/src/Globals/MQTT.cpp +++ b/src/src/Globals/MQTT.cpp @@ -5,9 +5,10 @@ // MQTT client WiFiClient mqtt; PubSubClient MQTTclient(mqtt); -bool MQTTclient_should_reconnect = true; -bool MQTTclient_connected = false; -int mqtt_reconnect_count = 0; +bool MQTTclient_should_reconnect = true; +bool MQTTclient_must_send_LWT_connected = false; +bool MQTTclient_connected = false; +int mqtt_reconnect_count = 0; #endif // USES_MQTT #ifdef USES_P037 diff --git a/src/src/Globals/MQTT.h b/src/src/Globals/MQTT.h index 50c47e424..f9f369a76 100644 --- a/src/src/Globals/MQTT.h +++ b/src/src/Globals/MQTT.h @@ -13,6 +13,7 @@ extern WiFiClient mqtt; extern PubSubClient MQTTclient; extern bool MQTTclient_should_reconnect; +extern bool MQTTclient_must_send_LWT_connected; extern bool MQTTclient_connected; extern int mqtt_reconnect_count; #endif // USES_MQTT From 394ecfc45538066ace55358a12d907f2b97f7f7f Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Wed, 15 Apr 2020 14:36:13 +0200 Subject: [PATCH 017/128] [MQTT] Stop trying to send LWT connected when client disconnects --- src/ESPEasy.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index d5df04936..9043b36bb 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -642,6 +642,7 @@ void updateMQTTclient_connected() { connectionError += getMQTT_state(); addLog(LOG_LEVEL_ERROR, connectionError); } + MQTTclient_must_send_LWT_connected = false; } else { schedule_all_tasks_using_MQTT_controller(); } From 1de04294cc9b6cb6fcb8769a0bce507f28523614 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Fri, 24 Apr 2020 12:32:35 +0200 Subject: [PATCH 018/128] - Atlas EZO new webserver added - Serial --> logging - No [TESTING] --- src/_P214_Atlas_EZO_pH.ino | 895 ++++++++++++++++++------------------ src/_P222_Atlas_EZO_ORP.ino | 726 ++++++++++++++--------------- 2 files changed, 815 insertions(+), 806 deletions(-) diff --git a/src/_P214_Atlas_EZO_pH.ino b/src/_P214_Atlas_EZO_pH.ino index 99f441f5d..ca4896405 100644 --- a/src/_P214_Atlas_EZO_pH.ino +++ b/src/_P214_Atlas_EZO_pH.ino @@ -1,445 +1,450 @@ -//######################################################################## -//################## Plugin 214 : Atlas Scientific EZO Ph sensor ######## -//######################################################################## - -// datasheet at https://www.atlas-scientific.com/_files/_datasheets/_circuit/pH_EZO_datasheet.pdf -// works only in i2c mode - -#define PLUGIN_214 -#define PLUGIN_ID_214 214 -#define PLUGIN_NAME_214 "Environment - Atlas Scientific pH EZO [TESTING]" -#define PLUGIN_VALUENAME1_214 "pH" -#define PLUGIN_VALUENAME2_214 "Voltage" - -boolean Plugin_214_init = false; - -boolean Plugin_214(byte function, struct EventStruct *event, String& string) -{ - boolean success = false; - - switch (function) - { - case PLUGIN_DEVICE_ADD: - { - Device[++deviceCount].Number = PLUGIN_ID_214; - Device[deviceCount].Type = DEVICE_TYPE_I2C; - Device[deviceCount].VType = SENSOR_TYPE_SINGLE; - Device[deviceCount].Ports = 0; - Device[deviceCount].PullUpOption = false; - Device[deviceCount].InverseLogicOption = false; - Device[deviceCount].FormulaOption = true; - Device[deviceCount].ValueCount = 2; - Device[deviceCount].SendDataOption = true; - Device[deviceCount].TimerOption = true; - Device[deviceCount].GlobalSyncOption = true; - break; - } - - case PLUGIN_GET_DEVICENAME: - { - string = F(PLUGIN_NAME_214); - break; - } - - case PLUGIN_GET_DEVICEVALUENAMES: - { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_214)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_214)); - break; - } - - case PLUGIN_WEBFORM_LOAD: - { - #define _P214_ATLASEZO_I2C_NB_OPTIONS 4 - byte I2Cchoice = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; - int optionValues[_P214_ATLASEZO_I2C_NB_OPTIONS] = { 0x63, 0x64, 0x65, 0x66 }; - addFormSelectorI2C(F("plugin_214_i2c"), _P214_ATLASEZO_I2C_NB_OPTIONS, optionValues, I2Cchoice); - - addFormSubHeader(F("General")); - - char sensordata[32]; - bool info; - info = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"i",sensordata); - - if (info) { - String boardInfo(sensordata); - - addHtml(F("Board type : ")); - int pos1 = boardInfo.indexOf(','); - int pos2 = boardInfo.lastIndexOf(','); - addHtml(boardInfo.substring(pos1+1,pos2)); - if (boardInfo.substring(pos1+1,pos2) != "pH"){ - addHtml(F(" WARNING : Board type should be 'pH', check your i2c Address ? ")); - } - addHtml(F("Board version :")); - addHtml(boardInfo.substring(pos2+1)); - addHtml(F("")); - - addHtml(F("")); - - } else { - addHtml(F("Unable to send command to device")); - success = false; - break; - } - - addFormCheckBox(F("Status LED"),F("Plugin_214_status_led"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]); - - char statussensordata[32]; - bool status; - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",statussensordata); - - if (status) { - String boardStatus(statussensordata); - - addHtml(F("Board restart code: ")); - int pos1 = boardStatus.indexOf(','); - int pos2 = boardStatus.lastIndexOf(','); - switch ((char)boardStatus.substring(pos1+1,pos2)[0]) - { - case 'P': - { - addHtml(F("powered off")); - break; - } - case 'S': - { - addHtml(F("software reset")); - break; - } - case 'B': - { - addHtml(F("brown out")); - break; - } - case 'W': - { - addHtml(F("watch dog")); - break; - } - case 'U': - default: - { - addHtml(F("unknown")); - break; - } - } - - addHtml(F("Board voltage :")); - addHtml(boardStatus.substring(pos2+1)); - addHtml(F(" V")); - - addHtml(F("")); - - } else { - addHtml(F("Unable to send status command to device")); - success = false; - break; - } - - addFormSubHeader(F("Calibration")); - - int nb_calibration_points = -1; - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0], "Cal,?",sensordata); - - if (status){ - if (strncmp(sensordata,"?Cal,",5)){ - char tmp[2]; - tmp[0] = sensordata[5]; - tmp[1] = '\0', - nb_calibration_points = atoi(tmp); - } - } - - addRowLabel(F("Middle")); - addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_M' step='0.01"),Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1],1,14); - if (nb_calibration_points > 0) { - addHtml(F(" OK")); - } else { - addHtml(F(" Not yet calibrated")); - } - addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_M"), false); - addHtml(F("\n\n")); - - addRowLabel(F("Low")); - addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_L' step='0.01"), Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2],1,14); - if (nb_calibration_points > 1) { - addHtml(F(" OK")); - } else { - addHtml(F(" Not yet calibrated")); - } - addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_L"), false); - addHtml(F("\n\n")); - - addHtml(F("High")); - addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_H' step='0.01"), Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3],1,14); - if (nb_calibration_points > 2) { - addHtml(F(" OK")); - } else { - addHtml(F(" Not yet calibrated")); - } - addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_H"), false); - addHtml(F("\n\n")); - - if (nb_calibration_points > 1){ - char sensordata[32]; - char cmd[8] = "Slope,?"; - bool status; - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd,sensordata); - - if (status){ - String slopeAnswer("Answer to 'Slope' command : "); - slopeAnswer += sensordata; - addFormNote(slopeAnswer); - } - } - - addFormSubHeader(F("Temperature compensation")); - char deviceTemperatureTemplate[40]; - LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); - addFormTextBox(F("Temperature "), F("Plugin_214_temperature_template"), deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); - addFormNote(F("You can use a formulae (and idealy refer to a temp sensor). ")); - float value; - char strValue[5]; - String deviceTemperatureTemplateString(deviceTemperatureTemplate); - String pooltempString(parseTemplate(deviceTemperatureTemplateString, 40)); - addHtml(F("
")); - if (Calculate(pooltempString.c_str(),&value) == CALCULATE_OK ){ - addHtml(F("Actual value : ")); - dtostrf(value,5,2,strValue); - addHtml(strValue); - } else { - addHtml(F("(It seems I can't parse your formulae)")); - } - - addHtml(F("
")); - - success = true; - break; - } - - case PLUGIN_WEBFORM_SAVE: - { - Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_214_i2c")); - - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_214_sensorVersion")); - - char sensordata[32]; - if (isFormItemChecked(F("Plugin_214_status_led"))) { - _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,1",sensordata); - } else { - _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,0",sensordata); - } - Settings.TaskDevicePluginConfig[event->TaskIndex][1] = isFormItemChecked(F("Plugin_214_status_led")); - - - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("Plugin_214_ref_cal_M")); - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2] = getFormItemFloat(F("Plugin_214_ref_cal_L")); - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3] = getFormItemFloat(F("Plugin_214_ref_cal_H")); - - String cmd ("Cal,"); - bool triggerCalibrate = false; - if (isFormItemChecked("Plugin_214_enable_cal_M")) { - cmd += "mid,"; - cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]; - triggerCalibrate = true; - } else if (isFormItemChecked("Plugin_214_enable_cal_L")){ - cmd += "low,"; - cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2]; - triggerCalibrate = true; - } else if (isFormItemChecked("Plugin_214_enable_cal_H")){ - cmd += "high,"; - cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3]; - triggerCalibrate = true; - } - if (triggerCalibrate){ - char sensordata[32]; - _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd.c_str(),sensordata); - } - - char deviceTemperatureTemplate[40]; - String tmpString = WebServer.arg(F("Plugin_214_temperature_template")); - strncpy(deviceTemperatureTemplate, tmpString.c_str(), sizeof(deviceTemperatureTemplate)-1); - deviceTemperatureTemplate[sizeof(deviceTemperatureTemplate)-1]=0; //be sure that our string ends with a \0 - - SaveCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); - - Plugin_214_init = false; - success = true; - break; - } - - case PLUGIN_INIT: - { - Plugin_214_init = true; - } - - case PLUGIN_READ: - { - char sensordata[32]; - bool status; - - //first set the temperature of reading - char deviceTemperatureTemplate[40]; - LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); - - String deviceTemperatureTemplateString(deviceTemperatureTemplate); - String pooltempString(parseTemplate(deviceTemperatureTemplateString, 40)); - //String setTemperature("T,"); - String setTemperature("RT,"); - float temperatureReading; - if (Calculate(pooltempString.c_str(),&temperatureReading) == CALCULATE_OK ){ - setTemperature += temperatureReading; - } else { - success = false; - break; - } - - //ok, now we can read the pH value with Temperature compensation - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],setTemperature.c_str(),sensordata); - - //ok, now we can read the pH value - //status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"r",sensordata); - - //we read the voltagedata char statussensordata[32]; - char voltagedata[32]; - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",voltagedata); - - - if (status){ - String sensorString(sensordata); - String voltage(voltagedata); - int pos = voltage.lastIndexOf(','); - UserVar[event->BaseVarIndex] = sensorString.toFloat(); - UserVar[event->BaseVarIndex + 1] = voltage.substring(pos+1).toFloat(); - } - else { - UserVar[event->BaseVarIndex] = -1; - UserVar[event->BaseVarIndex + 1] = -1; - } - - //go to sleep - //status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Sleep",sensordata); - - success = true; - break; - } - case PLUGIN_WRITE: - { - //TODO : do something more usefull ... - - String tmpString = string; - int argIndex = tmpString.indexOf(','); - if (argIndex) - tmpString = tmpString.substring(0, argIndex); - if (tmpString.equalsIgnoreCase(F("ATLASCMD"))) - { - success = true; - argIndex = string.lastIndexOf(','); - tmpString = string.substring(argIndex + 1); - if (tmpString.equalsIgnoreCase(F("CalMid"))){ - String log("Asking for Mid calibration "); - addLog(LOG_LEVEL_INFO, log); - } - else if (tmpString.equalsIgnoreCase(F("CalLow"))){ - String log("Asking for Low calibration "); - addLog(LOG_LEVEL_INFO, log); - } - else if (tmpString.equalsIgnoreCase(F("CalHigh"))){ - String log("Asking for High calibration "); - addLog(LOG_LEVEL_INFO, log); - } - } - break; - } - } - return success; -} - -// Call this function with two char arrays, one containing the command -// The other containing an allocatted char array for answer -// Returns true on success, false otherwise - -bool _P214_send_I2C_command(uint8_t I2Caddress,const char * cmd, char* sensordata) { - uint16_t sensor_bytes_received = 0; - - byte error; - byte i2c_response_code = 0; - byte in_char = 0; - - Serial.println(cmd); - Wire.beginTransmission(I2Caddress); - Wire.write(cmd); - error = Wire.endTransmission(); - - if (error != 0) { - return false; - } - - //don't read answer if we want to go to sleep - if (strncmp(cmd,"Sleep",5) == 0) { - return true; - } - - i2c_response_code = 254; - while (i2c_response_code == 254) { // in case the cammand takes longer to process, we keep looping here until we get a success or an error - - if ( - ( (cmd[0] == 'r' || cmd[0] == 'R') && cmd[1] == '\0' ) - || - ( ( strncmp(cmd,"cal",3) || strncmp(cmd,"Cal",3) ) && !strncmp(cmd,"Cal,?",5) ) - ) - { - delay(900); - } - else { - delay(300); - } - - Wire.requestFrom(I2Caddress, (uint8_t) 32); //call the circuit and request 32 bytes (this is more then we need). - i2c_response_code = Wire.read(); //read response code - - while (Wire.available()) { //read response - in_char = Wire.read(); - - if (in_char == 0) { //if we receive a null caracter, we're done - while (Wire.available()) { //purge the data line if needed - Wire.read(); - } - - break; //exit the while loop. - } - else { - sensordata[sensor_bytes_received] = in_char; //load this byte into our array. - sensor_bytes_received++; - } - } - sensordata[sensor_bytes_received] = '\0'; - - switch (i2c_response_code) { - case 1: - Serial.print( F("< success, answer = ")); - Serial.println(sensordata); - break; - - case 2: - Serial.println( F("< command failed")); - return false; - - case 254: - Serial.println( F("< command pending")); - break; - - case 255: - Serial.println( F("< no data")); - return false; - } - } - - Serial.println(sensordata); - return true; -} +//######################################################################## +//################## Plugin 214 : Atlas Scientific EZO Ph sensor ######## +//######################################################################## + +// datasheet at https://www.atlas-scientific.com/_files/_datasheets/_circuit/pH_EZO_datasheet.pdf +// works only in i2c mode + +#define PLUGIN_214 +#define PLUGIN_ID_214 214 +#define PLUGIN_NAME_214 "Environment - Atlas Scientific pH EZO [TESTING]" +#define PLUGIN_VALUENAME1_214 "pH" +#define PLUGIN_VALUENAME2_214 "Voltage" + +boolean Plugin_214_init = false; + +boolean Plugin_214(byte function, struct EventStruct *event, String& string) +{ + boolean success = false; + + switch (function) + { + case PLUGIN_DEVICE_ADD: + { + Device[++deviceCount].Number = PLUGIN_ID_214; + Device[deviceCount].Type = DEVICE_TYPE_I2C; + Device[deviceCount].VType = SENSOR_TYPE_SINGLE; + Device[deviceCount].Ports = 0; + Device[deviceCount].PullUpOption = false; + Device[deviceCount].InverseLogicOption = false; + Device[deviceCount].FormulaOption = true; + Device[deviceCount].ValueCount = 2; + Device[deviceCount].SendDataOption = true; + Device[deviceCount].TimerOption = true; + Device[deviceCount].GlobalSyncOption = true; + break; + } + + case PLUGIN_GET_DEVICENAME: + { + string = F(PLUGIN_NAME_214); + break; + } + + case PLUGIN_GET_DEVICEVALUENAMES: + { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_214)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_214)); + break; + } + + case PLUGIN_WEBFORM_LOAD: + { + #define _P214_ATLASEZO_I2C_NB_OPTIONS 4 + byte I2Cchoice = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; + int optionValues[_P214_ATLASEZO_I2C_NB_OPTIONS] = { 0x63, 0x64, 0x65, 0x66 }; + addFormSelectorI2C(F("plugin_214_i2c"), _P214_ATLASEZO_I2C_NB_OPTIONS, optionValues, I2Cchoice); + + addFormSubHeader(F("General")); + + char sensordata[32]; + bool info; + info = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"i",sensordata); + + if (info) { + String boardInfo(sensordata); + + addHtml(F("Board type : ")); + int pos1 = boardInfo.indexOf(','); + int pos2 = boardInfo.lastIndexOf(','); + addHtml(boardInfo.substring(pos1+1,pos2)); + if (boardInfo.substring(pos1+1,pos2) != "pH"){ + addHtml(F(" WARNING : Board type should be 'pH', check your i2c Address ? ")); + } + addHtml(F("Board version :")); + addHtml(boardInfo.substring(pos2+1)); + addHtml(F("")); + + addHtml(F("")); + + } else { + addHtml(F("Unable to send command to device")); + success = false; + break; + } + + addFormCheckBox(F("Status LED"),F("Plugin_214_status_led"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]); + + char statussensordata[32]; + bool status; + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",statussensordata); + + if (status) { + String boardStatus(statussensordata); + + addHtml(F("Board restart code: ")); + int pos1 = boardStatus.indexOf(','); + int pos2 = boardStatus.lastIndexOf(','); + switch ((char)boardStatus.substring(pos1+1,pos2)[0]) + { + case 'P': + { + addHtml(F("powered off")); + break; + } + case 'S': + { + addHtml(F("software reset")); + break; + } + case 'B': + { + addHtml(F("brown out")); + break; + } + case 'W': + { + addHtml(F("watch dog")); + break; + } + case 'U': + default: + { + addHtml(F("unknown")); + break; + } + } + + addHtml(F("Board voltage :")); + addHtml(boardStatus.substring(pos2+1)); + addHtml(F(" V")); + + addHtml(F("")); + + } else { + addHtml(F("Unable to send status command to device")); + success = false; + break; + } + + addFormSubHeader(F("Calibration")); + + int nb_calibration_points = -1; + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0], "Cal,?",sensordata); + + if (status){ + if (strncmp(sensordata,"?Cal,",5)){ + char tmp[2]; + tmp[0] = sensordata[5]; + tmp[1] = '\0', + nb_calibration_points = atoi(tmp); + } + } + + addRowLabel(F("Middle")); + addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_M' step='0.01"),Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1],1,14); + if (nb_calibration_points > 0) { + addHtml(F(" OK")); + } else { + addHtml(F(" Not yet calibrated")); + } + addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_M"), false); + addHtml(F("\n\n")); + + addRowLabel(F("Low")); + addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_L' step='0.01"), Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2],1,14); + if (nb_calibration_points > 1) { + addHtml(F(" OK")); + } else { + addHtml(F(" Not yet calibrated")); + } + addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_L"), false); + addHtml(F("\n\n")); + + addHtml(F("High")); + addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_H' step='0.01"), Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3],1,14); + if (nb_calibration_points > 2) { + addHtml(F(" OK")); + } else { + addHtml(F(" Not yet calibrated")); + } + addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_H"), false); + addHtml(F("\n\n")); + + if (nb_calibration_points > 1){ + char sensordata[32]; + char cmd[8] = "Slope,?"; + bool status; + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd,sensordata); + + if (status){ + String slopeAnswer("Answer to 'Slope' command : "); + slopeAnswer += sensordata; + addFormNote(slopeAnswer); + } + } + + addFormSubHeader(F("Temperature compensation")); + char deviceTemperatureTemplate[40]; + LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); + addFormTextBox(F("Temperature "), F("Plugin_214_temperature_template"), deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); + addFormNote(F("You can use a formulae (and idealy refer to a temp sensor). ")); + float value; + char strValue[5]; + String deviceTemperatureTemplateString(deviceTemperatureTemplate); + String pooltempString(parseTemplate(deviceTemperatureTemplateString, 40)); + addHtml(F("
")); + if (Calculate(pooltempString.c_str(),&value) == CALCULATE_OK ){ + addHtml(F("Actual value : ")); + dtostrf(value,5,2,strValue); + addHtml(strValue); + } else { + addHtml(F("(It seems I can't parse your formulae)")); + } + + addHtml(F("
")); + + success = true; + break; + } + + case PLUGIN_WEBFORM_SAVE: + { + Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_214_i2c")); + + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_214_sensorVersion")); + + char sensordata[32]; + if (isFormItemChecked(F("Plugin_214_status_led"))) { + _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,1",sensordata); + } else { + _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,0",sensordata); + } + Settings.TaskDevicePluginConfig[event->TaskIndex][1] = isFormItemChecked(F("Plugin_214_status_led")); + + + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("Plugin_214_ref_cal_M")); + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2] = getFormItemFloat(F("Plugin_214_ref_cal_L")); + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3] = getFormItemFloat(F("Plugin_214_ref_cal_H")); + + String cmd ("Cal,"); + bool triggerCalibrate = false; + if (isFormItemChecked("Plugin_214_enable_cal_M")) { + cmd += "mid,"; + cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]; + triggerCalibrate = true; + } else if (isFormItemChecked("Plugin_214_enable_cal_L")){ + cmd += "low,"; + cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2]; + triggerCalibrate = true; + } else if (isFormItemChecked("Plugin_214_enable_cal_H")){ + cmd += "high,"; + cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3]; + triggerCalibrate = true; + } + if (triggerCalibrate){ + char sensordata[32]; + _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd.c_str(),sensordata); + } + + char deviceTemperatureTemplate[40]; + String tmpString = web_server.arg(F("Plugin_214_temperature_template")); + strncpy(deviceTemperatureTemplate, tmpString.c_str(), sizeof(deviceTemperatureTemplate)-1); + deviceTemperatureTemplate[sizeof(deviceTemperatureTemplate)-1]=0; //be sure that our string ends with a \0 + + SaveCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); + + Plugin_214_init = false; + success = true; + break; + } + + case PLUGIN_INIT: + { + Plugin_214_init = true; + } + + case PLUGIN_READ: + { + char sensordata[32]; + bool status; + + //first set the temperature of reading + char deviceTemperatureTemplate[40]; + LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); + + String deviceTemperatureTemplateString(deviceTemperatureTemplate); + String pooltempString(parseTemplate(deviceTemperatureTemplateString, 40)); + //String setTemperature("T,"); + String setTemperature("RT,"); + float temperatureReading; + if (Calculate(pooltempString.c_str(),&temperatureReading) == CALCULATE_OK ){ + setTemperature += temperatureReading; + } else { + success = false; + break; + } + + //ok, now we can read the pH value with Temperature compensation + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],setTemperature.c_str(),sensordata); + + //ok, now we can read the pH value + //status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"r",sensordata); + + //we read the voltagedata char statussensordata[32]; + char voltagedata[32]; + status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",voltagedata); + + + if (status){ + String sensorString(sensordata); + String voltage(voltagedata); + int pos = voltage.lastIndexOf(','); + UserVar[event->BaseVarIndex] = sensorString.toFloat(); + UserVar[event->BaseVarIndex + 1] = voltage.substring(pos+1).toFloat(); + } + else { + UserVar[event->BaseVarIndex] = -1; + UserVar[event->BaseVarIndex + 1] = -1; + } + + //go to sleep + //status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Sleep",sensordata); + + success = true; + break; + } + case PLUGIN_WRITE: + { + //TODO : do something more usefull ... + + String tmpString = string; + int argIndex = tmpString.indexOf(','); + if (argIndex) + tmpString = tmpString.substring(0, argIndex); + if (tmpString.equalsIgnoreCase(F("ATLASCMD"))) + { + success = true; + argIndex = string.lastIndexOf(','); + tmpString = string.substring(argIndex + 1); + if (tmpString.equalsIgnoreCase(F("CalMid"))){ + String log("Asking for Mid calibration "); + addLog(LOG_LEVEL_INFO, log); + } + else if (tmpString.equalsIgnoreCase(F("CalLow"))){ + String log("Asking for Low calibration "); + addLog(LOG_LEVEL_INFO, log); + } + else if (tmpString.equalsIgnoreCase(F("CalHigh"))){ + String log("Asking for High calibration "); + addLog(LOG_LEVEL_INFO, log); + } + } + break; + } + } + return success; +} + +// Call this function with two char arrays, one containing the command +// The other containing an allocatted char array for answer +// Returns true on success, false otherwise + +bool _P214_send_I2C_command(uint8_t I2Caddress,const char * cmd, char* sensordata) { + uint16_t sensor_bytes_received = 0; + + byte error; + byte i2c_response_code = 0; + byte in_char = 0; + + addLog(LOG_LEVEL_DEBUG, String(cmd)); + Wire.beginTransmission(I2Caddress); + Wire.write(cmd); + error = Wire.endTransmission(); + + if (error != 0) { + //addLog(LOG_LEVEL_ERROR, error); + addLog(LOG_LEVEL_ERROR, F("Wire.endTransmission() returns error: Check pH shield")); + return false; + } + + //don't read answer if we want to go to sleep + if (strncmp(cmd,"Sleep",5) == 0) { + return true; + } + + i2c_response_code = 254; + while (i2c_response_code == 254) { // in case the cammand takes longer to process, we keep looping here until we get a success or an error + + if ( + ( (cmd[0] == 'r' || cmd[0] == 'R') && cmd[1] == '\0' ) + || + ( ( strncmp(cmd,"cal",3) || strncmp(cmd,"Cal",3) ) && !strncmp(cmd,"Cal,?",5) ) + ) + { + delay(900); + } + else { + delay(300); + } + + Wire.requestFrom(I2Caddress, (uint8_t) 32); //call the circuit and request 32 bytes (this is more then we need). + i2c_response_code = Wire.read(); //read response code + + while (Wire.available()) { //read response + in_char = Wire.read(); + + if (in_char == 0) { //if we receive a null caracter, we're done + while (Wire.available()) { //purge the data line if needed + Wire.read(); + } + + break; //exit the while loop. + } + else { + sensordata[sensor_bytes_received] = in_char; //load this byte into our array. + sensor_bytes_received++; + } + } + sensordata[sensor_bytes_received] = '\0'; + + switch (i2c_response_code) { + case 1: + { + String log = F("< success, answer = "); + log += sensordata; + addLog(LOG_LEVEL_DEBUG, log); + } + break; + + case 2: + addLog(LOG_LEVEL_DEBUG, F("< command failed")); + return false; + + case 254: + addLog(LOG_LEVEL_DEBUG, F("< command pending")); + break; + + case 255: + addLog(LOG_LEVEL_DEBUG, F("< no data")); + return false; + } + } + + addLog(LOG_LEVEL_DEBUG, sensordata); + return true; +} diff --git a/src/_P222_Atlas_EZO_ORP.ino b/src/_P222_Atlas_EZO_ORP.ino index edec85177..9515283b7 100644 --- a/src/_P222_Atlas_EZO_ORP.ino +++ b/src/_P222_Atlas_EZO_ORP.ino @@ -1,361 +1,365 @@ -//######################################################################## -//################## Plugin 222 : Atlas Scientific EZO ORP sensor ######## -//######################################################################## - -// datasheet at https://www.atlas-scientific.com/_files/_datasheets/_circuit/ORP_EZO_datasheet.pdf -// works only in i2c mode - -#define PLUGIN_222 -#define PLUGIN_ID_222 222 -#define PLUGIN_NAME_222 "Environment - Atlas Scientific ORP EZO [TESTING]" -#define PLUGIN_VALUENAME1_222 "ORP" -#define PLUGIN_VALUENAME2_222 "Voltage" - -boolean Plugin_222_init = false; - -boolean Plugin_222(byte function, struct EventStruct *event, String& string) -{ - boolean success = false; - - switch (function) - { - case PLUGIN_DEVICE_ADD: - { - Device[++deviceCount].Number = PLUGIN_ID_222; - Device[deviceCount].Type = DEVICE_TYPE_I2C; - Device[deviceCount].VType = SENSOR_TYPE_SINGLE; - Device[deviceCount].Ports = 0; - Device[deviceCount].PullUpOption = false; - Device[deviceCount].InverseLogicOption = false; - Device[deviceCount].FormulaOption = true; - Device[deviceCount].ValueCount = 2; - Device[deviceCount].SendDataOption = true; - Device[deviceCount].TimerOption = true; - Device[deviceCount].GlobalSyncOption = true; - break; - } - - case PLUGIN_GET_DEVICENAME: - { - string = F(PLUGIN_NAME_222); - break; - } - - case PLUGIN_GET_DEVICEVALUENAMES: - { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_222)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_222)); - break; - } - - case PLUGIN_WEBFORM_LOAD: - { - #define _P222_ATLASEZO_I2C_NB_OPTIONS 4 - byte I2Cchoice = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; - int optionValues[_P222_ATLASEZO_I2C_NB_OPTIONS] = { 0x62, 0x63, 0x64, 0x65 }; - addFormSelectorI2C(F("plugin_222_i2c"), _P222_ATLASEZO_I2C_NB_OPTIONS, optionValues, I2Cchoice); - - addFormSubHeader(F("General")); - - char sensordata[32]; - bool info; - info = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"i",sensordata); - - if (info) { - String boardInfo(sensordata); - - addHtml(F("Board type : ")); - int pos1 = boardInfo.indexOf(','); - int pos2 = boardInfo.lastIndexOf(','); - addHtml(boardInfo.substring(pos1+1,pos2)); - if (boardInfo.substring(pos1+1,pos2) != "ORP"){ - addHtml(F(" WARNING : Board type should be 'ORP', check your i2c Address ? ")); - } - addHtml(F("Board version :")); - addHtml(boardInfo.substring(pos2+1)); - addHtml(F("")); - - addHtml(F("")); - - } else { - addHtml(F("Unable to send command to device")); - success = false; - break; - } - - addFormCheckBox(F("Status LED"),F("Plugin_222_status_led"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]); - - char statussensordata[32]; - bool status; - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",statussensordata); - - if (status) { - String boardStatus(statussensordata); - - addHtml(F("Board restart code: ")); - int pos1 = boardStatus.indexOf(','); - int pos2 = boardStatus.lastIndexOf(','); - switch ((char)boardStatus.substring(pos1+1,pos2)[0]) - { - case 'P': - { - addHtml(F("powered off")); - break; - } - case 'S': - { - addHtml(F("software reset")); - break; - } - case 'B': - { - addHtml(F("brown out")); - break; - } - case 'W': - { - addHtml(F("watch dog")); - break; - } - case 'U': - default: - { - addHtml(F("unknown")); - break; - } - } - - addHtml(F("Board voltage :")); - addHtml(boardStatus.substring(pos2+1)); - addHtml(F(" V")); - - addHtml(F("")); - - } else { - addHtml(F("Unable to send status command to device")); - success = false; - break; - } - - addFormSubHeader(F("Calibration")); - - int nb_calibration_points = -1; - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0], "Cal,?",sensordata); - - if (status){ - if (strncmp(sensordata,"?Cal,",5)){ - char tmp[2]; - tmp[0] = sensordata[5]; - tmp[1] = '\0', - nb_calibration_points = atoi(tmp); - } - } - - addRowLabel(F("ORP Calibration")); - addFormNumericBox(F("Ref ORP"),F("Plugin_222_ref_cal_M' step='1"),Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1],0,1500); - if (nb_calibration_points > 0) { - addHtml(F(" OK")); - } else { - addHtml(F(" Not yet calibrated")); - } - addFormCheckBox(F("Enable"),F("Plugin_222_enable_cal_M"), false); - - if (nb_calibration_points > 1){ - char sensordata[32]; - char cmd[8] = "Slope,?"; - bool status; - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd,sensordata); - - if (status){ - String slopeAnswer("Answer to 'Slope' command : "); - slopeAnswer += sensordata; - addFormNote(slopeAnswer); - } - } - - addHtml(F("")); - - success = true; - break; - } - - case PLUGIN_WEBFORM_SAVE: - { - Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_222_i2c")); - - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_222_sensorVersion")); - - char sensordata[32]; - if (isFormItemChecked(F("Plugin_222_status_led"))) { - _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,1",sensordata); - } else { - _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,0",sensordata); - } - Settings.TaskDevicePluginConfig[event->TaskIndex][1] = isFormItemChecked(F("Plugin_222_status_led")); - - - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("Plugin_222_ref_cal_M")); - - String cmd ("Cal,"); - bool triggerCalibrate = false; - if (isFormItemChecked("Plugin_222_enable_cal_M")) { - cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]; - triggerCalibrate = true; - } - if (triggerCalibrate){ - char sensordata[32]; - _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd.c_str(),sensordata); - } - - Plugin_222_init = false; - success = true; - break; - } - - case PLUGIN_INIT: - { - Plugin_222_init = true; - } - - case PLUGIN_READ: - { - char sensordata[32]; - bool status; - - //ok, now we can read the ORP value - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"R",sensordata); - - //we read the voltagedata char statussensordata[32]; - char voltagedata[32]; - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",voltagedata); - - if (status){ - String sensorString(sensordata); - String voltage(voltagedata); - int pos = voltage.lastIndexOf(','); - UserVar[event->BaseVarIndex] = sensorString.toFloat(); - UserVar[event->BaseVarIndex + 1] = voltage.substring(pos+1).toFloat(); - } - else { - UserVar[event->BaseVarIndex] = -1; - UserVar[event->BaseVarIndex + 1] = -1; - } - - //go to sleep - //status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Sleep",sensordata); - - success = true; - break; - } - case PLUGIN_WRITE: - { - //TODO : do something more usefull ... - - String tmpString = string; - int argIndex = tmpString.indexOf(','); - if (argIndex) - tmpString = tmpString.substring(0, argIndex); - if (tmpString.equalsIgnoreCase(F("ATLASCMD"))) - { - success = true; - argIndex = string.lastIndexOf(','); - tmpString = string.substring(argIndex + 1); - if (tmpString.equalsIgnoreCase(F("CalMid"))){ - String log("Asking for calibration "); - addLog(LOG_LEVEL_INFO, log); - } - } - break; - } - } - return success; -} - -// Call this function with two char arrays, one containing the command -// The other containing an allocatted char array for answer -// Returns true on success, false otherwise - -bool _P222_send_I2C_command(uint8_t I2Caddress,const char * cmd, char* sensordata) { - uint16_t sensor_bytes_received = 0; - - byte error; - byte i2c_response_code = 0; - byte in_char = 0; - - Serial.println(cmd); - Wire.beginTransmission(I2Caddress); - Wire.write(cmd); - error = Wire.endTransmission(); - - if (error != 0) { - Serial.println(error); - return false; - } - - //don't read answer if we want to go to sleep - if (strncmp(cmd,"Sleep",5) == 0) { - return true; - } - - i2c_response_code = 254; - while (i2c_response_code == 254) { // in case the cammand takes longer to process, we keep looping here until we get a success or an error - - if ( - ( (cmd[0] == 'r' || cmd[0] == 'R') && cmd[1] == '\0' ) - || - ( ( strncmp(cmd,"cal",3) || strncmp(cmd,"Cal",3) ) && !strncmp(cmd,"Cal,?",5) ) - ) - { - delay(900); - } - else { - delay(300); - } - - Wire.requestFrom(I2Caddress, (uint8_t) 32); //call the circuit and request 32 bytes (this is more then we need). - i2c_response_code = Wire.read(); //read response code - - while (Wire.available()) { //read response - in_char = Wire.read(); - - if (in_char == 0) { //if we receive a null caracter, we're done - while (Wire.available()) { //purge the data line if needed - Wire.read(); - } - - break; //exit the while loop. - } - else { - sensordata[sensor_bytes_received] = in_char; //load this byte into our array. - sensor_bytes_received++; - } - } - sensordata[sensor_bytes_received] = '\0'; - - switch (i2c_response_code) { - case 1: - Serial.print( F("< success, answer = ")); - Serial.println(sensordata); - break; - - case 2: - Serial.println( F("< command failed")); - return false; - - case 254: - Serial.println( F("< command pending")); - break; - - case 255: - Serial.println( F("< no data")); - return false; - } - } - - Serial.println(sensordata); - return true; -} +//######################################################################## +//################## Plugin 222 : Atlas Scientific EZO ORP sensor ######## +//######################################################################## + +// datasheet at https://www.atlas-scientific.com/_files/_datasheets/_circuit/ORP_EZO_datasheet.pdf +// works only in i2c mode + +#define PLUGIN_222 +#define PLUGIN_ID_222 222 +#define PLUGIN_NAME_222 "Environment - Atlas Scientific ORP EZO" +#define PLUGIN_VALUENAME1_222 "ORP" +#define PLUGIN_VALUENAME2_222 "Voltage" + +boolean Plugin_222_init = false; + +boolean Plugin_222(byte function, struct EventStruct *event, String& string) +{ + boolean success = false; + + switch (function) + { + case PLUGIN_DEVICE_ADD: + { + Device[++deviceCount].Number = PLUGIN_ID_222; + Device[deviceCount].Type = DEVICE_TYPE_I2C; + Device[deviceCount].VType = SENSOR_TYPE_SINGLE; + Device[deviceCount].Ports = 0; + Device[deviceCount].PullUpOption = false; + Device[deviceCount].InverseLogicOption = false; + Device[deviceCount].FormulaOption = true; + Device[deviceCount].ValueCount = 2; + Device[deviceCount].SendDataOption = true; + Device[deviceCount].TimerOption = true; + Device[deviceCount].GlobalSyncOption = true; + break; + } + + case PLUGIN_GET_DEVICENAME: + { + string = F(PLUGIN_NAME_222); + break; + } + + case PLUGIN_GET_DEVICEVALUENAMES: + { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_222)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_222)); + break; + } + + case PLUGIN_WEBFORM_LOAD: + { + #define _P222_ATLASEZO_I2C_NB_OPTIONS 4 + byte I2Cchoice = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; + int optionValues[_P222_ATLASEZO_I2C_NB_OPTIONS] = { 0x62, 0x63, 0x64, 0x65 }; + addFormSelectorI2C(F("plugin_222_i2c"), _P222_ATLASEZO_I2C_NB_OPTIONS, optionValues, I2Cchoice); + + addFormSubHeader(F("General")); + + char sensordata[32]; + bool info; + info = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"i",sensordata); + + if (info) { + String boardInfo(sensordata); + + addHtml(F("Board type : ")); + int pos1 = boardInfo.indexOf(','); + int pos2 = boardInfo.lastIndexOf(','); + addHtml(boardInfo.substring(pos1+1,pos2)); + if (boardInfo.substring(pos1+1,pos2) != "ORP"){ + addHtml(F(" WARNING : Board type should be 'ORP', check your i2c Address ? ")); + } + addHtml(F("Board version :")); + addHtml(boardInfo.substring(pos2+1)); + addHtml(F("")); + + addHtml(F("")); + + } else { + addHtml(F("Unable to send command to device")); + success = false; + break; + } + + addFormCheckBox(F("Status LED"),F("Plugin_222_status_led"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]); + + char statussensordata[32]; + bool status; + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",statussensordata); + + if (status) { + String boardStatus(statussensordata); + + addHtml(F("Board restart code: ")); + int pos1 = boardStatus.indexOf(','); + int pos2 = boardStatus.lastIndexOf(','); + switch ((char)boardStatus.substring(pos1+1,pos2)[0]) + { + case 'P': + { + addHtml(F("powered off")); + break; + } + case 'S': + { + addHtml(F("software reset")); + break; + } + case 'B': + { + addHtml(F("brown out")); + break; + } + case 'W': + { + addHtml(F("watch dog")); + break; + } + case 'U': + default: + { + addHtml(F("unknown")); + break; + } + } + + addHtml(F("Board voltage :")); + addHtml(boardStatus.substring(pos2+1)); + addHtml(F(" V")); + + addHtml(F("")); + + } else { + addHtml(F("Unable to send status command to device")); + success = false; + break; + } + + addFormSubHeader(F("Calibration")); + + int nb_calibration_points = -1; + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0], "Cal,?",sensordata); + + if (status){ + if (strncmp(sensordata,"?Cal,",5)){ + char tmp[2]; + tmp[0] = sensordata[5]; + tmp[1] = '\0', + nb_calibration_points = atoi(tmp); + } + } + + addRowLabel(F("ORP Calibration")); + addFormNumericBox(F("Ref ORP"),F("Plugin_222_ref_cal_M' step='1"),Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1],0,1500); + if (nb_calibration_points > 0) { + addHtml(F(" OK")); + } else { + addHtml(F(" Not yet calibrated")); + } + addFormCheckBox(F("Enable"),F("Plugin_222_enable_cal_M"), false); + + if (nb_calibration_points > 1){ + char sensordata[32]; + char cmd[8] = "Slope,?"; + bool status; + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd,sensordata); + + if (status){ + String slopeAnswer("Answer to 'Slope' command : "); + slopeAnswer += sensordata; + addFormNote(slopeAnswer); + } + } + + addHtml(F("")); + + success = true; + break; + } + + case PLUGIN_WEBFORM_SAVE: + { + Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_222_i2c")); + + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_222_sensorVersion")); + + char sensordata[32]; + if (isFormItemChecked(F("Plugin_222_status_led"))) { + _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,1",sensordata); + } else { + _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,0",sensordata); + } + Settings.TaskDevicePluginConfig[event->TaskIndex][1] = isFormItemChecked(F("Plugin_222_status_led")); + + + Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("Plugin_222_ref_cal_M")); + + String cmd ("Cal,"); + bool triggerCalibrate = false; + if (isFormItemChecked("Plugin_222_enable_cal_M")) { + cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]; + triggerCalibrate = true; + } + if (triggerCalibrate){ + char sensordata[32]; + _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd.c_str(),sensordata); + } + + Plugin_222_init = false; + success = true; + break; + } + + case PLUGIN_INIT: + { + Plugin_222_init = true; + } + + case PLUGIN_READ: + { + char sensordata[32]; + bool status; + + //ok, now we can read the ORP value + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"R",sensordata); + + //we read the voltagedata char statussensordata[32]; + char voltagedata[32]; + status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",voltagedata); + + if (status){ + String sensorString(sensordata); + String voltage(voltagedata); + int pos = voltage.lastIndexOf(','); + UserVar[event->BaseVarIndex] = sensorString.toFloat(); + UserVar[event->BaseVarIndex + 1] = voltage.substring(pos+1).toFloat(); + } + else { + UserVar[event->BaseVarIndex] = -1; + UserVar[event->BaseVarIndex + 1] = -1; + } + + //go to sleep + //status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Sleep",sensordata); + + success = true; + break; + } + case PLUGIN_WRITE: + { + //TODO : do something more usefull ... + + String tmpString = string; + int argIndex = tmpString.indexOf(','); + if (argIndex) + tmpString = tmpString.substring(0, argIndex); + if (tmpString.equalsIgnoreCase(F("ATLASCMD"))) + { + success = true; + argIndex = string.lastIndexOf(','); + tmpString = string.substring(argIndex + 1); + if (tmpString.equalsIgnoreCase(F("CalMid"))){ + String log("Asking for calibration "); + addLog(LOG_LEVEL_INFO, log); + } + } + break; + } + } + return success; +} + +// Call this function with two char arrays, one containing the command +// The other containing an allocatted char array for answer +// Returns true on success, false otherwise + +bool _P222_send_I2C_command(uint8_t I2Caddress,const char * cmd, char* sensordata) { + uint16_t sensor_bytes_received = 0; + + byte error; + byte i2c_response_code = 0; + byte in_char = 0; + + addLog(LOG_LEVEL_DEBUG, String(cmd)); + Wire.beginTransmission(I2Caddress); + Wire.write(cmd); + error = Wire.endTransmission(); + + if (error != 0) { + //addLog(LOG_LEVEL_ERROR, error); + addLog(LOG_LEVEL_ERROR, F("Wire.endTransmission() returns error: Check ORP shield")); + return false; + } + + //don't read answer if we want to go to sleep + if (strncmp(cmd,"Sleep",5) == 0) { + return true; + } + + i2c_response_code = 254; + while (i2c_response_code == 254) { // in case the cammand takes longer to process, we keep looping here until we get a success or an error + + if ( + ( (cmd[0] == 'r' || cmd[0] == 'R') && cmd[1] == '\0' ) + || + ( ( strncmp(cmd,"cal",3) || strncmp(cmd,"Cal",3) ) && !strncmp(cmd,"Cal,?",5) ) + ) + { + delay(900); + } + else { + delay(300); + } + + Wire.requestFrom(I2Caddress, (uint8_t) 32); //call the circuit and request 32 bytes (this is more then we need). + i2c_response_code = Wire.read(); //read response code + + while (Wire.available()) { //read response + in_char = Wire.read(); + + if (in_char == 0) { //if we receive a null caracter, we're done + while (Wire.available()) { //purge the data line if needed + Wire.read(); + } + + break; //exit the while loop. + } + else { + sensordata[sensor_bytes_received] = in_char; //load this byte into our array. + sensor_bytes_received++; + } + } + sensordata[sensor_bytes_received] = '\0'; + + switch (i2c_response_code) { + case 1: + { + String log = F("< success, answer = "); + log += sensordata; + addLog(LOG_LEVEL_DEBUG, log); + } + break; + + case 2: + addLog(LOG_LEVEL_DEBUG, F("< command failed")); + return false; + + case 254: + addLog(LOG_LEVEL_DEBUG, F("< command pending")); + break; + + case 255: + addLog(LOG_LEVEL_DEBUG, F("< no data")); + return false; + } + } + + addLog(LOG_LEVEL_DEBUG, sensordata); + return true; +} From cba9b600973c7fde457a2c90817113e292a6f650 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Fri, 24 Apr 2020 13:16:54 +0200 Subject: [PATCH 019/128] =?UTF-8?q?Extended=20the=20great=20work=20from=20?= =?UTF-8?q?Micha=C5=82=20Obrembski=20mobrembski,=20so=20that:=20-=20mqtt?= =?UTF-8?q?=20works=20-=20WifiConnected=20works=20as=20EthernetConnected?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- platformio_esp32_envs.ini | 29 ++++++++++++++++++++- src/ESPEasy.ino | 53 ++++++++++++++++++++++++++++++++++++++- src/ESPEasyWifi.ino | 4 +++ 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index fff572e5e..2057567ed 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -29,7 +29,7 @@ build_flags = ${mqtt_flags.build_flags} [env:custom_ESP32_4M316k] extends = esp32_common platform = ${esp32_common.platform} -build_flags = ${esp32_common.build_flags} -DPLUGIN_BUILD_CUSTOM -DHAS_ETHERNET +build_flags = ${esp32_common.build_flags} -DPLUGIN_BUILD_CUSTOM board = esp32dev extra_scripts = ${esp32_common.extra_scripts} pre:pre_custom_esp32.py @@ -52,4 +52,31 @@ debug_tool = ftdi debug_extra_cmds = break Misc.ino:3011 extra_scripts = ${esp32_common.extra_scripts} +; Custom: 4096k version -------------------------- +[env:custom_ESP32_4M316k_ETH] +extends = esp32_common +platform = ${esp32_common.platform} +build_flags = ${esp32_common.build_flags} -DPLUGIN_BUILD_CUSTOM -DHAS_ETHERNET +board = esp32dev +extra_scripts = ${esp32_common.extra_scripts} + pre:pre_custom_esp32.py + +[env:test_ESP32_4M316k_ETH] +extends = esp32_common +platform = ${esp32_common.platform} +build_flags = ${esp32_common.build_flags} -DPLUGIN_SET_TEST_ESP32 -DHAS_ETHERNET +board = esp32dev +extra_scripts = ${esp32_common.extra_scripts} + + +[env:test_ESP32-wrover-kit_4M316k_ETH] +extends = esp32_common +platform = ${esp32_common.platform} +build_flags = ${esp32_common.build_flags} -DPLUGIN_SET_TEST_ESP32 -DHAS_ETHERNET +board = esp-wrover-kit +upload_protocol = ftdi +debug_tool = ftdi +debug_extra_cmds = break Misc.ino:3011 +extra_scripts = ${esp32_common.extra_scripts} + diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index 20df7794a..9c30d3b0a 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -1,6 +1,11 @@ #include +#ifdef HAS_ETHERNET +#include +static bool eth_connected = false; +#endif + #ifdef CONTINUOUS_INTEGRATION #pragma GCC diagnostic error "-Wall" #else @@ -369,9 +374,11 @@ void setup() rulesProcessing(event); // TD-er: Process events in the setup() now. } - WiFiConnectRelaxed(); #ifdef HAS_ETHERNET + WiFi.onEvent(ETHEvent); ETHConnectRelaxed(); +#else + WiFiConnectRelaxed(); #endif setWebserverRunning(true); @@ -550,7 +557,9 @@ void loop() updateLoopStats(); + #ifndef HAS_ETHERNET handle_unprocessedWiFiEvents(); + #endif bool firstLoopConnectionsEstablished = WiFiConnected() && firstLoop; if (firstLoopConnectionsEstablished) { @@ -1012,3 +1021,45 @@ void backgroundtasks() runningBackgroundTasks=false; STOP_TIMER(BACKGROUND_TASKS); } + +#ifdef HAS_ETHERNET +void ETHEvent(WiFiEvent_t event) +{ + switch (event) { + case SYSTEM_EVENT_ETH_START: + addLog(LOG_LEVEL_INFO, F("ETH Started")); + //set eth hostname here + //ETH.setHostname("esp32-ethernet"); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + addLog(LOG_LEVEL_INFO, F("ETH Connected")); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + { + String log = F("ETH MAC: "); + log += ETH.macAddress(); + log += F(", IPv4: "); + log += ETH.localIP().toString(); + if (ETH.fullDuplex()) { + log += F(", FULL_DUPLEX"); + } + log += F(", "); + log += ETH.linkSpeed(); + log += F("Mbps"); + addLog(LOG_LEVEL_INFO, log); + } + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + addLog(LOG_LEVEL_ERROR, F("ETH Disconnected")); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + addLog(LOG_LEVEL_INFO, F("ETH Stopped")); + eth_connected = false; + break; + default: + break; + } +} +#endif \ No newline at end of file diff --git a/src/ESPEasyWifi.ino b/src/ESPEasyWifi.ino index 4d6f56538..51898ea60 100644 --- a/src/ESPEasyWifi.ino +++ b/src/ESPEasyWifi.ino @@ -75,6 +75,10 @@ bool WiFiConnected() { START_TIMER; + #ifdef HAS_ETHERNET + return eth_connected; + #endif + if (unprocessedWifiEvents()) { return false; } if ((timerAPstart != 0) && timeOutReached(timerAPstart)) { From 32dfba3d86e5801b5fef86f28ae5165d622dbb8b Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Sat, 25 Apr 2020 00:52:33 +0200 Subject: [PATCH 020/128] - Moved ETHEvent from ESPEasy.ino to ESPEasyEthEvent.ino - Corrected Hostname Setting - ESPEasy P2P works now with some minor changes for IP-Address Handling in Network.ino --- src/ESPEasy.ino | 44 +------------------------------------- src/ESPEasyEth.ino | 1 - src/ESPEasyEthEvent.ino | 47 +++++++++++++++++++++++++++++++++++++++++ src/ESPEasyWifi.ino | 7 +++--- src/Networking.ino | 16 +++++++++++++- 5 files changed, 67 insertions(+), 48 deletions(-) create mode 100644 src/ESPEasyEthEvent.ino diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index 9c30d3b0a..b638224a9 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -1020,46 +1020,4 @@ void backgroundtasks() runningBackgroundTasks=false; STOP_TIMER(BACKGROUND_TASKS); -} - -#ifdef HAS_ETHERNET -void ETHEvent(WiFiEvent_t event) -{ - switch (event) { - case SYSTEM_EVENT_ETH_START: - addLog(LOG_LEVEL_INFO, F("ETH Started")); - //set eth hostname here - //ETH.setHostname("esp32-ethernet"); - break; - case SYSTEM_EVENT_ETH_CONNECTED: - addLog(LOG_LEVEL_INFO, F("ETH Connected")); - break; - case SYSTEM_EVENT_ETH_GOT_IP: - { - String log = F("ETH MAC: "); - log += ETH.macAddress(); - log += F(", IPv4: "); - log += ETH.localIP().toString(); - if (ETH.fullDuplex()) { - log += F(", FULL_DUPLEX"); - } - log += F(", "); - log += ETH.linkSpeed(); - log += F("Mbps"); - addLog(LOG_LEVEL_INFO, log); - } - eth_connected = true; - break; - case SYSTEM_EVENT_ETH_DISCONNECTED: - addLog(LOG_LEVEL_ERROR, F("ETH Disconnected")); - eth_connected = false; - break; - case SYSTEM_EVENT_ETH_STOP: - addLog(LOG_LEVEL_INFO, F("ETH Stopped")); - eth_connected = false; - break; - default: - break; - } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/ESPEasyEth.ino b/src/ESPEasyEth.ino index 9bc430272..26609fbac 100644 --- a/src/ESPEasyEth.ino +++ b/src/ESPEasyEth.ino @@ -51,7 +51,6 @@ bool ethPrepare() { addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!")); return false; } - ETH.setHostname(createRFCCompliantHostname(Settings.getHostname()).c_str()); ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); ethSetupStaticIPconfig(); return true; diff --git a/src/ESPEasyEthEvent.ino b/src/ESPEasyEthEvent.ino new file mode 100644 index 000000000..8f7e35d8a --- /dev/null +++ b/src/ESPEasyEthEvent.ino @@ -0,0 +1,47 @@ +#ifdef HAS_ETHERNET +void ETHEvent(WiFiEvent_t event) +{ + switch (event) { + case SYSTEM_EVENT_ETH_START: + addLog(LOG_LEVEL_INFO, F("ETH Started")); + char hostname[40]; + safe_strncpy(hostname, createRFCCompliantHostname(WifiGetAPssid()).c_str(), sizeof(hostname)); + ETH.setHostname(hostname); + { + String log = F("ETH Hostname: "); + log += String(hostname); + addLog(LOG_LEVEL_INFO, log); + } + break; + case SYSTEM_EVENT_ETH_CONNECTED: + addLog(LOG_LEVEL_INFO, F("ETH Connected")); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + { + String log = F("ETH MAC: "); + log += ETH.macAddress(); + log += F(", IPv4: "); + log += ETH.localIP().toString(); + if (ETH.fullDuplex()) { + log += F(", FULL_DUPLEX"); + } + log += F(", "); + log += ETH.linkSpeed(); + log += F("Mbps"); + addLog(LOG_LEVEL_INFO, log); + } + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + addLog(LOG_LEVEL_ERROR, F("ETH Disconnected")); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + addLog(LOG_LEVEL_INFO, F("ETH Stopped")); + eth_connected = false; + break; + default: + break; + } +} +#endif \ No newline at end of file diff --git a/src/ESPEasyWifi.ino b/src/ESPEasyWifi.ino index 51898ea60..9c0b5af35 100644 --- a/src/ESPEasyWifi.ino +++ b/src/ESPEasyWifi.ino @@ -73,11 +73,11 @@ // - Start/stop of AP mode // ******************************************************************************** bool WiFiConnected() { - START_TIMER; - #ifdef HAS_ETHERNET return eth_connected; - #endif + #else + + START_TIMER; if (unprocessedWifiEvents()) { return false; } @@ -133,6 +133,7 @@ bool WiFiConnected() { delay(1); STOP_TIMER(WIFI_NOTCONNECTED_STATS); return false; + #endif // HAS_ETHERNET } void WiFiConnectRelaxed() { diff --git a/src/Networking.ino b/src/Networking.ino index 16ee2fc47..593289c80 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -354,7 +354,11 @@ void sendSysInfoUDP(byte repeats) for (byte x = 0; x < 6; x++) { data[x + 2] = macread[x]; } + #ifdef HAS_ETHERNET + IPAddress ip = ETH.localIP(); + #else IPAddress ip = WiFi.localIP(); + #endif for (byte x = 0; x < 4; x++) { data[x + 8] = ip[x]; @@ -382,7 +386,11 @@ void sendSysInfoUDP(byte repeats) if (it != Nodes.end()) { + #ifdef HAS_ETHERNET + IPAddress ip = ETH.localIP(); + #else IPAddress ip = WiFi.localIP(); + #endif for (byte x = 0; x < 4; x++) { it->second.ip[x] = ip[x]; @@ -752,8 +760,14 @@ bool getSubnetRange(IPAddress& low, IPAddress& high) if (wifiStatus < ESPEASY_WIFI_GOT_IP) { return false; } - const IPAddress ip = WiFi.localIP(); + #ifdef HAS_ETHERNET + const IPAddress ip = ETH.localIP(); + const IPAddress subnet = ETH.subnetMask(); + #else + const IPAddress ip = WiFi.localIP(); const IPAddress subnet = WiFi.subnetMask(); + #endif + low = ip; high = ip; From 64a4bbcb8ada793155adc93d7553b307b0814e57 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Sat, 25 Apr 2020 11:17:11 +0200 Subject: [PATCH 021/128] Change requested by TD-er review: clarification of build file https://github.com/letscontrolit/ESPEasy/pull/2962/files/8ba2bb88eadb98c4691cbb1f40c4d5466cb7b5b8 --- platformio_esp32_envs.ini | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 2057567ed..a78e11641 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -54,29 +54,19 @@ extra_scripts = ${esp32_common.extra_scripts} ; Custom: 4096k version -------------------------- [env:custom_ESP32_4M316k_ETH] -extends = esp32_common -platform = ${esp32_common.platform} -build_flags = ${esp32_common.build_flags} -DPLUGIN_BUILD_CUSTOM -DHAS_ETHERNET -board = esp32dev -extra_scripts = ${esp32_common.extra_scripts} - pre:pre_custom_esp32.py +extends = env:custom_ESP32_4M316k +platform = ${env:custom_ESP32_4M316k.platform} +build_flags = ${env:custom_ESP32_4M316k.build_flags} -DHAS_ETHERNET [env:test_ESP32_4M316k_ETH] -extends = esp32_common -platform = ${esp32_common.platform} -build_flags = ${esp32_common.build_flags} -DPLUGIN_SET_TEST_ESP32 -DHAS_ETHERNET -board = esp32dev -extra_scripts = ${esp32_common.extra_scripts} +extends = env:test_ESP32_4M316k +platform = ${env:test_ESP32_4M316k.platform} +build_flags = ${env:test_ESP32_4M316k.build_flags} -DHAS_ETHERNET [env:test_ESP32-wrover-kit_4M316k_ETH] -extends = esp32_common -platform = ${esp32_common.platform} -build_flags = ${esp32_common.build_flags} -DPLUGIN_SET_TEST_ESP32 -DHAS_ETHERNET -board = esp-wrover-kit -upload_protocol = ftdi -debug_tool = ftdi -debug_extra_cmds = break Misc.ino:3011 -extra_scripts = ${esp32_common.extra_scripts} +extends = env:test_ESP32-wrover-kit_4M316k +platform = ${env:test_ESP32-wrover-kit_4M316k.platform} +build_flags = ${env:test_ESP32-wrover-kit_4M316k.build_flags} -DHAS_ETHERNET From 6632dec482e8266e9cc5c4e9d8ffc5ba622f637d Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Sun, 26 Apr 2020 22:29:56 +0200 Subject: [PATCH 022/128] ESP32 with Ethernet or Wifi, not both at the same time configurable via Hardware Page. - ESP P2P is working - Only ETH.beginPacket() with Standard Parameter is working at the moment, configuration will follow. - Network.in not cpp/h files but this will be changed in future - Some TODO: PKR: comments will be removed in the future, too --- platformio_esp32_envs.ini | 3 +- src/Controller.ino | 2 +- src/ESPEasy-Globals.cpp | 9 ++ src/ESPEasy-Globals.h | 7 + src/ESPEasy.ino | 52 ++++--- src/ESPEasyEth.ino | 49 +++++- src/ESPEasyEthEvent.ino | 3 + src/ESPEasyEthWifi.h | 14 ++ src/ESPEasyEth_ProcessEvent.ino | 6 +- src/ESPEasyStorage.ino | 1 + src/ESPEasyWiFiEvent.cpp | 18 +-- src/ESPEasyWifi.ino | 5 - src/ESPEasyWifi_ProcessEvent.ino | 10 +- src/ESPEasy_checks.ino | 2 +- src/ESPEasy_fdwdecl.h | 19 ++- src/Misc.ino | 5 +- src/Network.ino | 145 ++++++++++++++++++ src/Networking.ino | 53 +++---- src/StringProvider.ino | 15 +- src/StringProviderTypes.h | 1 + src/WebServer_HardwarePage.ino | 7 +- src/WebServer_RootPage.ino | 13 +- src/WebServer_SetupPage.ino | 4 +- src/WebServer_SysInfoPage.ino | 37 +++-- src/WebServer_SysVarPage.ino | 4 + src/WebServer_ToolsPage.ino | 1 + src/_C006.ino | 2 +- src/_C009.ino | 4 +- src/_C011.ino | 2 +- src/_C012.ino | 2 +- src/_C013.ino | 6 +- src/_C014.ino | 3 +- src/_C015.ino | 4 +- src/_C017.ino | 2 +- src/_CPlugin_Helper.cpp | 4 +- src/_P026_Sysinfo.ino | 8 +- src/_P036_FrameOLED.ino | 6 +- src/_P037_MQTTImport.ino | 2 +- src/_P089_Ping.ino | 2 +- src/src/Commands/HTTP.cpp | 2 +- src/src/Commands/UDP.cpp | 2 +- .../ControllerDelayHandlerStruct.h | 2 +- .../DataStructs/ControllerSettingsStruct.cpp | 4 +- src/src/DataStructs/ESPEasyDefaults.h | 7 +- src/src/DataStructs/SettingsStruct.cpp | 1 + src/src/DataStructs/SettingsStruct.h | 1 + src/src/Helpers/ESPEasy_time.cpp | 2 +- src/src/Helpers/SystemVariables.cpp | 8 + src/src/Helpers/SystemVariables.h | 2 + 49 files changed, 417 insertions(+), 146 deletions(-) create mode 100644 src/ESPEasyEthWifi.h create mode 100644 src/Network.ino diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 051ae11e5..52d3a24e8 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -22,7 +22,8 @@ build_flags = ${mqtt_flags.build_flags} -DCONFIG_FREERTOS_ASSERT_DISABLE -DCONFIG_LWIP_ESP_GRATUITOUS_ARP -DCONFIG_LWIP_GARP_TMR_INTERVAL=30 - +upload_flags = + -b921600 ; Custom: 4096k version -------------------------- diff --git a/src/Controller.ino b/src/Controller.ino index 652746f39..29ed7b4a9 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -285,7 +285,7 @@ String getMQTTclientID(const ControllerSettingsStruct& ControllerSettings) { \*********************************************************************************************/ bool MQTTCheck(controllerIndex_t controller_idx) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return false; } protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(controller_idx); diff --git a/src/ESPEasy-Globals.cpp b/src/ESPEasy-Globals.cpp index be9ea4f31..b463ecf46 100644 --- a/src/ESPEasy-Globals.cpp +++ b/src/ESPEasy-Globals.cpp @@ -2,6 +2,7 @@ #include "ESPEasy-Globals.h" #include "ESPEasy_plugindefs.h" +#include "ESPEasyEthWifi.h" #if defined(ESP32) @@ -23,6 +24,14 @@ bool dnsServerActive = false; //NTP status bool statusNTPInitialized = false; +// Ethernet Connectiopn status +#ifdef HAS_ETHERNET +uint8_t eth_wifi_mode = ETHERNET; + // WIFI = 0 + // ETHERNET = 1 +bool eth_connected = false; +#endif + // udp protocol stuff (syslog, global sync, node info list, ntp time) WiFiUDP portUDP; diff --git a/src/ESPEasy-Globals.h b/src/ESPEasy-Globals.h index 109000964..ce759fca6 100644 --- a/src/ESPEasy-Globals.h +++ b/src/ESPEasy-Globals.h @@ -224,6 +224,11 @@ extern bool statusNTPInitialized; // udp protocol stuff (syslog, global sync, node info list, ntp time) extern WiFiUDP portUDP; +// Ethernet Connectiopn status +#ifdef HAS_ETHERNET +extern uint8_t eth_wifi_mode; +extern bool eth_connected; +#endif @@ -430,6 +435,7 @@ struct GpioFactorySettingsStruct { i2c_scl = 5; eth_power = 12; eth_clock_mode = 3; + eth_wifi_mode = 1; break; // case DeviceModel_default: break; @@ -448,6 +454,7 @@ struct GpioFactorySettingsStruct { int8_t eth_mdio = DEFAULT_ETH_PIN_MDIO; int8_t eth_power = DEFAULT_ETH_PIN_POWER; int8_t eth_clock_mode = DEFAULT_ETH_CLOCK_MODE; + int8_t eth_wifi_mode = DEFAULT_ETH_WIFI_MODE; }; void addPredefinedPlugins(const GpioFactorySettingsStruct& gpio_settings); diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index b638224a9..8234a7b44 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -1,11 +1,6 @@ #include -#ifdef HAS_ETHERNET -#include -static bool eth_connected = false; -#endif - #ifdef CONTINUOUS_INTEGRATION #pragma GCC diagnostic error "-Wall" #else @@ -227,7 +222,7 @@ void setup() } emergencyReset(); - + String log = F("\n\n\rINIT : Booting version: "); log += F(BUILD_GIT); log += " ("; @@ -238,7 +233,6 @@ void setup() log += FreeMem(); addLog(LOG_LEVEL_INFO, log); - //warm boot if (readFromRTC()) { @@ -285,6 +279,18 @@ void setup() progMemMD5check(); LoadSettings(); + #ifdef HAS_ETHERNET + // This ensures, that changing WIFI OR ETHERNET MODE happens properly only after reboot. Changing without reboot would not be a good idea. + // This only works after LoadSettings(); + eth_wifi_mode = Settings.ETH_Wifi_Mode; + log = F("INIT : ETH_WIFI_MODE:"); + log += String(eth_wifi_mode); + log += F(" ("); + log += (eth_wifi_mode == WIFI ? F("WIFI") : F("ETHERNET")); + log += F(")"); + addLog(LOG_LEVEL_INFO, log); + #endif + Settings.UseRTOSMultitasking = false; // For now, disable it, we experience heap corruption. if (RTC.bootFailedCount > 10 && RTC.bootCounter > 10) { byte toDisable = RTC.bootFailedCount - 10; @@ -374,12 +380,11 @@ void setup() rulesProcessing(event); // TD-er: Process events in the setup() now. } -#ifdef HAS_ETHERNET + #ifdef HAS_ETHERNET WiFi.onEvent(ETHEvent); - ETHConnectRelaxed(); -#else - WiFiConnectRelaxed(); -#endif + #endif + + NetworkConnectRelaxed(); setWebserverRunning(true); @@ -557,11 +562,16 @@ void loop() updateLoopStats(); - #ifndef HAS_ETHERNET + #ifdef HAS_ETHERNET + // Handle WiFiEvents when compiled with HAS_ETHERNET but in WiFi Mode eth_wifi_mode (WIFI = 0, ETHERNET = 1) + if(eth_wifi_mode == WIFI) { + handle_unprocessedWiFiEvents(); + } + #else handle_unprocessedWiFiEvents(); #endif - bool firstLoopConnectionsEstablished = WiFiConnected() && firstLoop; + bool firstLoopConnectionsEstablished = NetworkConnected() && firstLoop; if (firstLoopConnectionsEstablished) { addLog(LOG_LEVEL_INFO, F("firstLoopConnectionsEstablished")); firstLoop = false; @@ -678,7 +688,7 @@ void updateMQTTclient_connected() { void runPeriodicalMQTT() { // MQTT_KEEPALIVE = 15 seconds. - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { updateMQTTclient_connected(); return; } @@ -773,7 +783,7 @@ void run10TimesPerSecond() { processNextEvent(); #ifdef USES_C015 - if (WiFiConnected()) + if (NetworkConnected()) Blynk_Run_c015(); #endif #ifndef USE_RTOS_MULTITASKING @@ -964,11 +974,11 @@ void backgroundtasks() return; } START_TIMER - const bool wifiConnected = WiFiConnected(); + const bool networkConnected = NetworkConnected(); runningBackgroundTasks=true; #if defined(ESP8266) - if (wifiConnected) { + if (networkConnected) { tcpCleanup(); } #endif @@ -993,14 +1003,14 @@ void backgroundtasks() dnsServer.processNextRequest(); #ifdef FEATURE_ARDUINO_OTA - if(Settings.ArduinoOTAEnable && wifiConnected) + if(Settings.ArduinoOTAEnable && networkConnected) ArduinoOTA.handle(); //once OTA is triggered, only handle that and dont do other stuff. (otherwise it fails) while (ArduinoOTAtriggered) { delay(0); - if (WiFiConnected()) { + if (NetworkConnected()) { ArduinoOTA.handle(); } } @@ -1009,7 +1019,7 @@ void backgroundtasks() #ifdef FEATURE_MDNS // Allow MDNS processing - if (wifiConnected) { + if (networkConnected) { MDNS.update(); } #endif diff --git a/src/ESPEasyEth.ino b/src/ESPEasyEth.ino index 26609fbac..4b002528f 100644 --- a/src/ESPEasyEth.ino +++ b/src/ESPEasyEth.ino @@ -2,12 +2,15 @@ #ifdef HAS_ETHERNET #include "ETH.h" +#include "ESPEasy-Globals.h" bool ethUseStaticIP() { return Settings.ETH_IP[0] != 0 && Settings.ETH_IP[3] != 255; } void ethSetupStaticIPconfig() { + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("ethSetupStaticIPConfig Started")); //setUseStaticIP(useStaticIP()); if (!ethUseStaticIP()) { return; } @@ -27,15 +30,23 @@ void ethSetupStaticIPconfig() { log += formatIP(dns); addLog(LOG_LEVEL_INFO, log); } + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("Before ETH.config")); ETH.config(ip, gw, subnet, dns); + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("After ETH.config")); } bool ethCheckSettings() { + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("ethCheckSettings Started")); bool result = true; if (Settings.ETH_Phy_Type != 0 && Settings.ETH_Phy_Type != 1) result = false; if (Settings.ETH_Clock_Mode > 3) result = false; + if (Settings.ETH_Wifi_Mode > 1) + result = false; if (Settings.ETH_Pin_mdc > MAX_GPIO) result = false; if (Settings.ETH_Pin_mdio > MAX_GPIO) @@ -46,17 +57,25 @@ bool ethCheckSettings() { } bool ethPrepare() { + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("ethPrepare Started")); if (!ethCheckSettings()) { addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!")); return false; } + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("Before ETH.config")); ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("After ETH.conif")); ethSetupStaticIPconfig(); return true; } String ethGetDebugClockModeStr() { + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("ethDebugColckModeStr Started")); switch (Settings.ETH_Clock_Mode) { case 0: return F("ETH_CLOCK_GPIO0_IN"); @@ -67,10 +86,25 @@ String ethGetDebugClockModeStr() { } } +String ethGetDebugEthWifiModeStr() { + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("ethGetDebugEthWifiMode Started")); + switch (eth_wifi_mode) + { + case 0: return F("WIFI"); + case 1: return F("ETHERNET"); + default: return F("ETH_WIFI_ERR"); + } +} + void ethPrintSettings() { + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("ethPrintSettings Started")); String settingsDebugLog; settingsDebugLog.reserve(115); - settingsDebugLog += F("ETH: PHY Type: "); + settingsDebugLog += F("Eth Wifi mode: "); + settingsDebugLog += ethGetDebugEthWifiModeStr(); + settingsDebugLog += F(" ETH: PHY Type: "); settingsDebugLog += Settings.ETH_Phy_Type == 0 ? F("ETH_PHY_LAN8720") : F("ETH_PHY_TLK110"); settingsDebugLog += F(" PHY Addr: "); settingsDebugLog += Settings.ETH_Phy_Addr; @@ -86,18 +120,29 @@ void ethPrintSettings() { } void ETHConnectRelaxed() { + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("ETHConnectRelaxed Started")); ethPrintSettings(); - if (!ethPrepare()) { + /*if (!ethPrepare()) { // Dead code for now... addLog(LOG_LEVEL_ERROR, F("ETH : Could not prepare ETH!")); return; } + // TODO: PKR Remove + addLog(LOG_LEVEL_INFO, F("Before ETH.begin")); ETH.begin(Settings.ETH_Phy_Addr, Settings.ETH_Pin_power, Settings.ETH_Pin_mdc, Settings.ETH_Pin_mdio, (eth_phy_type_t)Settings.ETH_Phy_Type, (eth_clock_mode_t)Settings.ETH_Clock_Mode); + // TODO: PKR Remove*/ + ETH.begin(); + addLog(LOG_LEVEL_INFO, F("After ETH.begin")); +} + +bool ETHConnected() { + return eth_connected; } #endif \ No newline at end of file diff --git a/src/ESPEasyEthEvent.ino b/src/ESPEasyEthEvent.ino index 8f7e35d8a..036bdc4af 100644 --- a/src/ESPEasyEthEvent.ino +++ b/src/ESPEasyEthEvent.ino @@ -40,6 +40,9 @@ void ETHEvent(WiFiEvent_t event) addLog(LOG_LEVEL_INFO, F("ETH Stopped")); eth_connected = false; break; + case SYSTEM_EVENT_GOT_IP6: + addLog(LOG_LEVEL_INFO, F("ETH Got IP6")); + break; default: break; } diff --git a/src/ESPEasyEthWifi.h b/src/ESPEasyEthWifi.h new file mode 100644 index 000000000..a7fec2e5d --- /dev/null +++ b/src/ESPEasyEthWifi.h @@ -0,0 +1,14 @@ +#ifdef HAS_ETHERNET +#ifndef ESPEASY_WTH_WIFI_H_ +#define ESPEASY_WTH_WIFI_H_ + +#ifndef WIFI +#define WIFI 0 +#endif + +#ifndef ETHERNET +#define ETHERNET 1 +#endif + +#endif // ESPEASY_WTH_WIFI_H_ +#endif // HAS_ETHERNET \ No newline at end of file diff --git a/src/ESPEasyEth_ProcessEvent.ino b/src/ESPEasyEth_ProcessEvent.ino index 3ed601e46..6353cc88e 100644 --- a/src/ESPEasyEth_ProcessEvent.ino +++ b/src/ESPEasyEth_ProcessEvent.ino @@ -204,7 +204,7 @@ void processGotIP() { if (processedGotIP) { return; } - IPAddress ip = WiFi.localIP(); + IPAddress ip = NetworkLocalIP(); if (!useStaticIP()) { if ((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)) { @@ -213,8 +213,8 @@ void processGotIP() { } processedGotIP = true; wifiStatus |= ESPEASY_WIFI_GOT_IP; - const IPAddress gw = WiFi.gatewayIP(); - const IPAddress subnet = WiFi.subnetMask(); + const IPAddress gw = NetworkGatewayIP(); + const IPAddress subnet = NetworkSubnetMask(); const long dhcp_duration = timeDiff(lastConnectMoment, lastGetIPmoment); if (loglevelActiveFor(LOG_LEVEL_INFO)) { diff --git a/src/ESPEasyStorage.ino b/src/ESPEasyStorage.ino index 2bc92cc1e..31ce4cf3b 100644 --- a/src/ESPEasyStorage.ino +++ b/src/ESPEasyStorage.ino @@ -185,6 +185,7 @@ String BuildFixes() Settings.ETH_Pin_power = DEFAULT_ETH_PIN_POWER; Settings.ETH_Phy_Type = DEFAULT_ETH_PHY_TYPE; Settings.ETH_Clock_Mode = DEFAULT_ETH_CLOCK_MODE; + Settings.ETH_Wifi_Mode = DEFAULT_ETH_WIFI_MODE; } Settings.Build = BUILD; diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index 4a8ee84ab..2892a21aa 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -1,12 +1,18 @@ +#include "ETH.h" #include "ESPEasyWiFiEvent.h" #include "src/Globals/ESPEasyWiFiEvent.h" #include "src/Globals/RTC.h" #include "ESPEasyTimeTypes.h" +#include "ESPEasy_Log.h" #include "src/DataStructs/RTCStruct.h" #include "src/Helpers/ESPEasy_time_calc.h" +#ifdef HAS_ETHERNET +extern bool eth_connected; +#endif + #ifdef ESP32 void WiFi_Access_Static_IP::set_use_static_ip(bool enabled) { _useStaticIp = enabled; @@ -99,18 +105,6 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { case SYSTEM_EVENT_SCAN_DONE: processedScanDone = false; break; -#ifdef HAS_ETHERNET - case SYSTEM_EVENT_ETH_START: - break; - case SYSTEM_EVENT_ETH_CONNECTED: - break; - case SYSTEM_EVENT_ETH_DISCONNECTED: - break; - case SYSTEM_EVENT_ETH_STOP: - break; - case SYSTEM_EVENT_ETH_GOT_IP: - break; -#endif default: break; } diff --git a/src/ESPEasyWifi.ino b/src/ESPEasyWifi.ino index 9c0b5af35..4d6f56538 100644 --- a/src/ESPEasyWifi.ino +++ b/src/ESPEasyWifi.ino @@ -73,10 +73,6 @@ // - Start/stop of AP mode // ******************************************************************************** bool WiFiConnected() { - #ifdef HAS_ETHERNET - return eth_connected; - #else - START_TIMER; if (unprocessedWifiEvents()) { return false; } @@ -133,7 +129,6 @@ bool WiFiConnected() { delay(1); STOP_TIMER(WIFI_NOTCONNECTED_STATS); return false; - #endif // HAS_ETHERNET } void WiFiConnectRelaxed() { diff --git a/src/ESPEasyWifi_ProcessEvent.ino b/src/ESPEasyWifi_ProcessEvent.ino index ee7ff8d55..e24802ff3 100644 --- a/src/ESPEasyWifi_ProcessEvent.ino +++ b/src/ESPEasyWifi_ProcessEvent.ino @@ -24,7 +24,7 @@ void handle_unprocessedWiFiEvents() delay(1); if (wifiConnectAttemptNeeded) { - WiFiConnectRelaxed(); + NetworkConnectRelaxed(); } // Process disconnect events before connect events. @@ -82,7 +82,7 @@ void handle_unprocessedWiFiEvents() markWiFi_services_initialized(); } } - } else if (!WiFiConnected()) { + } else if (!NetworkConnected()) { // Somehow the WiFi has entered a limbo state. // FIXME TD-er: This may happen on WiFi config with AP_STA mode active. // addLog(LOG_LEVEL_ERROR, F("Wifi status out sync")); @@ -223,7 +223,7 @@ void processGotIP() { // Only process GotIP events if we are connected. return; } - IPAddress ip = WiFi.localIP(); + IPAddress ip = NetworkLocalIP(); if (!useStaticIP()) { if ((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)) { @@ -232,8 +232,8 @@ void processGotIP() { } processedGotIP = true; wifiStatus |= ESPEASY_WIFI_GOT_IP; - const IPAddress gw = WiFi.gatewayIP(); - const IPAddress subnet = WiFi.subnetMask(); + const IPAddress gw = NetworkGatewayIP(); + const IPAddress subnet = NetworkSubnetMask(); const long dhcp_duration = timeDiff(lastConnectMoment, lastGetIPmoment); if (loglevelActiveFor(LOG_LEVEL_INFO)) { diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index 9eaac617a..58afe912b 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -54,7 +54,7 @@ void run_compiletime_checks() { check_size(); check_size(); check_size(); - check_size(); + check_size(); #if defined(USE_NON_STANDARD_24_TASKS) && defined(ESP8266) static_assert(TASKS_MAX == 24, "TASKS_MAX invalid size"); #endif diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index 3174b43da..c3ddd752b 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -66,8 +66,8 @@ bool connectClient(WiFiClient& client, String getWifiModeString(WiFiMode_t wifimode); -bool WiFiConnected(uint32_t timeout_ms); -bool WiFiConnected(); +bool NetworkConnected(uint32_t timeout_ms); +bool NetworkConnected(); bool useStaticIP(); bool hostReachable(const IPAddress& ip); bool hostReachable(const String& hostname); @@ -187,11 +187,24 @@ bool SourceNeedsStatusUpdate(byte eventSource); void WifiScan(bool async, bool quick = false); void WifiScan(); -void WiFiConnectRelaxed(); void WifiDisconnect(); void setAP(bool enable); void setSTA(bool enable); +// Used for Networking with Wifi or Ethernet +#include "ESPEasyEthWifi.h" +void NetworkConnectRelaxed(); +bool NetworkConnected(); +IPAddress NetworkLocalIP(); +IPAddress NetworkSubnetMask(); +IPAddress NetworkGatewayIP(); +IPAddress NetworkDnsIP (uint8_t dns_no=0); +// TODO: PKR: Change to NetworkMacAddress +//uint8_t * NetworkMacAddress(uint8_t* mac); +String NetworkMacAddress(); +String WifiGetAPssid(); +String createRFCCompliantHostname(String oldString); + #include "src/Globals/ESPEasyWiFiEvent.h" void setWifiMode(WiFiMode_t wifimode); diff --git a/src/Misc.ino b/src/Misc.ino index 9e85b1263..dfa122221 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -350,7 +350,7 @@ bool readyForSleep() return false; } - if (!WiFiConnected()) { + if (!NetworkConnected()) { // Allow 12 seconds to establish connections return timeOutReached(timerAwakeFromDeepSleep + 12000); } @@ -708,7 +708,7 @@ void statusLED(bool traffic) else { - if (WiFiConnected()) + if (NetworkConnected()) { long int delta = timePassedSince(gnLastUpdate); if (delta>0 || delta<0 ) @@ -1214,6 +1214,7 @@ void ResetFactory() Settings.ETH_Pin_power = gpio_settings.eth_power; Settings.ETH_Phy_Type = gpio_settings.eth_phytype; Settings.ETH_Clock_Mode = gpio_settings.eth_clock_mode; + Settings.ETH_Wifi_Mode = gpio_settings.eth_wifi_mode; /* Settings.GlobalSync = DEFAULT_USE_GLOBAL_SYNC; diff --git a/src/Network.ino b/src/Network.ino new file mode 100644 index 000000000..6f55aaff3 --- /dev/null +++ b/src/Network.ino @@ -0,0 +1,145 @@ +//#include "Network.h" + +/*#include "ESPEasy_fdwdecl.h" +#include "ESPEasy_Log.h" +#include "ESPEasy_common.h" +#include "src/Globals/Settings.h" +#include "src/DataStructs/TimingStats.h" + +#include "ESPEasyEth.ino" +#include "ESPEasyWifi.ino" +#include "ESPEasyWifi_ProcessEvent.ino"*/ + +/*********************************************************************************************\ + Ethernet or Wifi Support for ESP32 Build flag HAS_ETHERNET +\*********************************************************************************************/ +void NetworkConnectRelaxed() { +#ifdef HAS_ETHERNET + addLog(LOG_LEVEL_INFO, F("Connect to: ")); + addLog(LOG_LEVEL_INFO, ethGetDebugEthWifiModeStr()); + if(eth_wifi_mode == ETHERNET) { + ETHConnectRelaxed(); + } else { + WiFiConnectRelaxed(); + } +#else + WiFiConnectRelaxed(); +#endif +} + +bool NetworkConnected() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + return ETHConnected(); + } else { + return WiFiConnected(); + } + #else + return WiFiConnected(); + #endif +} + +IPAddress NetworkLocalIP() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(eth_connected) { + return ETH.localIP(); + } else { + addLog(LOG_LEVEL_ERROR, F("Call NetworkLocalIP() only on connected Ethernet!")); + return IPAddress(); + } + } else { + return WiFi.localIP(); + } + #else + return WiFi.localIP(); + #endif +} + +IPAddress NetworkSubnetMask() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(eth_connected) { + return ETH.subnetMask(); + } else { + addLog(LOG_LEVEL_ERROR, F("Call NetworkSubnetMask() only on connected Ethernet!")); + return IPAddress(); + } + } else { + return WiFi.subnetMask(); + } + #else + return WiFi.subnetMask(); + #endif +} + +IPAddress NetworkGatewayIP() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(eth_connected) { + return ETH.gatewayIP(); + } else { + addLog(LOG_LEVEL_ERROR, F("Call NetworkGatewayIP() only on connected Ethernet!")); + return IPAddress(); + } + } else { + return WiFi.gatewayIP(); + } + #else + return WiFi.gatewayIP(); + #endif +} + +// TODO: PKR: Check her with default variable +IPAddress NetworkDnsIP (uint8_t dns_no) { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(eth_connected) { + return ETH.dnsIP(); + } else { + addLog(LOG_LEVEL_ERROR, F("Call NetworkDnsIP(uint8_t dns_no) only on connected Ethernet!")); + return IPAddress(); + } + } else { + return WiFi.dnsIP(dns_no); + } + #else + return WiFi.dnsIP(dns_no); + #endif +} + +uint8_t * NetworkMacAddressAsBytes(uint8_t* mac) { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(eth_connected) { + // TODO: PKR: Change to NetworjMacAddress + return mac; + } else { + addLog(LOG_LEVEL_ERROR, F("Call NetworkMacAddressAsBytes(uint8_t* mac) only on connected Ethernet!")); + return mac; + } + } else { + return WiFi.macAddress(mac); + } + #else + return WiFi.macAddress(mac); + #endif + return WiFi.macAddress(mac); +} + +String NetworkMacAddress() { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + if(!eth_connected) { + addLog(LOG_LEVEL_ERROR, F("Call NetworkMacAddress() only on connected Ethernet!")); + } + } + #endif + + uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; + uint8_t *macread = NetworkMacAddressAsBytes(mac); + char macaddress[20]; + formatMAC(macread, macaddress); + + return String(macaddress); +} \ No newline at end of file diff --git a/src/Networking.ino b/src/Networking.ino index 593289c80..3463fc3ea 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -59,7 +59,7 @@ void etharp_gratuitous_r(struct netif *netif) { \*********************************************************************************************/ void syslog(byte logLevel, const char *message) { - if ((Settings.Syslog_IP[0] != 0) && WiFiConnected()) + if ((Settings.Syslog_IP[0] != 0) && NetworkConnected()) { IPAddress broadcastIP(Settings.Syslog_IP[0], Settings.Syslog_IP[1], Settings.Syslog_IP[2], Settings.Syslog_IP[3]); portUDP.beginPacket(broadcastIP, 514); @@ -225,7 +225,7 @@ void checkUDP() \*********************************************************************************************/ void SendUDPCommand(byte destUnit, const char *data, byte dataLength) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } @@ -249,7 +249,7 @@ void SendUDPCommand(byte destUnit, const char *data, byte dataLength) \*********************************************************************************************/ void sendUDP(byte unit, const byte *data, byte size) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } @@ -324,7 +324,7 @@ void refreshNodeList() \*********************************************************************************************/ void sendSysInfoUDP(byte repeats) { - if ((Settings.UDPPort == 0) || !WiFiConnected(10)) { + if ((Settings.UDPPort == 0) || !NetworkConnected(10)) { return; } @@ -354,12 +354,9 @@ void sendSysInfoUDP(byte repeats) for (byte x = 0; x < 6; x++) { data[x + 2] = macread[x]; } - #ifdef HAS_ETHERNET - IPAddress ip = ETH.localIP(); - #else - IPAddress ip = WiFi.localIP(); - #endif - + + IPAddress ip = NetworkLocalIP(); + for (byte x = 0; x < 4; x++) { data[x + 8] = ip[x]; } @@ -386,11 +383,7 @@ void sendSysInfoUDP(byte repeats) if (it != Nodes.end()) { - #ifdef HAS_ETHERNET - IPAddress ip = ETH.localIP(); - #else - IPAddress ip = WiFi.localIP(); - #endif + IPAddress ip = NetworkLocalIP(); for (byte x = 0; x < 4; x++) { it->second.ip[x] = ip[x]; @@ -409,7 +402,7 @@ void sendSysInfoUDP(byte repeats) Respond to HTTP XML requests for SSDP information \*********************************************************************************************/ void SSDP_schema(WiFiClient& client) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } @@ -760,14 +753,10 @@ bool getSubnetRange(IPAddress& low, IPAddress& high) if (wifiStatus < ESPEASY_WIFI_GOT_IP) { return false; } - #ifdef HAS_ETHERNET - const IPAddress ip = ETH.localIP(); - const IPAddress subnet = ETH.subnetMask(); - #else - const IPAddress ip = WiFi.localIP(); - const IPAddress subnet = WiFi.subnetMask(); - #endif - + + const IPAddress ip = NetworkLocalIP(); + const IPAddress subnet = NetworkSubnetMask(); + low = ip; high = ip; @@ -811,8 +800,8 @@ bool hasIPaddr() { #endif // ifdef CORE_POST_2_5_0 } -// Check WiFi connection. Maximum timeout 500 msec. -bool WiFiConnected(uint32_t timeout_ms) { +// Check connection. Maximum timeout 500 msec. +bool NetworkConnected(uint32_t timeout_ms) { uint32_t timer = millis() + (timeout_ms > 500 ? 500 : timeout_ms); uint32_t min_delay = timeout_ms / 20; @@ -822,7 +811,7 @@ bool WiFiConnected(uint32_t timeout_ms) { } // Apparently something needs network, perform check to see if it is ready now. - while (!WiFiConnected()) { + while (!NetworkConnected()) { if (timeOutReached(timer)) { return false; } @@ -832,7 +821,7 @@ bool WiFiConnected(uint32_t timeout_ms) { } bool hostReachable(const IPAddress& ip) { - if (!WiFiConnected()) { return false; } + if (!NetworkConnected()) { return false; } return true; // Disabled ping as requested here: // https://github.com/letscontrolit/ESPEasy/issues/1494#issuecomment-397872538 @@ -878,7 +867,7 @@ bool connectClient(WiFiClient& client, IPAddress ip, uint16_t port) { START_TIMER; - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } bool connected = (client.connect(ip, port) == 1); @@ -901,7 +890,7 @@ bool connectClient(WiFiClient& client, IPAddress ip, uint16_t port) bool resolveHostByName(const char *aHostname, IPAddress& aResult) { START_TIMER; - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ESP32) @@ -933,7 +922,7 @@ bool hostReachable(const String& hostname) { // Create a random port for the UDP connection. // Return true when successful. bool beginWiFiUDP_randomPort(WiFiUDP& udp) { - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } unsigned int attempts = 3; @@ -950,7 +939,7 @@ bool beginWiFiUDP_randomPort(WiFiUDP& udp) { } void sendGratuitousARP() { - if (!WiFiConnected()) { + if (!NetworkConnected()) { return; } #ifdef SUPPORT_ARP diff --git a/src/StringProvider.ino b/src/StringProvider.ino index c9097bde1..c063f4b4b 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -107,7 +107,8 @@ String getLabel(LabelType::Enum label) { case LabelType::ETH_DUPLEX: return F("Eth Mode"); case LabelType::ETH_SPEED: return F("Eth Speed"); case LabelType::ETH_STATE: return F("Eth State"); - case LabelType::ETH_SPEED_STATE: return F("Eth State"); + case LabelType::ETH_SPEED_STATE: return F("Eth Speed State"); + case LabelType::ETH_WIFI_MODE: return F("Eth Wifi Mode"); #endif } @@ -152,19 +153,19 @@ String getValue(LabelType::Enum label) { case LabelType::IP_CONFIG: return useStaticIP() ? getLabel(LabelType::IP_CONFIG_STATIC) : getLabel(LabelType::IP_CONFIG_DYNAMIC); case LabelType::IP_CONFIG_STATIC: break; case LabelType::IP_CONFIG_DYNAMIC: break; - case LabelType::IP_ADDRESS: return WiFi.localIP().toString(); + case LabelType::IP_ADDRESS: return NetworkLocalIP().toString(); case LabelType::IP_SUBNET: return WiFi.subnetMask().toString(); case LabelType::IP_ADDRESS_SUBNET: return String(getValue(LabelType::IP_ADDRESS) + F(" / ") + getValue(LabelType::IP_SUBNET)); - case LabelType::GATEWAY: return WiFi.gatewayIP().toString(); + case LabelType::GATEWAY: return NetworkGatewayIP().toString(); case LabelType::CLIENT_IP: return formatIP(web_server.client().remoteIP()); #ifdef FEATURE_MDNS case LabelType::M_DNS: return String(WifiGetHostname()) + F(".local"); #endif case LabelType::DNS: return String(getValue(LabelType::DNS_1) + F(" / ") + getValue(LabelType::DNS_2)); - case LabelType::DNS_1: return WiFi.dnsIP(0).toString(); - case LabelType::DNS_2: return WiFi.dnsIP(1).toString(); + case LabelType::DNS_1: return NetworkDnsIP(0).toString(); + case LabelType::DNS_2: return NetworkDnsIP(1).toString(); case LabelType::ALLOWED_IP_RANGE: return describeAllowedIPrange(); - case LabelType::STA_MAC: return WiFi.macAddress(); + case LabelType::STA_MAC: return NetworkMacAddress(); case LabelType::AP_MAC: break; case LabelType::SSID: return WiFi.SSID(); case LabelType::BSSID: return WiFi.BSSIDstr(); @@ -224,6 +225,8 @@ String getValue(LabelType::Enum label) { case LabelType::ETH_SPEED: return getEthSpeed(); case LabelType::ETH_STATE: return ETH.linkUp() ? F("Link Up") : F("Link Down"); case LabelType::ETH_SPEED_STATE: return getEthLinkSpeedState(); + // TODO: PKR: Same as ethwifidebug + case LabelType::ETH_WIFI_MODE: return (eth_wifi_mode == WIFI ? F("WIFI") : F("ETHERNET")); #endif } diff --git a/src/StringProviderTypes.h b/src/StringProviderTypes.h index bfbb2ae61..65f9373a4 100644 --- a/src/StringProviderTypes.h +++ b/src/StringProviderTypes.h @@ -108,6 +108,7 @@ enum Enum : short { ETH_SPEED, ETH_STATE, ETH_SPEED_STATE, + ETH_WIFI_MODE, #endif }; diff --git a/src/WebServer_HardwarePage.ino b/src/WebServer_HardwarePage.ino index 4926b7874..4f0d23730 100644 --- a/src/WebServer_HardwarePage.ino +++ b/src/WebServer_HardwarePage.ino @@ -28,6 +28,7 @@ void handle_hardware() { Settings.ETH_Pin_power = getFormItemInt(F("ethpower")); Settings.ETH_Phy_Type = getFormItemInt(F("ethtype")); Settings.ETH_Clock_Mode = getFormItemInt(F("ethclock")); + Settings.ETH_Wifi_Mode = getFormItemInt(F("ethwifi")); #endif int gpio = 0; @@ -85,11 +86,15 @@ void handle_hardware() { #endif // ifdef FEATURE_SD #ifdef HAS_ETHERNET addFormSubHeader(F("Ethernet")); + addRowLabel_tr_id(F("Ethernet or WIFI?"), "ethwifi"); + String ethWifiOptions[2] = { F("WIFI"), F("ETHERNET") }; + addSelector("ethwifi", 2, ethWifiOptions, NULL, NULL, Settings.ETH_Wifi_Mode, false, true); + addFormNote(F("Note: Change Switch between WIFI and ETHERNET requires reboot to activate")); addRowLabel_tr_id(F("Ethernet PHY type"), "ethtype"); String ethPhyTypes[2] = { F("LAN8710"), F("TLK110") }; addSelector("ethtype", 2, ethPhyTypes, NULL, NULL, Settings.ETH_Phy_Type, false, true); addFormNumericBox(F("Ethernet PHY Address"), "ethphy", Settings.ETH_Phy_Addr, 0, 255); - addFormNote(F("I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)")); + addFormNote(F("Note: I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)")); addFormPinSelect(formatGpioName_output("Ethernet MDC pin"), "ethmdc", Settings.ETH_Pin_mdc); addFormPinSelect(formatGpioName_input("Ethernet MIO pin"), "ethmdio", Settings.ETH_Pin_mdio); addFormPinSelect(formatGpioName_output("Ethernet Power pin"), "ethpower", Settings.ETH_Pin_power); diff --git a/src/WebServer_RootPage.ino b/src/WebServer_RootPage.ino index 3e87cd8cc..3066b0361 100644 --- a/src/WebServer_RootPage.ino +++ b/src/WebServer_RootPage.ino @@ -45,8 +45,8 @@ void handle_root() { ExecuteCommand_internal(VALUE_SOURCE_HTTP, sCommand.c_str()); } - // IPAddress ip = WiFi.localIP(); - // IPAddress gw = WiFi.gatewayIP(); + // IPAddress ip = NetworkLocalIP(); + // IPAddress gw = NetwrokGatewayIP(); addHtml(printWebString); addHtml(F("
")); @@ -109,7 +109,7 @@ void handle_root() { addRowLabelValue(LabelType::IP_ADDRESS); addRowLabel(getLabel(LabelType::WIFI_RSSI)); - if (WiFiConnected()) + if (NetworkConnected()) { String html; html.reserve(32); @@ -121,8 +121,11 @@ void handle_root() { } #ifdef HAS_ETHERNET - addRowLabelValue(LabelType::ETH_SPEED_STATE); - addRowLabelValue(LabelType::ETH_IP_ADDRESS); + addRowLabelValue(LabelType::ETH_WIFI_MODE); + if(eth_wifi_mode == ETHERNET) { + addRowLabelValue(LabelType::ETH_SPEED_STATE); + addRowLabelValue(LabelType::ETH_IP_ADDRESS); + } #endif #ifdef FEATURE_MDNS diff --git a/src/WebServer_SetupPage.ino b/src/WebServer_SetupPage.ino index b7c7b510f..11f2bc513 100644 --- a/src/WebServer_SetupPage.ino +++ b/src/WebServer_SetupPage.ino @@ -14,7 +14,7 @@ void handle_setup() { // Do not check client IP range allowed. TXBuffer.startStream(); - if (!WiFiConnected()) + if (!NetworkConnected()) { sendHeadandTail(F("TmplAP")); static byte status = 0; @@ -188,7 +188,7 @@ void handle_setup_finish() { html_TD(); if (!clientIPinSubnet()) { - String host = formatIP(WiFi.localIP()); + String host = formatIP(NetworkLocalIP()); String url = F("http://"); url += host; url += F("/config"); diff --git a/src/WebServer_SysInfoPage.ino b/src/WebServer_SysInfoPage.ino index 893482bd5..618010121 100644 --- a/src/WebServer_SysInfoPage.ino +++ b/src/WebServer_SysInfoPage.ino @@ -60,15 +60,16 @@ void handle_sysinfo_json() { } json_number(F("rssi"), String(WiFi.RSSI())); json_prop(F("dhcp"), useStaticIP() ? getLabel(LabelType::IP_CONFIG_STATIC) : getLabel(LabelType::IP_CONFIG_DYNAMIC)); - json_prop(F("ip"), formatIP(WiFi.localIP())); - json_prop(F("subnet"), formatIP(WiFi.subnetMask())); - json_prop(F("gw"), formatIP(WiFi.gatewayIP())); - json_prop(F("dns1"), formatIP(WiFi.dnsIP(0))); - json_prop(F("dns2"), formatIP(WiFi.dnsIP(1))); + json_prop(F("ip"), formatIP(NetworkLocalIP())); + json_prop(F("subnet"), formatIP(NetworkSubnetMask())); + json_prop(F("gw"), formatIP(NetworkGatewayIP())); + json_prop(F("dns1"), formatIP(NetworkDnsIP(0))); + json_prop(F("dns2"), formatIP(NetworkDnsIP(1))); json_prop(F("allowed_range"), describeAllowedIPrange()); uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; +// TODO: PKR: Change to NetworkMacAddress uint8_t *macread = WiFi.macAddress(mac); char macaddress[20]; formatMAC(macread, macaddress); @@ -313,25 +314,32 @@ void handle_sysinfo_basicInfo() { addRowLabelValue(LabelType::RESET_REASON); addRowLabelValue(LabelType::LAST_TASK_BEFORE_REBOOT); addRowLabelValue(LabelType::SW_WD_COUNT); + + #ifdef HAS_ETHERNET + addRowLabel(F("Network Type")); + addRowLabelValue(LabelType::ETH_WIFI_MODE); + #endif } #ifdef HAS_ETHERNET void handle_sysinfo_Ethernet() { - addTableSeparator(F("Ethernet"), 2, 3); - addRowLabelValue(LabelType::ETH_STATE); - addRowLabelValue(LabelType::ETH_SPEED); - addRowLabelValue(LabelType::ETH_DUPLEX); - addRowLabelValue(LabelType::ETH_MAC); - addRowLabelValue(LabelType::ETH_IP_ADDRESS_SUBNET); - addRowLabelValue(LabelType::ETH_IP_GATEWAY); - addRowLabelValue(LabelType::ETH_IP_DNS); + if(eth_wifi_mode == ETHERNET) { + addTableSeparator(F("Ethernet"), 2, 3); + addRowLabelValue(LabelType::ETH_STATE); + addRowLabelValue(LabelType::ETH_SPEED); + addRowLabelValue(LabelType::ETH_DUPLEX); + addRowLabelValue(LabelType::ETH_MAC); + addRowLabelValue(LabelType::ETH_IP_ADDRESS_SUBNET); + addRowLabelValue(LabelType::ETH_IP_GATEWAY); + addRowLabelValue(LabelType::ETH_IP_DNS); + } } #endif void handle_sysinfo_Network() { addTableSeparator(F("Network"), 2, 3, F("Wifi")); - if (WiFiConnected()) + if (eth_wifi_mode == WIFI && NetworkConnected()) { addRowLabel(F("Wifi")); # if defined(ESP8266) @@ -373,6 +381,7 @@ void handle_sysinfo_Network() { { uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; +// TODO: PKR: Change to NetworkMacAddress uint8_t *macread = WiFi.macAddress(mac); char macaddress[20]; formatMAC(macread, macaddress); diff --git a/src/WebServer_SysVarPage.ino b/src/WebServer_SysVarPage.ino index c480a2297..a434381fe 100644 --- a/src/WebServer_SysVarPage.ino +++ b/src/WebServer_SysVarPage.ino @@ -62,6 +62,10 @@ void handle_sysvars() { addTableSeparator(F("System status"), 3, 3); addSysVar_enum_html(SystemVariables::ISWIFI); + #ifdef HAS_ETHERNET + addSysVar_enum_html(SystemVariables::ETH_WIFI_MODE); + addSysVar_enum_html(SystemVariables::ETH_CONNECTED); + #endif addSysVar_enum_html(SystemVariables::ISNTP); addSysVar_enum_html(SystemVariables::ISMQTT); #ifdef USES_P037 diff --git a/src/WebServer_ToolsPage.ino b/src/WebServer_ToolsPage.ino index 3d1824e58..dfffe2643 100644 --- a/src/WebServer_ToolsPage.ino +++ b/src/WebServer_ToolsPage.ino @@ -73,6 +73,7 @@ void handle_tools() { addFormSubHeader(F("Wifi")); +// TODO: PKR: Add commands for ETHERNET addWideButtonPlusDescription(F("/?cmd=wificonnect"), F("Connect"), F("Connects to known Wifi network")); addWideButtonPlusDescription(F("/?cmd=wifidisconnect"), F("Disconnect"), F("Disconnect from wifi network")); diff --git a/src/_C006.ino b/src/_C006.ino index 6cc4fa7f0..453cccf1d 100644 --- a/src/_C006.ino +++ b/src/_C006.ino @@ -87,7 +87,7 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_SEND: { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { success = false; break; } diff --git a/src/_C009.ino b/src/_C009.ino index c7a86ad3b..af1f77fd2 100644 --- a/src/_C009.ino +++ b/src/_C009.ino @@ -123,9 +123,9 @@ bool do_process_c009_delay_queue(int controller_number, const C009_queue_element // embed IP, important if there is NAT/PAT // char ipStr[20]; - // IPAddress ip = WiFi.localIP(); + // IPAddress ip = NetworkLocalIP(); // sprintf_P(ipStr, PSTR("%u.%u.%u.%u"), ip[0], ip[1], ip[2], ip[3]); - ESP[F("ip")] = WiFi.localIP().toString(); + ESP[F("ip")] = NetworkLocalIP().toString(); // Create nested SENSOR json object JsonObject SENSOR = data.createNestedObject(String(F("SENSOR"))); diff --git a/src/_C011.ino b/src/_C011.ino index 6beab4c61..080402f5f 100644 --- a/src/_C011.ino +++ b/src/_C011.ino @@ -155,7 +155,7 @@ bool do_process_c011_delay_queue(int controller_number, const C011_queue_element boolean Create_schedule_HTTP_C011(struct EventStruct *event) { int controller_number = CPLUGIN_ID_011; - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return false; } MakeControllerSettings(ControllerSettings); diff --git a/src/_C012.ino b/src/_C012.ino index 35ba99aeb..9122791c5 100644 --- a/src/_C012.ino +++ b/src/_C012.ino @@ -93,7 +93,7 @@ bool do_process_c012_delay_queue(int controller_number, const C012_queue_element if (element.checkDone(true)) return true; } - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } return element.checkDone(Blynk_get(element.txt[element.valuesSent], element.controller_idx)); diff --git a/src/_C013.ino b/src/_C013.ino index 2b17d2332..005119814 100644 --- a/src/_C013.ino +++ b/src/_C013.ino @@ -114,7 +114,7 @@ bool CPlugin_013(CPlugin::Function function, struct EventStruct *event, String& // ******************************************************************************** void C013_SendUDPTaskInfo(byte destUnit, byte sourceTaskIndex, byte destTaskIndex) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } @@ -158,7 +158,7 @@ void C013_SendUDPTaskInfo(byte destUnit, byte sourceTaskIndex, byte destTaskInde void C013_SendUDPTaskData(byte destUnit, byte sourceTaskIndex, byte destTaskIndex) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } struct C013_SensorDataStruct dataReply; @@ -196,7 +196,7 @@ void C013_SendUDPTaskData(byte destUnit, byte sourceTaskIndex, byte destTaskInde \*********************************************************************************************/ void C013_sendUDP(byte unit, byte *data, byte size) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return; } NodesMap::iterator it; diff --git a/src/_C014.ino b/src/_C014.ino index 966d6d65e..abfafe828 100644 --- a/src/_C014.ino +++ b/src/_C014.ino @@ -243,9 +243,10 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& // $localip Device → Controller IP of the device on the local network Yes Yes #ifdef CPLUGIN_014_V3 - CPlugin_014_sendMQTTdevice(pubname,"$localip",formatIP(WiFi.localIP()).c_str(),errorCounter); + CPlugin_014_sendMQTTdevice(pubname,"$localip",formatIP(NetworkLocalIP()).c_str(),errorCounter); // $mac Device → Controller Mac address of the device network interface. The format MUST be of the type A1:B2:C3:D4:E5:F6 Yes Yes + // TODO: PKR: Change to NetworkMacAddress CPlugin_014_sendMQTTdevice(pubname,"$mac",WiFi.macAddress().c_str(),errorCounter); // $implementation Device → Controller An identifier for the Homie implementation (example esp8266) Yes Yes diff --git a/src/_C015.ino b/src/_C015.ino index ed64025a3..7d1ccca0e 100644 --- a/src/_C015.ino +++ b/src/_C015.ino @@ -212,7 +212,7 @@ bool do_process_c015_delay_queue(int controller_plugin_number, const C015_queue_ // controller has been disabled. Answer true to flush queue. return true; - if (!WiFiConnected()) { + if (!NetworkConnected()) { return false; } @@ -231,7 +231,7 @@ bool do_process_c015_delay_queue(int controller_plugin_number, const C015_queue_ boolean Blynk_keep_connection_c015(int controllerIndex, ControllerSettingsStruct& ControllerSettings){ - if (!WiFiConnected()) + if (!NetworkConnected()) return false; if (!Blynk.connected()){ diff --git a/src/_C017.ino b/src/_C017.ino index 8e9cf7190..0ba051f5f 100644 --- a/src/_C017.ino +++ b/src/_C017.ino @@ -86,7 +86,7 @@ bool do_process_c017_delay_queue(int controller_number, const C017_queue_element if (valueCount == 0) return true; //exit if we don't have anything to send. - if (!WiFiConnected(10)) + if (!NetworkConnected(10)) { return false; } diff --git a/src/_CPlugin_Helper.cpp b/src/_CPlugin_Helper.cpp index 0428d449d..23c0cc5a1 100644 --- a/src/_CPlugin_Helper.cpp +++ b/src/_CPlugin_Helper.cpp @@ -273,7 +273,7 @@ bool count_connection_results(bool success, const String& prefix, int controller bool try_connect_host(int controller_number, WiFiUDP& client, ControllerSettingsStruct& ControllerSettings) { START_TIMER; - if (!WiFiConnected()) { return false; } + if (!NetworkConnected()) { return false; } client.setTimeout(ControllerSettings.ClientTimeout); #ifndef BUILD_NO_DEBUG log_connecting_to(F("UDP : "), controller_number, ControllerSettings); @@ -293,7 +293,7 @@ bool try_connect_host(int controller_number, WiFiClient& client, ControllerSetti bool try_connect_host(int controller_number, WiFiClient& client, ControllerSettingsStruct& ControllerSettings, const String& loglabel) { START_TIMER; - if (!WiFiConnected()) { return false; } + if (!NetworkConnected()) { return false; } // Use WiFiClient class to create TCP connections client.setTimeout(ControllerSettings.ClientTimeout); diff --git a/src/_P026_Sysinfo.ino b/src/_P026_Sysinfo.ino index 33ed4424b..d1f60864b 100644 --- a/src/_P026_Sysinfo.ino +++ b/src/_P026_Sysinfo.ino @@ -212,22 +212,22 @@ float P026_get_value(int type) } case 5: { - value = WiFi.localIP()[0]; + value = NetworkLocalIP()[0]; break; } case 6: { - value = WiFi.localIP()[1]; + value = NetworkLocalIP()[1]; break; } case 7: { - value = WiFi.localIP()[2]; + value = NetworkLocalIP()[2]; break; } case 8: { - value = WiFi.localIP()[3]; + value = NetworkLocalIP()[3]; break; } case 9: diff --git a/src/_P036_FrameOLED.ino b/src/_P036_FrameOLED.ino index 1535d3b75..36405f260 100644 --- a/src/_P036_FrameOLED.ino +++ b/src/_P036_FrameOLED.ino @@ -867,7 +867,7 @@ void display_header() { } switch (_HeaderContent) { case eSSID: - if (WiFiConnected()) { + if (NetworkConnected()) { strHeader = WiFi.SSID(); } else { @@ -1344,7 +1344,7 @@ void display_scrolling_lines(int nlines) { //Draw Signal Strength Bars, return true when there was an update. bool display_wifibars() { - const bool connected = WiFiConnected(); + const bool connected = NetworkConnected(); const int nbars_filled = (WiFi.RSSI() + 100) / 12; // all bars filled if RSSI better than -46dB const int newState = connected ? nbars_filled : P36_WIFI_STATE_NOT_CONNECTED; if (newState == lastWiFiState) @@ -1366,7 +1366,7 @@ bool display_wifibars() { display->setColor(BLACK); display->fillRect(x , y, size_x, size_y); display->setColor(WHITE); - if (WiFiConnected()) { + if (NetworkConnected()) { for (uint8_t ibar = 0; ibar < nbars; ibar++) { int16_t height = size_y * (ibar + 1) / nbars; int16_t xpos = x + ibar * width; diff --git a/src/_P037_MQTTImport.ino b/src/_P037_MQTTImport.ino index 594ca60ab..31ffa64f9 100644 --- a/src/_P037_MQTTImport.ino +++ b/src/_P037_MQTTImport.ino @@ -418,7 +418,7 @@ boolean MQTTConnect_037() if (MQTTclient_037->connected()) return true; // define stuff for the client - this could also be done in the intial declaration of MQTTclient_037 - if (!WiFiConnected(100)) { + if (!NetworkConnected(100)) { Plugin_037_update_connect_status(); return false; // Not connected, so no use in wasting time to connect to a host. } diff --git a/src/_P089_Ping.ino b/src/_P089_Ping.ino index 5ad4a6dd5..1273eebc4 100644 --- a/src/_P089_Ping.ino +++ b/src/_P089_Ping.ino @@ -76,7 +76,7 @@ public: is_failure = true; /* This ping lost for sure */ - if (!WiFiConnected()) { + if (!NetworkConnected()) { return true; } diff --git a/src/src/Commands/HTTP.cpp b/src/src/Commands/HTTP.cpp index bd69b7394..96abdbcb1 100644 --- a/src/src/Commands/HTTP.cpp +++ b/src/src/Commands/HTTP.cpp @@ -14,7 +14,7 @@ String Command_HTTP_SendToHTTP(struct EventStruct *event, const char* Line) { - if (WiFiConnected()) { + if (NetworkConnected()) { String host = parseString(Line, 2); const int port = parseCommandArgumentInt(Line, 2); if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { diff --git a/src/src/Commands/UDP.cpp b/src/src/Commands/UDP.cpp index 252386c23..09c58e11c 100644 --- a/src/src/Commands/UDP.cpp +++ b/src/src/Commands/UDP.cpp @@ -39,7 +39,7 @@ String Command_UPD_SendTo(struct EventStruct *event, const char *Line) String Command_UDP_SendToUPD(struct EventStruct *event, const char *Line) { - if (WiFiConnected()) { + if (NetworkConnected()) { String ip = parseString(Line, 2); int port = parseCommandArgumentInt(Line, 2); diff --git a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h index abe68e766..94ecd7188 100644 --- a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h +++ b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h @@ -192,7 +192,7 @@ struct ControllerDelayHandlerStruct { MakeControllerSettings (ControllerSettings); \ LoadControllerSettings(element->controller_idx, ControllerSettings); \ C##NNN####M##_DelayHandler.configureControllerSettings(ControllerSettings); \ - if (!WiFiConnected(10)) { \ + if (!NetworkConnected(10)) { \ scheduleNextDelayQueue(TIMER_C##NNN####M##_DELAY_QUEUE, C##NNN####M##_DelayHandler.getNextScheduleTime()); \ return; \ } \ diff --git a/src/src/DataStructs/ControllerSettingsStruct.cpp b/src/src/DataStructs/ControllerSettingsStruct.cpp index 8036aec50..8b9bb08a1 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.cpp +++ b/src/src/DataStructs/ControllerSettingsStruct.cpp @@ -85,7 +85,7 @@ void ControllerSettingsStruct::setHostname(const String& controllerhostname) { } boolean ControllerSettingsStruct::checkHostReachable(bool quick) { - if (!WiFiConnected(10)) { + if (!NetworkConnected(10)) { return false; // Not connected, so no use in wasting time to connect to a host. } delay(1); // Make sure the Watchdog will not trigger a reset. @@ -166,7 +166,7 @@ bool ControllerSettingsStruct::updateIPcache() { return true; } - if (!WiFiConnected()) { return false; } + if (!NetworkConnected()) { return false; } IPAddress tmpIP; if (resolveHostByName(HostName, tmpIP)) { diff --git a/src/src/DataStructs/ESPEasyDefaults.h b/src/src/DataStructs/ESPEasyDefaults.h index 68b659996..fb3068d2f 100644 --- a/src/src/DataStructs/ESPEasyDefaults.h +++ b/src/src/DataStructs/ESPEasyDefaults.h @@ -187,7 +187,12 @@ #define DEFAULT_ETH_PIN_POWER -1 #endif #ifndef DEFAULT_ETH_CLOCK_MODE -#define DEFAULT_ETH_CLOCK_MODE 3 +#define DEFAULT_ETH_CLOCK_MODE 0 +#endif +#ifndef DEFAULT_ETH_WIFI_MODE +#define DEFAULT_ETH_WIFI_MODE 1 // TODO: PKR: Change perhaps to 0 + // 0 WIFI + // 1 ETHERNET #endif diff --git a/src/src/DataStructs/SettingsStruct.cpp b/src/src/DataStructs/SettingsStruct.cpp index 3358c60e2..91ceef28d 100644 --- a/src/src/DataStructs/SettingsStruct.cpp +++ b/src/src/DataStructs/SettingsStruct.cpp @@ -216,6 +216,7 @@ void SettingsStruct_tmpl::clearMisc() { ETH_Pin_power = -1; ETH_Phy_Type = 0; ETH_Clock_Mode = 0; + ETH_Wifi_Mode = 0; for (byte i = 0; i < 17; ++i) { PinBootStates[i] = 0; } BaudRate = 0; diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index db57944e5..0f83d8219 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -187,6 +187,7 @@ class SettingsStruct_tmpl byte ETH_Gateway[4]; byte ETH_Subnet[4]; byte ETH_DNS[4]; + uint8_t ETH_Wifi_Mode; }; /* diff --git a/src/src/Helpers/ESPEasy_time.cpp b/src/src/Helpers/ESPEasy_time.cpp index b39e7eb78..d759ccc22 100644 --- a/src/src/Helpers/ESPEasy_time.cpp +++ b/src/src/Helpers/ESPEasy_time.cpp @@ -215,7 +215,7 @@ bool ESPEasy_time::systemTimePresent() const { bool ESPEasy_time::getNtpTime(double& unixTime_d) { - if (!Settings.UseNTP || !WiFiConnected(10)) { + if (!Settings.UseNTP || !NetworkConnected(10)) { return false; } IPAddress timeServerIP; diff --git a/src/src/Helpers/SystemVariables.cpp b/src/src/Helpers/SystemVariables.cpp index 2a8fa647c..4963d644c 100644 --- a/src/src/Helpers/SystemVariables.cpp +++ b/src/src/Helpers/SystemVariables.cpp @@ -89,6 +89,10 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode) case ISNTP: value = String(statusNTPInitialized); break; case ISWIFI: value = String(wifiStatus); break; // 0=disconnected, 1=connected, 2=got ip, 3=services initialized + #ifdef HAS_ETHERNET + case ETH_WIFI_MODE: value = (eth_wifi_mode == WIFI ? "WIFI" : "ETHERNET"); break; // 0=WIFI, 1=ETH + case ETH_CONNECTED: value = String(eth_connected); break; // 0=disconnected, 1=connected + #endif case LCLTIME: value = getValue(LabelType::LOCAL_TIME); break; case LCLTIME_AM: value = node_time.getDateTimeString_ampm('-', ':', ' '); break; case LF: value = "\n"; break; @@ -243,6 +247,10 @@ String SystemVariables::toString(SystemVariables::Enum enumval) case Enum::ISMQTTIMP: return F("%ismqttimp%"); case Enum::ISNTP: return F("%isntp%"); case Enum::ISWIFI: return F("%iswifi%"); + #ifdef HAS_ETHERNET + case Enum::ETH_WIFI_MODE: return F("%eth_wifi_mode%"); + case Enum::ETH_CONNECTED: return F("%eth_connected%"); + #endif case Enum::LCLTIME: return F("%lcltime%"); case Enum::LCLTIME_AM: return F("%lcltime_am%"); case Enum::LF: return F("%LF%"); diff --git a/src/src/Helpers/SystemVariables.h b/src/src/Helpers/SystemVariables.h index 67421791b..ec24e684b 100644 --- a/src/src/Helpers/SystemVariables.h +++ b/src/src/Helpers/SystemVariables.h @@ -17,6 +17,8 @@ public: ISMQTTIMP, ISNTP, ISWIFI, + ETH_WIFI_MODE, + ETH_CONNECTED, LCLTIME, LCLTIME_AM, LF, From 09a149e7c42aea94113e02cdb94b2395d133ee04 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Sun, 26 Apr 2020 23:16:33 +0200 Subject: [PATCH 023/128] Removed some comments Build now working with HAS_ETHERNET not defined --- src/ESPEasy_fdwdecl.h | 3 +-- src/Network.ino | 4 +--- src/StringProvider.ino | 1 - src/WebServer_HardwarePage.ino | 4 ++-- src/WebServer_JSON.ino | 1 + src/WebServer_SysInfoPage.ino | 8 +++++--- src/WebServer_ToolsPage.ino | 1 - src/_C014.ino | 1 - src/src/DataStructs/ESPEasyDefaults.h | 2 +- src/src/Helpers/SystemVariables.cpp | 2 ++ 10 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index c3ddd752b..f1880a48f 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -199,8 +199,7 @@ IPAddress NetworkLocalIP(); IPAddress NetworkSubnetMask(); IPAddress NetworkGatewayIP(); IPAddress NetworkDnsIP (uint8_t dns_no=0); -// TODO: PKR: Change to NetworkMacAddress -//uint8_t * NetworkMacAddress(uint8_t* mac); +uint8_t * NetworkMacAddressAsBytes(uint8_t* mac); String NetworkMacAddress(); String WifiGetAPssid(); String createRFCCompliantHostname(String oldString); diff --git a/src/Network.ino b/src/Network.ino index 6f55aaff3..bb8060651 100644 --- a/src/Network.ino +++ b/src/Network.ino @@ -90,7 +90,6 @@ IPAddress NetworkGatewayIP() { #endif } -// TODO: PKR: Check her with default variable IPAddress NetworkDnsIP (uint8_t dns_no) { #ifdef HAS_ETHERNET if(eth_wifi_mode == ETHERNET) { @@ -112,8 +111,7 @@ uint8_t * NetworkMacAddressAsBytes(uint8_t* mac) { #ifdef HAS_ETHERNET if(eth_wifi_mode == ETHERNET) { if(eth_connected) { - // TODO: PKR: Change to NetworjMacAddress - return mac; + return WiFi.macAddress(mac); } else { addLog(LOG_LEVEL_ERROR, F("Call NetworkMacAddressAsBytes(uint8_t* mac) only on connected Ethernet!")); return mac; diff --git a/src/StringProvider.ino b/src/StringProvider.ino index c063f4b4b..947c0fcd7 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -225,7 +225,6 @@ String getValue(LabelType::Enum label) { case LabelType::ETH_SPEED: return getEthSpeed(); case LabelType::ETH_STATE: return ETH.linkUp() ? F("Link Up") : F("Link Down"); case LabelType::ETH_SPEED_STATE: return getEthLinkSpeedState(); - // TODO: PKR: Same as ethwifidebug case LabelType::ETH_WIFI_MODE: return (eth_wifi_mode == WIFI ? F("WIFI") : F("ETHERNET")); #endif diff --git a/src/WebServer_HardwarePage.ino b/src/WebServer_HardwarePage.ino index 4f0d23730..f143be84d 100644 --- a/src/WebServer_HardwarePage.ino +++ b/src/WebServer_HardwarePage.ino @@ -89,12 +89,12 @@ void handle_hardware() { addRowLabel_tr_id(F("Ethernet or WIFI?"), "ethwifi"); String ethWifiOptions[2] = { F("WIFI"), F("ETHERNET") }; addSelector("ethwifi", 2, ethWifiOptions, NULL, NULL, Settings.ETH_Wifi_Mode, false, true); - addFormNote(F("Note: Change Switch between WIFI and ETHERNET requires reboot to activate")); + addFormNote(F("Change Switch between WIFI and ETHERNET requires reboot to activate")); addRowLabel_tr_id(F("Ethernet PHY type"), "ethtype"); String ethPhyTypes[2] = { F("LAN8710"), F("TLK110") }; addSelector("ethtype", 2, ethPhyTypes, NULL, NULL, Settings.ETH_Phy_Type, false, true); addFormNumericBox(F("Ethernet PHY Address"), "ethphy", Settings.ETH_Phy_Addr, 0, 255); - addFormNote(F("Note: I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)")); + addFormNote(F("I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)")); addFormPinSelect(formatGpioName_output("Ethernet MDC pin"), "ethmdc", Settings.ETH_Pin_mdc); addFormPinSelect(formatGpioName_input("Ethernet MIO pin"), "ethmdio", Settings.ETH_Pin_mdio); addFormPinSelect(formatGpioName_output("Ethernet Power pin"), "ethpower", Settings.ETH_Pin_power); diff --git a/src/WebServer_JSON.ino b/src/WebServer_JSON.ino index 5625d65dd..7e3ed9b04 100644 --- a/src/WebServer_JSON.ino +++ b/src/WebServer_JSON.ino @@ -97,6 +97,7 @@ void handle_json() #endif // ifdef SUPPORT_ARP stream_next_json_object_value(LabelType::CONNECTION_FAIL_THRESH); stream_last_json_object_value(LabelType::WIFI_RSSI); + // TODO: PKR: Add ETH Objects addHtml(F(",\n")); } diff --git a/src/WebServer_SysInfoPage.ino b/src/WebServer_SysInfoPage.ino index 618010121..b85f670e3 100644 --- a/src/WebServer_SysInfoPage.ino +++ b/src/WebServer_SysInfoPage.ino @@ -69,7 +69,6 @@ void handle_sysinfo_json() { uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; -// TODO: PKR: Change to NetworkMacAddress uint8_t *macread = WiFi.macAddress(mac); char macaddress[20]; formatMAC(macread, macaddress); @@ -339,7 +338,11 @@ void handle_sysinfo_Ethernet() { void handle_sysinfo_Network() { addTableSeparator(F("Network"), 2, 3, F("Wifi")); - if (eth_wifi_mode == WIFI && NetworkConnected()) + if ( + #ifdef HAS_ETHERNET + eth_wifi_mode == WIFI && + #endif + NetworkConnected()) { addRowLabel(F("Wifi")); # if defined(ESP8266) @@ -381,7 +384,6 @@ void handle_sysinfo_Network() { { uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; -// TODO: PKR: Change to NetworkMacAddress uint8_t *macread = WiFi.macAddress(mac); char macaddress[20]; formatMAC(macread, macaddress); diff --git a/src/WebServer_ToolsPage.ino b/src/WebServer_ToolsPage.ino index dfffe2643..3d1824e58 100644 --- a/src/WebServer_ToolsPage.ino +++ b/src/WebServer_ToolsPage.ino @@ -73,7 +73,6 @@ void handle_tools() { addFormSubHeader(F("Wifi")); -// TODO: PKR: Add commands for ETHERNET addWideButtonPlusDescription(F("/?cmd=wificonnect"), F("Connect"), F("Connects to known Wifi network")); addWideButtonPlusDescription(F("/?cmd=wifidisconnect"), F("Disconnect"), F("Disconnect from wifi network")); diff --git a/src/_C014.ino b/src/_C014.ino index abfafe828..1e668d252 100644 --- a/src/_C014.ino +++ b/src/_C014.ino @@ -246,7 +246,6 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& CPlugin_014_sendMQTTdevice(pubname,"$localip",formatIP(NetworkLocalIP()).c_str(),errorCounter); // $mac Device → Controller Mac address of the device network interface. The format MUST be of the type A1:B2:C3:D4:E5:F6 Yes Yes - // TODO: PKR: Change to NetworkMacAddress CPlugin_014_sendMQTTdevice(pubname,"$mac",WiFi.macAddress().c_str(),errorCounter); // $implementation Device → Controller An identifier for the Homie implementation (example esp8266) Yes Yes diff --git a/src/src/DataStructs/ESPEasyDefaults.h b/src/src/DataStructs/ESPEasyDefaults.h index fb3068d2f..8bf9fcf67 100644 --- a/src/src/DataStructs/ESPEasyDefaults.h +++ b/src/src/DataStructs/ESPEasyDefaults.h @@ -190,7 +190,7 @@ #define DEFAULT_ETH_CLOCK_MODE 0 #endif #ifndef DEFAULT_ETH_WIFI_MODE -#define DEFAULT_ETH_WIFI_MODE 1 // TODO: PKR: Change perhaps to 0 +#define DEFAULT_ETH_WIFI_MODE 0 // 0 WIFI // 1 ETHERNET #endif diff --git a/src/src/Helpers/SystemVariables.cpp b/src/src/Helpers/SystemVariables.cpp index 4963d644c..1aab35692 100644 --- a/src/src/Helpers/SystemVariables.cpp +++ b/src/src/Helpers/SystemVariables.cpp @@ -89,6 +89,7 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode) case ISNTP: value = String(statusNTPInitialized); break; case ISWIFI: value = String(wifiStatus); break; // 0=disconnected, 1=connected, 2=got ip, 3=services initialized + // TODO: PKR: Add ETH Objects #ifdef HAS_ETHERNET case ETH_WIFI_MODE: value = (eth_wifi_mode == WIFI ? "WIFI" : "ETHERNET"); break; // 0=WIFI, 1=ETH case ETH_CONNECTED: value = String(eth_connected); break; // 0=disconnected, 1=connected @@ -247,6 +248,7 @@ String SystemVariables::toString(SystemVariables::Enum enumval) case Enum::ISMQTTIMP: return F("%ismqttimp%"); case Enum::ISNTP: return F("%isntp%"); case Enum::ISWIFI: return F("%iswifi%"); + // TODO: PKR: Add ETH Objects #ifdef HAS_ETHERNET case Enum::ETH_WIFI_MODE: return F("%eth_wifi_mode%"); case Enum::ETH_CONNECTED: return F("%eth_connected%"); From 845d25621a0c0c62abb851a691b33be5b676e5f9 Mon Sep 17 00:00:00 2001 From: tonhuisman Date: Mon, 27 Apr 2020 11:26:48 +0200 Subject: [PATCH 024/128] [P064] Gesture - APDS-9960 plugin: Added switching plugin mode and settings to fine-tune without recompiling source [APDS-9960 library] Added extensions and applied fixes from original Github project (including not merged yet improvements) [P064] Added/updated documentation for Gesture - APDS-9960 plugin [Documentation] Updated footer copyright notice to show 2018..2020 --- docs/source/Plugin/P064.rst | 40 +++- .../Plugin/_plugin_substitutions_p06x.repl | 4 +- docs/source/conf.py | 2 +- .../src/SparkFun_APDS9960.cpp | 66 +++++-- .../src/SparkFun_APDS9960.h | 8 + src/_P064_APDS9960.ino | 173 ++++++++++++++---- 6 files changed, 242 insertions(+), 51 deletions(-) diff --git a/docs/source/Plugin/P064.rst b/docs/source/Plugin/P064.rst index 0e6c6b9d9..9100cbe81 100644 --- a/docs/source/Plugin/P064.rst +++ b/docs/source/Plugin/P064.rst @@ -1,4 +1,4 @@ -.. include:: ../Plugin/_plugin_substitutions_p06x.repl +.. include:: ../Plugin/_plugin_substitutions_p06x.repl .. _P064_page: |P064_typename| @@ -21,6 +21,44 @@ Maintainer: |P064_maintainer| Used libraries: |P064_usedlibraries| +Description +----------- + +The APDS9960 sensor provides Gesture, Proximity and Ambient Light data or R/G/B color values from the light sensor, depending on the Plugin Mode. After changing the Plugin Mode, the Values arguments may need to be adjusted according to their function (Gesture, Proximity, Light or R, G, B). If the initial Values names are used, they will be replaced when switching the Plugin Mode, and the settings are actually saved. + +There is only 1 I2C address available for this sensor, so that default value is shown. + +The Gain, LED Drive and LED Boost parameters may need adjustment from the defaults as some of the low-cost clone sensors aren't as carefully calibrated as the original SparkFun or AdaFruit sensors. The suggested defaults are taken from the original SparkFun driver software settings. When first configuring this plugin it is advised to start with these default settings, and adjust when the sensor isn't responding as required. + +For the R/G/B Colors mode, only Light Sensor Gain and Light Sensor LED Drive parameters are available. They correspond with the Ambient Light Sensor Gain and Proximity/ALS LED Drive parameters (and use the same settings storage), but with different labels. + +NB: Defaults are *not* automatically set after adding the plugin! + +Gesture parameters +------------------ + +Gesture Gain: Selection of the gain factor, select from 1x, 2x, 4x (default) or 8x. + +Gesture LED Drive: Selection of the current to drive the Gesture IR LED, select from 100 mA (default), 50 mA, 25 mA or 12.5 mA. + +Gesture LED Boost: Selection of the LED Boost factor, select from 100%, 150%, 200% or 300% (default). + +Proximity & Ambient Light Sensor parameters +------------------------------------------- + +Proximity Gain: Selection of the gain factor, select from 1x, 2x, 4x (default) or 8x. + +Ambient Light Sensor Gain: Selection of the gain factor, select from 1x, 2x, 4x (default) or 8x. + +Proximity/ALS LED Drive: Selection of the current to drive the Proximity/Ambient Light Sensor IR LED, select from 100 mA (default), 50 mA, 25 mA or 12.5 mA. + +R/G/B Colors parameters +----------------------- + +Light Sensor Gain: Selection of the gain factor, select from 1x, 2x, 4x (default) or 8x. + +Light Sensor LED Drive: Selection of the current to drive the Light Sensor IR LED, select from 100 mA (default), 50 mA, 25 mA or 12.5 mA. + Supported hardware ------------------ diff --git a/docs/source/Plugin/_plugin_substitutions_p06x.repl b/docs/source/Plugin/_plugin_substitutions_p06x.repl index 1253c0137..05dfba88c 100644 --- a/docs/source/Plugin/_plugin_substitutions_p06x.repl +++ b/docs/source/Plugin/_plugin_substitutions_p06x.repl @@ -52,7 +52,7 @@ .. |P064_name| replace:: :cyan:`APDS9960` .. |P064_type| replace:: :cyan:`Gesture` -.. |P064_typename| replace:: :cyan:`Gestrure - APDS9960` +.. |P064_typename| replace:: :cyan:`Gesture - APDS9960` .. |P064_porttype| replace:: `.` .. |P064_status| replace:: :red:`DEVELOPMENT` .. |P064_github| replace:: P064_APDS9960.ino @@ -61,7 +61,7 @@ .. |P064_shortinfo| replace:: `.` .. |P064_maintainer| replace:: `.` .. |P064_compileinfo| replace:: `.` -.. |P064_usedlibraries| replace:: `.` +.. |P064_usedlibraries| replace:: https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor (extended and improved) .. |P065_name| replace:: :cyan:`DFPlayer-Mini MP3` .. |P065_type| replace:: :cyan:`Notify` diff --git a/docs/source/conf.py b/docs/source/conf.py index b7db5f66e..672f6e3bc 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -21,7 +21,7 @@ import sphinx_bootstrap_theme # -- Project information ----------------------------------------------------- project = u'ESP Easy' -copyright = u'2018, ESP Easy' +copyright = u'2018..2020, ESP Easy' author = u'Grovkillen, TD-er & Friends' # The short X.Y version diff --git a/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.cpp b/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.cpp index f11ec50ec..8eeef6f16 100644 --- a/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.cpp +++ b/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.cpp @@ -9,6 +9,12 @@ * This library interfaces the Avago APDS-9960 to Arduino over I2C. The library * relies on the Arduino Wire (I2C) library. to use the library, instantiate an * APDS9960 object, call init(), and call the appropriate functions. + * + * Original library can be found here: https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor + * + * 2020-04-27 tonhuisman + * - Added fixes suggested in original library (PR25) + * - Applied suggested improvement, but not yet fixed issue #23 * * APDS-9960 current draw tests (default parameters): * Off: 1mA @@ -37,6 +43,11 @@ SparkFun_APDS9960::SparkFun_APDS9960() gesture_state_ = 0; gesture_motion_ = DIR_NONE; + + gesture_gain_ = 0; + proximity_gain_ = 0; + proximity_ldrive_ = 0; + ambient_gain_ = 0; } /** @@ -53,6 +64,21 @@ SparkFun_APDS9960::~SparkFun_APDS9960() * @return True if initialized successfully. False otherwise. */ bool SparkFun_APDS9960::init() +{ + return init(DEFAULT_GGAIN, DEFAULT_GLDRIVE, DEFAULT_AGAIN, DEFAULT_PGAIN, DEFAULT_LDRIVE); +} + +/** + * @brief Configures I2C communications and initializes registers to defaults + * + * @param[in] ggain Gesture gain constant (0..3) + * @param[in] gldrive Gesture Led Drive constant (0..3) + * @param[in] again Ambient Light Sensor gain constant (0..3) + * @param[in] pgain Proximity gain constant (0..3) + * @param[in] ldrive Proximity and Ambient Light Sensor Led Drive constant (0..3) + * @return True if initialized successfully. False otherwise. + */ +bool SparkFun_APDS9960::init(uint8_t ggain, uint8_t gldrive, uint8_t again, uint8_t pgain, uint8_t led_drive) { uint8_t id; @@ -63,7 +89,7 @@ bool SparkFun_APDS9960::init() if( !wireReadDataByte(APDS9960_ID, id) ) { return false; } - if( !(id == APDS9960_ID_1 || id == APDS9960_ID_2) ) { + if( !(id == APDS9960_ID_1 || id == APDS9960_ID_2 || id == APDS9960_ID_3) ) { // Add support for GY-9960LLC as requested in original library github return false; } @@ -91,15 +117,18 @@ bool SparkFun_APDS9960::init() if( !wireWriteDataByte(APDS9960_CONFIG1, DEFAULT_CONFIG1) ) { return false; } - if( !setLEDDrive(DEFAULT_LDRIVE) ) { + if( !setLEDDrive(led_drive) ) { return false; } - if( !setProximityGain(DEFAULT_PGAIN) ) { + proximity_ldrive_ = led_drive; + if( !setProximityGain(pgain) ) { return false; } - if( !setAmbientLightGain(DEFAULT_AGAIN) ) { + proximity_gain_ = pgain; + if( !setAmbientLightGain(again) ) { return false; } + ambient_gain_ = again; if( !setProxIntLowThresh(DEFAULT_PILT) ) { return false; } @@ -132,10 +161,11 @@ bool SparkFun_APDS9960::init() if( !wireWriteDataByte(APDS9960_GCONF1, DEFAULT_GCONF1) ) { return false; } - if( !setGestureGain(DEFAULT_GGAIN) ) { + if( !setGestureGain(ggain) ) { return false; } - if( !setGestureLEDDrive(DEFAULT_GLDRIVE) ) { + gesture_gain_ = ggain; + if( !setGestureLEDDrive(gldrive) ) { return false; } if( !setGestureWaitTime(DEFAULT_GWTIME) ) { @@ -266,7 +296,7 @@ bool SparkFun_APDS9960::enableLightSensor(bool interrupts) { /* Set default gain, interrupts, enable power, and enable sensor */ - if( !setAmbientLightGain(DEFAULT_AGAIN) ) { + if( !setAmbientLightGain(ambient_gain_) ) { return false; } if( interrupts ) { @@ -315,10 +345,10 @@ bool SparkFun_APDS9960::disableLightSensor() bool SparkFun_APDS9960::enableProximitySensor(bool interrupts) { /* Set default gain, LED, interrupts, enable power, and enable sensor */ - if( !setProximityGain(DEFAULT_PGAIN) ) { + if( !setProximityGain(proximity_gain_) ) { return false; } - if( !setLEDDrive(DEFAULT_LDRIVE) ) { + if( !setLEDDrive(proximity_ldrive_) ) { return false; } if( interrupts ) { @@ -363,7 +393,17 @@ bool SparkFun_APDS9960::disableProximitySensor() * @param[in] interrupts true to enable hardware external interrupt on gesture * @return True if engine enabled correctly. False on error. */ -bool SparkFun_APDS9960::enableGestureSensor(bool interrupts) +bool SparkFun_APDS9960::enableGestureSensor(bool interrupts) { + return enableGestureSensor(interrupts, LED_BOOST_300); +} +/** + * @brief Starts the gesture recognition engine on the APDS-9960 + * + * @param[in] interrupts true to enable hardware external interrupt on gesture + * @param[in] Led-boost value (0..3 = 100, 150, 200, 300%; 3 = default) + * @return True if engine enabled correctly. False on error. + */ +bool SparkFun_APDS9960::enableGestureSensor(bool interrupts, uint8_t led_boost) { /* Enable gesture mode @@ -379,7 +419,7 @@ bool SparkFun_APDS9960::enableGestureSensor(bool interrupts) if( !wireWriteDataByte(APDS9960_PPULSE, DEFAULT_GESTURE_PPULSE) ) { return false; } - if( !setLEDBoost(LED_BOOST_300) ) { + if( !setLEDBoost(led_boost) ) { return false; } if( interrupts ) { @@ -464,9 +504,9 @@ bool SparkFun_APDS9960::isGestureAvailable() int SparkFun_APDS9960::readGesture() { uint8_t fifo_level = 0; - uint8_t bytes_read = 0; uint8_t fifo_data[128]; uint8_t gstatus; + int bytes_read = 0; // Fixed Issue #23 reported in original library source int motion; int i; @@ -2267,7 +2307,7 @@ bool SparkFun_APDS9960::wireWriteDataBlock( uint8_t reg, Wire.beginTransmission(APDS9960_I2C_ADDR); Wire.write(reg); for(i = 0; i < len; i++) { - Wire.beginTransmission(val[i]); + Wire.write(val[i]); // Improvement suggested by Koepel in issue #24 in original library } if( Wire.endTransmission() != 0 ) { return false; diff --git a/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.h b/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.h index 81a8cfc6a..74cc2b067 100644 --- a/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.h +++ b/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.h @@ -33,6 +33,7 @@ /* Acceptable device IDs */ #define APDS9960_ID_1 0xAB #define APDS9960_ID_2 0x9C +#define APDS9960_ID_3 0xA8 // Add support for GY-9960LLC as requested in original library github /* Misc parameters */ #define FIFO_PAUSE_TIME 30 // Wait period (ms) between FIFO reads @@ -223,6 +224,7 @@ public: SparkFun_APDS9960(); ~SparkFun_APDS9960(); bool init(); + bool init(uint8_t ggain, uint8_t gldrive, uint8_t again, uint8_t pgain, uint8_t led_drive); uint8_t getMode(); bool setMode(uint8_t mode, uint8_t enable); @@ -236,6 +238,7 @@ public: bool enableProximitySensor(bool interrupts = false); bool disableProximitySensor(); bool enableGestureSensor(bool interrupts = true); + bool enableGestureSensor(bool interrupts, uint8_t led_boost); bool disableGestureSensor(); /* LED drive strength control */ @@ -344,6 +347,11 @@ private: int gesture_far_count_; int gesture_state_; int gesture_motion_; + + uint8_t gesture_gain_; + uint8_t proximity_gain_; + uint8_t proximity_ldrive_; + uint8_t ambient_gain_; }; #endif diff --git a/src/_P064_APDS9960.ino b/src/_P064_APDS9960.ino index 53f6bffdd..f549a82a0 100644 --- a/src/_P064_APDS9960.ino +++ b/src/_P064_APDS9960.ino @@ -14,6 +14,11 @@ // Note: The chip has a wide view-of-angle. If housing is in this angle the chip blocks! +// 2020-04-25 tonhuisman: Added Plugin Mode setting to switch between Proximity/Ambient Light Sensor or R/G/B Colors. +// Added settings for Gain (Gesture, Proximity, Ambient Light Sensor), Led Power (Gesture and Proximity/ALS) and Led Boost (Gesture) +// to allow better tuning for use of the sensor. Also adapted the SparkFun_APDS9960 driver for enabling this. +// R/G/B Colors mode has it's settings shared with the Gesture/Proximity/ALS as they are the exact same parameters, but with different labels only. + #define PLUGIN_064 @@ -22,18 +27,19 @@ #define PLUGIN_VALUENAME1_064 "Gesture" #define PLUGIN_VALUENAME2_064 "Proximity" #define PLUGIN_VALUENAME3_064 "Light" -/* + #define PLUGIN_VALUENAME4_064 "R" #define PLUGIN_VALUENAME5_064 "G" #define PLUGIN_VALUENAME6_064 "B" -*/ + +#define PLUGIN_MODE_GPL_064 0 // GPL = Gesture/Proximity/(Ambient) Light Sensor mode +#define PLUGIN_MODE_RGB_064 1 // RGB = R/G/B Colors mode #include //Lib is modified to work with ESP #include "_Plugin_Helper.h" SparkFun_APDS9960* PLUGIN_064_pds = NULL; - boolean Plugin_064(byte function, struct EventStruct *event, String& string) { boolean success = false; @@ -65,14 +71,15 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) case PLUGIN_GET_DEVICEVALUENAMES: { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_064)); - /* - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[4], PSTR(PLUGIN_VALUENAME5_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[5], PSTR(PLUGIN_VALUENAME6_064)); - */ + if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { // Gesture/Proximity/ALS mode + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_064)); + } else { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME4_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME5_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME6_064)); + } break; } @@ -83,6 +90,86 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) int optionValues[1] = { 0x39 }; addFormSelectorI2C(F("i2c_addr"), 1, optionValues, addr); //Only for display I2C address + String optionsPluginMode[2]; + optionsPluginMode[0] = F("Gesture/Proximity/Ambient Light Sensor"); + optionsPluginMode[1] = F("R/G/B Colors"); + int optionsPluginModeValues[2] = {PLUGIN_MODE_GPL_064, PLUGIN_MODE_RGB_064}; + addFormSelector(F("Plugin Mode"), F("p064_mode"), 2, optionsPluginMode, optionsPluginModeValues, PCONFIG(1), true); + addFormNote(F("After changing Plugin Mode you may want to change the Values names, below.")); + + if (PCONFIG(1) == PLUGIN_MODE_RGB_064 // R/G/B Colors mode and default Gesture/Proximity/ALS values: Set new default names + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_064)) == 0 + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_064)) == 0 + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_064)) == 0) { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME4_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME5_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME6_064)); + } + if (PCONFIG(1) == PLUGIN_MODE_GPL_064 // Gesture/Proximity/ALS mode and default R/G/B values: Set new default names + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME4_064)) == 0 + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME5_064)) == 0 + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME6_064)) == 0) { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_064)); + } + + // Gain options, multiple gain optionsets in SparkFun_APDS9960.h have the same valueset, so only defined once here + String optionsGain[4]; + optionsGain[0] = F("1x"); + optionsGain[1] = F("2x"); + optionsGain[2] = F("4x (default)"); + optionsGain[3] = F("8x"); + int optionsGainValues[4] = {PGAIN_1X, PGAIN_2X, PGAIN_4X, PGAIN_8X}; // Also used for optionsALSGain + // Ambient Light Sensor Gain options, values are equal to PGAIN values, so again avoid duplication + String optionsALSGain[4]; + optionsALSGain[0] = F("1x"); + optionsALSGain[1] = F("4x (default)"); + optionsALSGain[2] = F("16x"); + optionsALSGain[3] = F("64x"); + // Led_Drive options, all Led_Drive optionsets in SparkFun_APDS9960.h have the same valueset, so only defined once here + String optionsLedDrive[4]; + optionsLedDrive[0] = F("100 mA (default)"); + optionsLedDrive[1] = F("50 mA"); + optionsLedDrive[2] = F("25 mA"); + optionsLedDrive[3] = F("12.5 mA"); + int optionsLedDriveValues[4] = {LED_DRIVE_100MA, LED_DRIVE_50MA, LED_DRIVE_25MA, LED_DRIVE_12_5MA}; + // Gesture Led-boost values + String optionsLedBoost[4]; + optionsLedBoost[0] = F("100 %"); + optionsLedBoost[1] = F("150 %"); + optionsLedBoost[2] = F("200 %"); + optionsLedBoost[3] = F("300 % (default)"); + int optionsLedBoostValues[4] = {LED_BOOST_100, LED_BOOST_150, LED_BOOST_200, LED_BOOST_300}; + + String lightSensorGainLabel; + String lightSensorDriveLabel; + + if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { // Gesture/Proximity/ALS mode + addFormSubHeader(F("Gesture parameters")); + + addFormSelector(F("Gesture Gain"), F("p064_ggain"), 4, optionsGain, optionsGainValues, PCONFIG(2)); + + addFormSelector(F("Gesture LED Drive"), F("p064_gldrive"), 4, optionsLedDrive, optionsLedDriveValues, PCONFIG(3)); + + addFormSelector(F("Gesture LED Boost"), F("p064_lboost"), 4, optionsLedBoost, optionsLedBoostValues, PCONFIG(4)); + + addFormSubHeader(F("Proximity & Ambient Light Sensor parameters")); + + addFormSelector(F("Proximity Gain"), F("p064_pgain"), 4, optionsGain, optionsGainValues, PCONFIG(5)); + + lightSensorGainLabel = F("Ambient Light Sensor Gain"); + lightSensorDriveLabel = F("Proximity & ALS LED Drive"); + } else { + addFormSubHeader(F("R/G/B Colors parameters")); + + lightSensorGainLabel = F("Light Sensor Gain"); + lightSensorDriveLabel = F("Light Sensor LED Drive"); + } + addFormSelector(lightSensorGainLabel, F("p064_again"), 4, optionsALSGain, optionsGainValues, PCONFIG(6)); + + addFormSelector(lightSensorDriveLabel, F("p064_ldrive"), 4, optionsLedDrive, optionsLedDriveValues, PCONFIG(7)); + success = true; break; } @@ -91,6 +178,16 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) { //PCONFIG(0) = getFormItemInt(F("i2c_addr")); + PCONFIG(1) = getFormItemInt(F("p064_mode")); + if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { + PCONFIG(2) = getFormItemInt(F("p064_ggain")); + PCONFIG(3) = getFormItemInt(F("p064_gldrive")); + PCONFIG(4) = getFormItemInt(F("p064_lboost")); + PCONFIG(5) = getFormItemInt(F("p064_pgain")); + } + PCONFIG(6) = getFormItemInt(F("p064_again")); + PCONFIG(7) = getFormItemInt(F("p064_ldrive")); + success = true; break; } @@ -102,7 +199,7 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) PLUGIN_064_pds = new SparkFun_APDS9960(); String log = F("APDS : "); - if ( PLUGIN_064_pds->init() ) + if (PLUGIN_064_pds->init(PCONFIG(2), PCONFIG(3), PCONFIG(5), PCONFIG(6), PCONFIG(7)) ) { log += F("Init"); @@ -110,17 +207,24 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) if (! PLUGIN_064_pds->enableLightSensor(false)) log += F(" - Error during light sensor init!"); - if (! PLUGIN_064_pds->enableProximitySensor(false)) - log += F(" - Error during proximity sensor init!"); + if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { // Gesture/Proximity/ALS mode + if (! PLUGIN_064_pds->enableProximitySensor(false)) + log += F(" - Error during proximity sensor init!"); - if (! PLUGIN_064_pds->enableGestureSensor(false)) - log += F(" - Error during gesture sensor init!"); + if (! PLUGIN_064_pds->enableGestureSensor(false, PCONFIG(4))) + log += F(" - Error during gesture sensor init!"); + } } else { log += F("Error during APDS-9960 init!"); } + // Forced reset values + UserVar[event->BaseVarIndex + 0] = 0.0; + UserVar[event->BaseVarIndex + 1] = 0.0; + UserVar[event->BaseVarIndex + 2] = 0.0; + addLog(LOG_LEVEL_INFO, log); success = true; break; @@ -131,7 +235,7 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) if (!PLUGIN_064_pds) break; - if ( !PLUGIN_064_pds->isGestureAvailable() ) + if (PCONFIG(1) != PLUGIN_MODE_GPL_064 || !PLUGIN_064_pds->isGestureAvailable() ) break; int gesture = PLUGIN_064_pds->readGesture(); @@ -182,25 +286,26 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) if (1) { - uint8_t proximity_data = 0; - PLUGIN_064_pds->readProximity(proximity_data); - UserVar[event->BaseVarIndex + 1] = (float)proximity_data; + if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { // Gesture/Proximity/ALS mode + uint8_t proximity_data = 0; + PLUGIN_064_pds->readProximity(proximity_data); + UserVar[event->BaseVarIndex + 1] = (float)proximity_data; - uint16_t ambient_light = 0; - PLUGIN_064_pds->readAmbientLight(ambient_light); - UserVar[event->BaseVarIndex + 2] = (float)ambient_light; + uint16_t ambient_light = 0; + PLUGIN_064_pds->readAmbientLight(ambient_light); + UserVar[event->BaseVarIndex + 2] = (float)ambient_light; - /* - uint16_t red_light = 0; - uint16_t green_light = 0; - uint16_t blue_light = 0; - PLUGIN_064_pds->readRedLight(red_light); - PLUGIN_064_pds->readGreenLight(green_light); - PLUGIN_064_pds->readBlueLight(blue_light); - UserVar[event->BaseVarIndex + 3] = (float)red_light; - UserVar[event->BaseVarIndex + 4] = (float)green_light; - UserVar[event->BaseVarIndex + 5] = (float)blue_light; - */ + } else { + uint16_t red_light = 0; + uint16_t green_light = 0; + uint16_t blue_light = 0; + PLUGIN_064_pds->readRedLight(red_light); + PLUGIN_064_pds->readGreenLight(green_light); + PLUGIN_064_pds->readBlueLight(blue_light); + UserVar[event->BaseVarIndex + 0] = (float)red_light; + UserVar[event->BaseVarIndex + 1] = (float)green_light; + UserVar[event->BaseVarIndex + 2] = (float)blue_light; + } } success = true; From 8f83091d04e173330b4a840c960db00059ca8127 Mon Sep 17 00:00:00 2001 From: tonhuisman Date: Mon, 27 Apr 2020 20:36:09 +0200 Subject: [PATCH 025/128] [P064] Made code-readability and other improvements as TD-er suggested, fixed a swapped argument bug --- .../src/SparkFun_APDS9960.cpp | 6 +- .../src/SparkFun_APDS9960.h | 2 +- src/_P064_APDS9960.ino | 149 ++++++++++-------- 3 files changed, 86 insertions(+), 71 deletions(-) diff --git a/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.cpp b/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.cpp index 8eeef6f16..16526af66 100644 --- a/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.cpp +++ b/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.cpp @@ -65,7 +65,7 @@ SparkFun_APDS9960::~SparkFun_APDS9960() */ bool SparkFun_APDS9960::init() { - return init(DEFAULT_GGAIN, DEFAULT_GLDRIVE, DEFAULT_AGAIN, DEFAULT_PGAIN, DEFAULT_LDRIVE); + return init(DEFAULT_GGAIN, DEFAULT_GLDRIVE, DEFAULT_PGAIN, DEFAULT_AGAIN, DEFAULT_LDRIVE); } /** @@ -73,12 +73,12 @@ bool SparkFun_APDS9960::init() * * @param[in] ggain Gesture gain constant (0..3) * @param[in] gldrive Gesture Led Drive constant (0..3) - * @param[in] again Ambient Light Sensor gain constant (0..3) * @param[in] pgain Proximity gain constant (0..3) + * @param[in] again Ambient Light Sensor gain constant (0..3) * @param[in] ldrive Proximity and Ambient Light Sensor Led Drive constant (0..3) * @return True if initialized successfully. False otherwise. */ -bool SparkFun_APDS9960::init(uint8_t ggain, uint8_t gldrive, uint8_t again, uint8_t pgain, uint8_t led_drive) +bool SparkFun_APDS9960::init(uint8_t ggain, uint8_t gldrive, uint8_t pgain, uint8_t again, uint8_t led_drive) { uint8_t id; diff --git a/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.h b/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.h index 74cc2b067..d24885721 100644 --- a/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.h +++ b/lib/SparkFun_APDS-9960_Sensor_Arduino_Library/src/SparkFun_APDS9960.h @@ -224,7 +224,7 @@ public: SparkFun_APDS9960(); ~SparkFun_APDS9960(); bool init(); - bool init(uint8_t ggain, uint8_t gldrive, uint8_t again, uint8_t pgain, uint8_t led_drive); + bool init(uint8_t ggain, uint8_t gldrive, uint8_t pgain, uint8_t again, uint8_t led_drive); uint8_t getMode(); bool setMode(uint8_t mode, uint8_t enable); diff --git a/src/_P064_APDS9960.ino b/src/_P064_APDS9960.ino index f549a82a0..7c78cdb9b 100644 --- a/src/_P064_APDS9960.ino +++ b/src/_P064_APDS9960.ino @@ -22,18 +22,30 @@ #define PLUGIN_064 -#define PLUGIN_ID_064 64 -#define PLUGIN_NAME_064 "Gesture - APDS9960 [DEVELOPMENT]" -#define PLUGIN_VALUENAME1_064 "Gesture" -#define PLUGIN_VALUENAME2_064 "Proximity" -#define PLUGIN_VALUENAME3_064 "Light" +#define PLUGIN_ID_064 64 +#define PLUGIN_NAME_064 "Gesture - APDS9960 [DEVELOPMENT]" +#define PLUGIN_GPL_VALUENAME1_064 "Gesture" +#define PLUGIN_GPL_VALUENAME2_064 "Proximity" +#define PLUGIN_GPL_VALUENAME3_064 "Light" -#define PLUGIN_VALUENAME4_064 "R" -#define PLUGIN_VALUENAME5_064 "G" -#define PLUGIN_VALUENAME6_064 "B" +#define PLUGIN_RGB_VALUENAME1_064 "R" +#define PLUGIN_RGB_VALUENAME2_064 "G" +#define PLUGIN_RGB_VALUENAME3_064 "B" -#define PLUGIN_MODE_GPL_064 0 // GPL = Gesture/Proximity/(Ambient) Light Sensor mode -#define PLUGIN_MODE_RGB_064 1 // RGB = R/G/B Colors mode +#define PLUGIN_MODE_GPL_064 0 // GPL = Gesture/Proximity/(Ambient) Light Sensor mode +#define PLUGIN_MODE_RGB_064 1 // RGB = R/G/B Colors mode + +#define P064_ADDR PCONFIG(0) +#define P064_MODE PCONFIG(1) +#define P064_GGAIN PCONFIG(2) +#define P064_GLDRIVE PCONFIG(3) +#define P064_LED_BOOST PCONFIG(4) +#define P064_PGAIN PCONFIG(5) +#define P064_AGAIN PCONFIG(6) +#define P064_LDRIVE PCONFIG(7) + +#define P064_IS_GPL_SENSOR (P064_MODE == PLUGIN_MODE_GPL_064) +#define P064_IS_RGB_SENSOR (P064_MODE == PLUGIN_MODE_RGB_064) #include //Lib is modified to work with ESP #include "_Plugin_Helper.h" @@ -71,21 +83,21 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) case PLUGIN_GET_DEVICEVALUENAMES: { - if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { // Gesture/Proximity/ALS mode - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_064)); + if (P064_IS_GPL_SENSOR) { // Gesture/Proximity/ALS mode + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_GPL_VALUENAME1_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_GPL_VALUENAME2_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_GPL_VALUENAME3_064)); } else { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME4_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME5_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME6_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_RGB_VALUENAME1_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_RGB_VALUENAME2_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_RGB_VALUENAME3_064)); } break; } case PLUGIN_WEBFORM_LOAD: { - byte addr = 0x39; // PCONFIG(0); chip has only 1 address + byte addr = 0x39; // P064_ADDR; chip has only 1 address int optionValues[1] = { 0x39 }; addFormSelectorI2C(F("i2c_addr"), 1, optionValues, addr); //Only for display I2C address @@ -94,24 +106,32 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) optionsPluginMode[0] = F("Gesture/Proximity/Ambient Light Sensor"); optionsPluginMode[1] = F("R/G/B Colors"); int optionsPluginModeValues[2] = {PLUGIN_MODE_GPL_064, PLUGIN_MODE_RGB_064}; - addFormSelector(F("Plugin Mode"), F("p064_mode"), 2, optionsPluginMode, optionsPluginModeValues, PCONFIG(1), true); + addFormSelector(F("Plugin Mode"), F("p064_mode"), 2, optionsPluginMode, optionsPluginModeValues, P064_MODE, true); addFormNote(F("After changing Plugin Mode you may want to change the Values names, below.")); - if (PCONFIG(1) == PLUGIN_MODE_RGB_064 // R/G/B Colors mode and default Gesture/Proximity/ALS values: Set new default names - && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_064)) == 0 - && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_064)) == 0 - && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_064)) == 0) { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME4_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME5_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME6_064)); + if (P064_IS_RGB_SENSOR // R/G/B Colors mode and default Gesture/Proximity/ALS values: Set new default names + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_GPL_VALUENAME1_064)) == 0 + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_GPL_VALUENAME2_064)) == 0 + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_GPL_VALUENAME3_064)) == 0) { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_RGB_VALUENAME1_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_RGB_VALUENAME2_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_RGB_VALUENAME3_064)); + // Reset values + UserVar[event->BaseVarIndex + 0] = 0.0; + UserVar[event->BaseVarIndex + 1] = 0.0; + UserVar[event->BaseVarIndex + 2] = 0.0; } - if (PCONFIG(1) == PLUGIN_MODE_GPL_064 // Gesture/Proximity/ALS mode and default R/G/B values: Set new default names - && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME4_064)) == 0 - && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME5_064)) == 0 - && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME6_064)) == 0) { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_064)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_064)); + if (P064_IS_GPL_SENSOR // Gesture/Proximity/ALS mode and default R/G/B values: Set new default names + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_RGB_VALUENAME1_064)) == 0 + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_RGB_VALUENAME2_064)) == 0 + && strcmp_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_RGB_VALUENAME3_064)) == 0) { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_GPL_VALUENAME1_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_GPL_VALUENAME2_064)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_GPL_VALUENAME3_064)); + // Reset values + UserVar[event->BaseVarIndex + 0] = 0.0; + UserVar[event->BaseVarIndex + 1] = 0.0; + UserVar[event->BaseVarIndex + 2] = 0.0; } // Gain options, multiple gain optionsets in SparkFun_APDS9960.h have the same valueset, so only defined once here @@ -145,30 +165,30 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) String lightSensorGainLabel; String lightSensorDriveLabel; - if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { // Gesture/Proximity/ALS mode + if (P064_IS_GPL_SENSOR) { // Gesture/Proximity/ALS mode addFormSubHeader(F("Gesture parameters")); - addFormSelector(F("Gesture Gain"), F("p064_ggain"), 4, optionsGain, optionsGainValues, PCONFIG(2)); + addFormSelector(F("Gesture Gain"), F("p064_ggain"), 4, optionsGain, optionsGainValues, P064_GGAIN); - addFormSelector(F("Gesture LED Drive"), F("p064_gldrive"), 4, optionsLedDrive, optionsLedDriveValues, PCONFIG(3)); + addFormSelector(F("Gesture LED Drive"), F("p064_gldrive"), 4, optionsLedDrive, optionsLedDriveValues, P064_GLDRIVE); - addFormSelector(F("Gesture LED Boost"), F("p064_lboost"), 4, optionsLedBoost, optionsLedBoostValues, PCONFIG(4)); + addFormSelector(F("Gesture LED Boost"), F("p064_lboost"), 4, optionsLedBoost, optionsLedBoostValues, P064_LED_BOOST); addFormSubHeader(F("Proximity & Ambient Light Sensor parameters")); - addFormSelector(F("Proximity Gain"), F("p064_pgain"), 4, optionsGain, optionsGainValues, PCONFIG(5)); + addFormSelector(F("Proximity Gain"), F("p064_pgain"), 4, optionsGain, optionsGainValues, P064_PGAIN); - lightSensorGainLabel = F("Ambient Light Sensor Gain"); + lightSensorGainLabel = F("Ambient Light Sensor Gain"); lightSensorDriveLabel = F("Proximity & ALS LED Drive"); } else { addFormSubHeader(F("R/G/B Colors parameters")); - lightSensorGainLabel = F("Light Sensor Gain"); + lightSensorGainLabel = F("Light Sensor Gain"); lightSensorDriveLabel = F("Light Sensor LED Drive"); } - addFormSelector(lightSensorGainLabel, F("p064_again"), 4, optionsALSGain, optionsGainValues, PCONFIG(6)); + addFormSelector(lightSensorGainLabel, F("p064_again"), 4, optionsALSGain, optionsGainValues, P064_AGAIN); - addFormSelector(lightSensorDriveLabel, F("p064_ldrive"), 4, optionsLedDrive, optionsLedDriveValues, PCONFIG(7)); + addFormSelector(lightSensorDriveLabel, F("p064_ldrive"), 4, optionsLedDrive, optionsLedDriveValues, P064_LDRIVE); success = true; break; @@ -176,17 +196,17 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) case PLUGIN_WEBFORM_SAVE: { - //PCONFIG(0) = getFormItemInt(F("i2c_addr")); + // P064_ADDR = getFormItemInt(F("i2c_addr")); - PCONFIG(1) = getFormItemInt(F("p064_mode")); - if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { - PCONFIG(2) = getFormItemInt(F("p064_ggain")); - PCONFIG(3) = getFormItemInt(F("p064_gldrive")); - PCONFIG(4) = getFormItemInt(F("p064_lboost")); - PCONFIG(5) = getFormItemInt(F("p064_pgain")); + P064_MODE = getFormItemInt(F("p064_mode")); + if (P064_IS_GPL_SENSOR) { + P064_GGAIN = getFormItemInt(F("p064_ggain")); + P064_GLDRIVE = getFormItemInt(F("p064_gldrive")); + P064_LED_BOOST = getFormItemInt(F("p064_lboost")); + P064_PGAIN = getFormItemInt(F("p064_pgain")); } - PCONFIG(6) = getFormItemInt(F("p064_again")); - PCONFIG(7) = getFormItemInt(F("p064_ldrive")); + P064_AGAIN = getFormItemInt(F("p064_again")); + P064_LDRIVE = getFormItemInt(F("p064_ldrive")); success = true; break; @@ -199,7 +219,7 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) PLUGIN_064_pds = new SparkFun_APDS9960(); String log = F("APDS : "); - if (PLUGIN_064_pds->init(PCONFIG(2), PCONFIG(3), PCONFIG(5), PCONFIG(6), PCONFIG(7)) ) + if (PLUGIN_064_pds->init(P064_GGAIN, P064_GLDRIVE, P064_PGAIN, P064_AGAIN, P064_LDRIVE) ) { log += F("Init"); @@ -207,11 +227,11 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) if (! PLUGIN_064_pds->enableLightSensor(false)) log += F(" - Error during light sensor init!"); - if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { // Gesture/Proximity/ALS mode + if (P064_IS_GPL_SENSOR) { // Gesture/Proximity/ALS mode if (! PLUGIN_064_pds->enableProximitySensor(false)) log += F(" - Error during proximity sensor init!"); - if (! PLUGIN_064_pds->enableGestureSensor(false, PCONFIG(4))) + if (! PLUGIN_064_pds->enableGestureSensor(false, P064_LED_BOOST)) log += F(" - Error during gesture sensor init!"); } } @@ -220,11 +240,6 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) log += F("Error during APDS-9960 init!"); } - // Forced reset values - UserVar[event->BaseVarIndex + 0] = 0.0; - UserVar[event->BaseVarIndex + 1] = 0.0; - UserVar[event->BaseVarIndex + 2] = 0.0; - addLog(LOG_LEVEL_INFO, log); success = true; break; @@ -235,7 +250,7 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) if (!PLUGIN_064_pds) break; - if (PCONFIG(1) != PLUGIN_MODE_GPL_064 || !PLUGIN_064_pds->isGestureAvailable() ) + if (P064_MODE != PLUGIN_MODE_GPL_064 || !PLUGIN_064_pds->isGestureAvailable() ) break; int gesture = PLUGIN_064_pds->readGesture(); @@ -265,7 +280,7 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) log += gesture; log += ')'; - UserVar[event->BaseVarIndex] = (float)gesture; + UserVar[event->BaseVarIndex] = static_cast(gesture); event->sensorType = SENSOR_TYPE_SWITCH; sendData(event); @@ -286,14 +301,14 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) if (1) { - if (PCONFIG(1) == PLUGIN_MODE_GPL_064) { // Gesture/Proximity/ALS mode + if (P064_IS_GPL_SENSOR) { // Gesture/Proximity/ALS mode uint8_t proximity_data = 0; PLUGIN_064_pds->readProximity(proximity_data); - UserVar[event->BaseVarIndex + 1] = (float)proximity_data; + UserVar[event->BaseVarIndex + 1] = static_cast(proximity_data); uint16_t ambient_light = 0; PLUGIN_064_pds->readAmbientLight(ambient_light); - UserVar[event->BaseVarIndex + 2] = (float)ambient_light; + UserVar[event->BaseVarIndex + 2] = static_cast(ambient_light); } else { uint16_t red_light = 0; @@ -302,9 +317,9 @@ boolean Plugin_064(byte function, struct EventStruct *event, String& string) PLUGIN_064_pds->readRedLight(red_light); PLUGIN_064_pds->readGreenLight(green_light); PLUGIN_064_pds->readBlueLight(blue_light); - UserVar[event->BaseVarIndex + 0] = (float)red_light; - UserVar[event->BaseVarIndex + 1] = (float)green_light; - UserVar[event->BaseVarIndex + 2] = (float)blue_light; + UserVar[event->BaseVarIndex + 0] = static_cast(red_light); + UserVar[event->BaseVarIndex + 1] = static_cast(green_light); + UserVar[event->BaseVarIndex + 2] = static_cast(blue_light); } } From a6f75806f0e133631398940963ad1b3c6f38aee3 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Mon, 27 Apr 2020 21:59:21 +0200 Subject: [PATCH 026/128] - Ethernet Commands - remove useless comments - ETH.config moved after ETH.begin - Added note: Be aware with ESPEasyP2P Network, since IP Address will change. There could be conflicts. - Ethernet JSON - Ethernet Variables --- src/Command.ino | 13 ++++++ src/ESPEasyEth.ino | 38 +++--------------- src/StringProvider.ino | 23 ++++++----- src/StringProviderTypes.h | 1 + src/WebServer_HardwarePage.ino | 1 + src/WebServer_JSON.ino | 18 +++++++++ src/WebServer_SysInfoPage.ino | 11 +++++ src/WebServer_SysVarPage.ino | 17 ++++++-- src/src/Commands/Common.cpp | 60 ++++++++++++++++++++++++++++ src/src/Commands/Common.h | 12 ++++++ src/src/Commands/Networks.cpp | 62 ++++++++++++++++++++++++++++- src/src/Commands/Networks.h | 11 +++++ src/src/Helpers/SystemVariables.cpp | 28 ++++++++++--- src/src/Helpers/SystemVariables.h | 14 ++++++- 14 files changed, 252 insertions(+), 57 deletions(-) diff --git a/src/Command.ino b/src/Command.ino index d43feabfd..57b7f2460 100644 --- a/src/Command.ino +++ b/src/Command.ino @@ -168,6 +168,19 @@ bool executeInternalCommand(const char *cmd, struct EventStruct *event, const ch break; } case 'e': { + #ifdef HAS_ETHERNET + COMMAND_CASE( "ethphyadr", Command_ETH_Phy_Addr, 1); // Network Command + COMMAND_CASE( "ethpinmdc", Command_ETH_Pin_mdc, 1); // Network Command + COMMAND_CASE( "ethpinmdio", Command_ETH_Pin_mdio, 1); // Network Command + COMMAND_CASE( "ethpinpower", Command_ETH_Pin_power, 1); // Network Command + COMMAND_CASE( "ethphytype", Command_ETH_Phy_Type, 1); // Network Command + COMMAND_CASE("ethclockmode", Command_ETH_Clock_Mode, 1); // Network Command + COMMAND_CASE( "ethip", Command_ETH_IP, 1); // Network Command + COMMAND_CASE( "ethgateway", Command_ETH_Gateway, 1); // Network Command + COMMAND_CASE( "ethsubnet", Command_ETH_Subnet, 1); // Network Command + COMMAND_CASE( "ethdns", Command_ETH_DNS, 1); // Network Command + COMMAND_CASE( "ethwifimode", Command_ETH_Wifi_Mode, 1); // Network Command + #endif // HAS_ETHERNET COMMAND_CASE("erasesdkwifi", Command_WiFi_Erase, 0); // WiFi.h COMMAND_CASE( "event", Command_Rules_Events, -1); // Rule.h COMMAND_CASE("executerules", Command_Rules_Execute, -1); // Rule.h diff --git a/src/ESPEasyEth.ino b/src/ESPEasyEth.ino index 4b002528f..11a9759ff 100644 --- a/src/ESPEasyEth.ino +++ b/src/ESPEasyEth.ino @@ -9,10 +9,6 @@ bool ethUseStaticIP() { } void ethSetupStaticIPconfig() { - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("ethSetupStaticIPConfig Started")); - //setUseStaticIP(useStaticIP()); - if (!ethUseStaticIP()) { return; } const IPAddress ip = Settings.ETH_IP; const IPAddress gw = Settings.ETH_Gateway; @@ -30,16 +26,10 @@ void ethSetupStaticIPconfig() { log += formatIP(dns); addLog(LOG_LEVEL_INFO, log); } - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("Before ETH.config")); ETH.config(ip, gw, subnet, dns); - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("After ETH.config")); } bool ethCheckSettings() { - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("ethCheckSettings Started")); bool result = true; if (Settings.ETH_Phy_Type != 0 && Settings.ETH_Phy_Type != 1) result = false; @@ -57,25 +47,17 @@ bool ethCheckSettings() { } bool ethPrepare() { - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("ethPrepare Started")); if (!ethCheckSettings()) { addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!")); return false; } - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("Before ETH.config")); ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("After ETH.conif")); ethSetupStaticIPconfig(); return true; } String ethGetDebugClockModeStr() { - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("ethDebugColckModeStr Started")); switch (Settings.ETH_Clock_Mode) { case 0: return F("ETH_CLOCK_GPIO0_IN"); @@ -87,8 +69,6 @@ String ethGetDebugClockModeStr() { } String ethGetDebugEthWifiModeStr() { - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("ethGetDebugEthWifiMode Started")); switch (eth_wifi_mode) { case 0: return F("WIFI"); @@ -98,8 +78,6 @@ String ethGetDebugEthWifiModeStr() { } void ethPrintSettings() { - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("ethPrintSettings Started")); String settingsDebugLog; settingsDebugLog.reserve(115); settingsDebugLog += F("Eth Wifi mode: "); @@ -120,25 +98,19 @@ void ethPrintSettings() { } void ETHConnectRelaxed() { - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("ETHConnectRelaxed Started")); ethPrintSettings(); - /*if (!ethPrepare()) { - // Dead code for now... - addLog(LOG_LEVEL_ERROR, F("ETH : Could not prepare ETH!")); - return; - } - // TODO: PKR Remove - addLog(LOG_LEVEL_INFO, F("Before ETH.begin")); ETH.begin(Settings.ETH_Phy_Addr, Settings.ETH_Pin_power, Settings.ETH_Pin_mdc, Settings.ETH_Pin_mdio, (eth_phy_type_t)Settings.ETH_Phy_Type, (eth_clock_mode_t)Settings.ETH_Clock_Mode); - // TODO: PKR Remove*/ - ETH.begin(); addLog(LOG_LEVEL_INFO, F("After ETH.begin")); + if (!ethPrepare()) { + // Dead code for now... + addLog(LOG_LEVEL_ERROR, F("ETH : Could not prepare ETH!")); + return; + } } bool ETHConnected() { diff --git a/src/StringProvider.ino b/src/StringProvider.ino index 947c0fcd7..fbe9602e3 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -109,6 +109,7 @@ String getLabel(LabelType::Enum label) { case LabelType::ETH_STATE: return F("Eth State"); case LabelType::ETH_SPEED_STATE: return F("Eth Speed State"); case LabelType::ETH_WIFI_MODE: return F("Eth Wifi Mode"); + case LabelType::ETH_CONNECTED: return F("Eth connected"); #endif } @@ -154,10 +155,11 @@ String getValue(LabelType::Enum label) { case LabelType::IP_CONFIG_STATIC: break; case LabelType::IP_CONFIG_DYNAMIC: break; case LabelType::IP_ADDRESS: return NetworkLocalIP().toString(); - case LabelType::IP_SUBNET: return WiFi.subnetMask().toString(); + case LabelType::IP_SUBNET: return NetworkSubnetMask().toString(); case LabelType::IP_ADDRESS_SUBNET: return String(getValue(LabelType::IP_ADDRESS) + F(" / ") + getValue(LabelType::IP_SUBNET)); case LabelType::GATEWAY: return NetworkGatewayIP().toString(); case LabelType::CLIENT_IP: return formatIP(web_server.client().remoteIP()); + #ifdef FEATURE_MDNS case LabelType::M_DNS: return String(WifiGetHostname()) + F(".local"); #endif @@ -215,17 +217,18 @@ String getValue(LabelType::Enum label) { case LabelType::OTA_2STEP: break; case LabelType::OTA_POSSIBLE: break; #ifdef HAS_ETHERNET - case LabelType::ETH_IP_ADDRESS: return ETH.localIP().toString(); - case LabelType::ETH_IP_SUBNET: return ETH.subnetMask().toString(); + case LabelType::ETH_IP_ADDRESS: return NetworkLocalIP().toString(); + case LabelType::ETH_IP_SUBNET: return NetworkSubnetMask().toString(); case LabelType::ETH_IP_ADDRESS_SUBNET: return String(getValue(LabelType::ETH_IP_ADDRESS) + F(" / ") + getValue(LabelType::ETH_IP_SUBNET)); - case LabelType::ETH_IP_GATEWAY: return ETH.gatewayIP().toString(); - case LabelType::ETH_IP_DNS: return ETH.dnsIP().toString(); - case LabelType::ETH_MAC: return ETH.macAddress(); - case LabelType::ETH_DUPLEX: return ETH.fullDuplex() ? F("Full Duplex") : F("Half Duplex"); - case LabelType::ETH_SPEED: return getEthSpeed(); - case LabelType::ETH_STATE: return ETH.linkUp() ? F("Link Up") : F("Link Down"); - case LabelType::ETH_SPEED_STATE: return getEthLinkSpeedState(); + case LabelType::ETH_IP_GATEWAY: return NetworkGatewayIP().toString(); + case LabelType::ETH_IP_DNS: return NetworkDnsIP().toString(); + case LabelType::ETH_MAC: return NetworkMacAddress(); + case LabelType::ETH_DUPLEX: return eth_connected ? (ETH.fullDuplex() ? F("Full Duplex") : F("Half Duplex")) : F("No Ethernet"); + case LabelType::ETH_SPEED: return eth_connected ? getEthSpeed() : F("No Ethernet"); + case LabelType::ETH_STATE: return eth_connected ? (ETH.linkUp() ? F("Link Up") : F("Link Down")) : F("No Ethernet"); + case LabelType::ETH_SPEED_STATE: return eth_connected ? getEthLinkSpeedState() : F("No Ethernet"); case LabelType::ETH_WIFI_MODE: return (eth_wifi_mode == WIFI ? F("WIFI") : F("ETHERNET")); + case LabelType::ETH_CONNECTED: return String(eth_connected); // 0=disconnected, 1=connected #endif } diff --git a/src/StringProviderTypes.h b/src/StringProviderTypes.h index 65f9373a4..0ced1ae16 100644 --- a/src/StringProviderTypes.h +++ b/src/StringProviderTypes.h @@ -109,6 +109,7 @@ enum Enum : short { ETH_STATE, ETH_SPEED_STATE, ETH_WIFI_MODE, + ETH_CONNECTED, #endif }; diff --git a/src/WebServer_HardwarePage.ino b/src/WebServer_HardwarePage.ino index f143be84d..71a5a2541 100644 --- a/src/WebServer_HardwarePage.ino +++ b/src/WebServer_HardwarePage.ino @@ -90,6 +90,7 @@ void handle_hardware() { String ethWifiOptions[2] = { F("WIFI"), F("ETHERNET") }; addSelector("ethwifi", 2, ethWifiOptions, NULL, NULL, Settings.ETH_Wifi_Mode, false, true); addFormNote(F("Change Switch between WIFI and ETHERNET requires reboot to activate")); + addFormNote(F("Be aware with ESPEasyP2P Network, since IP Address will change. There could be conflicts.")); addRowLabel_tr_id(F("Ethernet PHY type"), "ethtype"); String ethPhyTypes[2] = { F("LAN8710"), F("TLK110") }; addSelector("ethtype", 2, ethPhyTypes, NULL, NULL, Settings.ETH_Phy_Type, false, true); diff --git a/src/WebServer_JSON.ino b/src/WebServer_JSON.ino index 7e3ed9b04..b4364addc 100644 --- a/src/WebServer_JSON.ino +++ b/src/WebServer_JSON.ino @@ -13,6 +13,9 @@ void handle_json() const bool showSpecificTask = validTaskIndex(taskNr); bool showSystem = true; bool showWifi = true; + #ifdef HAS_ETHERNET + bool showEthernet = true; + #endif bool showDataAcquisition = true; bool showTaskDetails = true; bool showNodes = true; @@ -23,6 +26,9 @@ void handle_json() if (view == F("sensorupdate")) { showSystem = false; showWifi = false; + #ifdef HAS_ETHERNET + showEthernet = false; + #endif showDataAcquisition = false; showTaskDetails = false; showNodes = false; @@ -101,6 +107,18 @@ void handle_json() addHtml(F(",\n")); } + #ifdef HAS_ETHERNET + if (showEthernet) { + addHtml(F("\"Ethernet\":{\n")); + stream_next_json_object_value(LabelType::ETH_WIFI_MODE); + stream_next_json_object_value(LabelType::ETH_CONNECTED); + stream_next_json_object_value(LabelType::ETH_DUPLEX); + stream_next_json_object_value(LabelType::ETH_SPEED); + stream_next_json_object_value(LabelType::ETH_STATE); + stream_last_json_object_value(LabelType::ETH_SPEED_STATE); + } + #endif + if (showNodes) { bool comma_between = false; diff --git a/src/WebServer_SysInfoPage.ino b/src/WebServer_SysInfoPage.ino index b85f670e3..ebc5b6a29 100644 --- a/src/WebServer_SysInfoPage.ino +++ b/src/WebServer_SysInfoPage.ino @@ -87,6 +87,17 @@ void handle_sysinfo_json() { json_number(F("reconnects"), String(wifi_reconnects)); json_close(); +#ifdef HAS_ETHERNET + json_open(false, F("ethernet")); + json_prop(F("ethwifimode"), getValue(LabelType::ETH_WIFI_MODE)); + json_prop(F("ethconnected"), getValue(LabelType::ETH_CONNECTED); + json_prop(F("ethduplex"), getValue(LabelType::ETH_DUPLEX); + json_prop(F("ethspeed"), getValue(LabelType::ETH_SPEED); + json_prop(F("ethstate"), getValue(LabelType::ETH_STATE); + json_prop(F("ethspeedstate"), getValue(LabelType::ETH_SPEED_STATE); + json.close(); +#endif + json_open(false, F("firmware")); json_prop(F("build"), String(BUILD)); json_prop(F("notes"), F(BUILD_NOTES)); diff --git a/src/WebServer_SysVarPage.ino b/src/WebServer_SysVarPage.ino index a434381fe..f0e70f2e8 100644 --- a/src/WebServer_SysVarPage.ino +++ b/src/WebServer_SysVarPage.ino @@ -44,11 +44,24 @@ void handle_sysvars() { #endif // if defined(ESP8266) addSysVar_enum_html(SystemVariables::IP); addSysVar_enum_html(SystemVariables::IP4); + addSysVar_enum_html(SystemVariables::SUBNET); + addSysVar_enum_html(SystemVariables::GATEWAY); + addSysVar_enum_html(SystemVariables::DNS); addSysVar_enum_html(SystemVariables::RSSI); addSysVar_enum_html(SystemVariables::SSID); addSysVar_enum_html(SystemVariables::BSSID); addSysVar_enum_html(SystemVariables::WI_CH); +#ifdef HAS_ETHERNET + addTableSeparator(F("Ethernet"), 3, 3); + addSysVar_enum_html(SystemVariables::ETHWIFIMODE); + addSysVar_enum_html(SystemVariables::ETHCONNECTED); + addSysVar_enum_html(SystemVariables::ETHDUPLEX); + addSysVar_enum_html(SystemVariables::ETHSPEED); + addSysVar_enum_html(SystemVariables::ETHSTATE); + addSysVar_enum_html(SystemVariables::ETHSPEEDSTATE); + #endif + addTableSeparator(F("System"), 3, 3); addSysVar_enum_html(SystemVariables::UNIT_sysvar); addSysVar_enum_html(SystemVariables::SYSLOAD); @@ -62,10 +75,6 @@ void handle_sysvars() { addTableSeparator(F("System status"), 3, 3); addSysVar_enum_html(SystemVariables::ISWIFI); - #ifdef HAS_ETHERNET - addSysVar_enum_html(SystemVariables::ETH_WIFI_MODE); - addSysVar_enum_html(SystemVariables::ETH_CONNECTED); - #endif addSysVar_enum_html(SystemVariables::ISNTP); addSysVar_enum_html(SystemVariables::ISMQTT); #ifdef USES_P037 diff --git a/src/src/Commands/Common.cpp b/src/src/Commands/Common.cpp index 0df55f0ab..79113e08a 100644 --- a/src/src/Commands/Common.cpp +++ b/src/src/Commands/Common.cpp @@ -153,3 +153,63 @@ String Command_GetORSetBool(struct EventStruct *event, } return return_command_success(); } + +String Command_GetORSetUint8_t(struct EventStruct *event, + const String & targetDescription, + const char *Line, + uint8_t *value, + int arg) +{ + bool hasArgument = false; + { + // Check if command is valid. Leave in separate scope to delete the TmpStr1 + String TmpStr1; + + if (GetArgv(Line, TmpStr1, arg + 1)) { + hasArgument = true; + TmpStr1.toLowerCase(); + + if (isInt(TmpStr1)) { + *value = (uint8_t)atoi(TmpStr1.c_str()); + } + else if (strcmp_P(PSTR("WIFI"), TmpStr1.c_str()) == 0) { *value = 0; } + else if (strcmp_P(PSTR("ETHERNET"), TmpStr1.c_str()) == 0) { *value = 1; } + } + } + + if (hasArgument) { + String result = targetDescription; + result += *value; + return return_result(event, result); + } + return return_command_success(); +} + +String Command_GetORSetInt8_t(struct EventStruct *event, + const String & targetDescription, + const char *Line, + int8_t *value, + int arg) +{ + bool hasArgument = false; + { + // Check if command is valid. Leave in separate scope to delete the TmpStr1 + String TmpStr1; + + if (GetArgv(Line, TmpStr1, arg + 1)) { + hasArgument = true; + TmpStr1.toLowerCase(); + + if (isInt(TmpStr1)) { + *value = (int8_t)atoi(TmpStr1.c_str()); + } + } + } + + if (hasArgument) { + String result = targetDescription; + result += *value; + return return_result(event, result); + } + return return_command_success(); +} diff --git a/src/src/Commands/Common.h b/src/src/Commands/Common.h index 4fc0e86f6..014d870f8 100644 --- a/src/src/Commands/Common.h +++ b/src/src/Commands/Common.h @@ -37,4 +37,16 @@ String Command_GetORSetBool(struct EventStruct *event, bool *value, int arg); +String Command_GetORSetUint8_t(struct EventStruct *event, + const String & targetDescription, + const char *Line, + uint8_t *value, + int arg); + +String Command_GetORSetInt8_t(struct EventStruct *event, + const String & targetDescription, + const char *Line, + int8_t *value, + int arg); + #endif // COMMAND_COMMON_H diff --git a/src/src/Commands/Networks.cpp b/src/src/Commands/Networks.cpp index a1c2a36e7..24bf82613 100644 --- a/src/src/Commands/Networks.cpp +++ b/src/src/Commands/Networks.cpp @@ -5,7 +5,7 @@ #include "../Globals/Settings.h" #include "../../ESPEasy_fdwdecl.h" - +#include "ETH.h" String Command_AccessInfo_Ls(struct EventStruct *event, const char* Line) { @@ -38,4 +38,62 @@ String Command_IP (struct EventStruct *event, const char* Line) String Command_Subnet (struct EventStruct *event, const char* Line) { return Command_GetORSetIP(event, F("Subnet:"), Line, Settings.Subnet,WiFi.subnetMask(),1); -} \ No newline at end of file +} + +#ifdef HAS_ETHERNET +String Command_ETH_Phy_Addr (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetUint8_t(event, F("ETH_Phy_Addr:"), Line, (uint8_t*)&Settings.ETH_Phy_Addr,1); +} + +String Command_ETH_Pin_mdc (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetInt8_t(event, F("ETH_Pin_mdc:"), Line, (int8_t*)&Settings.ETH_Pin_mdc,1); +} + +String Command_ETH_Pin_mdio (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetInt8_t(event, F("ETH_Pin_mdio:"), Line, (int8_t*)&Settings.ETH_Pin_mdio,1); +} + +String Command_ETH_Pin_power (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetInt8_t(event, F("ETH_Pin_power:"), Line, (int8_t*)&Settings.ETH_Pin_power,1); +} + +String Command_ETH_Phy_Type (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetInt8_t(event, F("ETH_Phy_Type:"), Line, (int8_t*)&Settings.ETH_Phy_Type,1); +} + +String Command_ETH_Clock_Mode (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetUint8_t(event, F("ETH_Clock_Mode:"), Line, (uint8_t*)&Settings.ETH_Clock_Mode,1); +} + +String Command_ETH_IP (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetIP(event, F("ETH_IP:"), Line, Settings.ETH_IP,ETH.localIP(),1); +} + +String Command_ETH_Gateway (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetIP(event, F("ETH_Gateway:"), Line, Settings.ETH_Gateway,ETH.gatewayIP(),1); +} + +String Command_ETH_Subnet (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetIP(event, F("ETH_Subnet:"), Line, Settings.ETH_Subnet,ETH.subnetMask(),1); +} + +String Command_ETH_DNS (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetIP(event, F("ETH_DNS:"), Line, Settings.ETH_DNS,ETH.dnsIP(),1); +} + +String Command_ETH_Wifi_Mode (struct EventStruct *event, const char* Line) +{ + return Command_GetORSetUint8_t(event, F("ETH_Wifi_Mode:"), Line, (uint8_t*)&Settings.ETH_Wifi_Mode,1); +} + +#endif \ No newline at end of file diff --git a/src/src/Commands/Networks.h b/src/src/Commands/Networks.h index 4a55c7676..1b6745f52 100644 --- a/src/src/Commands/Networks.h +++ b/src/src/Commands/Networks.h @@ -10,5 +10,16 @@ String Command_DNS (struct EventStruct *event, const char* Line); String Command_Gateway (struct EventStruct *event, const char* Line); String Command_IP (struct EventStruct *event, const char* Line); String Command_Subnet (struct EventStruct *event, const char* Line); +String Command_ETH_Phy_Addr (struct EventStruct *event, const char* Line); +String Command_ETH_Pin_mdc (struct EventStruct *event, const char* Line); +String Command_ETH_Pin_mdio (struct EventStruct *event, const char* Line); +String Command_ETH_Pin_power (struct EventStruct *event, const char* Line); +String Command_ETH_Phy_Type (struct EventStruct *event, const char* Line); +String Command_ETH_Clock_Mode (struct EventStruct *event, const char* Line); +String Command_ETH_IP (struct EventStruct *event, const char* Line); +String Command_ETH_Gateway (struct EventStruct *event, const char* Line); +String Command_ETH_Subnet (struct EventStruct *event, const char* Line); +String Command_ETH_DNS (struct EventStruct *event, const char* Line); +String Command_ETH_Wifi_Mode (struct EventStruct *event, const char* Line); #endif // COMMAND_NETWORKS_H diff --git a/src/src/Helpers/SystemVariables.cpp b/src/src/Helpers/SystemVariables.cpp index 1aab35692..96d09811f 100644 --- a/src/src/Helpers/SystemVariables.cpp +++ b/src/src/Helpers/SystemVariables.cpp @@ -73,7 +73,11 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode) case BSSID: value = String((wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? F("00:00:00:00:00:00") : WiFi.BSSIDstr()); break; case CR: value = "\r"; break; case IP: value = getValue(LabelType::IP_ADDRESS); break; - case IP4: value = String( (int) WiFi.localIP()[3] ); break; // 4th IP octet + case IP4: value = String( (int) NetworkLocalIP()[3] ); break; // 4th IP octet + case SUBNET: value = getValue(LabelType::IP_SUBNET); break; + case DNS: value = getValue(LabelType::DNS); break; + case GATEWAY: value = getValue(LabelType::GATEWAY); break; + case CLIENTIP: value = getValue(LabelType::CLIENT_IP); break; #ifdef USES_MQTT case ISMQTT: value = String(MQTTclient_connected); break; #else // ifdef USES_MQTT @@ -91,8 +95,13 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode) case ISWIFI: value = String(wifiStatus); break; // 0=disconnected, 1=connected, 2=got ip, 3=services initialized // TODO: PKR: Add ETH Objects #ifdef HAS_ETHERNET - case ETH_WIFI_MODE: value = (eth_wifi_mode == WIFI ? "WIFI" : "ETHERNET"); break; // 0=WIFI, 1=ETH - case ETH_CONNECTED: value = String(eth_connected); break; // 0=disconnected, 1=connected + + case ETHWIFIMODE: value = getValue(LabelType::ETH_WIFI_MODE); break; // 0=WIFI, 1=ETH + case ETHCONNECTED: value = getValue(LabelType::ETH_CONNECTED); break; // 0=disconnected, 1=connected + case ETHDUPLEX: value = getValue(LabelType::ETH_DUPLEX); break; + case ETHSPEED: value = getValue(LabelType::ETH_SPEED); break; + case ETHSTATE: value = getValue(LabelType::ETH_STATE); break; + case ETHSPEEDSTATE: value = getValue(LabelType::ETH_SPEED_STATE); break; #endif case LCLTIME: value = getValue(LabelType::LOCAL_TIME); break; case LCLTIME_AM: value = node_time.getDateTimeString_ampm('-', ':', ' '); break; @@ -244,14 +253,21 @@ String SystemVariables::toString(SystemVariables::Enum enumval) case Enum::CR: return F("%CR%"); case Enum::IP4: return F("%ip4%"); case Enum::IP: return F("%ip%"); + case Enum::SUBNET: return F("%subnet%"); + case Enum::DNS: return F("%dns%"); + case Enum::GATEWAY: return F("%gateway%"); + case Enum::CLIENTIP: return F("%clientip%"); case Enum::ISMQTT: return F("%ismqtt%"); case Enum::ISMQTTIMP: return F("%ismqttimp%"); case Enum::ISNTP: return F("%isntp%"); case Enum::ISWIFI: return F("%iswifi%"); - // TODO: PKR: Add ETH Objects #ifdef HAS_ETHERNET - case Enum::ETH_WIFI_MODE: return F("%eth_wifi_mode%"); - case Enum::ETH_CONNECTED: return F("%eth_connected%"); + case Enum::ETHWIFIMODE: return F("%ethwifimode%"); + case Enum::ETHCONNECTED: return F("%ethconnected%"); + case Enum::ETHDUPLEX: return F("%ethduplex%"); + case Enum::ETHSPEED: return F("%ethspeed%"); + case Enum::ETHSTATE: return F("%ethstate%"); + case Enum::ETHSPEEDSTATE: return F("%ethspeedstate%"); #endif case Enum::LCLTIME: return F("%lcltime%"); case Enum::LCLTIME_AM: return F("%lcltime_am%"); diff --git a/src/src/Helpers/SystemVariables.h b/src/src/Helpers/SystemVariables.h index ec24e684b..d44920ce7 100644 --- a/src/src/Helpers/SystemVariables.h +++ b/src/src/Helpers/SystemVariables.h @@ -13,12 +13,22 @@ public: CR, IP, IP4, // 4th IP octet + SUBNET, + GATEWAY, + DNS, + CLIENTIP, ISMQTT, ISMQTTIMP, ISNTP, ISWIFI, - ETH_WIFI_MODE, - ETH_CONNECTED, + #ifdef HAS_ETHERNET + ETHWIFIMODE, + ETHCONNECTED, + ETHDUPLEX, + ETHSPEED, + ETHSTATE, + ETHSPEEDSTATE, + #endif LCLTIME, LCLTIME_AM, LF, From 24d9dc19a46f60fdb0904a2f736618718ee2ab2e Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Mon, 27 Apr 2020 22:18:55 +0200 Subject: [PATCH 027/128] - ETHEvents moved to WifiEvents, because they are the same type --- src/ESPEasy.ino | 4 ---- src/ESPEasyEthEvent.ino | 50 ---------------------------------------- src/ESPEasyWiFiEvent.cpp | 44 +++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 54 deletions(-) delete mode 100644 src/ESPEasyEthEvent.ino diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index 8234a7b44..0f55651d0 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -380,10 +380,6 @@ void setup() rulesProcessing(event); // TD-er: Process events in the setup() now. } - #ifdef HAS_ETHERNET - WiFi.onEvent(ETHEvent); - #endif - NetworkConnectRelaxed(); setWebserverRunning(true); diff --git a/src/ESPEasyEthEvent.ino b/src/ESPEasyEthEvent.ino deleted file mode 100644 index 036bdc4af..000000000 --- a/src/ESPEasyEthEvent.ino +++ /dev/null @@ -1,50 +0,0 @@ -#ifdef HAS_ETHERNET -void ETHEvent(WiFiEvent_t event) -{ - switch (event) { - case SYSTEM_EVENT_ETH_START: - addLog(LOG_LEVEL_INFO, F("ETH Started")); - char hostname[40]; - safe_strncpy(hostname, createRFCCompliantHostname(WifiGetAPssid()).c_str(), sizeof(hostname)); - ETH.setHostname(hostname); - { - String log = F("ETH Hostname: "); - log += String(hostname); - addLog(LOG_LEVEL_INFO, log); - } - break; - case SYSTEM_EVENT_ETH_CONNECTED: - addLog(LOG_LEVEL_INFO, F("ETH Connected")); - break; - case SYSTEM_EVENT_ETH_GOT_IP: - { - String log = F("ETH MAC: "); - log += ETH.macAddress(); - log += F(", IPv4: "); - log += ETH.localIP().toString(); - if (ETH.fullDuplex()) { - log += F(", FULL_DUPLEX"); - } - log += F(", "); - log += ETH.linkSpeed(); - log += F("Mbps"); - addLog(LOG_LEVEL_INFO, log); - } - eth_connected = true; - break; - case SYSTEM_EVENT_ETH_DISCONNECTED: - addLog(LOG_LEVEL_ERROR, F("ETH Disconnected")); - eth_connected = false; - break; - case SYSTEM_EVENT_ETH_STOP: - addLog(LOG_LEVEL_INFO, F("ETH Stopped")); - eth_connected = false; - break; - case SYSTEM_EVENT_GOT_IP6: - addLog(LOG_LEVEL_INFO, F("ETH Got IP6")); - break; - default: - break; - } -} -#endif \ No newline at end of file diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index 2892a21aa..39319c7ae 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -4,6 +4,7 @@ #include "src/Globals/RTC.h" #include "ESPEasyTimeTypes.h" #include "ESPEasy_Log.h" +#include "ESPEasy_fdwdecl.h" #include "src/DataStructs/RTCStruct.h" @@ -105,6 +106,49 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { case SYSTEM_EVENT_SCAN_DONE: processedScanDone = false; break; +#ifdef HAS_ETHERNET + case SYSTEM_EVENT_ETH_START: + addLog(LOG_LEVEL_INFO, F("ETH Started")); + char hostname[40]; + safe_strncpy(hostname, createRFCCompliantHostname(WifiGetAPssid()).c_str(), sizeof(hostname)); + ETH.setHostname(hostname); + { + String log = F("ETH Hostname: "); + log += String(hostname); + addLog(LOG_LEVEL_INFO, log); + } + break; + case SYSTEM_EVENT_ETH_CONNECTED: + addLog(LOG_LEVEL_INFO, F("ETH Connected")); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + { + String log = F("ETH MAC: "); + log += ETH.macAddress(); + log += F(", IPv4: "); + log += ETH.localIP().toString(); + if (ETH.fullDuplex()) { + log += F(", FULL_DUPLEX"); + } + log += F(", "); + log += ETH.linkSpeed(); + log += F("Mbps"); + addLog(LOG_LEVEL_INFO, log); + } + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + addLog(LOG_LEVEL_ERROR, F("ETH Disconnected")); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + addLog(LOG_LEVEL_INFO, F("ETH Stopped")); + eth_connected = false; + break; + case SYSTEM_EVENT_GOT_IP6: + addLog(LOG_LEVEL_INFO, F("ETH Got IP6")); + break; +#endif //HAS_ETHERNET default: break; } From 6585a48f396a7a838b1a87abc24437c244673a1f Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Mon, 27 Apr 2020 22:56:26 +0200 Subject: [PATCH 028/128] ESPEasyEth.ino --> ESPEasyEth.cpp/h Network.ino --> Network.cpp/h --- src/{ESPEasyEth.ino => ESPEasyEth.cpp} | 1 + src/ESPEasyEth.h | 16 ++++++++++++++++ src/ESPEasy_fdwdecl.h | 2 ++ src/{Network.ino => Network.cpp} | 16 ++++++++-------- src/Network.h | 16 ++++++++++++++++ src/StringProvider.ino | 1 + 6 files changed, 44 insertions(+), 8 deletions(-) rename src/{ESPEasyEth.ino => ESPEasyEth.cpp} (99%) create mode 100644 src/ESPEasyEth.h rename src/{Network.ino => Network.cpp} (88%) create mode 100644 src/Network.h diff --git a/src/ESPEasyEth.ino b/src/ESPEasyEth.cpp similarity index 99% rename from src/ESPEasyEth.ino rename to src/ESPEasyEth.cpp index 11a9759ff..e6b340911 100644 --- a/src/ESPEasyEth.ino +++ b/src/ESPEasyEth.cpp @@ -1,3 +1,4 @@ +#include "ESPEasyEth.h" #ifdef HAS_ETHERNET diff --git a/src/ESPEasyEth.h b/src/ESPEasyEth.h new file mode 100644 index 000000000..a0bf7c8b2 --- /dev/null +++ b/src/ESPEasyEth.h @@ -0,0 +1,16 @@ +#ifndef ESPEASY_ETH_H +#define ESPEASY_ETH_H + +#include "ESPEasy_common.h" + +bool ethUseStaticIP(); +void ethSetupStaticIPconfig(); +bool ethCheckSettings(); +bool ethPrepare(); +String ethGetDebugClockModeStr(); +String ethGetDebugEthWifiModeStr(); +void ethPrintSettings(); +void ETHConnectRelaxed(); +bool ETHConnected(); + +#endif // ESPEASY_ETH_H \ No newline at end of file diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index f1880a48f..3eeb16ddf 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -203,6 +203,8 @@ uint8_t * NetworkMacAddressAsBytes(uint8_t* mac); String NetworkMacAddress(); String WifiGetAPssid(); String createRFCCompliantHostname(String oldString); +void WiFiConnectRelaxed(); +bool WiFiConnected(); #include "src/Globals/ESPEasyWiFiEvent.h" diff --git a/src/Network.ino b/src/Network.cpp similarity index 88% rename from src/Network.ino rename to src/Network.cpp index bb8060651..77ecf9ccc 100644 --- a/src/Network.ino +++ b/src/Network.cpp @@ -1,14 +1,14 @@ -//#include "Network.h" +#include "Network.h" -/*#include "ESPEasy_fdwdecl.h" +#include "ESPEasy_fdwdecl.h" +#include "ESPEasy-Globals.h" #include "ESPEasy_Log.h" -#include "ESPEasy_common.h" -#include "src/Globals/Settings.h" -#include "src/DataStructs/TimingStats.h" +#include "ESPEasyEth.h" +//#include "ESPEasy_common.h" +//#include "src/Globals/Settings.h" +//#include "src/DataStructs/TimingStats.h" -#include "ESPEasyEth.ino" -#include "ESPEasyWifi.ino" -#include "ESPEasyWifi_ProcessEvent.ino"*/ +#include "ETH.h" /*********************************************************************************************\ Ethernet or Wifi Support for ESP32 Build flag HAS_ETHERNET diff --git a/src/Network.h b/src/Network.h new file mode 100644 index 000000000..90f5c316b --- /dev/null +++ b/src/Network.h @@ -0,0 +1,16 @@ +#ifndef NETWORK_H +#define NETWORK_H + +#include "ESPEasy_common.h" + +void NetworkConnectRelaxed(); +bool NetworkConnected(); +IPAddress NetworkLocalIP(); +IPAddress NetworkSubnetMask(); +IPAddress NetworkGatewayIP(); +IPAddress NetworkDnsIP (uint8_t dns_no); +uint8_t * NetworkMacAddressAsBytes(uint8_t* mac); +String NetworkMacAddress(); + + +#endif // NETWORK_H \ No newline at end of file diff --git a/src/StringProvider.ino b/src/StringProvider.ino index fbe9602e3..4945a5b95 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -1,4 +1,5 @@ #include "StringProviderTypes.h" +#include "ETH.h" String getInternalLabel(LabelType::Enum label, char replaceSpace) { return to_internal_string(getLabel(label), replaceSpace); From a489b41230c158f6a7b9c07db57041e8d9384507 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Tue, 28 Apr 2020 19:44:26 +0200 Subject: [PATCH 029/128] ESPEasyWiFi_credentials.ino --> cpp/h ESPEasyWiFi_ProcessEvent.ino --> cpp/h ESPEasyWiFi.ino --> cpp/h --- src/ESPEasy.ino | 2 + src/ESPEasyEth_ProcessEvent.ino | 426 ------------------ src/ESPEasyStorage.ino | 1 + ...ntials.ino => ESPEasyWiFi_credentials.cpp} | 4 + src/ESPEasyWiFi_credentials.h | 11 + src/{ESPEasyWifi.ino => ESPEasyWifi.cpp} | 11 +- src/ESPEasyWifi.h | 44 ++ ...Event.ino => ESPEasyWifi_ProcessEvent.cpp} | 10 + src/ESPEasyWifi_ProcessEvent.h | 15 + src/ESPEasy_fdwdecl.h | 21 +- src/Network.cpp | 5 - src/StringProvider.ino | 2 +- 12 files changed, 105 insertions(+), 447 deletions(-) delete mode 100644 src/ESPEasyEth_ProcessEvent.ino rename src/{ESPEasyWiFi_credentials.ino => ESPEasyWiFi_credentials.cpp} (92%) create mode 100644 src/ESPEasyWiFi_credentials.h rename src/{ESPEasyWifi.ino => ESPEasyWifi.cpp} (98%) create mode 100644 src/ESPEasyWifi.h rename src/{ESPEasyWifi_ProcessEvent.ino => ESPEasyWifi_ProcessEvent.cpp} (97%) create mode 100644 src/ESPEasyWifi_ProcessEvent.h diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index 0f55651d0..33034c9dc 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -118,6 +118,8 @@ #include "src/Globals/Services.h" #include "src/Globals/Settings.h" #include "src/Globals/Statistics.h" +#include "ESPEasyWiFi_credentials.h" +#include "ESPEasyWifi_ProcessEvent.h" #if FEATURE_ADC_VCC ADC_MODE(ADC_VCC); diff --git a/src/ESPEasyEth_ProcessEvent.ino b/src/ESPEasyEth_ProcessEvent.ino deleted file mode 100644 index 6353cc88e..000000000 --- a/src/ESPEasyEth_ProcessEvent.ino +++ /dev/null @@ -1,426 +0,0 @@ -#include "src/Globals/ESPEasyWiFiEvent.h" - -/* -bool unprocessedWifiEvents() { - if (processedConnect && processedDisconnect && processedGotIP && processedDHCPTimeout) - { - return false; - } - return true; -} - -// ******************************************************************************** -// Called from the loop() to make sure events are processed as soon as possible. -// These functions are called from Setup() or Loop() and thus may call delay() or yield() -// ******************************************************************************** -void handle_unprocessedWiFiEvents() -{ - if (WiFi.status() == WL_DISCONNECTED) { - delay(100); - } - - if ((wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) || unprocessedWifiEvents()) { - // WiFi connection is not yet available, so introduce some extra delays to - // help the background tasks managing wifi connections - delay(1); - - if (wifiConnectAttemptNeeded) { - WiFiConnectRelaxed(); - } - - // Process disconnect events before connect events. - if (!processedDisconnect) { - #ifndef BUILD_NO_DEBUG - addLog(LOG_LEVEL_DEBUG, F("WIFI : Entering processDisconnect()")); - #endif // ifndef BUILD_NO_DEBUG - processDisconnect(); - } - - if (!processedConnect) { - #ifndef BUILD_NO_DEBUG - addLog(LOG_LEVEL_DEBUG, F("WIFI : Entering processConnect()")); - #endif // ifndef BUILD_NO_DEBUG - processConnect(); - } - - if (!processedGotIP) { - #ifndef BUILD_NO_DEBUG - addLog(LOG_LEVEL_DEBUG, F("WIFI : Entering processGotIP()")); - #endif // ifndef BUILD_NO_DEBUG - processGotIP(); - } - - if (!processedDHCPTimeout) { - #ifndef BUILD_NO_DEBUG - addLog(LOG_LEVEL_DEBUG, F("WIFI : DHCP timeout, Calling disconnect()")); - #endif // ifndef BUILD_NO_DEBUG - processedDHCPTimeout = true; - processDisconnect(); - } - - if (wifiStatus & ESPEASY_WIFI_CONNECTED) { - // The actual connection has been made, no need to wait for IP to release this semaphore. - wifiConnectInProgress = false; - } - - if ((wifiStatus & ESPEASY_WIFI_GOT_IP) && (wifiStatus & ESPEASY_WIFI_CONNECTED) && WiFi.isConnected()) { - markWiFi_services_initialized(); - } - } else if (!WiFiConnected()) { - // Somehow the WiFi has entered a limbo state. - // FIXME TD-er: This may happen on WiFi config with AP_STA mode active. - // addLog(LOG_LEVEL_ERROR, F("Wifi status out sync")); - // resetWiFi(); - if (loglevelActiveFor(LOG_LEVEL_ERROR)) { - String wifilog = F("WIFI : Wifi status out sync WiFi.status() = "); - wifilog += String(WiFi.status()); - - addLog(LOG_LEVEL_ERROR, wifilog); - } - } - - if (wifiStatus == ESPEASY_WIFI_DISCONNECTED) { - #ifndef BUILD_NO_DEBUG - - if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { - String wifilog = F("WIFI : Disconnected: WiFi.status() = "); - wifilog += String(WiFi.status()); - - addLog(LOG_LEVEL_DEBUG, wifilog); - } - #endif // ifndef BUILD_NO_DEBUG - - // While connecting to WiFi make sure the device has ample time to do so - delay(10); - } - - if (!processedDisconnectAPmode) { processDisconnectAPmode(); } - - if (!processedConnectAPmode) { processConnectAPmode(); } - - if (timerAPoff != 0) { processDisableAPmode(); } - - if (!processedScanDone) { processScanDone(); } - - if (wifi_connect_attempt > 0) { - // We only want to clear this counter if the connection is currently stable. - if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) { - if (timePassedSince(lastConnectMoment) > WIFI_CONNECTION_CONSIDERED_STABLE) { - // Connection considered stable - wifi_connect_attempt = 0; - - if (!WiFi.getAutoConnect()) { - WiFi.setAutoConnect(true); - } - } else { - if (WiFi.getAutoConnect()) { - WiFi.setAutoConnect(false); - } - } - } - } -} - -// ******************************************************************************** -// Functions to process the data gathered from the events. -// These functions are called from Setup() or Loop() and thus may call delay() or yield() -// ******************************************************************************** -void processDisconnect() { - if (processedDisconnect) { return; } - processedDisconnect = true; - wifiStatus = ESPEASY_WIFI_DISCONNECTED; -// setWebserverRunning(false); - delay(100); // FIXME TD-er: See https://github.com/letscontrolit/ESPEasy/issues/1987#issuecomment-451644424 - - if (Settings.UseRules) { - eventQueue.add(F("WiFi#Disconnected")); - } - - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("WIFI : Disconnected! Reason: '"); - log += getLastDisconnectReason(); - log += '\''; - - if (lastConnectedDuration > 0) { - log += F(" Connected for "); - log += format_msec_duration(lastConnectedDuration); - } - addLog(LOG_LEVEL_INFO, log); - } - - if (Settings.WiFiRestart_connection_lost()) { - setWifiMode(WIFI_OFF); - delay(100); - } - logConnectionStatus(); -} - -void processConnect() { - if (processedConnect) { return; } - processedConnect = true; - wifiStatus |= ESPEASY_WIFI_CONNECTED; - delay(100); // FIXME TD-er: See https://github.com/letscontrolit/ESPEasy/issues/1987#issuecomment-451644424 - ++wifi_reconnects; - - if (wifiStatus < ESPEASY_WIFI_CONNECTED) { return; } - - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - const long connect_duration = timeDiff(last_wifi_connect_attempt_moment, lastConnectMoment); - String log = F("WIFI : Connected! AP: "); - log += WiFi.SSID(); - log += " ("; - log += WiFi.BSSIDstr(); - log += F(") Ch: "); - log += RTC.lastWiFiChannel; - - if ((connect_duration > 0) && (connect_duration < 30000)) { - // Just log times when they make sense. - log += F(" Duration: "); - log += connect_duration; - log += F(" ms"); - } - addLog(LOG_LEVEL_INFO, log); - } - - if (Settings.UseRules) { - if (bssid_changed) { - eventQueue.add(F("WiFi#ChangedAccesspoint")); - } - - if (channel_changed) { - eventQueue.add(F("WiFi#ChangedWiFichannel")); - } - } - - if (useStaticIP()) { - markGotIP(); // in static IP config the got IP event is never fired. - } - saveToRTC(); - - logConnectionStatus(); -} - -void processGotIP() { - if (processedGotIP) { - return; - } - IPAddress ip = NetworkLocalIP(); - - if (!useStaticIP()) { - if ((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)) { - return; - } - } - processedGotIP = true; - wifiStatus |= ESPEASY_WIFI_GOT_IP; - const IPAddress gw = NetworkGatewayIP(); - const IPAddress subnet = NetworkSubnetMask(); - const long dhcp_duration = timeDiff(lastConnectMoment, lastGetIPmoment); - - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("WIFI : "); - - if (useStaticIP()) { - log += F("Static IP: "); - } else { - log += F("DHCP IP: "); - } - log += formatIP(ip); - log += " ("; - log += WifiGetHostname(); - log += F(") GW: "); - log += formatIP(gw); - log += F(" SN: "); - log += formatIP(subnet); - - if ((dhcp_duration > 0) && (dhcp_duration < 30000)) { - // Just log times when they make sense. - log += F(" duration: "); - log += dhcp_duration; - log += F(" ms"); - } - addLog(LOG_LEVEL_INFO, log); - } - - // Might not work in core 2.5.0 - // See https://github.com/esp8266/Arduino/issues/5839 - if ((Settings.IP_Octet != 0) && (Settings.IP_Octet != 255)) - { - ip[3] = Settings.IP_Octet; - - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("IP : Fixed IP octet:"); - log += formatIP(ip); - addLog(LOG_LEVEL_INFO, log); - } - WiFi.config(ip, gw, subnet); - } - - // First try to get the time, since that may be used in logs - if (node_time.systemTimePresent()) { - node_time.initTime(); - } -#ifdef USES_MQTT - mqtt_reconnect_count = 0; - MQTTclient_should_reconnect = true; - timermqtt_interval = 100; - setIntervalTimer(TIMER_MQTT); -#endif // USES_MQTT - sendGratuitousARP_now(); - - if (Settings.UseRules) - { - eventQueue.add(F("WiFi#Connected")); - } - statusLED(true); - - // WiFi.scanDelete(); - - if (wifiSetup) { - // Wifi setup was active, Apparently these settings work. - wifiSetup = false; - SaveSettings(); - } - logConnectionStatus(); -} - -// A client disconnected from the AP on this node. -void processDisconnectAPmode() { - if (processedDisconnectAPmode) { return; } - processedDisconnectAPmode = true; - - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - const int nrStationsConnected = WiFi.softAPgetStationNum(); - String log = F("AP Mode: Client disconnected: "); - log += formatMAC(lastMacDisconnectedAPmode); - log += F(" Connected devices: "); - log += nrStationsConnected; - addLog(LOG_LEVEL_INFO, log); - } -} - -// Client connects to AP on this node -void processConnectAPmode() { - if (processedConnectAPmode) { return; } - processedConnectAPmode = true; - // Extend timer to switch off AP. - timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION; - - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("AP Mode: Client connected: "); - log += formatMAC(lastMacConnectedAPmode); - log += F(" Connected devices: "); - log += WiFi.softAPgetStationNum(); - addLog(LOG_LEVEL_INFO, log); - } - setWebserverRunning(true); - - // Start DNS, only used if the ESP has no valid WiFi config - // It will reply with it's own address on all DNS requests - // (captive portal concept) - if (!dnsServerActive) { - dnsServerActive = true; - dnsServer.start(DNS_PORT, "*", apIP); - } -} - -// Switch of AP mode when timeout reached and no client connected anymore. -void processDisableAPmode() { - if (timerAPoff == 0) { return; } - - if (WifiIsAP(WiFi.getMode())) { - // disable AP after timeout and no clients connected. - if (timeOutReached(timerAPoff) && (WiFi.softAPgetStationNum() == 0)) { - setAP(false); - } - } - - if (!WifiIsAP(WiFi.getMode())) { - timerAPoff = 0; - } -} - -void processScanDone() { - if (processedScanDone) { return; } - - // Better act on the scan done event, as it may get triggered for normal wifi begin calls. - int8_t scanCompleteStatus = WiFi.scanComplete(); - switch (scanCompleteStatus) { - case 0: // Nothing (yet) found - if (timePassedSince(lastGetScanMoment) > 5000) { - processedScanDone = true; - } - return; - case -1: // WIFI_SCAN_RUNNING - return; - case -2: // WIFI_SCAN_FAILED - addLog(LOG_LEVEL_ERROR, F("WiFi : Scan failed")); - processedScanDone = true; - return; - } - - lastGetScanMoment = millis(); - processedScanDone = true; - - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("WIFI : Scan finished, found: "); - log += scanCompleteStatus; - addLog(LOG_LEVEL_INFO, log); - } - - int bestScanID = -1; - int32_t bestRssi = -1000; - uint8_t bestWiFiSettings = RTC.lastWiFiSettingsIndex; - - if (selectValidWiFiSettings() && scanCompleteStatus > 0) { - const uint8_t startWiFiSettings = RTC.lastWiFiSettingsIndex; - bool done = false; - while (!done) { - String ssid_to_check = getLastWiFiSettingsSSID(); - for (int i = 0; i < scanCompleteStatus; ++i) { - if (WiFi.SSID(i) == ssid_to_check) { - int32_t rssi = WiFi.RSSI(i); - - if (bestRssi < rssi) { - bestRssi = rssi; - bestScanID = i; - bestWiFiSettings = RTC.lastWiFiSettingsIndex; - } - } - } - - // Select the next WiFi settings. - // RTC.lastWiFiSettingsIndex may be updated. - if (!selectNextWiFiSettings()) { - done = true; - } - if (startWiFiSettings == RTC.lastWiFiSettingsIndex) { - done = true; - } - } - - if (bestScanID >= 0) { - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("WIFI : Selected: "); - log += formatScanResult(bestScanID, " "); - addLog(LOG_LEVEL_INFO, log); - } - RTC.lastWiFiSettingsIndex = bestWiFiSettings; - uint8_t *scanbssid = WiFi.BSSID(bestScanID); - - if (scanbssid) { - for (int i = 0; i < 6; ++i) { - RTC.lastBSSID[i] = *(scanbssid + i); - } - } - } - } -} - - -void markWiFi_services_initialized() { - wifiStatus = ESPEASY_WIFI_SERVICES_INITIALIZED; - wifiConnectInProgress = false; - setWebserverRunning(true); -} -*/ \ No newline at end of file diff --git a/src/ESPEasyStorage.ino b/src/ESPEasyStorage.ino index 31ce4cf3b..cbffb745c 100644 --- a/src/ESPEasyStorage.ino +++ b/src/ESPEasyStorage.ino @@ -1,3 +1,4 @@ +#include "ESPEasyWifi.h" #include "src/Globals/Cache.h" #include "src/Globals/CRCValues.h" #include "src/Globals/ResetFactoryDefaultPref.h" diff --git a/src/ESPEasyWiFi_credentials.ino b/src/ESPEasyWiFi_credentials.cpp similarity index 92% rename from src/ESPEasyWiFi_credentials.ino rename to src/ESPEasyWiFi_credentials.cpp index 3289fa2fb..aea8a2c5a 100644 --- a/src/ESPEasyWiFi_credentials.ino +++ b/src/ESPEasyWiFi_credentials.cpp @@ -1,3 +1,7 @@ +#include "ESPEasyWiFi_credentials.h" +#include "src/Globals/RTC.h" +#include "src/Globals/SecuritySettings.h" + // ******************************************************************************** // Manage WiFi credentials // ******************************************************************************** diff --git a/src/ESPEasyWiFi_credentials.h b/src/ESPEasyWiFi_credentials.h new file mode 100644 index 000000000..f608100d9 --- /dev/null +++ b/src/ESPEasyWiFi_credentials.h @@ -0,0 +1,11 @@ +#ifndef ESPEASYWIFI_CREDENTIALS_H +#define ESPEASYWIFI_CREDENTIALS_H + +const char* getLastWiFiSettingsSSID(); +const char* getLastWiFiSettingsPassphrase(); +bool selectNextWiFiSettings(); +bool selectValidWiFiSettings(); +bool wifiSettingsValid(const char *ssid, const char *pass); + + +#endif // ESPEASYWIFI_CREDENTIALS_H \ No newline at end of file diff --git a/src/ESPEasyWifi.ino b/src/ESPEasyWifi.cpp similarity index 98% rename from src/ESPEasyWifi.ino rename to src/ESPEasyWifi.cpp index 4d6f56538..3252cf756 100644 --- a/src/ESPEasyWifi.ino +++ b/src/ESPEasyWifi.cpp @@ -1,10 +1,11 @@ -#define WIFI_RECONNECT_WAIT 20000 // in milliSeconds -#define WIFI_AP_OFF_TIMER_DURATION 60000 // in milliSeconds -#define WIFI_CONNECTION_CONSIDERED_STABLE 300000 // in milliSeconds -#define WIFI_ALLOW_AP_AFTERBOOT_PERIOD 5 // in minutes - +#include "ESPEasyWifi.h" +#include "ESPEasyWifi_ProcessEvent.h" #include "src/Globals/ESPEasyWiFiEvent.h" #include "ESPEasy-Globals.h" +#include "ESPEasyWiFi_credentials.h" +#include "src/DataStructs/TimingStats.h" +#include "src/Globals/RTC.h" +#include "src/Globals/SecuritySettings.h" // ******************************************************************************** // WiFi state diff --git a/src/ESPEasyWifi.h b/src/ESPEasyWifi.h new file mode 100644 index 000000000..b34e978bf --- /dev/null +++ b/src/ESPEasyWifi.h @@ -0,0 +1,44 @@ +#ifndef ESPEASY_ETH_H +#define ESPEASY_ETH_H + +#include "ESPEasy_common.h" + +#if defined(ESP8266) + # include + # include +#endif // if defined(ESP8266) +#if defined(ESP32) + # include + # include +#endif // if defined(ESP32) + + +#define WIFI_RECONNECT_WAIT 20000 // in milliSeconds +#define WIFI_AP_OFF_TIMER_DURATION 60000 // in milliSeconds +#define WIFI_CONNECTION_CONSIDERED_STABLE 300000 // in milliSeconds +#define WIFI_ALLOW_AP_AFTERBOOT_PERIOD 5 // in minutes + +bool WiFiConnected(); +void WiFiConnectRelaxed(); +bool prepareWiFi(); +void resetWiFi(); +void WifiDisconnect(); +void WifiScan(bool async, bool quick); +void WifiScan(); +void setSTA(bool enable); +void setAP(bool enable); +String getWifiModeString(WiFiMode_t wifimode); +void setWifiMode(WiFiMode_t wifimode); +bool WifiIsAP(WiFiMode_t wifimode); +String WifiGetAPssid(); +bool useStaticIP(); +bool wifiConnectTimeoutReached(); +bool wifiAPmodeActivelyUsed(); +void setConnectionSpeed(); +void setupStaticIPconfig(); +String formatScanResult(int i, const String& separator); +String formatScanResult(int i, const String& separator, int32_t& rssi); +void logConnectionStatus(); +String getLastDisconnectReason(); + +#endif // ESPEASY_ETH_H \ No newline at end of file diff --git a/src/ESPEasyWifi_ProcessEvent.ino b/src/ESPEasyWifi_ProcessEvent.cpp similarity index 97% rename from src/ESPEasyWifi_ProcessEvent.ino rename to src/ESPEasyWifi_ProcessEvent.cpp index e24802ff3..4ca80207c 100644 --- a/src/ESPEasyWifi_ProcessEvent.ino +++ b/src/ESPEasyWifi_ProcessEvent.cpp @@ -1,4 +1,14 @@ +#include "ESPEasyWifi_ProcessEvent.h" +#include "ESPEasy-Globals.h" +#include "Network.h" +#include "ESPEasyWifi.h" +#include "ESPEasyWiFi_credentials.h" +#include "ESPEasy_fdwdecl.h" #include "src/Globals/ESPEasyWiFiEvent.h" +#include "src/Globals/RTC.h" +#include "src/Globals/MQTT.h" +#include "src/Helpers/ESPEasy_time_calc.h" +#include "src/DataStructs/SchedulerTimers.h" bool unprocessedWifiEvents() { if (processedConnect && processedDisconnect && processedGotIP && processedDHCPTimeout) diff --git a/src/ESPEasyWifi_ProcessEvent.h b/src/ESPEasyWifi_ProcessEvent.h new file mode 100644 index 000000000..21f70cc69 --- /dev/null +++ b/src/ESPEasyWifi_ProcessEvent.h @@ -0,0 +1,15 @@ +#ifndef ESPEASYWIFI_PROCESSEVENT_H +#define ESPEASYWIFI_PROCESSEVENT_H + +bool unprocessedWifiEvents(); +void handle_unprocessedWiFiEvents(); +void processDisconnect(); +void processConnect(); +void processGotIP(); +void processDisconnectAPmode(); +void processConnectAPmode(); +void processDisableAPmode(); +void processScanDone(); +void markWiFi_services_initialized(); + +#endif //ESPEASYWIFI_PROCESSEVENT_H \ No newline at end of file diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index 3eeb16ddf..7d9df47d8 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -72,8 +72,11 @@ bool useStaticIP(); bool hostReachable(const IPAddress& ip); bool hostReachable(const String& hostname); void formatMAC(const uint8_t * mac, char (& strMAC)[20]); +String formatMAC(const uint8_t *mac); String to_json_object_value(const String& object, const String& value); +void htmlEscape(String& html, char c); +void htmlEscape(String& html); bool I2C_read_bytes(uint8_t i2caddr, @@ -142,6 +145,7 @@ String formatToHex(unsigned long value, const String& prefix); String formatToHex(unsigned long value); String formatToHex_decimal(unsigned long value); String getNumerical(const String& tBuf, bool mustBeInteger); +String format_msec_duration(long duration); float getCPUload(); int getLoopCountPerSec(); @@ -150,6 +154,7 @@ void setLogLevelFor(byte destination, byte logLevel); uint16_t getPortFromKey(uint32_t key); void initRTC(); +boolean saveToRTC(); void deepSleepStart(int dsdelay); bool setControllerEnableStatus(controllerIndex_t controllerIndex, bool enabled); bool setTaskEnableStatus(taskIndex_t taskIndex, bool enabled); @@ -193,18 +198,11 @@ void setSTA(bool enable); // Used for Networking with Wifi or Ethernet #include "ESPEasyEthWifi.h" -void NetworkConnectRelaxed(); -bool NetworkConnected(); -IPAddress NetworkLocalIP(); -IPAddress NetworkSubnetMask(); -IPAddress NetworkGatewayIP(); -IPAddress NetworkDnsIP (uint8_t dns_no=0); -uint8_t * NetworkMacAddressAsBytes(uint8_t* mac); -String NetworkMacAddress(); +#include "Network.h" String WifiGetAPssid(); -String createRFCCompliantHostname(String oldString); void WiFiConnectRelaxed(); bool WiFiConnected(); +String createRFCCompliantHostname(String oldString); #include "src/Globals/ESPEasyWiFiEvent.h" @@ -217,13 +215,16 @@ unsigned long FreeMem(void); void ResetFactory(); void reboot(); void SendUDPCommand(byte destUnit, const char *data, byte dataLength); +bool hasIPaddr(); #include void printDirectory(File dir, int numTabs); void delayBackground(unsigned long dsdelay); -void setIntervalTimerOverride(unsigned long id, unsigned long msecFromNow); //implemented in Scheduler.ino +//implemented in Scheduler.ino +void setIntervalTimerOverride(unsigned long id, unsigned long msecFromNow); +void sendGratuitousARP_now(); byte PluginCall(byte Function, struct EventStruct *event, String& str); diff --git a/src/Network.cpp b/src/Network.cpp index 77ecf9ccc..c921e33ca 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -1,13 +1,8 @@ #include "Network.h" - #include "ESPEasy_fdwdecl.h" #include "ESPEasy-Globals.h" #include "ESPEasy_Log.h" #include "ESPEasyEth.h" -//#include "ESPEasy_common.h" -//#include "src/Globals/Settings.h" -//#include "src/DataStructs/TimingStats.h" - #include "ETH.h" /*********************************************************************************************\ diff --git a/src/StringProvider.ino b/src/StringProvider.ino index 4945a5b95..17381eb34 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -222,7 +222,7 @@ String getValue(LabelType::Enum label) { case LabelType::ETH_IP_SUBNET: return NetworkSubnetMask().toString(); case LabelType::ETH_IP_ADDRESS_SUBNET: return String(getValue(LabelType::ETH_IP_ADDRESS) + F(" / ") + getValue(LabelType::ETH_IP_SUBNET)); case LabelType::ETH_IP_GATEWAY: return NetworkGatewayIP().toString(); - case LabelType::ETH_IP_DNS: return NetworkDnsIP().toString(); + case LabelType::ETH_IP_DNS: return NetworkDnsIP(0).toString(); case LabelType::ETH_MAC: return NetworkMacAddress(); case LabelType::ETH_DUPLEX: return eth_connected ? (ETH.fullDuplex() ? F("Full Duplex") : F("Half Duplex")) : F("No Ethernet"); case LabelType::ETH_SPEED: return eth_connected ? getEthSpeed() : F("No Ethernet"); From e68e6eca3cc4d8e321e32597495f313f7abf095d Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Tue, 28 Apr 2020 20:13:49 +0200 Subject: [PATCH 030/128] Network.h/cpp --> ESPEasyNetwork.h/cpp --- src/{Network.cpp => ESPEasyNetwork.cpp} | 2 +- src/{Network.h => ESPEasyNetwork.h} | 0 src/ESPEasyWifi_ProcessEvent.cpp | 2 +- src/ESPEasy_fdwdecl.h | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/{Network.cpp => ESPEasyNetwork.cpp} (95%) rename src/{Network.h => ESPEasyNetwork.h} (100%) diff --git a/src/Network.cpp b/src/ESPEasyNetwork.cpp similarity index 95% rename from src/Network.cpp rename to src/ESPEasyNetwork.cpp index c921e33ca..9d351c853 100644 --- a/src/Network.cpp +++ b/src/ESPEasyNetwork.cpp @@ -1,4 +1,4 @@ -#include "Network.h" +#include "ESPEasyNetwork.h" #include "ESPEasy_fdwdecl.h" #include "ESPEasy-Globals.h" #include "ESPEasy_Log.h" diff --git a/src/Network.h b/src/ESPEasyNetwork.h similarity index 100% rename from src/Network.h rename to src/ESPEasyNetwork.h diff --git a/src/ESPEasyWifi_ProcessEvent.cpp b/src/ESPEasyWifi_ProcessEvent.cpp index 4ca80207c..06fd375ac 100644 --- a/src/ESPEasyWifi_ProcessEvent.cpp +++ b/src/ESPEasyWifi_ProcessEvent.cpp @@ -1,6 +1,6 @@ #include "ESPEasyWifi_ProcessEvent.h" #include "ESPEasy-Globals.h" -#include "Network.h" +#include "ESPEasyNetwork.h" #include "ESPEasyWifi.h" #include "ESPEasyWiFi_credentials.h" #include "ESPEasy_fdwdecl.h" diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index 7d9df47d8..a332fe750 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -198,7 +198,7 @@ void setSTA(bool enable); // Used for Networking with Wifi or Ethernet #include "ESPEasyEthWifi.h" -#include "Network.h" +#include "ESPEasyNetwork.h" String WifiGetAPssid(); void WiFiConnectRelaxed(); bool WiFiConnected(); From db94e1668c8c0e750198d5ebcd3a7b7f8c9920ce Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Tue, 28 Apr 2020 20:18:20 +0200 Subject: [PATCH 031/128] removed upload flags --- platformio_esp32_envs.ini | 2 -- 1 file changed, 2 deletions(-) diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 52d3a24e8..1bfc0e7ec 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -22,8 +22,6 @@ build_flags = ${mqtt_flags.build_flags} -DCONFIG_FREERTOS_ASSERT_DISABLE -DCONFIG_LWIP_ESP_GRATUITOUS_ARP -DCONFIG_LWIP_GARP_TMR_INTERVAL=30 -upload_flags = - -b921600 ; Custom: 4096k version -------------------------- From 691824477f76bef1d78e5b0c6ea9551fccf22ecc Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Tue, 28 Apr 2020 21:18:59 +0200 Subject: [PATCH 032/128] - New events: ETHERNET#Connected and ETHERNET#Disconnected --- src/ESPEasyWiFiEvent.cpp | 4 ++++ src/ESPEasyWifi_ProcessEvent.cpp | 21 ++++++++++++++++++++- src/ESPEasyWifi_ProcessEvent.h | 5 +++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index 39319c7ae..638ecea7a 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -1,5 +1,6 @@ #include "ETH.h" #include "ESPEasyWiFiEvent.h" +#include "ESPEasyWifi_ProcessEvent.h" #include "src/Globals/ESPEasyWiFiEvent.h" #include "src/Globals/RTC.h" #include "ESPEasyTimeTypes.h" @@ -120,6 +121,8 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { break; case SYSTEM_EVENT_ETH_CONNECTED: addLog(LOG_LEVEL_INFO, F("ETH Connected")); + eth_connected = true; + processEthernetConnected(); break; case SYSTEM_EVENT_ETH_GOT_IP: { @@ -140,6 +143,7 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { case SYSTEM_EVENT_ETH_DISCONNECTED: addLog(LOG_LEVEL_ERROR, F("ETH Disconnected")); eth_connected = false; + processEthernetDisconnected(); break; case SYSTEM_EVENT_ETH_STOP: addLog(LOG_LEVEL_INFO, F("ETH Stopped")); diff --git a/src/ESPEasyWifi_ProcessEvent.cpp b/src/ESPEasyWifi_ProcessEvent.cpp index 06fd375ac..01d7f86c2 100644 --- a/src/ESPEasyWifi_ProcessEvent.cpp +++ b/src/ESPEasyWifi_ProcessEvent.cpp @@ -452,4 +452,23 @@ void markWiFi_services_initialized() { wifiConnectInProgress = false; processedDHCPTimeout = true; // FIXME TD-er: Is this ever happening? -} \ No newline at end of file +} + +#ifdef HAS_ETHERNET + +void processEthernetConnected() { + if (Settings.UseRules) + { + eventQueue.add(F("ETHERNET#Connected")); + } + statusLED(true); +} + +void processEthernetDisconnected() { + if (Settings.UseRules) + { + eventQueue.add(F("ETHERNET#Disconnected")); + } +} + +#endif \ No newline at end of file diff --git a/src/ESPEasyWifi_ProcessEvent.h b/src/ESPEasyWifi_ProcessEvent.h index 21f70cc69..78c4a1161 100644 --- a/src/ESPEasyWifi_ProcessEvent.h +++ b/src/ESPEasyWifi_ProcessEvent.h @@ -12,4 +12,9 @@ void processDisableAPmode(); void processScanDone(); void markWiFi_services_initialized(); +#ifdef HAS_ETHERNET +void processEthernetConnected(); +void processEthernetDisconnected(); +#endif + #endif //ESPEASYWIFI_PROCESSEVENT_H \ No newline at end of file From b1a3d747c05078280db80eedd7fff082c5bea4c4 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Tue, 28 Apr 2020 21:48:59 +0200 Subject: [PATCH 033/128] Fixed https://travis-ci.org/github/letscontrolit/ESPEasy/builds/680698472 ci build error --- src/ESPEasyNetwork.cpp | 3 +++ src/ESPEasyNetwork.h | 2 +- src/ESPEasyWiFiEvent.cpp | 2 ++ src/StringProvider.ino | 2 ++ src/src/Commands/Networks.cpp | 2 ++ 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ESPEasyNetwork.cpp b/src/ESPEasyNetwork.cpp index 9d351c853..828df3e16 100644 --- a/src/ESPEasyNetwork.cpp +++ b/src/ESPEasyNetwork.cpp @@ -3,7 +3,10 @@ #include "ESPEasy-Globals.h" #include "ESPEasy_Log.h" #include "ESPEasyEth.h" + +#ifdef HAS_ETHERNET #include "ETH.h" +#endif /*********************************************************************************************\ Ethernet or Wifi Support for ESP32 Build flag HAS_ETHERNET diff --git a/src/ESPEasyNetwork.h b/src/ESPEasyNetwork.h index 90f5c316b..4a9d91d99 100644 --- a/src/ESPEasyNetwork.h +++ b/src/ESPEasyNetwork.h @@ -1,7 +1,7 @@ #ifndef NETWORK_H #define NETWORK_H -#include "ESPEasy_common.h" +#include "ESPEasy-Globals.h" void NetworkConnectRelaxed(); bool NetworkConnected(); diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index 638ecea7a..bead31154 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -1,4 +1,6 @@ +#ifdef HAS_ETHERNET #include "ETH.h" +#endif #include "ESPEasyWiFiEvent.h" #include "ESPEasyWifi_ProcessEvent.h" #include "src/Globals/ESPEasyWiFiEvent.h" diff --git a/src/StringProvider.ino b/src/StringProvider.ino index 17381eb34..549729a8a 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -1,5 +1,7 @@ #include "StringProviderTypes.h" +#ifdef HAS_ETHERNET #include "ETH.h" +#endif String getInternalLabel(LabelType::Enum label, char replaceSpace) { return to_internal_string(getLabel(label), replaceSpace); diff --git a/src/src/Commands/Networks.cpp b/src/src/Commands/Networks.cpp index 24bf82613..737c756c6 100644 --- a/src/src/Commands/Networks.cpp +++ b/src/src/Commands/Networks.cpp @@ -5,7 +5,9 @@ #include "../Globals/Settings.h" #include "../../ESPEasy_fdwdecl.h" +#ifdef HAS_ETHERNET #include "ETH.h" +#endif String Command_AccessInfo_Ls(struct EventStruct *event, const char* Line) { From cde90522830b42bbdc3580888086e2d7e1efb9ca Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Tue, 28 Apr 2020 23:28:45 +0200 Subject: [PATCH 034/128] Fixed ci compile bug https://travis-ci.org/github/letscontrolit/ESPEasy/builds/680724129 --- src/ESPEasyNetwork.cpp | 21 +++++++++++++++++++++ src/ESPEasyNetwork.h | 3 +++ src/ESPEasyWiFiEvent.cpp | 2 +- src/ESPEasyWifi.cpp | 14 ++++---------- src/ESPEasyWifi.h | 1 - src/ESPEasyWifi_ProcessEvent.cpp | 2 +- src/ESPEasy_fdwdecl.h | 2 -- src/Networking.ino | 10 ---------- src/StringProvider.ino | 3 ++- src/WebServer.ino | 5 +++-- 10 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/ESPEasyNetwork.cpp b/src/ESPEasyNetwork.cpp index 828df3e16..d91921cad 100644 --- a/src/ESPEasyNetwork.cpp +++ b/src/ESPEasyNetwork.cpp @@ -138,4 +138,25 @@ String NetworkMacAddress() { formatMAC(macread, macaddress); return String(macaddress); +} + +// ******************************************************************************** +// Determine Wifi AP name to set. (also used for mDNS) +// ******************************************************************************** +String NetworkGetAPssid() +{ + return Settings.getHostname(); +} + +String NetworkGetHostname() { + return createRFCCompliantHostname(NetworkGetAPssid()); +} + +// Create hostname with - instead of spaces +String createRFCCompliantHostname(String oldString) { + String result(oldString); + + result.replace(" ", "-"); + result.replace("_", "-"); // See RFC952 + return result; } \ No newline at end of file diff --git a/src/ESPEasyNetwork.h b/src/ESPEasyNetwork.h index 4a9d91d99..c9d14ad14 100644 --- a/src/ESPEasyNetwork.h +++ b/src/ESPEasyNetwork.h @@ -11,6 +11,9 @@ IPAddress NetworkGatewayIP(); IPAddress NetworkDnsIP (uint8_t dns_no); uint8_t * NetworkMacAddressAsBytes(uint8_t* mac); String NetworkMacAddress(); +String NetworkGetAPssid(); +String NetworkGetHostname(); +String createRFCCompliantHostname(String oldString); #endif // NETWORK_H \ No newline at end of file diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index bead31154..67c8f5b57 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -113,7 +113,7 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { case SYSTEM_EVENT_ETH_START: addLog(LOG_LEVEL_INFO, F("ETH Started")); char hostname[40]; - safe_strncpy(hostname, createRFCCompliantHostname(WifiGetAPssid()).c_str(), sizeof(hostname)); + safe_strncpy(hostname, NetworkGetHostname()).c_str(), sizeof(hostname)); ETH.setHostname(hostname); { String log = F("ETH Hostname: "); diff --git a/src/ESPEasyWifi.cpp b/src/ESPEasyWifi.cpp index 3252cf756..279fc6068 100644 --- a/src/ESPEasyWifi.cpp +++ b/src/ESPEasyWifi.cpp @@ -1,4 +1,5 @@ #include "ESPEasyWifi.h" +#include "ESPEasyNetwork.h" #include "ESPEasyWifi_ProcessEvent.h" #include "src/Globals/ESPEasyWiFiEvent.h" #include "ESPEasy-Globals.h" @@ -6,6 +7,7 @@ #include "src/DataStructs/TimingStats.h" #include "src/Globals/RTC.h" #include "src/Globals/SecuritySettings.h" +#include "src/Helpers/ESPEasy_time_calc.h" // ******************************************************************************** // WiFi state @@ -204,7 +206,7 @@ bool prepareWiFi() { } setSTA(true); char hostname[40]; - safe_strncpy(hostname, createRFCCompliantHostname(WifiGetAPssid()).c_str(), sizeof(hostname)); + safe_strncpy(hostname, NetworkGetHostname().c_str(), sizeof(hostname)); #if defined(ESP8266) wifi_station_set_hostname(hostname); @@ -382,7 +384,7 @@ void setAPinternal(bool enable) if (enable) { // create and store unique AP SSID/PW to prevent ESP from starting AP mode with default SSID and No password! // setup ssid for AP Mode when needed - String softAPSSID = WifiGetAPssid(); + String softAPSSID = NetworkGetAPssid(); String pwd = SecuritySettings.WifiAPKey; IPAddress subnet(DEFAULT_AP_SUBNET); @@ -507,14 +509,6 @@ bool WifiIsSTA(WiFiMode_t wifimode) #endif // if defined(ESP32) } -// ******************************************************************************** -// Determine Wifi AP name to set. (also used for mDNS) -// ******************************************************************************** -String WifiGetAPssid() -{ - return Settings.getHostname(); -} - bool useStaticIP() { return Settings.IP[0] != 0 && Settings.IP[0] != 255; } diff --git a/src/ESPEasyWifi.h b/src/ESPEasyWifi.h index b34e978bf..34c294237 100644 --- a/src/ESPEasyWifi.h +++ b/src/ESPEasyWifi.h @@ -30,7 +30,6 @@ void setAP(bool enable); String getWifiModeString(WiFiMode_t wifimode); void setWifiMode(WiFiMode_t wifimode); bool WifiIsAP(WiFiMode_t wifimode); -String WifiGetAPssid(); bool useStaticIP(); bool wifiConnectTimeoutReached(); bool wifiAPmodeActivelyUsed(); diff --git a/src/ESPEasyWifi_ProcessEvent.cpp b/src/ESPEasyWifi_ProcessEvent.cpp index 01d7f86c2..ef0b2b70a 100644 --- a/src/ESPEasyWifi_ProcessEvent.cpp +++ b/src/ESPEasyWifi_ProcessEvent.cpp @@ -256,7 +256,7 @@ void processGotIP() { } log += formatIP(ip); log += " ("; - log += createRFCCompliantHostname(WifiGetAPssid()); + log += NetworkGetHostname(); log += F(") GW: "); log += formatIP(gw); log += F(" SN: "); diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index a332fe750..414d8018b 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -199,10 +199,8 @@ void setSTA(bool enable); // Used for Networking with Wifi or Ethernet #include "ESPEasyEthWifi.h" #include "ESPEasyNetwork.h" -String WifiGetAPssid(); void WiFiConnectRelaxed(); bool WiFiConnected(); -String createRFCCompliantHostname(String oldString); #include "src/Globals/ESPEasyWiFiEvent.h" diff --git a/src/Networking.ino b/src/Networking.ino index 3463fc3ea..d6fcd992f 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -1005,16 +1005,6 @@ String splitURL(const String& fullURL, String& host, uint16_t& port, String& fil return fullURL.substring(endhost); } -// Create hostname with - instead of spaces -String createRFCCompliantHostname(String oldString) -{ - String result(oldString); - - result.replace(" ", "-"); - result.replace("_", "-"); // See RFC952 - return result; -} - #ifdef USE_SETTINGS_ARCHIVE // Download a file from a given URL and save to a local file named "file_save" diff --git a/src/StringProvider.ino b/src/StringProvider.ino index 549729a8a..a4d0d8319 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -1,4 +1,5 @@ #include "StringProviderTypes.h" +#include "ESPEasyNetwork.h" #ifdef HAS_ETHERNET #include "ETH.h" #endif @@ -164,7 +165,7 @@ String getValue(LabelType::Enum label) { case LabelType::CLIENT_IP: return formatIP(web_server.client().remoteIP()); #ifdef FEATURE_MDNS - case LabelType::M_DNS: return String(WifiGetHostname()) + F(".local"); + case LabelType::M_DNS: return String(NetworkGetHostname()) + F(".local"); #endif case LabelType::DNS: return String(getValue(LabelType::DNS_1) + F(" / ") + getValue(LabelType::DNS_2)); case LabelType::DNS_1: return NetworkDnsIP(0).toString(); diff --git a/src/WebServer.ino b/src/WebServer.ino index ac9f5aba7..7467c5ca6 100644 --- a/src/WebServer.ino +++ b/src/WebServer.ino @@ -4,6 +4,7 @@ #include +#include "ESPEasyNetwork.h" #include "src/Globals/CPlugins.h" #include "src/Globals/Device.h" #include "src/Globals/TXBuffer.h" @@ -314,8 +315,8 @@ void set_mDNS() { if (webserverRunning) { addLog(LOG_LEVEL_INFO, F("WIFI : Starting mDNS...")); - bool mdns_started = MDNS.begin(WifiGetHostname().c_str()); - MDNS.setInstanceName(WifiGetHostname()); // Needed for when the hostname has changed. + bool mdns_started = MDNS.begin(NetworkGetHostname().c_str()); + MDNS.setInstanceName(NetworkGetHostname()); // Needed for when the hostname has changed. if (loglevelActiveFor(LOG_LEVEL_INFO)) { String log = F("WIFI : "); From 250a345e33042418f429e3ce38bf2f66897debf5 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Wed, 29 Apr 2020 12:21:20 +0200 Subject: [PATCH 035/128] Fixed bug reported by mobremski --- src/ESPEasyWiFiEvent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index 67c8f5b57..017afb8e5 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -113,7 +113,7 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { case SYSTEM_EVENT_ETH_START: addLog(LOG_LEVEL_INFO, F("ETH Started")); char hostname[40]; - safe_strncpy(hostname, NetworkGetHostname()).c_str(), sizeof(hostname)); + safe_strncpy(hostname, NetworkGetHostname().c_str(), sizeof(hostname)); ETH.setHostname(hostname); { String log = F("ETH Hostname: "); From c0bdea0941bb40ec112cbbf1cfa1cbc09cea81fa Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Wed, 29 Apr 2020 12:21:20 +0200 Subject: [PATCH 036/128] - UDP / ESPEasyP2P now works for ETHERNET - Hostname Handling refactored for better overview: - String NetworkGetHostNameFromSettings() returns Settings.getHostname() - String NetworkCreateRFCCompliantHostname() creates a RFCcompliant Hostname from Settings.cpp - String NetworkGetHostname() returns the Hostname prevoiusly set in ETH or Wifi dependong on Mode - MacAddress Handling refactored - String NetworkMacAddress() returns the Mac addres of ETH or Wifi depending on Mode - String WifiSoftAPmacAddress() returns WiFi.softAPmacAddress(mac) as String --- src/ESPEasy.ino | 7 ++++- src/ESPEasyEth.cpp | 16 +++++++++-- src/ESPEasyNetwork.cpp | 53 +++++++++++++++++++++-------------- src/ESPEasyNetwork.h | 4 ++- src/ESPEasyWiFiEvent.cpp | 8 ------ src/ESPEasyWifi.cpp | 2 +- src/Networking.ino | 11 ++++---- src/StringProvider.ino | 10 ++----- src/WebServer_SysInfoPage.ino | 41 ++++++--------------------- src/_C014.ino | 2 +- src/src/Commands/Settings.cpp | 2 +- 11 files changed, 76 insertions(+), 80 deletions(-) diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index 8691172a5..28fcb2938 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -995,7 +995,12 @@ void backgroundtasks() if (webserverRunning) { web_server.handleClient(); } - if (WiFi.getMode() != WIFI_OFF) { + if (WiFi.getMode() != WIFI_OFF + // This makes UDP working for ETHERNET + #ifdef HAS_ETHERNET + || eth_connected + #endif + ) { checkUDP(); } } diff --git a/src/ESPEasyEth.cpp b/src/ESPEasyEth.cpp index e6b340911..feacd6c1a 100644 --- a/src/ESPEasyEth.cpp +++ b/src/ESPEasyEth.cpp @@ -1,9 +1,10 @@ -#include "ESPEasyEth.h" - #ifdef HAS_ETHERNET +#include "ESPEasyEth.h" +#include "ESPEasyNetwork.h" #include "ETH.h" #include "ESPEasy-Globals.h" +#include "eth_phy/phy.h" bool ethUseStaticIP() { return Settings.ETH_IP[0] != 0 && Settings.ETH_IP[3] != 255; @@ -53,6 +54,9 @@ bool ethPrepare() { addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!")); return false; } + char hostname[40]; + safe_strncpy(hostname, NetworkCreateRFCCompliantHostname().c_str(), sizeof(hostname)); + ETH.setHostname(hostname); ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); ethSetupStaticIPconfig(); return true; @@ -98,6 +102,14 @@ void ethPrintSettings() { addLog(LOG_LEVEL_INFO, settingsDebugLog); } +String ETHMacAddress() { + uint8_t mac[6]; + char macStr[18] = { 0 }; + esp_eth_get_mac(mac); + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + void ETHConnectRelaxed() { ethPrintSettings(); ETH.begin(Settings.ETH_Phy_Addr, diff --git a/src/ESPEasyNetwork.cpp b/src/ESPEasyNetwork.cpp index d91921cad..9b6b2b861 100644 --- a/src/ESPEasyNetwork.cpp +++ b/src/ESPEasyNetwork.cpp @@ -105,29 +105,13 @@ IPAddress NetworkDnsIP (uint8_t dns_no) { #endif } -uint8_t * NetworkMacAddressAsBytes(uint8_t* mac) { - #ifdef HAS_ETHERNET - if(eth_wifi_mode == ETHERNET) { - if(eth_connected) { - return WiFi.macAddress(mac); - } else { - addLog(LOG_LEVEL_ERROR, F("Call NetworkMacAddressAsBytes(uint8_t* mac) only on connected Ethernet!")); - return mac; - } - } else { - return WiFi.macAddress(mac); - } - #else - return WiFi.macAddress(mac); - #endif - return WiFi.macAddress(mac); -} - String NetworkMacAddress() { #ifdef HAS_ETHERNET if(eth_wifi_mode == ETHERNET) { if(!eth_connected) { addLog(LOG_LEVEL_ERROR, F("Call NetworkMacAddress() only on connected Ethernet!")); + } else { + return ETH.macAddress(); } } #endif @@ -140,16 +124,35 @@ String NetworkMacAddress() { return String(macaddress); } +uint8_t * NetworkMacAddressAsBytes(uint8_t* mac) { + return WiFi.macAddress(mac); +} + +String NetworkGetHostname() { + #ifdef ESP32 + #ifdef HAS_ETHERNET + if(Settings.ETH_Wifi_Mode == ETHERNET) { + return String(ETH.getHostname()); + } + return String(WiFi.getHostname()); + #else + return String(WiFi.getHostname()); + #endif + #else + return String(WiFi.hostname()); + #endif +} + // ******************************************************************************** // Determine Wifi AP name to set. (also used for mDNS) // ******************************************************************************** -String NetworkGetAPssid() +String NetworkGetHostNameFromSettings() { return Settings.getHostname(); } -String NetworkGetHostname() { - return createRFCCompliantHostname(NetworkGetAPssid()); +String NetworkCreateRFCCompliantHostname() { + return createRFCCompliantHostname(NetworkGetHostNameFromSettings()); } // Create hostname with - instead of spaces @@ -159,4 +162,12 @@ String createRFCCompliantHostname(String oldString) { result.replace(" ", "-"); result.replace("_", "-"); // See RFC952 return result; +} + +String WifiSoftAPmacAddress() { + uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; + uint8_t *macread = WiFi.softAPmacAddress(mac); + char macaddress[20]; + formatMAC(macread, macaddress); + return String(macaddress); } \ No newline at end of file diff --git a/src/ESPEasyNetwork.h b/src/ESPEasyNetwork.h index c9d14ad14..cdb774e85 100644 --- a/src/ESPEasyNetwork.h +++ b/src/ESPEasyNetwork.h @@ -11,9 +11,11 @@ IPAddress NetworkGatewayIP(); IPAddress NetworkDnsIP (uint8_t dns_no); uint8_t * NetworkMacAddressAsBytes(uint8_t* mac); String NetworkMacAddress(); -String NetworkGetAPssid(); +String NetworkGetHostNameFromSettings(); String NetworkGetHostname(); +String NetworkCreateRFCCompliantHostname(); String createRFCCompliantHostname(String oldString); +String WifiSoftAPmacAddress(); #endif // NETWORK_H \ No newline at end of file diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index 67c8f5b57..2b9c17e86 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -112,14 +112,6 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { #ifdef HAS_ETHERNET case SYSTEM_EVENT_ETH_START: addLog(LOG_LEVEL_INFO, F("ETH Started")); - char hostname[40]; - safe_strncpy(hostname, NetworkGetHostname()).c_str(), sizeof(hostname)); - ETH.setHostname(hostname); - { - String log = F("ETH Hostname: "); - log += String(hostname); - addLog(LOG_LEVEL_INFO, log); - } break; case SYSTEM_EVENT_ETH_CONNECTED: addLog(LOG_LEVEL_INFO, F("ETH Connected")); diff --git a/src/ESPEasyWifi.cpp b/src/ESPEasyWifi.cpp index 279fc6068..05dff9d98 100644 --- a/src/ESPEasyWifi.cpp +++ b/src/ESPEasyWifi.cpp @@ -384,7 +384,7 @@ void setAPinternal(bool enable) if (enable) { // create and store unique AP SSID/PW to prevent ESP from starting AP mode with default SSID and No password! // setup ssid for AP Mode when needed - String softAPSSID = NetworkGetAPssid(); + String softAPSSID = NetworkCreateRFCCompliantHostname(); String pwd = SecuritySettings.WifiAPKey; IPAddress subnet(DEFAULT_AP_SUBNET); diff --git a/src/Networking.ino b/src/Networking.ino index d6fcd992f..eeb0f83c6 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -346,7 +346,8 @@ void sendSysInfoUDP(byte repeats) for (byte counter = 0; counter < repeats; counter++) { uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; - uint8_t *macread = WiFi.macAddress(mac); + uint8_t *macread = NetworkMacAddressAsBytes(mac); + byte data[80]; data[0] = 255; data[1] = 1; @@ -406,7 +407,7 @@ void SSDP_schema(WiFiClient& client) { return; } - const IPAddress ip = WiFi.localIP(); + const IPAddress ip = NetworkLocalIP(); const uint32_t chipId = ESP.getChipId(); char uuid[64]; sprintf_P(uuid, PSTR("38323636-4558-4dda-9188-cda0e6%02x%02x%02x"), @@ -498,7 +499,7 @@ bool SSDP_begin() { _server->ref(); ip_addr_t ifaddr; - ifaddr.addr = WiFi.localIP(); + ifaddr.addr = NetworkLocalIP(); ip_addr_t multicast_addr; multicast_addr.addr = (uint32_t)SSDP_MULTICAST_ADDR; @@ -544,7 +545,7 @@ bool SSDP_begin() { Send SSDP messages (notify & responses) \*********************************************************************************************/ void SSDP_send(byte method) { - uint32_t ip = WiFi.localIP(); + uint32_t ip = NetworkLocalIP(); // FIXME TD-er: Why create String objects of these flashstrings? String _ssdp_response_template = F( @@ -563,7 +564,7 @@ void SSDP_send(byte method) { "CACHE-CONTROL: max-age=%u\r\n" // SSDP_INTERVAL "SERVER: Arduino/1.0 UPNP/1.1 ESPEasy/%u\r\n" // _modelNumber "USN: uuid:%s\r\n" // _uuid - "LOCATION: http://%u.%u.%u.%u:80/ssdp.xml\r\n" // WiFi.localIP(), + "LOCATION: http://%u.%u.%u.%u:80/ssdp.xml\r\n" // NetworkLocalIP(), "\r\n"); { char uuid[64] = { 0 }; diff --git a/src/StringProvider.ino b/src/StringProvider.ino index a4d0d8319..618e92824 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -127,12 +127,8 @@ String getValue(LabelType::Enum label) { { case LabelType::UNIT_NR: return String(Settings.Unit); case LabelType::UNIT_NAME: return String(Settings.Name); // Only return the set name, no appended unit. - case LabelType::HOST_NAME: - #ifdef ESP32 - return WiFi.getHostname(); - #else - return WiFi.hostname(); - #endif + case LabelType::HOST_NAME: return NetworkGetHostname(); + case LabelType::LOCAL_TIME: return node_time.getDateTimeString('-',':',' '); case LabelType::UPTIME: return String(wdcounter / 2); @@ -172,7 +168,7 @@ String getValue(LabelType::Enum label) { case LabelType::DNS_2: return NetworkDnsIP(1).toString(); case LabelType::ALLOWED_IP_RANGE: return describeAllowedIPrange(); case LabelType::STA_MAC: return NetworkMacAddress(); - case LabelType::AP_MAC: break; + case LabelType::AP_MAC: return WifiSoftAPmacAddress(); case LabelType::SSID: return WiFi.SSID(); case LabelType::BSSID: return WiFi.BSSIDstr(); case LabelType::CHANNEL: return String(WiFi.channel()); diff --git a/src/WebServer_SysInfoPage.ino b/src/WebServer_SysInfoPage.ino index ebc5b6a29..0e49534f6 100644 --- a/src/WebServer_SysInfoPage.ino +++ b/src/WebServer_SysInfoPage.ino @@ -66,24 +66,13 @@ void handle_sysinfo_json() { json_prop(F("dns1"), formatIP(NetworkDnsIP(0))); json_prop(F("dns2"), formatIP(NetworkDnsIP(1))); json_prop(F("allowed_range"), describeAllowedIPrange()); - - - uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; - uint8_t *macread = WiFi.macAddress(mac); - char macaddress[20]; - formatMAC(macread, macaddress); - - json_prop(F("sta_mac"), macaddress); - - macread = WiFi.softAPmacAddress(mac); - formatMAC(macread, macaddress); - - json_prop(F("ap_mac"), macaddress); - json_prop(F("ssid"), WiFi.SSID()); - json_prop(F("bssid"), WiFi.BSSIDstr()); - json_number(F("channel"), String(WiFi.channel())); - json_prop(F("connected"), format_msec_duration(timeDiff(lastConnectMoment, millis()))); - json_prop(F("ldr"), getLastDisconnectReason()); + json_prop(F("sta_mac"), NetworkMacAddress()); + json_prop(F("ap_mac"), WifiSoftAPmacAddress()); + json_prop(F("ssid"), WiFi.SSID()); + json_prop(F("bssid"), WiFi.BSSIDstr()); + json_number(F("channel"), String(WiFi.channel())); + json_prop(F("connected"), format_msec_duration(timeDiff(lastConnectMoment, millis()))); + json_prop(F("ldr"), getLastDisconnectReason()); json_number(F("reconnects"), String(wifi_reconnects)); json_close(); @@ -391,20 +380,8 @@ void handle_sysinfo_Network() { addRowLabelValue(LabelType::CLIENT_IP); addRowLabelValue(LabelType::DNS); addRowLabelValue(LabelType::ALLOWED_IP_RANGE); - addRowLabel(getLabel(LabelType::STA_MAC)); - - { - uint8_t mac[] = { 0, 0, 0, 0, 0, 0 }; - uint8_t *macread = WiFi.macAddress(mac); - char macaddress[20]; - formatMAC(macread, macaddress); - addHtml(macaddress); - - addRowLabel(getLabel(LabelType::AP_MAC)); - macread = WiFi.softAPmacAddress(mac); - formatMAC(macread, macaddress); - addHtml(macaddress); - } + addRowLabelValue(LabelType::STA_MAC); + addRowLabelValue(LabelType::AP_MAC); addRowLabel(getLabel(LabelType::SSID)); { diff --git a/src/_C014.ino b/src/_C014.ino index 1e668d252..d8588d232 100644 --- a/src/_C014.ino +++ b/src/_C014.ino @@ -246,7 +246,7 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& CPlugin_014_sendMQTTdevice(pubname,"$localip",formatIP(NetworkLocalIP()).c_str(),errorCounter); // $mac Device → Controller Mac address of the device network interface. The format MUST be of the type A1:B2:C3:D4:E5:F6 Yes Yes - CPlugin_014_sendMQTTdevice(pubname,"$mac",WiFi.macAddress().c_str(),errorCounter); + CPlugin_014_sendMQTTdevice(pubname,"$mac",NetworkMacAddress().c_str(),errorCounter); // $implementation Device → Controller An identifier for the Homie implementation (example esp8266) Yes Yes #if defined(ESP8266) diff --git a/src/src/Commands/Settings.cpp b/src/src/Commands/Settings.cpp index 00637baab..23022d996 100644 --- a/src/src/Commands/Settings.cpp +++ b/src/src/Commands/Settings.cpp @@ -71,7 +71,7 @@ String Command_Settings_Print(struct EventStruct *event, const char* Line) serialPrintln(); serialPrintln(F("System Info")); - serialPrint(F(" IP Address : ")); serialPrintln(WiFi.localIP().toString()); + serialPrint(F(" IP Address : ")); serialPrintln(NetworkLocalIP().toString()); serialPrint(F(" Build : ")); serialPrintln(String((int)BUILD)); serialPrint(F(" Name : ")); serialPrintln(Settings.Name); serialPrint(F(" Unit : ")); serialPrintln(String((int)Settings.Unit)); From 0a2896a0f30716ab4b37b7f88708a37a00d63529 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Wed, 29 Apr 2020 22:12:09 +0200 Subject: [PATCH 037/128] This String function is not needed, because there is a ETH.macAddress() which returns a String. I changed it to the byte version of the function and now uint8_t * NetworkMacAddressAsBytes(uint8_t* mac) returns either this in Ethernet mode or WiFi.macAddress(mac) in Wifi mode. --- src/ESPEasyEth.cpp | 7 ++----- src/ESPEasyEth.h | 5 ++++- src/ESPEasyNetwork.cpp | 8 ++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/ESPEasyEth.cpp b/src/ESPEasyEth.cpp index feacd6c1a..587040022 100644 --- a/src/ESPEasyEth.cpp +++ b/src/ESPEasyEth.cpp @@ -102,12 +102,9 @@ void ethPrintSettings() { addLog(LOG_LEVEL_INFO, settingsDebugLog); } -String ETHMacAddress() { - uint8_t mac[6]; - char macStr[18] = { 0 }; +uint8_t * ETHMacAddress(uint8_t* mac) { esp_eth_get_mac(mac); - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return String(macStr); + return mac; } void ETHConnectRelaxed() { diff --git a/src/ESPEasyEth.h b/src/ESPEasyEth.h index a0bf7c8b2..b130144e9 100644 --- a/src/ESPEasyEth.h +++ b/src/ESPEasyEth.h @@ -1,3 +1,4 @@ +#ifdef HAS_ETHERNET #ifndef ESPEASY_ETH_H #define ESPEASY_ETH_H @@ -12,5 +13,7 @@ String ethGetDebugEthWifiModeStr(); void ethPrintSettings(); void ETHConnectRelaxed(); bool ETHConnected(); +uint8_t * ETHMacAddress(uint8_t* mac); -#endif // ESPEASY_ETH_H \ No newline at end of file +#endif // ESPEASY_ETH_H +#endif \ No newline at end of file diff --git a/src/ESPEasyNetwork.cpp b/src/ESPEasyNetwork.cpp index 9b6b2b861..67e3e03c6 100644 --- a/src/ESPEasyNetwork.cpp +++ b/src/ESPEasyNetwork.cpp @@ -125,7 +125,15 @@ String NetworkMacAddress() { } uint8_t * NetworkMacAddressAsBytes(uint8_t* mac) { + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + return ETHMacAddress(mac); + } else { + return WiFi.macAddress(mac); + } + #else return WiFi.macAddress(mac); + #endif } String NetworkGetHostname() { From d326264c370cd2b5fffb2c9a09ac222a6c91bd2f Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Thu, 30 Apr 2020 11:26:05 +0200 Subject: [PATCH 038/128] Check changed as requested by TD-er --- src/ESPEasyEth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ESPEasyEth.cpp b/src/ESPEasyEth.cpp index 587040022..5d7ce21bd 100644 --- a/src/ESPEasyEth.cpp +++ b/src/ESPEasyEth.cpp @@ -7,7 +7,7 @@ #include "eth_phy/phy.h" bool ethUseStaticIP() { - return Settings.ETH_IP[0] != 0 && Settings.ETH_IP[3] != 255; + return Settings.ETH_IP[0] != 0 && Settings.ETH_IP[0] != 255; } void ethSetupStaticIPconfig() { From 7f1b359c316013cb7028069b363fbffd3c90d74a Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Thu, 30 Apr 2020 21:24:20 +0200 Subject: [PATCH 039/128] addFormNote(F("Be aware with ESPEasyP2P Network, since IP Address will change. There could be conflicts.")); not used anymore because P2P UDP works good --- platformio_esp32_envs.ini | 2 ++ src/ESPEasy.ino | 10 ++++++++++ src/StringProvider.ino | 2 +- src/WebServer_HardwarePage.ino | 1 - 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 1bfc0e7ec..3ba788261 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -22,6 +22,8 @@ build_flags = ${mqtt_flags.build_flags} -DCONFIG_FREERTOS_ASSERT_DISABLE -DCONFIG_LWIP_ESP_GRATUITOUS_ARP -DCONFIG_LWIP_GARP_TMR_INTERVAL=30 +upload_port = /dev/cu.wchusbserial14630 +upload_speed = 921600 ; Custom: 4096k version -------------------------- diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index 28fcb2938..62197a67a 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -916,8 +916,18 @@ void runEach30Seconds() log += connectionFailures; log += F(" FreeMem "); log += FreeMem(); + #ifdef HAS_ETHERNET + if(eth_wifi_mode == ETHERNET) { + log += F( " EthSpeedState "); + log += getValue(LabelType::ETH_SPEED_STATE); + } else { + log += F(" WiFiStatus "); + log += WiFi.status(); + } + #else log += F(" WiFiStatus "); log += WiFi.status(); + #endif // log += F(" ListenInterval "); // log += WiFi.getListenInterval(); addLog(LOG_LEVEL_INFO, log); diff --git a/src/StringProvider.ino b/src/StringProvider.ino index 618e92824..474d10263 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -228,7 +228,7 @@ String getValue(LabelType::Enum label) { case LabelType::ETH_STATE: return eth_connected ? (ETH.linkUp() ? F("Link Up") : F("Link Down")) : F("No Ethernet"); case LabelType::ETH_SPEED_STATE: return eth_connected ? getEthLinkSpeedState() : F("No Ethernet"); case LabelType::ETH_WIFI_MODE: return (eth_wifi_mode == WIFI ? F("WIFI") : F("ETHERNET")); - case LabelType::ETH_CONNECTED: return String(eth_connected); // 0=disconnected, 1=connected + case LabelType::ETH_CONNECTED: return (eth_connected ? F("CONNECTED") : F("DISCONNECTED")); // 0=disconnected, 1=connected #endif } diff --git a/src/WebServer_HardwarePage.ino b/src/WebServer_HardwarePage.ino index 71a5a2541..f143be84d 100644 --- a/src/WebServer_HardwarePage.ino +++ b/src/WebServer_HardwarePage.ino @@ -90,7 +90,6 @@ void handle_hardware() { String ethWifiOptions[2] = { F("WIFI"), F("ETHERNET") }; addSelector("ethwifi", 2, ethWifiOptions, NULL, NULL, Settings.ETH_Wifi_Mode, false, true); addFormNote(F("Change Switch between WIFI and ETHERNET requires reboot to activate")); - addFormNote(F("Be aware with ESPEasyP2P Network, since IP Address will change. There could be conflicts.")); addRowLabel_tr_id(F("Ethernet PHY type"), "ethtype"); String ethPhyTypes[2] = { F("LAN8710"), F("TLK110") }; addSelector("ethtype", 2, ethPhyTypes, NULL, NULL, Settings.ETH_Phy_Type, false, true); From efebcc8d0135e0c0a4f9e7661c810980695935d2 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Thu, 30 Apr 2020 21:27:12 +0200 Subject: [PATCH 040/128] removede personal upload flags --- platformio_esp32_envs.ini | 2 -- 1 file changed, 2 deletions(-) diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 3ba788261..1bfc0e7ec 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -22,8 +22,6 @@ build_flags = ${mqtt_flags.build_flags} -DCONFIG_FREERTOS_ASSERT_DISABLE -DCONFIG_LWIP_ESP_GRATUITOUS_ARP -DCONFIG_LWIP_GARP_TMR_INTERVAL=30 -upload_port = /dev/cu.wchusbserial14630 -upload_speed = 921600 ; Custom: 4096k version -------------------------- From b0577f3447b422d34afead804a3046c27e6e3d43 Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Fri, 1 May 2020 13:43:47 +0200 Subject: [PATCH 041/128] _P124_Atlas_EZO_pH.ino and _P222_Atlas_EZO_ORP.ino deleted since ther are not in ESPEasy but in Playground. There is another Issu, to put them in ESPEasy mega --- src/_P214_Atlas_EZO_pH.ino | 450 ------------------------------------ src/_P222_Atlas_EZO_ORP.ino | 365 ----------------------------- 2 files changed, 815 deletions(-) delete mode 100644 src/_P214_Atlas_EZO_pH.ino delete mode 100644 src/_P222_Atlas_EZO_ORP.ino diff --git a/src/_P214_Atlas_EZO_pH.ino b/src/_P214_Atlas_EZO_pH.ino deleted file mode 100644 index ca4896405..000000000 --- a/src/_P214_Atlas_EZO_pH.ino +++ /dev/null @@ -1,450 +0,0 @@ -//######################################################################## -//################## Plugin 214 : Atlas Scientific EZO Ph sensor ######## -//######################################################################## - -// datasheet at https://www.atlas-scientific.com/_files/_datasheets/_circuit/pH_EZO_datasheet.pdf -// works only in i2c mode - -#define PLUGIN_214 -#define PLUGIN_ID_214 214 -#define PLUGIN_NAME_214 "Environment - Atlas Scientific pH EZO [TESTING]" -#define PLUGIN_VALUENAME1_214 "pH" -#define PLUGIN_VALUENAME2_214 "Voltage" - -boolean Plugin_214_init = false; - -boolean Plugin_214(byte function, struct EventStruct *event, String& string) -{ - boolean success = false; - - switch (function) - { - case PLUGIN_DEVICE_ADD: - { - Device[++deviceCount].Number = PLUGIN_ID_214; - Device[deviceCount].Type = DEVICE_TYPE_I2C; - Device[deviceCount].VType = SENSOR_TYPE_SINGLE; - Device[deviceCount].Ports = 0; - Device[deviceCount].PullUpOption = false; - Device[deviceCount].InverseLogicOption = false; - Device[deviceCount].FormulaOption = true; - Device[deviceCount].ValueCount = 2; - Device[deviceCount].SendDataOption = true; - Device[deviceCount].TimerOption = true; - Device[deviceCount].GlobalSyncOption = true; - break; - } - - case PLUGIN_GET_DEVICENAME: - { - string = F(PLUGIN_NAME_214); - break; - } - - case PLUGIN_GET_DEVICEVALUENAMES: - { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_214)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_214)); - break; - } - - case PLUGIN_WEBFORM_LOAD: - { - #define _P214_ATLASEZO_I2C_NB_OPTIONS 4 - byte I2Cchoice = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; - int optionValues[_P214_ATLASEZO_I2C_NB_OPTIONS] = { 0x63, 0x64, 0x65, 0x66 }; - addFormSelectorI2C(F("plugin_214_i2c"), _P214_ATLASEZO_I2C_NB_OPTIONS, optionValues, I2Cchoice); - - addFormSubHeader(F("General")); - - char sensordata[32]; - bool info; - info = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"i",sensordata); - - if (info) { - String boardInfo(sensordata); - - addHtml(F("Board type : ")); - int pos1 = boardInfo.indexOf(','); - int pos2 = boardInfo.lastIndexOf(','); - addHtml(boardInfo.substring(pos1+1,pos2)); - if (boardInfo.substring(pos1+1,pos2) != "pH"){ - addHtml(F(" WARNING : Board type should be 'pH', check your i2c Address ? ")); - } - addHtml(F("Board version :")); - addHtml(boardInfo.substring(pos2+1)); - addHtml(F("")); - - addHtml(F("")); - - } else { - addHtml(F("Unable to send command to device")); - success = false; - break; - } - - addFormCheckBox(F("Status LED"),F("Plugin_214_status_led"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]); - - char statussensordata[32]; - bool status; - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",statussensordata); - - if (status) { - String boardStatus(statussensordata); - - addHtml(F("Board restart code: ")); - int pos1 = boardStatus.indexOf(','); - int pos2 = boardStatus.lastIndexOf(','); - switch ((char)boardStatus.substring(pos1+1,pos2)[0]) - { - case 'P': - { - addHtml(F("powered off")); - break; - } - case 'S': - { - addHtml(F("software reset")); - break; - } - case 'B': - { - addHtml(F("brown out")); - break; - } - case 'W': - { - addHtml(F("watch dog")); - break; - } - case 'U': - default: - { - addHtml(F("unknown")); - break; - } - } - - addHtml(F("Board voltage :")); - addHtml(boardStatus.substring(pos2+1)); - addHtml(F(" V")); - - addHtml(F("")); - - } else { - addHtml(F("Unable to send status command to device")); - success = false; - break; - } - - addFormSubHeader(F("Calibration")); - - int nb_calibration_points = -1; - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0], "Cal,?",sensordata); - - if (status){ - if (strncmp(sensordata,"?Cal,",5)){ - char tmp[2]; - tmp[0] = sensordata[5]; - tmp[1] = '\0', - nb_calibration_points = atoi(tmp); - } - } - - addRowLabel(F("Middle")); - addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_M' step='0.01"),Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1],1,14); - if (nb_calibration_points > 0) { - addHtml(F(" OK")); - } else { - addHtml(F(" Not yet calibrated")); - } - addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_M"), false); - addHtml(F("\n\n")); - - addRowLabel(F("Low")); - addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_L' step='0.01"), Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2],1,14); - if (nb_calibration_points > 1) { - addHtml(F(" OK")); - } else { - addHtml(F(" Not yet calibrated")); - } - addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_L"), false); - addHtml(F("\n\n")); - - addHtml(F("High")); - addFormNumericBox(F("Ref Ph"),F("Plugin_214_ref_cal_H' step='0.01"), Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3],1,14); - if (nb_calibration_points > 2) { - addHtml(F(" OK")); - } else { - addHtml(F(" Not yet calibrated")); - } - addFormCheckBox(F("Enable"),F("Plugin_214_enable_cal_H"), false); - addHtml(F("\n\n")); - - if (nb_calibration_points > 1){ - char sensordata[32]; - char cmd[8] = "Slope,?"; - bool status; - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd,sensordata); - - if (status){ - String slopeAnswer("Answer to 'Slope' command : "); - slopeAnswer += sensordata; - addFormNote(slopeAnswer); - } - } - - addFormSubHeader(F("Temperature compensation")); - char deviceTemperatureTemplate[40]; - LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); - addFormTextBox(F("Temperature "), F("Plugin_214_temperature_template"), deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); - addFormNote(F("You can use a formulae (and idealy refer to a temp sensor). ")); - float value; - char strValue[5]; - String deviceTemperatureTemplateString(deviceTemperatureTemplate); - String pooltempString(parseTemplate(deviceTemperatureTemplateString, 40)); - addHtml(F("
")); - if (Calculate(pooltempString.c_str(),&value) == CALCULATE_OK ){ - addHtml(F("Actual value : ")); - dtostrf(value,5,2,strValue); - addHtml(strValue); - } else { - addHtml(F("(It seems I can't parse your formulae)")); - } - - addHtml(F("
")); - - success = true; - break; - } - - case PLUGIN_WEBFORM_SAVE: - { - Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_214_i2c")); - - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_214_sensorVersion")); - - char sensordata[32]; - if (isFormItemChecked(F("Plugin_214_status_led"))) { - _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,1",sensordata); - } else { - _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,0",sensordata); - } - Settings.TaskDevicePluginConfig[event->TaskIndex][1] = isFormItemChecked(F("Plugin_214_status_led")); - - - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("Plugin_214_ref_cal_M")); - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2] = getFormItemFloat(F("Plugin_214_ref_cal_L")); - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3] = getFormItemFloat(F("Plugin_214_ref_cal_H")); - - String cmd ("Cal,"); - bool triggerCalibrate = false; - if (isFormItemChecked("Plugin_214_enable_cal_M")) { - cmd += "mid,"; - cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]; - triggerCalibrate = true; - } else if (isFormItemChecked("Plugin_214_enable_cal_L")){ - cmd += "low,"; - cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][2]; - triggerCalibrate = true; - } else if (isFormItemChecked("Plugin_214_enable_cal_H")){ - cmd += "high,"; - cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3]; - triggerCalibrate = true; - } - if (triggerCalibrate){ - char sensordata[32]; - _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd.c_str(),sensordata); - } - - char deviceTemperatureTemplate[40]; - String tmpString = web_server.arg(F("Plugin_214_temperature_template")); - strncpy(deviceTemperatureTemplate, tmpString.c_str(), sizeof(deviceTemperatureTemplate)-1); - deviceTemperatureTemplate[sizeof(deviceTemperatureTemplate)-1]=0; //be sure that our string ends with a \0 - - SaveCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); - - Plugin_214_init = false; - success = true; - break; - } - - case PLUGIN_INIT: - { - Plugin_214_init = true; - } - - case PLUGIN_READ: - { - char sensordata[32]; - bool status; - - //first set the temperature of reading - char deviceTemperatureTemplate[40]; - LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemperatureTemplate, sizeof(deviceTemperatureTemplate)); - - String deviceTemperatureTemplateString(deviceTemperatureTemplate); - String pooltempString(parseTemplate(deviceTemperatureTemplateString, 40)); - //String setTemperature("T,"); - String setTemperature("RT,"); - float temperatureReading; - if (Calculate(pooltempString.c_str(),&temperatureReading) == CALCULATE_OK ){ - setTemperature += temperatureReading; - } else { - success = false; - break; - } - - //ok, now we can read the pH value with Temperature compensation - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],setTemperature.c_str(),sensordata); - - //ok, now we can read the pH value - //status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"r",sensordata); - - //we read the voltagedata char statussensordata[32]; - char voltagedata[32]; - status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",voltagedata); - - - if (status){ - String sensorString(sensordata); - String voltage(voltagedata); - int pos = voltage.lastIndexOf(','); - UserVar[event->BaseVarIndex] = sensorString.toFloat(); - UserVar[event->BaseVarIndex + 1] = voltage.substring(pos+1).toFloat(); - } - else { - UserVar[event->BaseVarIndex] = -1; - UserVar[event->BaseVarIndex + 1] = -1; - } - - //go to sleep - //status = _P214_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Sleep",sensordata); - - success = true; - break; - } - case PLUGIN_WRITE: - { - //TODO : do something more usefull ... - - String tmpString = string; - int argIndex = tmpString.indexOf(','); - if (argIndex) - tmpString = tmpString.substring(0, argIndex); - if (tmpString.equalsIgnoreCase(F("ATLASCMD"))) - { - success = true; - argIndex = string.lastIndexOf(','); - tmpString = string.substring(argIndex + 1); - if (tmpString.equalsIgnoreCase(F("CalMid"))){ - String log("Asking for Mid calibration "); - addLog(LOG_LEVEL_INFO, log); - } - else if (tmpString.equalsIgnoreCase(F("CalLow"))){ - String log("Asking for Low calibration "); - addLog(LOG_LEVEL_INFO, log); - } - else if (tmpString.equalsIgnoreCase(F("CalHigh"))){ - String log("Asking for High calibration "); - addLog(LOG_LEVEL_INFO, log); - } - } - break; - } - } - return success; -} - -// Call this function with two char arrays, one containing the command -// The other containing an allocatted char array for answer -// Returns true on success, false otherwise - -bool _P214_send_I2C_command(uint8_t I2Caddress,const char * cmd, char* sensordata) { - uint16_t sensor_bytes_received = 0; - - byte error; - byte i2c_response_code = 0; - byte in_char = 0; - - addLog(LOG_LEVEL_DEBUG, String(cmd)); - Wire.beginTransmission(I2Caddress); - Wire.write(cmd); - error = Wire.endTransmission(); - - if (error != 0) { - //addLog(LOG_LEVEL_ERROR, error); - addLog(LOG_LEVEL_ERROR, F("Wire.endTransmission() returns error: Check pH shield")); - return false; - } - - //don't read answer if we want to go to sleep - if (strncmp(cmd,"Sleep",5) == 0) { - return true; - } - - i2c_response_code = 254; - while (i2c_response_code == 254) { // in case the cammand takes longer to process, we keep looping here until we get a success or an error - - if ( - ( (cmd[0] == 'r' || cmd[0] == 'R') && cmd[1] == '\0' ) - || - ( ( strncmp(cmd,"cal",3) || strncmp(cmd,"Cal",3) ) && !strncmp(cmd,"Cal,?",5) ) - ) - { - delay(900); - } - else { - delay(300); - } - - Wire.requestFrom(I2Caddress, (uint8_t) 32); //call the circuit and request 32 bytes (this is more then we need). - i2c_response_code = Wire.read(); //read response code - - while (Wire.available()) { //read response - in_char = Wire.read(); - - if (in_char == 0) { //if we receive a null caracter, we're done - while (Wire.available()) { //purge the data line if needed - Wire.read(); - } - - break; //exit the while loop. - } - else { - sensordata[sensor_bytes_received] = in_char; //load this byte into our array. - sensor_bytes_received++; - } - } - sensordata[sensor_bytes_received] = '\0'; - - switch (i2c_response_code) { - case 1: - { - String log = F("< success, answer = "); - log += sensordata; - addLog(LOG_LEVEL_DEBUG, log); - } - break; - - case 2: - addLog(LOG_LEVEL_DEBUG, F("< command failed")); - return false; - - case 254: - addLog(LOG_LEVEL_DEBUG, F("< command pending")); - break; - - case 255: - addLog(LOG_LEVEL_DEBUG, F("< no data")); - return false; - } - } - - addLog(LOG_LEVEL_DEBUG, sensordata); - return true; -} diff --git a/src/_P222_Atlas_EZO_ORP.ino b/src/_P222_Atlas_EZO_ORP.ino deleted file mode 100644 index 9515283b7..000000000 --- a/src/_P222_Atlas_EZO_ORP.ino +++ /dev/null @@ -1,365 +0,0 @@ -//######################################################################## -//################## Plugin 222 : Atlas Scientific EZO ORP sensor ######## -//######################################################################## - -// datasheet at https://www.atlas-scientific.com/_files/_datasheets/_circuit/ORP_EZO_datasheet.pdf -// works only in i2c mode - -#define PLUGIN_222 -#define PLUGIN_ID_222 222 -#define PLUGIN_NAME_222 "Environment - Atlas Scientific ORP EZO" -#define PLUGIN_VALUENAME1_222 "ORP" -#define PLUGIN_VALUENAME2_222 "Voltage" - -boolean Plugin_222_init = false; - -boolean Plugin_222(byte function, struct EventStruct *event, String& string) -{ - boolean success = false; - - switch (function) - { - case PLUGIN_DEVICE_ADD: - { - Device[++deviceCount].Number = PLUGIN_ID_222; - Device[deviceCount].Type = DEVICE_TYPE_I2C; - Device[deviceCount].VType = SENSOR_TYPE_SINGLE; - Device[deviceCount].Ports = 0; - Device[deviceCount].PullUpOption = false; - Device[deviceCount].InverseLogicOption = false; - Device[deviceCount].FormulaOption = true; - Device[deviceCount].ValueCount = 2; - Device[deviceCount].SendDataOption = true; - Device[deviceCount].TimerOption = true; - Device[deviceCount].GlobalSyncOption = true; - break; - } - - case PLUGIN_GET_DEVICENAME: - { - string = F(PLUGIN_NAME_222); - break; - } - - case PLUGIN_GET_DEVICEVALUENAMES: - { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_222)); - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_222)); - break; - } - - case PLUGIN_WEBFORM_LOAD: - { - #define _P222_ATLASEZO_I2C_NB_OPTIONS 4 - byte I2Cchoice = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; - int optionValues[_P222_ATLASEZO_I2C_NB_OPTIONS] = { 0x62, 0x63, 0x64, 0x65 }; - addFormSelectorI2C(F("plugin_222_i2c"), _P222_ATLASEZO_I2C_NB_OPTIONS, optionValues, I2Cchoice); - - addFormSubHeader(F("General")); - - char sensordata[32]; - bool info; - info = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"i",sensordata); - - if (info) { - String boardInfo(sensordata); - - addHtml(F("Board type : ")); - int pos1 = boardInfo.indexOf(','); - int pos2 = boardInfo.lastIndexOf(','); - addHtml(boardInfo.substring(pos1+1,pos2)); - if (boardInfo.substring(pos1+1,pos2) != "ORP"){ - addHtml(F(" WARNING : Board type should be 'ORP', check your i2c Address ? ")); - } - addHtml(F("Board version :")); - addHtml(boardInfo.substring(pos2+1)); - addHtml(F("")); - - addHtml(F("")); - - } else { - addHtml(F("Unable to send command to device")); - success = false; - break; - } - - addFormCheckBox(F("Status LED"),F("Plugin_222_status_led"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]); - - char statussensordata[32]; - bool status; - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",statussensordata); - - if (status) { - String boardStatus(statussensordata); - - addHtml(F("Board restart code: ")); - int pos1 = boardStatus.indexOf(','); - int pos2 = boardStatus.lastIndexOf(','); - switch ((char)boardStatus.substring(pos1+1,pos2)[0]) - { - case 'P': - { - addHtml(F("powered off")); - break; - } - case 'S': - { - addHtml(F("software reset")); - break; - } - case 'B': - { - addHtml(F("brown out")); - break; - } - case 'W': - { - addHtml(F("watch dog")); - break; - } - case 'U': - default: - { - addHtml(F("unknown")); - break; - } - } - - addHtml(F("Board voltage :")); - addHtml(boardStatus.substring(pos2+1)); - addHtml(F(" V")); - - addHtml(F("")); - - } else { - addHtml(F("Unable to send status command to device")); - success = false; - break; - } - - addFormSubHeader(F("Calibration")); - - int nb_calibration_points = -1; - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0], "Cal,?",sensordata); - - if (status){ - if (strncmp(sensordata,"?Cal,",5)){ - char tmp[2]; - tmp[0] = sensordata[5]; - tmp[1] = '\0', - nb_calibration_points = atoi(tmp); - } - } - - addRowLabel(F("ORP Calibration")); - addFormNumericBox(F("Ref ORP"),F("Plugin_222_ref_cal_M' step='1"),Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1],0,1500); - if (nb_calibration_points > 0) { - addHtml(F(" OK")); - } else { - addHtml(F(" Not yet calibrated")); - } - addFormCheckBox(F("Enable"),F("Plugin_222_enable_cal_M"), false); - - if (nb_calibration_points > 1){ - char sensordata[32]; - char cmd[8] = "Slope,?"; - bool status; - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd,sensordata); - - if (status){ - String slopeAnswer("Answer to 'Slope' command : "); - slopeAnswer += sensordata; - addFormNote(slopeAnswer); - } - } - - addHtml(F("")); - - success = true; - break; - } - - case PLUGIN_WEBFORM_SAVE: - { - Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_222_i2c")); - - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("plugin_222_sensorVersion")); - - char sensordata[32]; - if (isFormItemChecked(F("Plugin_222_status_led"))) { - _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,1",sensordata); - } else { - _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"L,0",sensordata); - } - Settings.TaskDevicePluginConfig[event->TaskIndex][1] = isFormItemChecked(F("Plugin_222_status_led")); - - - Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("Plugin_222_ref_cal_M")); - - String cmd ("Cal,"); - bool triggerCalibrate = false; - if (isFormItemChecked("Plugin_222_enable_cal_M")) { - cmd += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]; - triggerCalibrate = true; - } - if (triggerCalibrate){ - char sensordata[32]; - _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],cmd.c_str(),sensordata); - } - - Plugin_222_init = false; - success = true; - break; - } - - case PLUGIN_INIT: - { - Plugin_222_init = true; - } - - case PLUGIN_READ: - { - char sensordata[32]; - bool status; - - //ok, now we can read the ORP value - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"R",sensordata); - - //we read the voltagedata char statussensordata[32]; - char voltagedata[32]; - status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Status",voltagedata); - - if (status){ - String sensorString(sensordata); - String voltage(voltagedata); - int pos = voltage.lastIndexOf(','); - UserVar[event->BaseVarIndex] = sensorString.toFloat(); - UserVar[event->BaseVarIndex + 1] = voltage.substring(pos+1).toFloat(); - } - else { - UserVar[event->BaseVarIndex] = -1; - UserVar[event->BaseVarIndex + 1] = -1; - } - - //go to sleep - //status = _P222_send_I2C_command(Settings.TaskDevicePluginConfig[event->TaskIndex][0],"Sleep",sensordata); - - success = true; - break; - } - case PLUGIN_WRITE: - { - //TODO : do something more usefull ... - - String tmpString = string; - int argIndex = tmpString.indexOf(','); - if (argIndex) - tmpString = tmpString.substring(0, argIndex); - if (tmpString.equalsIgnoreCase(F("ATLASCMD"))) - { - success = true; - argIndex = string.lastIndexOf(','); - tmpString = string.substring(argIndex + 1); - if (tmpString.equalsIgnoreCase(F("CalMid"))){ - String log("Asking for calibration "); - addLog(LOG_LEVEL_INFO, log); - } - } - break; - } - } - return success; -} - -// Call this function with two char arrays, one containing the command -// The other containing an allocatted char array for answer -// Returns true on success, false otherwise - -bool _P222_send_I2C_command(uint8_t I2Caddress,const char * cmd, char* sensordata) { - uint16_t sensor_bytes_received = 0; - - byte error; - byte i2c_response_code = 0; - byte in_char = 0; - - addLog(LOG_LEVEL_DEBUG, String(cmd)); - Wire.beginTransmission(I2Caddress); - Wire.write(cmd); - error = Wire.endTransmission(); - - if (error != 0) { - //addLog(LOG_LEVEL_ERROR, error); - addLog(LOG_LEVEL_ERROR, F("Wire.endTransmission() returns error: Check ORP shield")); - return false; - } - - //don't read answer if we want to go to sleep - if (strncmp(cmd,"Sleep",5) == 0) { - return true; - } - - i2c_response_code = 254; - while (i2c_response_code == 254) { // in case the cammand takes longer to process, we keep looping here until we get a success or an error - - if ( - ( (cmd[0] == 'r' || cmd[0] == 'R') && cmd[1] == '\0' ) - || - ( ( strncmp(cmd,"cal",3) || strncmp(cmd,"Cal",3) ) && !strncmp(cmd,"Cal,?",5) ) - ) - { - delay(900); - } - else { - delay(300); - } - - Wire.requestFrom(I2Caddress, (uint8_t) 32); //call the circuit and request 32 bytes (this is more then we need). - i2c_response_code = Wire.read(); //read response code - - while (Wire.available()) { //read response - in_char = Wire.read(); - - if (in_char == 0) { //if we receive a null caracter, we're done - while (Wire.available()) { //purge the data line if needed - Wire.read(); - } - - break; //exit the while loop. - } - else { - sensordata[sensor_bytes_received] = in_char; //load this byte into our array. - sensor_bytes_received++; - } - } - sensordata[sensor_bytes_received] = '\0'; - - switch (i2c_response_code) { - case 1: - { - String log = F("< success, answer = "); - log += sensordata; - addLog(LOG_LEVEL_DEBUG, log); - } - break; - - case 2: - addLog(LOG_LEVEL_DEBUG, F("< command failed")); - return false; - - case 254: - addLog(LOG_LEVEL_DEBUG, F("< command pending")); - break; - - case 255: - addLog(LOG_LEVEL_DEBUG, F("< no data")); - return false; - } - } - - addLog(LOG_LEVEL_DEBUG, sensordata); - return true; -} From 2faf88fd2303b15b12c2071e8b7b250038cf6134 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Tue, 5 May 2020 00:40:41 +0200 Subject: [PATCH 042/128] [LittleFS] Make switching between SPIFFS and LittleFS easy to do Just add "_LittleFS" to the PIO env label and it will compile with LittleFS instead of SPIFFS. First impression: - Load speed of web page is just WOW! (average 170 msec) - Saving settings is terribly slow (1...2 seconds) --- .travis.yml | 4 +- platformio_esp82xx_envs.ini | 25 ++++++-- src/ESPEasy-Globals.h | 6 +- src/ESPEasy.ino | 2 +- src/ESPEasyRTC.ino | 16 +++--- src/ESPEasyRules.ino | 4 +- src/ESPEasyStorage.ino | 70 +++++++++++------------ src/ESPEasy_common.h | 6 ++ src/Misc.ino | 14 ++--- src/Networking.ino | 2 +- src/StringProvider.ino | 13 +++-- src/StringProviderTypes.h | 4 +- src/WebServer.ino | 8 +-- src/WebServer_FileList.ino | 8 +-- src/WebServer_LoadFromFS.ino | 2 +- src/WebServer_RootPage.ino | 2 +- src/WebServer_Rules.ino | 10 ++-- src/WebServer_SysInfoPage.ino | 4 +- src/_C016.ino | 2 +- src/src/DataStructs/TimingStats.cpp | 4 +- src/src/DataStructs/TimingStats.h | 4 +- tools/pio/generate-compiletime-defines.py | 13 ++++- 22 files changed, 131 insertions(+), 92 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7bbec2885..64b1bfcaf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,7 +59,7 @@ script: #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e minimal_core_270_sdk3_ESP8266_1M_OTA_FHEM_HA #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e minimal_core_270_sdk3_ESP8285_1M_OTA_Domoticz #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e minimal_core_270_sdk3_ESP8285_1M_OTA_FHEM_HA - #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e normal_ESP8266_16M + #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e normal_ESP8266_16M_LittleFS - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e normal_ESP8266_1M - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e normal_ESP8266_1M_VCC - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e normal_ESP8266_4M1M @@ -72,7 +72,7 @@ script: - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_ESP32_4M316k - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_ESP8266_4M1M_VCC #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_ESP8266_4M1M_VCC_MDNS_SD - #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_beta_ESP8266_16M + #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_beta_ESP8266_16M_LittleFS - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_beta_ESP8266_4M1M before_deploy: diff --git a/platformio_esp82xx_envs.ini b/platformio_esp82xx_envs.ini index 55a54157b..39cc4a7bf 100644 --- a/platformio_esp82xx_envs.ini +++ b/platformio_esp82xx_envs.ini @@ -49,7 +49,7 @@ lib_ignore = ${beta_platform.lib_ignore} extra_scripts = ${esp8266_scripts_custom.extra_scripts} -; Custom: 4M2M version -------------------------- +; Custom: 4M2M version -- SPIFFS -------------- [env:custom_ESP8266_4M2M] extends = esp8266_4M2M platform = ${regular_platform.platform} @@ -60,6 +60,19 @@ build_flags = ${regular_platform.build_flags} lib_ignore = ${regular_platform.lib_ignore} extra_scripts = ${esp8266_scripts_custom.extra_scripts} +; Custom: 4M2M version -- LittleFS -------------- +; LittleFS is determined by using "LittleFS" in the pio env name +[env:custom_ESP8266_4M2M_LittleFS] +extends = esp8266_4M2M +platform = ${regular_platform.platform} +platform_packages = ${regular_platform.platform_packages} +build_flags = ${regular_platform.build_flags} + ${esp8266_4M1M.build_flags} + -DPLUGIN_BUILD_CUSTOM +lib_ignore = ${regular_platform.lib_ignore} +extra_scripts = ${esp8266_scripts_custom.extra_scripts} + + ; Custom: 1M version -------------------------- [env:custom_ESP8266_1M] extends = esp8266_1M @@ -149,8 +162,9 @@ platform_packages = ${regular_platform.platform_packages} build_flags = ${regular_platform.build_flags} ${esp8266_4M1M.build_flags} -; NORMAL: 16M version -------------------------- -[env:normal_ESP8266_16M] +; NORMAL: 16M version --- LittleFS -------------- +; LittleFS is determined by using "LittleFS" in the pio env name +[env:normal_ESP8266_16M_LittleFS] extends = esp8266_16M platform = ${regular_platform.platform} platform_packages = ${regular_platform.platform_packages} @@ -338,8 +352,9 @@ platform_packages = ${testing_beta.platform_packages} build_flags = ${testing_beta.build_flags} ${esp8266_4M1M.build_flags} - -[env:test_beta_ESP8266_16M] +; Test: 16M version -- LittleFS -------------- +; LittleFS is determined by using "LittleFS" in the pio env name +[env:test_beta_ESP8266_16M_LittleFS] extends = esp8266_16M platform = ${testing_beta.platform} platform_packages = ${testing_beta.platform_packages} diff --git a/src/ESPEasy-Globals.h b/src/ESPEasy-Globals.h index 5375d5b82..185d9a636 100644 --- a/src/ESPEasy-Globals.h +++ b/src/ESPEasy-Globals.h @@ -182,7 +182,11 @@ extern NotificationStruct Notification[NPLUGIN_MAX]; #define FILE_RULES "/rules1.txt" #include // #include "esp32_ping.h" - #include "SPIFFS.h" + #ifdef USE_LITTLEFS + #include "LittleFS.h" + #else + #include "SPIFFS.h" + #endif #include #include "esp_wifi.h" // Needed to call ESP-IDF functions like esp_wifi_.... #ifdef FEATURE_MDNS diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index d066c6f0a..7fefd19a9 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -226,7 +226,7 @@ void setup() if (SpiffsSectors() < 32) { - serialPrintln(F("\nNo (or too small) SPIFFS area..\nSystem Halted\nPlease reflash with 128k SPIFFS minimum!")); + serialPrintln(F("\nNo (or too small) FS area..\nSystem Halted\nPlease reflash with 128k FS minimum!")); while (true) delay(1); } diff --git a/src/ESPEasyRTC.ino b/src/ESPEasyRTC.ino index 9326a3a21..5b8bec791 100644 --- a/src/ESPEasyRTC.ino +++ b/src/ESPEasyRTC.ino @@ -45,16 +45,16 @@ // Locations where to store the cached data -// As a file on the SPIFFS filesystem +// As a file on the filesystem #define CACHE_STORAGE_SPIFFS 0 -// Between the sketch and SPIFFS, including OTA area (will overwrite this area when performing OTA) +// Between the sketch and FS, including OTA area (will overwrite this area when performing OTA) #define CACHE_STORAGE_OTA_FREE 1 -// Only use the free space between sketch and SPIFFS, thus avoid OTA area +// Only use the free space between sketch and FS, thus avoid OTA area #define CACHE_STORAGE_NO_OTA_FREE 2 -// Use space after SPIFFS. (e.g. on 16M flash partitioned as 4M, or 4M flash partitioned as 2M) +// Use space after FS. (e.g. on 16M flash partitioned as 4M, or 4M flash partitioned as 2M) #define CACHE_STORAGE_BEHIND_SPIFFS 3 @@ -313,7 +313,7 @@ struct RTC_cache_handler_struct for (int i = 0; i < 2; ++i) { String fname = createCacheFilename(RTC_cache.readFileNr); - if (SPIFFS.exists(fname)) { + if (ESPEASY_FS.exists(fname)) { if (i != 0) { // First attempt failed, so stored read position is not valid RTC_cache.readPos = 0; @@ -346,7 +346,7 @@ struct RTC_cache_handler_struct } islast = peekfilenr > RTC_cache.writeFileNr; - if (SPIFFS.exists(fname)) { + if (ESPEASY_FS.exists(fname)) { return fname; } return ""; @@ -360,7 +360,7 @@ struct RTC_cache_handler_struct if (tryDeleteFile(fname)) { #ifdef RTC_STRUCT_DEBUG - String log = F("RTC : Removed file from SPIFFS: "); + String log = F("RTC : Removed file from FS: "); log += fname; addLog(LOG_LEVEL_INFO, String(log)); #endif // ifdef RTC_STRUCT_DEBUG @@ -503,7 +503,7 @@ private: // } if (SpiffsFull()) { #ifdef RTC_STRUCT_DEBUG - addLog(LOG_LEVEL_ERROR, String(F("RTC : SPIFFS full"))); + addLog(LOG_LEVEL_ERROR, String(F("RTC : FS full"))); #endif // ifdef RTC_STRUCT_DEBUG return false; } diff --git a/src/ESPEasyRules.ino b/src/ESPEasyRules.ino index 9f60893f1..a45d20e19 100644 --- a/src/ESPEasyRules.ino +++ b/src/ESPEasyRules.ino @@ -48,7 +48,7 @@ void checkRuleSets() { fileName += x + 1; fileName += F(".txt"); - if (SPIFFS.exists(fileName)) { + if (ESPEASY_FS.exists(fileName)) { activeRuleSets[x] = true; } else { @@ -122,7 +122,7 @@ void rulesProcessing(String& event) { String fileName = EventToFileName(event); // if exists processed the rule file - if (SPIFFS.exists(fileName)) { + if (ESPEASY_FS.exists(fileName)) { rulesProcessingFile(fileName, event); } #ifndef BUILD_NO_DEBUG diff --git a/src/ESPEasyStorage.ino b/src/ESPEasyStorage.ino index 700e60898..c2246bb4d 100644 --- a/src/ESPEasyStorage.ino +++ b/src/ESPEasyStorage.ino @@ -4,7 +4,7 @@ #include "src/Globals/Plugins.h" /********************************************************************************************\ - SPIFFS error handling + file system error handling Look here for error # reference: https://github.com/pellepl/spiffs/blob/master/src/spiffs.h \*********************************************************************************************/ String FileError(int line, const char *fname) @@ -63,7 +63,7 @@ String appendToFile(const String& fname, const uint8_t *data, unsigned int size) } bool fileExists(const String& fname) { - return SPIFFS.exists(fname); + return ESPEASY_FS.exists(fname); } fs::File tryOpenFile(const String& fname, const String& mode) { @@ -73,14 +73,14 @@ fs::File tryOpenFile(const String& fname, const String& mode) { if ((mode == "r") && !fileExists(fname)) { return f; } - f = SPIFFS.open(fname, mode.c_str()); + f = ESPEASY_FS.open(fname, mode.c_str()); STOP_TIMER(TRY_OPEN_FILE); return f; } bool tryRenameFile(const String& fname_old, const String& fname_new) { if (fileExists(fname_old) && !fileExists(fname_new)) { - return SPIFFS.rename(fname_old, fname_new); + return ESPEASY_FS.rename(fname_old, fname_new); } return false; } @@ -88,7 +88,7 @@ bool tryRenameFile(const String& fname_old, const String& fname_new) { bool tryDeleteFile(const String& fname) { if (fname.length() > 0) { - bool res = SPIFFS.remove(fname); + bool res = ESPEASY_FS.remove(fname); // A call to GarbageCollection() will at most erase a single block. (e.g. 8k block size) // A deleted file may have covered more than a single block, so try to clear multiple blocks. @@ -191,11 +191,11 @@ void fileSystemCheck() checkRAM(F("fileSystemCheck")); addLog(LOG_LEVEL_INFO, F("FS : Mounting...")); - if (SPIFFS.begin()) + if (ESPEASY_FS.begin()) { #if defined(ESP8266) fs::FSInfo fs_info; - SPIFFS.info(fs_info); + ESPEASY_FS.info(fs_info); if (loglevelActiveFor(LOG_LEVEL_INFO)) { String log = F("FS : Mount successful, used "); @@ -240,12 +240,12 @@ bool GarbageCollection() { // Perform garbage collection START_TIMER; - if (SPIFFS.gc()) { + if (ESPEASY_FS.gc()) { addLog(LOG_LEVEL_INFO, F("FS : Success garbage collection")); - STOP_TIMER(SPIFFS_GC_SUCCESS); + STOP_TIMER(FS_GC_SUCCESS); return true; } - STOP_TIMER(SPIFFS_GC_FAIL); + STOP_TIMER(FS_GC_FAIL); return false; #else // ifdef CORE_POST_2_6_0 @@ -255,7 +255,7 @@ bool GarbageCollection() { } /********************************************************************************************\ - Save settings to SPIFFS + Save settings to file system \*********************************************************************************************/ String SaveSettings(void) { @@ -334,7 +334,7 @@ void afterloadSettings() { } /********************************************************************************************\ - Load settings from SPIFFS + Load settings from file system \*********************************************************************************************/ String LoadSettings() { @@ -610,7 +610,7 @@ String SaveStringArray(SettingsType::Enum settingsType, int index, const String /********************************************************************************************\ - Save Task settings to SPIFFS + Save Task settings to file system \*********************************************************************************************/ String SaveTaskSettings(taskIndex_t TaskIndex) { @@ -631,7 +631,7 @@ String SaveTaskSettings(taskIndex_t TaskIndex) } /********************************************************************************************\ - Load Task settings from SPIFFS + Load Task settings from file system \*********************************************************************************************/ String LoadTaskSettings(taskIndex_t TaskIndex) { @@ -669,7 +669,7 @@ String LoadTaskSettings(taskIndex_t TaskIndex) } /********************************************************************************************\ - Save Custom Task settings to SPIFFS + Save Custom Task settings to file system \*********************************************************************************************/ String SaveCustomTaskSettings(taskIndex_t TaskIndex, byte *memAddress, int datasize) { @@ -707,7 +707,7 @@ String ClearCustomTaskSettings(taskIndex_t TaskIndex) } /********************************************************************************************\ - Load Custom Task settings from SPIFFS + Load Custom Task settings from file system \*********************************************************************************************/ String LoadCustomTaskSettings(taskIndex_t TaskIndex, byte *memAddress, int datasize) { @@ -734,7 +734,7 @@ String LoadCustomTaskSettings(taskIndex_t TaskIndex, String strings[], uint16_t } /********************************************************************************************\ - Save Controller settings to SPIFFS + Save Controller settings to file system \*********************************************************************************************/ String SaveControllerSettings(controllerIndex_t ControllerIndex, ControllerSettingsStruct& controller_settings) { @@ -745,7 +745,7 @@ String SaveControllerSettings(controllerIndex_t ControllerIndex, ControllerSetti } /********************************************************************************************\ - Load Controller settings to SPIFFS + Load Controller settings to file system \*********************************************************************************************/ String LoadControllerSettings(controllerIndex_t ControllerIndex, ControllerSettingsStruct& controller_settings) { checkRAM(F("LoadControllerSettings")); @@ -768,7 +768,7 @@ String ClearCustomControllerSettings(controllerIndex_t ControllerIndex) } /********************************************************************************************\ - Save Custom Controller settings to SPIFFS + Save Custom Controller settings to file system \*********************************************************************************************/ String SaveCustomControllerSettings(controllerIndex_t ControllerIndex, byte *memAddress, int datasize) { @@ -777,7 +777,7 @@ String SaveCustomControllerSettings(controllerIndex_t ControllerIndex, byte *mem } /********************************************************************************************\ - Load Custom Controller settings to SPIFFS + Load Custom Controller settings to file system \*********************************************************************************************/ String LoadCustomControllerSettings(controllerIndex_t ControllerIndex, byte *memAddress, int datasize) { @@ -786,7 +786,7 @@ String LoadCustomControllerSettings(controllerIndex_t ControllerIndex, byte *mem } /********************************************************************************************\ - Save Controller settings to SPIFFS + Save Controller settings to file system \*********************************************************************************************/ String SaveNotificationSettings(int NotificationIndex, byte *memAddress, int datasize) { @@ -795,7 +795,7 @@ String SaveNotificationSettings(int NotificationIndex, byte *memAddress, int dat } /********************************************************************************************\ - Load Controller settings to SPIFFS + Load Controller settings to file system \*********************************************************************************************/ String LoadNotificationSettings(int NotificationIndex, byte *memAddress, int datasize) { @@ -804,7 +804,7 @@ String LoadNotificationSettings(int NotificationIndex, byte *memAddress, int dat } /********************************************************************************************\ - Init a file with zeros on SPIFFS + Init a file with zeros on file system \*********************************************************************************************/ String InitFile(const String& fname, int datasize) { @@ -830,7 +830,7 @@ String InitFile(const String& fname, int datasize) } /********************************************************************************************\ - Save data into config file on SPIFFS + Save data into config file on file system \*********************************************************************************************/ String SaveToFile(const char *fname, int index, const byte *memAddress, int datasize) { @@ -965,7 +965,7 @@ String ClearInFile(const char *fname, int index, int datasize) } /********************************************************************************************\ - Load data from config file on SPIFFS + Load data from config file on file system \*********************************************************************************************/ String LoadFromFile(const char *fname, int offset, byte *memAddress, int datasize) { @@ -1072,7 +1072,7 @@ String ClearInFile(SettingsType::Enum settingsType, int index) { } /********************************************************************************************\ - Check SPIFFS area settings + Check file system area settings \*********************************************************************************************/ int SpiffsSectors() { @@ -1097,11 +1097,11 @@ size_t SpiffsUsedBytes() { size_t result = 1; // Do not output 0, this may be used in divisions. #ifdef ESP32 - result = SPIFFS.usedBytes(); + result = ESPEASY_FS.usedBytes(); #endif // ifdef ESP32 #ifdef ESP8266 fs::FSInfo fs_info; - SPIFFS.info(fs_info); + ESPEASY_FS.info(fs_info); result = fs_info.usedBytes; #endif // ifdef ESP8266 return result; @@ -1111,25 +1111,25 @@ size_t SpiffsTotalBytes() { size_t result = 1; // Do not output 0, this may be used in divisions. #ifdef ESP32 - result = SPIFFS.totalBytes(); + result = ESPEASY_FS.totalBytes(); #endif // ifdef ESP32 #ifdef ESP8266 fs::FSInfo fs_info; - SPIFFS.info(fs_info); + ESPEASY_FS.info(fs_info); result = fs_info.totalBytes; #endif // ifdef ESP8266 return result; } size_t SpiffsBlocksize() { - size_t result = 8192; // Some default viable for most 1 MB SPIFFS filesystems + size_t result = 8192; // Some default viable for most 1 MB file systems #ifdef ESP32 result = 8192; // Just assume 8k, since we cannot query it #endif // ifdef ESP32 #ifdef ESP8266 fs::FSInfo fs_info; - SPIFFS.info(fs_info); + ESPEASY_FS.info(fs_info); result = fs_info.blockSize; #endif // ifdef ESP8266 return result; @@ -1143,7 +1143,7 @@ size_t SpiffsPagesize() { #endif // ifdef ESP32 #ifdef ESP8266 fs::FSInfo fs_info; - SPIFFS.info(fs_info); + ESPEASY_FS.info(fs_info); result = fs_info.pageSize; #endif // ifdef ESP8266 return result; @@ -1205,7 +1205,7 @@ bool getCacheFileCounters(uint16_t& lowest, uint16_t& highest, size_t& filesizeH highest = 0; filesizeHighest = 0; #ifdef ESP8266 - Dir dir = SPIFFS.openDir("cache"); + Dir dir = ESPEASY_FS.openDir("cache"); while (dir.next()) { String filename = dir.fileName(); @@ -1224,7 +1224,7 @@ bool getCacheFileCounters(uint16_t& lowest, uint16_t& highest, size_t& filesizeH } #endif // ESP8266 #ifdef ESP32 - File root = SPIFFS.open("/cache"); + File root = ESPEASY_FS.open("/cache"); File file = root.openNextFile(); while (file) diff --git a/src/ESPEasy_common.h b/src/ESPEasy_common.h index b69eebbc5..dce51298f 100644 --- a/src/ESPEasy_common.h +++ b/src/ESPEasy_common.h @@ -22,6 +22,12 @@ namespace std #include "src/DataStructs/ESPEasyDefaults.h" +#ifdef USE_LITTLEFS + #include + #define ESPEASY_FS LittleFS +#else + #define ESPEASY_FS SPIFFS +#endif // Include custom first, then build info. (one may want to set BUILD_GIT for example) #include "ESPEasy_buildinfo.h" diff --git a/src/Misc.ino b/src/Misc.ino index 75667355b..73a6c5834 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -1141,14 +1141,14 @@ void ResetFactory() RTC.factoryResetCounter++; saveToRTC(); - //always format on factory reset, in case of corrupt SPIFFS - SPIFFS.end(); + //always format on factory reset, in case of corrupt FS + ESPEASY_FS.end(); serialPrintln(F("RESET: formatting...")); - SPIFFS.format(); + ESPEASY_FS.format(); serialPrintln(F("RESET: formatting done...")); - if (!SPIFFS.begin()) + if (!ESPEASY_FS.begin()) { - serialPrintln(F("RESET: FORMAT SPIFFS FAILED!")); + serialPrintln(F("RESET: FORMAT FS FAILED!")); return; } @@ -1567,7 +1567,7 @@ void prepareShutdown() process_serialWriteBuffer(); flushAndDisconnectAllClients(); saveUserVarToRTC(); - SPIFFS.end(); + ESPEASY_FS.end(); delay(100); // give the node time to flush all before reboot or sleep node_time.now(); saveToRTC(); @@ -2766,7 +2766,7 @@ void ArduinoOTAInit() ArduinoOTA.onStart([]() { serialPrintln(F("OTA : Start upload")); ArduinoOTAtriggered = true; - SPIFFS.end(); //important, otherwise it fails + ESPEASY_FS.end(); //important, otherwise it fails }); ArduinoOTA.onEnd([]() { diff --git a/src/Networking.ino b/src/Networking.ino index 47c29d577..72753685f 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -1075,7 +1075,7 @@ bool downloadFile(const String& url, String file_save, const String& user, const } long len = http.getSize(); - File f = SPIFFS.open(file_save, "w"); + File f = ESPEASY_FS.open(file_save, "w"); if (f) { uint8_t buff[128]; diff --git a/src/StringProvider.ino b/src/StringProvider.ino index 53b10179c..1e61c7cdc 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -96,8 +96,13 @@ String getLabel(LabelType::Enum label) { case LabelType::FLASH_WRITE_COUNT: return F("Flash Writes"); case LabelType::SKETCH_SIZE: return F("Sketch Size"); case LabelType::SKETCH_FREE: return F("Sketch Free"); - case LabelType::SPIFFS_SIZE: return F("SPIFFS Size"); - case LabelType::SPIFFS_FREE: return F("SPIFFS Free"); + #ifdef USE_LITTLEFS + case LabelType::FS_SIZE: return F("Little FS Size"); + case LabelType::FS_FREE: return F("Little FS Free"); + #else + case LabelType::FS_SIZE: return F("SPIFFS Size"); + case LabelType::FS_FREE: return F("SPIFFS Free"); + #endif case LabelType::MAX_OTA_SKETCH_SIZE: return F("Max. OTA Sketch Size"); case LabelType::OTA_2STEP: return F("OTA 2-step Needed"); case LabelType::OTA_POSSIBLE: return F("OTA possible"); @@ -201,8 +206,8 @@ String getValue(LabelType::Enum label) { case LabelType::FLASH_WRITE_COUNT: break; case LabelType::SKETCH_SIZE: break; case LabelType::SKETCH_FREE: break; - case LabelType::SPIFFS_SIZE: break; - case LabelType::SPIFFS_FREE: break; + case LabelType::FS_SIZE: break; + case LabelType::FS_FREE: break; case LabelType::MAX_OTA_SKETCH_SIZE: break; case LabelType::OTA_2STEP: break; case LabelType::OTA_POSSIBLE: break; diff --git a/src/StringProviderTypes.h b/src/StringProviderTypes.h index 04abfdbae..82d976d27 100644 --- a/src/StringProviderTypes.h +++ b/src/StringProviderTypes.h @@ -95,8 +95,8 @@ enum Enum : short { FLASH_WRITE_COUNT, SKETCH_SIZE, SKETCH_FREE, - SPIFFS_SIZE, - SPIFFS_FREE, + FS_SIZE, + FS_FREE, MAX_OTA_SKETCH_SIZE, OTA_2STEP, OTA_POSSIBLE, diff --git a/src/WebServer.ino b/src/WebServer.ino index ac9f5aba7..dfd23ce6b 100644 --- a/src/WebServer.ino +++ b/src/WebServer.ino @@ -568,7 +568,7 @@ void getWebPageTemplateVar(const String& varName) else if (varName == F("logo")) { - if (SPIFFS.exists(F("esp.png"))) + if (ESPEASY_FS.exists(F("esp.png"))) { addHtml(F("")); } @@ -576,7 +576,7 @@ void getWebPageTemplateVar(const String& varName) else if (varName == F("css")) { - if (SPIFFS.exists(F("esp.css"))) // now css is written in writeDefaultCSS() to SPIFFS and always present + if (ESPEASY_FS.exists(F("esp.css"))) // now css is written in writeDefaultCSS() to FS and always present // if (0) //TODO { addHtml(F("")); @@ -623,7 +623,7 @@ void writeDefaultCSS(void) { return; // TODO - if (!SPIFFS.exists(F("esp.css"))) + if (!ESPEASY_FS.exists(F("esp.css"))) { String defaultCSS; @@ -632,7 +632,7 @@ void writeDefaultCSS(void) if (f) { if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("CSS : Writing default CSS file to SPIFFS ("); + String log = F("CSS : Writing default CSS file to FS ("); log += defaultCSS.length(); log += F(" bytes)"); addLog(LOG_LEVEL_INFO, log); diff --git a/src/WebServer_FileList.ino b/src/WebServer_FileList.ino index f45b3c8fb..3e5dca5cc 100644 --- a/src/WebServer_FileList.ino +++ b/src/WebServer_FileList.ino @@ -37,7 +37,7 @@ void handle_filelist_json() { addHtml("[{"); bool firstentry = true; # if defined(ESP32) - File root = SPIFFS.open("/"); + File root = ESPEASY_FS.open("/"); File file = root.openNextFile(); int count = -1; @@ -62,7 +62,7 @@ void handle_filelist_json() { } # endif // if defined(ESP32) # if defined(ESP8266) - fs::Dir dir = SPIFFS.openDir(""); + fs::Dir dir = ESPEASY_FS.openDir(""); int count = -1; @@ -156,7 +156,7 @@ void handle_filelist() { # if defined(ESP8266) - fs::Dir dir = SPIFFS.openDir(""); + fs::Dir dir = ESPEASY_FS.openDir(""); while (dir.next() && count < endIdx) { @@ -181,7 +181,7 @@ void handle_filelist() { moreFilesPresent = dir.next(); # endif // if defined(ESP8266) # if defined(ESP32) - File root = SPIFFS.open("/"); + File root = ESPEASY_FS.open("/"); File file = root.openNextFile(); while (file && count < endIdx) diff --git a/src/WebServer_LoadFromFS.ino b/src/WebServer_LoadFromFS.ino index d1c1b3255..ad90eee04 100644 --- a/src/WebServer_LoadFromFS.ino +++ b/src/WebServer_LoadFromFS.ino @@ -1,6 +1,6 @@ // ******************************************************************************** -// Web Interface server web file from SPIFFS +// Web Interface server web file from FS // ******************************************************************************** bool loadFromFS(boolean spiffs, String path) { // path is a deepcopy, since it will be changed here. diff --git a/src/WebServer_RootPage.ino b/src/WebServer_RootPage.ino index 150e9230a..c70331fe5 100644 --- a/src/WebServer_RootPage.ino +++ b/src/WebServer_RootPage.ino @@ -18,7 +18,7 @@ void handle_root() { if (!isLoggedIn()) { return; } navMenuIndex = 0; - // if index.htm exists on SPIFFS serve that one (first check if gziped version exists) + // if index.htm exists on FS serve that one (first check if gziped version exists) if (loadFromFS(true, F("/index.htm.gz"))) { return; } if (loadFromFS(false, F("/index.htm.gz"))) { return; } diff --git a/src/WebServer_Rules.ino b/src/WebServer_Rules.ino index a2d3ef144..600cf61db 100644 --- a/src/WebServer_Rules.ino +++ b/src/WebServer_Rules.ino @@ -60,7 +60,7 @@ void handle_rules() { } else // changed set, check if file exists and create new { - if (!SPIFFS.exists(fileName)) + if (!ESPEASY_FS.exists(fileName)) { log += F(" Create new file: "); log += fileName; @@ -349,7 +349,7 @@ void handle_rules_delete() { if (fileName.length() > 0) { - removed = SPIFFS.remove(fileName); + removed = ESPEASY_FS.remove(fileName); } if (removed) @@ -422,7 +422,7 @@ bool handle_rules_edit(String originalUri, bool isAddNew) { Serial.print(F("File name: ")); Serial.println(fileName); #endif // ifdef WEBSERVER_RULES_DEBUG - bool isEdit = SPIFFS.exists(fileName); + bool isEdit = ESPEASY_FS.exists(fileName); if (web_server.args() > 0) { @@ -596,7 +596,7 @@ bool EnumerateFileAndDirectory(String & rootPath bool next = true; #ifdef ESP8266 - fs::Dir dir = SPIFFS.openDir(rootPath); + fs::Dir dir = ESPEASY_FS.openDir(rootPath); Serial.print(F("Enumerate files of ")); Serial.println(rootPath); @@ -620,7 +620,7 @@ bool EnumerateFileAndDirectory(String & rootPath hasMore = dir.next(); #endif // ifdef ESP8266 #ifdef ESP32 - File root = SPIFFS.open(rootPath); + File root = ESPEASY_FS.open(rootPath); if (root) { diff --git a/src/WebServer_SysInfoPage.ino b/src/WebServer_SysInfoPage.ino index b37c3544a..fdb317be0 100644 --- a/src/WebServer_SysInfoPage.ino +++ b/src/WebServer_SysInfoPage.ino @@ -596,7 +596,7 @@ void handle_sysinfo_Storage() { } - addRowLabel(getLabel(LabelType::SPIFFS_SIZE)); + addRowLabel(getLabel(LabelType::FS_SIZE)); { String html; html.reserve(32); @@ -620,7 +620,7 @@ void handle_sysinfo_Storage() { { # if defined(ESP8266) fs::FSInfo fs_info; - SPIFFS.info(fs_info); + ESPEASY_FS.info(fs_info); addRowLabel(F("Maximum open files")); addHtml(String(fs_info.maxOpenFiles)); diff --git a/src/_C016.ino b/src/_C016.ino index adbb803b2..1fd5221e8 100644 --- a/src/_C016.ino +++ b/src/_C016.ino @@ -16,7 +16,7 @@ Typical sample sets contain: These are the result of any plugin sending data to this controller. The controller can save the samples from RTC memory to several places on the flash: -- Files on SPIFFS +- Files on FS - Part reserved for OTA update (TODO) - Unused flash after the partitioned space (TODO) diff --git a/src/src/DataStructs/TimingStats.cpp b/src/src/DataStructs/TimingStats.cpp index c2ef903b1..67a43f756 100644 --- a/src/src/DataStructs/TimingStats.cpp +++ b/src/src/DataStructs/TimingStats.cpp @@ -214,8 +214,8 @@ String getMiscStatsName(int stat) { case WIFI_NOTCONNECTED_STATS: return F("WiFi.isConnected() (fail)"); case LOAD_TASK_SETTINGS: return F("LoadTaskSettings()"); case TRY_OPEN_FILE: return F("TryOpenFile()"); - case SPIFFS_GC_SUCCESS: return F("SPIFFS GC success"); - case SPIFFS_GC_FAIL: return F("SPIFFS GC fail"); + case FS_GC_SUCCESS: return F("ESPEASY_FS GC success"); + case FS_GC_FAIL: return F("ESPEASY_FS GC fail"); case RULES_PROCESSING: return F("rulesProcessing()"); case GRAT_ARP_STATS: return F("sendGratuitousARP()"); case BACKGROUND_TASKS: return F("backgroundtasks()"); diff --git a/src/src/DataStructs/TimingStats.h b/src/src/DataStructs/TimingStats.h index 9a836f617..920734ac6 100644 --- a/src/src/DataStructs/TimingStats.h +++ b/src/src/DataStructs/TimingStats.h @@ -63,8 +63,8 @@ # define WIFI_NOTCONNECTED_STATS 42 # define LOAD_TASK_SETTINGS 43 # define TRY_OPEN_FILE 44 -# define SPIFFS_GC_SUCCESS 45 -# define SPIFFS_GC_FAIL 46 +# define FS_GC_SUCCESS 45 +# define FS_GC_FAIL 46 # define PARSE_SYSVAR 47 # define PARSE_SYSVAR_NOCHANGE 48 # define PARSE_TEMPLATE_PADDED 49 diff --git a/tools/pio/generate-compiletime-defines.py b/tools/pio/generate-compiletime-defines.py index bcfc89ad0..559c422de 100644 --- a/tools/pio/generate-compiletime-defines.py +++ b/tools/pio/generate-compiletime-defines.py @@ -18,6 +18,15 @@ def get_git_description(): return Repository('.').head.shorthand +def deduct_flags_from_pioenv(): + fs_str = "SPIFFS" + if "LittleFS" in env["PIOENV"]: + fs_str = "LittleFS" + env.Append(CPPDEFINES=[ + "USE_LITTLEFS"]) + print("\u001b[33m File System: \u001b[0m {}".format(fs_str)) + + # needed to wrap in a number of double quotes. # one level for adding it to the list of defines # another level to have the string quoted in the .cpp file @@ -53,11 +62,11 @@ def gen_compiletime_defines(node): CCFLAGS=env["CCFLAGS"] ) - #return node +print("\u001b[32m Compile time defines \u001b[0m") +deduct_flags_from_pioenv() # Set the binary filename in the environment to be used in other build steps env.Replace(PROGNAME=create_binary_filename()) -print("\u001b[32m Compile time defines \u001b[0m") print("\u001b[33m PROGNAME: \u001b[0m {}".format(env['PROGNAME'])) print("\u001b[33m BUILD_PLATFORM: \u001b[0m {}".format(platform.platform())) print("\u001b[33m GIT_HEAD: \u001b[0m {}".format(get_git_description())) From ca034db1ad4feda5f2e8c00a1883b68880de99bc Mon Sep 17 00:00:00 2001 From: Peter Kretz Date: Wed, 6 May 2020 21:27:22 +0200 Subject: [PATCH 043/128] - Error in Network Name fpr WiFi fixed - logging improvements --- src/ESPEasyWiFiEvent.cpp | 16 +++++++++++----- src/ESPEasyWifi.cpp | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index 2b9c17e86..939b1e884 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -121,13 +121,19 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { case SYSTEM_EVENT_ETH_GOT_IP: { String log = F("ETH MAC: "); - log += ETH.macAddress(); - log += F(", IPv4: "); - log += ETH.localIP().toString(); + log += NetworkMacAddress(); + log += F(" IPv4: "); + log += NetworkLocalIP().toString(); + log += " ("; + log += NetworkGetHostname(); + log += F(") GW: "); + log += NetworkGatewayIP().toString(); + log += F(" SN: "); + log += NetworkSubnetMask().toString(); if (ETH.fullDuplex()) { - log += F(", FULL_DUPLEX"); + log += F(" FULL_DUPLEX"); } - log += F(", "); + log += F(" "); log += ETH.linkSpeed(); log += F("Mbps"); addLog(LOG_LEVEL_INFO, log); diff --git a/src/ESPEasyWifi.cpp b/src/ESPEasyWifi.cpp index 05dff9d98..f4d55eb66 100644 --- a/src/ESPEasyWifi.cpp +++ b/src/ESPEasyWifi.cpp @@ -206,7 +206,7 @@ bool prepareWiFi() { } setSTA(true); char hostname[40]; - safe_strncpy(hostname, NetworkGetHostname().c_str(), sizeof(hostname)); + safe_strncpy(hostname, NetworkCreateRFCCompliantHostname().c_str(), sizeof(hostname)); #if defined(ESP8266) wifi_station_set_hostname(hostname); From dbb5522f30d62e690911f12a3741186aea9ec965 Mon Sep 17 00:00:00 2001 From: Florin Date: Fri, 22 May 2020 23:04:33 -0400 Subject: [PATCH 044/128] Disable Arduino OTA by default for ESP32 --- src/ESPEasyStorage.ino | 4 ++++ src/ESPEasy_common.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ESPEasyStorage.ino b/src/ESPEasyStorage.ino index 700e60898..61bd882e2 100644 --- a/src/ESPEasyStorage.ino +++ b/src/ESPEasyStorage.ino @@ -3,6 +3,10 @@ #include "src/Globals/ResetFactoryDefaultPref.h" #include "src/Globals/Plugins.h" +#ifdef ESP32 //MFD: These were missing when not using the ARDUINO_OTA lib + #include + #include +#endif /********************************************************************************************\ SPIFFS error handling Look here for error # reference: https://github.com/pellepl/spiffs/blob/master/src/spiffs.h diff --git a/src/ESPEasy_common.h b/src/ESPEasy_common.h index b69eebbc5..a9fcdbbf1 100644 --- a/src/ESPEasy_common.h +++ b/src/ESPEasy_common.h @@ -106,7 +106,7 @@ String getUnknownString(); // #define FEATURE_MDNS #endif #if defined(ESP32) - #define FEATURE_ARDUINO_OTA + //#define FEATURE_ARDUINO_OTA //#define FEATURE_MDNS #endif From 749c335bf10406bc79613f50f3f83a584914171b Mon Sep 17 00:00:00 2001 From: tonhuisman Date: Sat, 23 May 2020 14:42:16 +0200 Subject: [PATCH 045/128] [Rules page] Add RTD help button and fix page layout issue ('Old Engine') --- src/WebServer_Rules.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WebServer_Rules.ino b/src/WebServer_Rules.ino index a2d3ef144..ac72a7d75 100644 --- a/src/WebServer_Rules.ino +++ b/src/WebServer_Rules.ino @@ -98,7 +98,9 @@ void handle_rules() { addHtml(F("")); addSelector(F("set"), RULESETS_MAX, options, optionValues, NULL, choice, true, true); addHelpButton(F("Tutorial_Rules")); + addRTDHelpButton(F("Rules/Rules.html")); + html_TR_TD(); Rule_showRuleTextArea(fileName); html_TR_TD(); From e25fd0551cff17eb6443204261dcd48835fa1f6d Mon Sep 17 00:00:00 2001 From: sakinit Date: Sat, 23 May 2020 19:46:28 +0200 Subject: [PATCH 046/128] Revert P1WifiGateway to 30cbb4c to bugfix this more generic code --- src/_P044_P1WifiGateway.ino | 601 +++++++++++++++++++----------------- 1 file changed, 324 insertions(+), 277 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index 9c4653d1e..3b58a27b2 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -9,43 +9,237 @@ // see http://romix.macuser.nl for kits //####################################################################################################### -#include "_Plugin_Helper.h" - #define PLUGIN_044 #define PLUGIN_ID_044 44 #define PLUGIN_NAME_044 "Communication - P1 Wifi Gateway" #define PLUGIN_VALUENAME1_044 "P1WifiGateway" -#define P044_STATUS_LED 12 -#define P044_BUFFER_SIZE 1024 -#define P044_NETBUF_SIZE 128 -#define P044_DISABLED 0 -#define P044_WAITING 1 -#define P044_READING 2 -#define P044_CHECKSUM 3 -#define P044_DONE 4 +#define P044_STATUS_LED 12 +#define P044_BUFFER_SIZE 1024 +#define P044_NETBUF_SIZE 128 +#define P044_DISABLED 0 +#define P044_WAITING 1 +#define P044_READING 2 +#define P044_CHECKSUM 3 +#define P044_DONE 4 -boolean Plugin_044_init = false; -boolean serialdebug = false; -char* Plugin_044_serial_buf = nullptr; -unsigned int bytes_read = 0; -boolean CRCcheck = false; -unsigned int currCRC = 0; -int checkI = 0; +#define P044_result_no_error 0 +#define P044_result_error_start_detected 1 +#define P044_result_error_data_corrupt 2 +#define P044_result_error_invalid_crc 3 +#define P044_result_data_sent 4 -WiFiServer *P1GatewayServer = nullptr; -WiFiClient P1GatewayClient; -// Fixme TD-er: Reverted to old implementation for now. -// This one has been reverted in https://github.com/letscontrolit/ESPEasy/pull/2352 -// Since both plugins (P020 and P044) are almost identical in handling serial data. -// However that version of P044 had a number of other fixes which may be very useful anyway. + +struct P044_data_struct : public PluginTaskData_base { + + P044_data_struct(unsigned int portnumber) { + clearBuffer(); + P1GatewayServer = new WiFiServer(portnumber); + if (nullptr != P1GatewayServer) { + P1GatewayServer->begin(); + init = true; + } + } + + ~P044_data_struct() { + if (nullptr != P1GatewayServer) { + P1GatewayServer->close(); + delete P1GatewayServer; + P1GatewayServer = nullptr; + } + } + + void clearBuffer() { + serial_buffer = ""; + serial_buffer.reserve(P044_BUFFER_SIZE); + bytes_read = 0; + } + + void addChar(char ch) { + serial_buffer += ch; + ++bytes_read; + } + + /* checkDatagram + checks whether the P044_CHECKSUM of the data received from P1 matches the P044_CHECKSUM attached to the + telegram + based on code written by Jan ten Hove + https://github.com/jantenhove/P1-Meter-ESP8266 + */ + bool checkDatagram(int len) { + int startChar = serial_buffer.lastIndexOf('/', len); + int endChar = serial_buffer.lastIndexOf('!', len); + bool validCRCFound = false; + + if (!CRCcheck) return true; + +/* + if (serialdebug) { + serialPrint(F("input length: ")); + serialPrintln(String(len)); + serialPrint("Start char \\ : "); + serialPrintln(String(startChar)); + serialPrint(F("End char ! : ")); + serialPrintln(String(endChar)); + } +*/ + + if (endChar >= 0) + { + currCRC = CRC16(0x0000, serial_buffer, endChar - startChar + 1); + + char messageCRC[5]; + strncpy(messageCRC, &serial_buffer[endChar + 1], 4); + messageCRC[4] = 0; + if (serialdebug) { + for (int cnt = 0; cnt < len; cnt++) + serialPrint(serial_buffer.substring(cnt)); + } + + validCRCFound = (strtoul(messageCRC, NULL, 16) == currCRC); + currCRC = 0; + } + return validCRCFound; + } + + + /* + validP1char + checks whether the incoming character is a valid one for a P1 datagram. Returns false if not, which signals corrupt datagram + */ + bool validP1char(char ch) { + if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) + { + return true; + } + switch (ch) { + case '.': + case '!': + case ' ': + case '\\': // Single backslash, but escaped in C++ + case '\r': + case '\n': + case '(': + case ')': + case '-': + case '*': + case ':': + return true; + } + return false; + } + + + + byte readSerialData(int RXWait, char& ch) { + byte result = P044_result_no_error; + if (P1GatewayClient.connected()) + { + if (RXWait == 0) + RXWait = 1; + int timeOut = RXWait; + while (timeOut > 0) + { + while (Serial.available() && state != P044_DONE) { + if (bytes_read < P044_BUFFER_SIZE - 5) { + ch = Serial.read(); + digitalWrite(P044_STATUS_LED, 1); + switch (state) { + case P044_DISABLED: //ignore incoming data + break; + case P044_WAITING: + if (ch == '/') { + clearBuffer(); + addChar(ch); + state = P044_READING; + } // else ignore data + break; + case P044_READING: + if (ch == '!') { + if (CRCcheck) { + state = P044_CHECKSUM; + } else { + state = P044_DONE; + } + } + if (validP1char(ch)) { + addChar(ch); + } else if (ch=='/') { + result = P044_result_error_start_detected; + clearBuffer(); + addChar(ch); + } else { // input is non-ascii + result = P044_result_error_data_corrupt; + Serial.flush(); + clearBuffer(); + state = P044_WAITING; + } + break; + case P044_CHECKSUM: + ++checkI; + if (checkI == 4) { + checkI = 0; + state = P044_DONE; + } + addChar(ch); + break; + case P044_DONE: + // serial_buffer[bytes_read]= '\n'; + // bytes_read++; + // serial_buffer[bytes_read] = 0; + break; + } + } + else + { + Serial.read(); // when the buffer is full, just read remaining input, but do not store... + clearBuffer(); + state = P044_WAITING; // reset + } + digitalWrite(P044_STATUS_LED, 0); + timeOut = RXWait; // if serial received, reset timeout counter + } + delay(1); + --timeOut; + } + + if (state == P044_DONE) { + if (checkDatagram(bytes_read)) { + addChar('\r'); + addChar('\n'); + // No longer needed for the string to be null-terminated, since .c_str() does deliver 0-terminated char array pointer +// serial_buffer[bytes_read] = 0; + P1GatewayClient.write(serial_buffer.c_str(), bytes_read); + P1GatewayClient.flush(); + result = P044_result_data_sent; + } else { + result = P044_result_error_invalid_crc; + } + clearBuffer(); + state = P044_WAITING; + } // state == P044_DONE + } + return result; + } + + + WiFiServer *P1GatewayServer = nullptr; + WiFiClient P1GatewayClient; + String serial_buffer; + unsigned int bytes_read = 0; + unsigned int currCRC = 0; + int state = P044_DISABLED; + int checkI = 0; + byte connectionState = 0; + boolean init = false; + boolean serialdebug = false; + boolean CRCcheck = false; +}; boolean Plugin_044(byte function, struct EventStruct *event, String& string) { boolean success = false; - static byte connectionState = 0; - static int state = P044_DISABLED; switch (function) { @@ -73,24 +267,17 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) case PLUGIN_WEBFORM_LOAD: { + LoadTaskSettings(event->TaskIndex); addFormNumericBox(F("TCP Port"), F("p044_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]); addFormNumericBox(F("Baud Rate"), F("p044_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]); - addFormNumericBox(F("Data bits"), F("p044_data"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]); - byte choice = ExtraTaskSettings.TaskDevicePluginConfigLong[3]; - String options[3]; - options[0] = F("No parity"); - options[1] = F("Even"); - options[2] = F("Odd"); - int optionValues[3] = { 0, 2, 3 }; - addFormSelector(F("Parity"), F("p044_parity"), 3, options, optionValues, choice); - - addFormNumericBox(F("Stop bits"), F("p044_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]); + byte serialConfChoice = serialHelper_convertOldSerialConfig(PCONFIG(1)); + serialHelper_serialconfig_webformLoad(event, serialConfChoice); // FIXME TD-er: Why isn't this using the normal pin selection functions? - addFormPinSelect(F("Reset target after boot"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]); + addFormPinSelect(F("Reset target after boot"), F("taskdevicepin1"), CONFIG_PIN1); - addFormNumericBox(F("RX Receive Timeout (mSec)"), F("p044_rxwait"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]); + addFormNumericBox(F("RX Receive Timeout (mSec)"), F("p044_rxwait"), PCONFIG(0)); success = true; break; @@ -98,12 +285,11 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) case PLUGIN_WEBFORM_SAVE: { + LoadTaskSettings(event->TaskIndex); ExtraTaskSettings.TaskDevicePluginConfigLong[0] = getFormItemInt(F("p044_port")); ExtraTaskSettings.TaskDevicePluginConfigLong[1] = getFormItemInt(F("p044_baud")); - ExtraTaskSettings.TaskDevicePluginConfigLong[2] = getFormItemInt(F("p044_data")); - ExtraTaskSettings.TaskDevicePluginConfigLong[3] = getFormItemInt(F("p044_parity")); - ExtraTaskSettings.TaskDevicePluginConfigLong[4] = getFormItemInt(F("p044_stop")); - Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("p044_rxwait")); + PCONFIG(0) = getFormItemInt(F("p044_rxwait")); + PCONFIG(1) = serialHelper_serialconfig_webformSave(); success = true; break; @@ -115,100 +301,89 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) digitalWrite(P044_STATUS_LED, 0); LoadTaskSettings(event->TaskIndex); - if ((ExtraTaskSettings.TaskDevicePluginConfigLong[0] != 0) && (ExtraTaskSettings.TaskDevicePluginConfigLong[1] != 0)) + if ((ExtraTaskSettings.TaskDevicePluginConfigLong[0] == 0) || + (ExtraTaskSettings.TaskDevicePluginConfigLong[1] == 0)) + { + break; + } + + #if defined(ESP8266) + byte serialconfig = 0; + #elif defined(ESP32) + uint32_t serialconfig = 0x8000000; + #endif + serialconfig |= serialHelper_convertOldSerialConfig(PCONFIG(1)); + #if defined(ESP8266) + Serial.begin(ExtraTaskSettings.TaskDevicePluginConfigLong[1], (SerialConfig)serialconfig); + #elif defined(ESP32) + Serial.begin(ExtraTaskSettings.TaskDevicePluginConfigLong[1], serialconfig); + #endif + + initPluginTaskData(event->TaskIndex, new P044_data_struct(ExtraTaskSettings.TaskDevicePluginConfigLong[0])); + P044_data_struct *P044_data = + static_cast(getPluginTaskData(event->TaskIndex)); + if (nullptr == P044_data || !P044_data->init) { + break; + } + + if (CONFIG_PIN1 != -1) { - #if defined(ESP8266) - byte serialconfig = 0x10; - #endif - #if defined(ESP32) - uint32_t serialconfig = 0x8000010; - #endif - serialconfig += ExtraTaskSettings.TaskDevicePluginConfigLong[3]; - serialconfig += (ExtraTaskSettings.TaskDevicePluginConfigLong[2] - 5) << 2; - if (ExtraTaskSettings.TaskDevicePluginConfigLong[4] == 2) - serialconfig += 0x20; - #if defined(ESP8266) - Serial.begin(ExtraTaskSettings.TaskDevicePluginConfigLong[1], (SerialConfig)serialconfig); - #endif - #if defined(ESP32) - Serial.begin(ExtraTaskSettings.TaskDevicePluginConfigLong[1], serialconfig); - #endif - if (P1GatewayServer) - { - P1GatewayServer->close(); - delete P1GatewayServer; - } - P1GatewayServer = new WiFiServer(ExtraTaskSettings.TaskDevicePluginConfigLong[0]); - P1GatewayServer->begin(); - - if (!Plugin_044_serial_buf) - Plugin_044_serial_buf = new char[P044_BUFFER_SIZE]; - - if (Settings.TaskDevicePin1[event->TaskIndex] != -1) - { - pinMode(Settings.TaskDevicePin1[event->TaskIndex], OUTPUT); - digitalWrite(Settings.TaskDevicePin1[event->TaskIndex], LOW); - delay(500); - digitalWrite(Settings.TaskDevicePin1[event->TaskIndex], HIGH); - pinMode(Settings.TaskDevicePin1[event->TaskIndex], INPUT_PULLUP); - } - - Plugin_044_init = true; + pinMode(CONFIG_PIN1, OUTPUT); + digitalWrite(CONFIG_PIN1, LOW); + delay(500); + digitalWrite(CONFIG_PIN1, HIGH); + pinMode(CONFIG_PIN1, INPUT_PULLUP); } blinkLED(); - if (ExtraTaskSettings.TaskDevicePluginConfigLong[1] == 115200) { addLog(LOG_LEVEL_DEBUG, F("P1 : DSMR version 4 meter, CRC on")); - CRCcheck = true; + P044_data->CRCcheck = true; } else { addLog(LOG_LEVEL_DEBUG, F("P1 : DSMR version 4 meter, CRC off")); - CRCcheck = false; + P044_data->CRCcheck = false; } - - state = P044_WAITING; + P044_data->state = P044_WAITING; success = true; break; } case PLUGIN_EXIT: { - if (P1GatewayServer) { - P1GatewayServer->close(); - delete P1GatewayServer; - P1GatewayServer = NULL; - } - if (Plugin_044_serial_buf) { - delete[] Plugin_044_serial_buf; - } + clearPluginTaskData(event->TaskIndex); success = true; break; } case PLUGIN_TEN_PER_SECOND: { - if (Plugin_044_init) + P044_data_struct *P044_data = + static_cast(getPluginTaskData(event->TaskIndex)); + if (nullptr == P044_data) { + break; + } + + if (P044_data->init) { - if (P1GatewayServer->hasClient()) + if (P044_data->P1GatewayServer->hasClient()) { - if (P1GatewayClient) P1GatewayClient.stop(); - P1GatewayClient = P1GatewayServer->available(); - P1GatewayClient.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT); + if (P044_data->P1GatewayClient) P044_data->P1GatewayClient.stop(); + P044_data->P1GatewayClient = P044_data->P1GatewayServer->available(); addLog(LOG_LEVEL_ERROR, F("P1 : Client connected!")); } - if (P1GatewayClient.connected()) + if (P044_data->P1GatewayClient.connected()) { - connectionState = 1; + P044_data->connectionState = 1; uint8_t net_buf[P044_NETBUF_SIZE]; - int count = P1GatewayClient.available(); + int count = P044_data->P1GatewayClient.available(); if (count > 0) { size_t net_bytes_read; if (count > P044_NETBUF_SIZE) count = P044_NETBUF_SIZE; - net_bytes_read = P1GatewayClient.read(net_buf, count); + net_bytes_read = P044_data->P1GatewayClient.read(net_buf, count); Serial.write(net_buf, net_bytes_read); Serial.flush(); // Waits for the transmission of outgoing serial data to complete @@ -219,17 +394,16 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) addLog(LOG_LEVEL_ERROR, F("P1 : Error: network buffer full!")); } net_buf[count] = 0; // before logging as a char array, zero terminate the last position to be safe. - char log[P044_NETBUF_SIZE + 40] = {0}; + char log[P044_NETBUF_SIZE + 40]; sprintf_P(log, PSTR("P1 : Error: N>: %s"), (char*)net_buf); - ZERO_TERMINATE(log); addLog(LOG_LEVEL_DEBUG, log); } } else { - if (connectionState == 1) // there was a client connected before... + if (P044_data->connectionState == 1) // there was a client connected before... { - connectionState = 0; + P044_data->connectionState = 0; addLog(LOG_LEVEL_ERROR, F("P1 : Client disconnected!")); } @@ -244,111 +418,8 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) case PLUGIN_SERIAL_IN: { - if (Plugin_044_init) - { - if (P1GatewayClient.connected()) - { - int RXWait = Settings.TaskDevicePluginConfig[event->TaskIndex][0]; - if (RXWait == 0) - RXWait = 1; - int timeOut = RXWait; - while (timeOut > 0) - { - while (Serial.available() && state != P044_DONE) { - if (bytes_read < P044_BUFFER_SIZE - 5) { - char ch = Serial.read(); - digitalWrite(P044_STATUS_LED, 1); - switch (state) { - case P044_DISABLED: //ignore incoming data - break; - case P044_WAITING: - if (ch == '/') { - Plugin_044_serial_buf[0] = ch; - bytes_read=1; - state = P044_READING; - } // else ignore data - break; - case P044_READING: - if (ch == '!') { - if (CRCcheck) { - state = P044_CHECKSUM; - } else { - state = P044_DONE; - } - } - if (validP1char(ch)) { - Plugin_044_serial_buf[bytes_read] = ch; - bytes_read++; - } else if (ch=='/') { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Start detected, discarded input.")); - Plugin_044_serial_buf[0] = ch; - bytes_read = 1; - } else { // input is non-ascii - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: DATA corrupt, discarded input.")); - Serial.flush(); - bytes_read = 0; - state = P044_WAITING; - } - break; - case P044_CHECKSUM: - checkI ++; - if (checkI == 4) { - checkI = 0; - state = P044_DONE; - } - Plugin_044_serial_buf[bytes_read] = ch; - bytes_read++; - break; - case P044_DONE: - // Plugin_044_serial_buf[bytes_read]= '\n'; - // bytes_read++; - // Plugin_044_serial_buf[bytes_read] = 0; - break; - } - } - else - { - Serial.read(); // when the buffer is full, just read remaining input, but do not store... - bytes_read = 0; - state = P044_WAITING; // reset - } - digitalWrite(P044_STATUS_LED, 0); - timeOut = RXWait; // if serial received, reset timeout counter - } - delay(1); - timeOut--; - } - - if (state == P044_DONE) { - if (checkDatagram(bytes_read)) { - Plugin_044_serial_buf[bytes_read] = '\r'; - bytes_read++; - Plugin_044_serial_buf[bytes_read] = '\n'; - bytes_read++; - Plugin_044_serial_buf[bytes_read] = 0; - P1GatewayClient.write((const uint8_t*)Plugin_044_serial_buf, bytes_read); - P1GatewayClient.flush(); - addLog(LOG_LEVEL_DEBUG, F("P1 : data send!")); - blinkLED(); - - if (Settings.UseRules) - { - LoadTaskSettings(event->TaskIndex); - String eventString = getTaskDeviceName(event->TaskIndex); - eventString += F("#Data"); - eventQueue.add(eventString); - } - - } else { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); - } - - bytes_read = 0; - state = P044_WAITING; - } // state == P044_DONE - } - success = true; - } + P044_handle_serial_in(event); + success = true; break; } @@ -360,32 +431,50 @@ void blinkLED() { delay(500); digitalWrite(P044_STATUS_LED, 0); } -/* - validP1char - checks whether the incoming character is a valid one for a P1 datagram. Returns false if not, which signals corrupt datagram -*/ -bool validP1char(char ch) { - if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '.') || (ch == '!') || (ch == ' ') || (ch == 92) || (ch == 13) || (ch == '\n') || (ch == '(') || (ch == ')') || (ch == '-') || (ch == '*') || (ch == ':') ) - { - return true; - } else { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: invalid char read from P1")); - if (serialdebug) { - serialPrint(F("faulty char>")); - serialPrint(String(ch)); - serialPrintln("<"); - } - return false; - } -} -int FindCharInArrayRev(char array[], char c, int len) { - for (int i = len - 1; i >= 0; i--) { - if (array[i] == c) { - return i; + +void P044_handle_serial_in(struct EventStruct *event) { + P044_data_struct *P044_data = + static_cast(getPluginTaskData(event->TaskIndex)); + if (nullptr == P044_data || !P044_data->init) { + return; + } + + char ch; + switch (P044_data->readSerialData(PCONFIG(0), ch)) { + case P044_result_data_sent: + addLog(LOG_LEVEL_DEBUG, F("P1 : data send!")); + blinkLED(); + if (Settings.UseRules) + { + LoadTaskSettings(event->TaskIndex); + String eventString = getTaskDeviceName(event->TaskIndex); + eventString += F("#Data"); + rulesProcessing(eventString); + } + break; + case P044_result_error_start_detected: + { + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Start detected, discarded input.")); + break; } + case P044_result_error_data_corrupt: + { + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: DATA corrupt, discarded input.")); + if (P044_data->serialdebug) { + serialPrint(F("faulty char>")); + serialPrint(String(ch)); + serialPrintln("<"); + } + break; + } + case P044_result_error_invalid_crc: + { + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); + break; + } + } - return -1; } /* @@ -393,11 +482,11 @@ int FindCharInArrayRev(char array[], char c, int len) { based on code written by Jan ten Hove https://github.com/jantenhove/P1-Meter-ESP8266 */ -unsigned int CRC16(unsigned int crc, unsigned char *buf, int len) +unsigned int CRC16(unsigned int crc, const String& buf, int len) { for (int pos = 0; pos < len; pos++) { - crc ^= (unsigned int)buf[pos]; // XOR byte into least sig. byte of crc + crc ^= static_cast(buf[pos]); // XOR byte into least sig. byte of crc for (int i = 8; i != 0; i--) { // Loop over each bit if ((crc & 0x0001) != 0) { // If the LSB is set @@ -412,46 +501,4 @@ unsigned int CRC16(unsigned int crc, unsigned char *buf, int len) return crc; } -/* checkDatagram - checks whether the P044_CHECKSUM of the data received from P1 matches the P044_CHECKSUM attached to the - telegram - based on code written by Jan ten Hove - https://github.com/jantenhove/P1-Meter-ESP8266 -*/ -bool checkDatagram(int len) { - int startChar = FindCharInArrayRev(Plugin_044_serial_buf, '/', len); - int endChar = FindCharInArrayRev(Plugin_044_serial_buf, '!', len); - bool validCRCFound = false; - - if (!CRCcheck) return true; - - if (serialdebug) { - serialPrint(F("input length: ")); - serialPrintln(String(len)); - serialPrint("Start char \\ : "); - serialPrintln(String(startChar)); - serialPrint(F("End char ! : ")); - serialPrintln(String(endChar)); - } - - if (endChar >= 0) - { - currCRC = CRC16(0x0000, (unsigned char *) Plugin_044_serial_buf, endChar - startChar + 1); - - char messageCRC[5]; - strncpy(messageCRC, Plugin_044_serial_buf + endChar + 1, 4); - messageCRC[4] = 0; - if (serialdebug) { - for (int cnt = 0; cnt < len; cnt++) - serialPrint(String(Plugin_044_serial_buf[cnt])); - } - - validCRCFound = (strtoul(messageCRC, NULL, 16) == currCRC); - if (!validCRCFound) { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: invalid CRC found")); - } - currCRC = 0; - } - return validCRCFound; -} #endif // USES_P044 From f4589662c01d8cb2edd8d731020b5c4a56480692 Mon Sep 17 00:00:00 2001 From: sakinit Date: Sat, 23 May 2020 19:46:56 +0200 Subject: [PATCH 047/128] Cherry-pick relevant P1WifiGateway updates since 30cbb4c Cherry-picked from commits 591988c, 5fe5121, 9c384ee, 1de1350 --- src/_P044_P1WifiGateway.ino | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index 3b58a27b2..df6af8769 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -9,6 +9,8 @@ // see http://romix.macuser.nl for kits //####################################################################################################### +#include "_Plugin_Helper.h" + #define PLUGIN_044 #define PLUGIN_ID_044 44 #define PLUGIN_NAME_044 "Communication - P1 Wifi Gateway" @@ -370,6 +372,7 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) { if (P044_data->P1GatewayClient) P044_data->P1GatewayClient.stop(); P044_data->P1GatewayClient = P044_data->P1GatewayServer->available(); + P044_data->P1GatewayClient.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT); addLog(LOG_LEVEL_ERROR, F("P1 : Client connected!")); } @@ -394,8 +397,9 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) addLog(LOG_LEVEL_ERROR, F("P1 : Error: network buffer full!")); } net_buf[count] = 0; // before logging as a char array, zero terminate the last position to be safe. - char log[P044_NETBUF_SIZE + 40]; + char log[P044_NETBUF_SIZE + 40] = {0}; sprintf_P(log, PSTR("P1 : Error: N>: %s"), (char*)net_buf); + ZERO_TERMINATE(log); addLog(LOG_LEVEL_DEBUG, log); } } @@ -450,7 +454,7 @@ void P044_handle_serial_in(struct EventStruct *event) { LoadTaskSettings(event->TaskIndex); String eventString = getTaskDeviceName(event->TaskIndex); eventString += F("#Data"); - rulesProcessing(eventString); + eventQueue.add(eventString); } break; case P044_result_error_start_detected: From 792656938b314a9cffbc0e8a778601b42a838fe2 Mon Sep 17 00:00:00 2001 From: sakinit Date: Sat, 23 May 2020 19:47:36 +0200 Subject: [PATCH 048/128] Fix the datagram check to be able to send valid messages again Tested for DSMR version 4, CRC on, with Domoticz as client --- src/_P044_P1WifiGateway.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index df6af8769..f6e3fe8bf 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -70,8 +70,8 @@ struct P044_data_struct : public PluginTaskData_base { https://github.com/jantenhove/P1-Meter-ESP8266 */ bool checkDatagram(int len) { - int startChar = serial_buffer.lastIndexOf('/', len); - int endChar = serial_buffer.lastIndexOf('!', len); + int startChar = serial_buffer.lastIndexOf('/'); + int endChar = serial_buffer.lastIndexOf('!'); bool validCRCFound = false; if (!CRCcheck) return true; @@ -96,7 +96,7 @@ struct P044_data_struct : public PluginTaskData_base { messageCRC[4] = 0; if (serialdebug) { for (int cnt = 0; cnt < len; cnt++) - serialPrint(serial_buffer.substring(cnt)); + serialPrint(serial_buffer.substring(cnt, 1)); } validCRCFound = (strtoul(messageCRC, NULL, 16) == currCRC); From e055f401dadc85830deeff8cd14b623cc38481e9 Mon Sep 17 00:00:00 2001 From: sakinit Date: Sat, 23 May 2020 19:48:09 +0200 Subject: [PATCH 049/128] Fix the serial reading algorithm The serial data reading algorithm is 'reverted' to commit 1de1350 to handle the parsing results within reading loop again. E.g. the 'start detected' error is logged again. --- src/_P044_P1WifiGateway.ino | 238 ++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 132 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index f6e3fe8bf..c6038f530 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -25,12 +25,6 @@ #define P044_CHECKSUM 3 #define P044_DONE 4 -#define P044_result_no_error 0 -#define P044_result_error_start_detected 1 -#define P044_result_error_data_corrupt 2 -#define P044_result_error_invalid_crc 3 -#define P044_result_data_sent 4 - struct P044_data_struct : public PluginTaskData_base { @@ -132,100 +126,114 @@ struct P044_data_struct : public PluginTaskData_base { return false; } + void handle_serial_in(struct EventStruct *event) { + int RXWait = PCONFIG(0); - byte readSerialData(int RXWait, char& ch) { - byte result = P044_result_no_error; - if (P1GatewayClient.connected()) + if (RXWait == 0) + RXWait = 1; + int timeOut = RXWait; + while (timeOut > 0) { - if (RXWait == 0) - RXWait = 1; - int timeOut = RXWait; - while (timeOut > 0) - { - while (Serial.available() && state != P044_DONE) { - if (bytes_read < P044_BUFFER_SIZE - 5) { - ch = Serial.read(); - digitalWrite(P044_STATUS_LED, 1); - switch (state) { - case P044_DISABLED: //ignore incoming data - break; - case P044_WAITING: - if (ch == '/') { - clearBuffer(); - addChar(ch); - state = P044_READING; - } // else ignore data - break; - case P044_READING: - if (ch == '!') { - if (CRCcheck) { - state = P044_CHECKSUM; - } else { - state = P044_DONE; - } - } - if (validP1char(ch)) { - addChar(ch); - } else if (ch=='/') { - result = P044_result_error_start_detected; - clearBuffer(); - addChar(ch); - } else { // input is non-ascii - result = P044_result_error_data_corrupt; - Serial.flush(); - clearBuffer(); - state = P044_WAITING; - } - break; - case P044_CHECKSUM: - ++checkI; - if (checkI == 4) { - checkI = 0; + while (Serial.available() && state != P044_DONE) { + if (bytes_read < P044_BUFFER_SIZE - 5) { + char ch = Serial.read(); + digitalWrite(P044_STATUS_LED, 1); + switch (state) { + case P044_DISABLED: //ignore incoming data + break; + case P044_WAITING: + if (ch == '/') { + clearBuffer(); + addChar(ch); + state = P044_READING; + } // else ignore data + break; + case P044_READING: + if (ch == '!') { + if (CRCcheck) { + state = P044_CHECKSUM; + } else { state = P044_DONE; } + } + if (validP1char(ch)) { addChar(ch); - break; - case P044_DONE: - // serial_buffer[bytes_read]= '\n'; - // bytes_read++; - // serial_buffer[bytes_read] = 0; - break; - } + } else if (ch=='/') { + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Start detected, discarded input.")); + clearBuffer(); + addChar(ch); + } else { // input is non-ascii + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: DATA corrupt, discarded input.")); + if (serialdebug) { + serialPrint(F("faulty char>")); + serialPrint(String(ch)); + serialPrintln("<"); + } + clearBuffer(); + state = P044_WAITING; + } + break; + case P044_CHECKSUM: + ++checkI; + if (checkI == 4) { + checkI = 0; + state = P044_DONE; + } + addChar(ch); + break; + case P044_DONE: + // Plugin_044_serial_buf[bytes_read]= '\n'; + // bytes_read++; + // Plugin_044_serial_buf[bytes_read] = 0; + break; } - else - { - Serial.read(); // when the buffer is full, just read remaining input, but do not store... - clearBuffer(); - state = P044_WAITING; // reset - } - digitalWrite(P044_STATUS_LED, 0); - timeOut = RXWait; // if serial received, reset timeout counter } - delay(1); - --timeOut; + else + { + Serial.read(); // when the buffer is full, just read remaining input, but do not store... + clearBuffer(); + bytes_read = 0; + state = P044_WAITING; // reset + } + digitalWrite(P044_STATUS_LED, 0); + timeOut = RXWait; // if serial received, reset timeout counter + } + delay(1); + timeOut--; + } + + if (state == P044_DONE) { + if (checkDatagram(bytes_read)) { + addChar('\r'); + addChar('\n'); + // No longer needed for the string to be null-terminated, since .c_str() does deliver 0-terminated char array pointer +// serial_buffer[bytes_read] = 0; + P1GatewayClient.write(serial_buffer.c_str(), bytes_read); + P1GatewayClient.flush(); + + // start: was exported + addLog(LOG_LEVEL_DEBUG, F("P1 : data send!")); + blinkLED(); + + if (Settings.UseRules) + { + LoadTaskSettings(event->TaskIndex); + String eventString = getTaskDeviceName(event->TaskIndex); + eventString += F("#Data"); + eventQueue.add(eventString); + } + // end: was exported + + } else { + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); } - if (state == P044_DONE) { - if (checkDatagram(bytes_read)) { - addChar('\r'); - addChar('\n'); - // No longer needed for the string to be null-terminated, since .c_str() does deliver 0-terminated char array pointer -// serial_buffer[bytes_read] = 0; - P1GatewayClient.write(serial_buffer.c_str(), bytes_read); - P1GatewayClient.flush(); - result = P044_result_data_sent; - } else { - result = P044_result_error_invalid_crc; - } - clearBuffer(); - state = P044_WAITING; - } // state == P044_DONE - } - return result; + clearBuffer(); + state = P044_WAITING; + } // state == P044_DONE } - WiFiServer *P1GatewayServer = nullptr; WiFiClient P1GatewayClient; String serial_buffer; @@ -422,7 +430,16 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) case PLUGIN_SERIAL_IN: { - P044_handle_serial_in(event); + P044_data_struct *P044_data = + static_cast(getPluginTaskData(event->TaskIndex)); + if (nullptr == P044_data || !P044_data->init) { + break; + } + + if (P044_data->P1GatewayClient.connected()) + { + P044_data->handle_serial_in(event); + } success = true; break; } @@ -437,49 +454,6 @@ void blinkLED() { } -void P044_handle_serial_in(struct EventStruct *event) { - P044_data_struct *P044_data = - static_cast(getPluginTaskData(event->TaskIndex)); - if (nullptr == P044_data || !P044_data->init) { - return; - } - - char ch; - switch (P044_data->readSerialData(PCONFIG(0), ch)) { - case P044_result_data_sent: - addLog(LOG_LEVEL_DEBUG, F("P1 : data send!")); - blinkLED(); - if (Settings.UseRules) - { - LoadTaskSettings(event->TaskIndex); - String eventString = getTaskDeviceName(event->TaskIndex); - eventString += F("#Data"); - eventQueue.add(eventString); - } - break; - case P044_result_error_start_detected: - { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Start detected, discarded input.")); - break; - } - case P044_result_error_data_corrupt: - { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: DATA corrupt, discarded input.")); - if (P044_data->serialdebug) { - serialPrint(F("faulty char>")); - serialPrint(String(ch)); - serialPrintln("<"); - } - break; - } - case P044_result_error_invalid_crc: - { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); - break; - } - - } -} /* CRC16 From f46b260414016add281e6cdf214c64efd031b4ab Mon Sep 17 00:00:00 2001 From: sakinit Date: Sat, 23 May 2020 19:48:41 +0200 Subject: [PATCH 050/128] Fix P1WifiGateway webserver start When the plugin task data is initialized, the execution order is: - construct new data (and previously: start webserver) - destroy existing data As the webserver is stopped at destruction of the existing data, start the webserver after the existing data is destroyed ( and no longer at construction). --- src/_P044_P1WifiGateway.ino | 47 ++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index c6038f530..05de1bb4b 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -29,18 +29,28 @@ struct P044_data_struct : public PluginTaskData_base { - P044_data_struct(unsigned int portnumber) { + P044_data_struct() { clearBuffer(); - P1GatewayServer = new WiFiServer(portnumber); - if (nullptr != P1GatewayServer) { - P1GatewayServer->begin(); - init = true; - } } ~P044_data_struct() { + stopServer(); + } + + void startServer(unsigned int portnumber) { + stopServer(); + P1GatewayServer = new WiFiServer(portnumber); + if (nullptr != P1GatewayServer) { + P1GatewayServer->begin(); + addLog(LOG_LEVEL_DEBUG, String(F("P1 : WiFi server started at port ")) + portnumber); + } + } + + void stopServer() { + clearBuffer(); if (nullptr != P1GatewayServer) { P1GatewayServer->close(); + addLog(LOG_LEVEL_DEBUG, F("P1 : WiFi server closed")); delete P1GatewayServer; P1GatewayServer = nullptr; } @@ -52,6 +62,10 @@ struct P044_data_struct : public PluginTaskData_base { bytes_read = 0; } + bool isInit() const { + return nullptr != P1GatewayServer; + } + void addChar(char ch) { serial_buffer += ch; ++bytes_read; @@ -242,7 +256,6 @@ struct P044_data_struct : public PluginTaskData_base { int state = P044_DISABLED; int checkI = 0; byte connectionState = 0; - boolean init = false; boolean serialdebug = false; boolean CRCcheck = false; }; @@ -278,8 +291,8 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) case PLUGIN_WEBFORM_LOAD: { LoadTaskSettings(event->TaskIndex); - addFormNumericBox(F("TCP Port"), F("p044_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]); - addFormNumericBox(F("Baud Rate"), F("p044_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]); + addFormNumericBox(F("TCP Port"), F("p044_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0], 0); + addFormNumericBox(F("Baud Rate"), F("p044_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1], 0); byte serialConfChoice = serialHelper_convertOldSerialConfig(PCONFIG(1)); serialHelper_serialconfig_webformLoad(event, serialConfChoice); @@ -287,7 +300,7 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) // FIXME TD-er: Why isn't this using the normal pin selection functions? addFormPinSelect(F("Reset target after boot"), F("taskdevicepin1"), CONFIG_PIN1); - addFormNumericBox(F("RX Receive Timeout (mSec)"), F("p044_rxwait"), PCONFIG(0)); + addFormNumericBox(F("RX Receive Timeout (mSec)"), F("p044_rxwait"), PCONFIG(0), 0); success = true; break; @@ -329,10 +342,16 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) Serial.begin(ExtraTaskSettings.TaskDevicePluginConfigLong[1], serialconfig); #endif - initPluginTaskData(event->TaskIndex, new P044_data_struct(ExtraTaskSettings.TaskDevicePluginConfigLong[0])); + initPluginTaskData(event->TaskIndex, new P044_data_struct()); P044_data_struct *P044_data = static_cast(getPluginTaskData(event->TaskIndex)); - if (nullptr == P044_data || !P044_data->init) { + if (nullptr == P044_data) { + break; + } + + P044_data->startServer(ExtraTaskSettings.TaskDevicePluginConfigLong[0]); + + if (!P044_data->isInit()) { break; } @@ -374,7 +393,7 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) break; } - if (P044_data->init) + if (P044_data->isInit()) { if (P044_data->P1GatewayServer->hasClient()) { @@ -432,7 +451,7 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) { P044_data_struct *P044_data = static_cast(getPluginTaskData(event->TaskIndex)); - if (nullptr == P044_data || !P044_data->init) { + if (nullptr == P044_data || !P044_data->isInit()) { break; } From 87570b676a7f70bfbf1b7d6af7e4a52683e00720 Mon Sep 17 00:00:00 2001 From: sakinit Date: Sat, 23 May 2020 22:35:32 +0200 Subject: [PATCH 051/128] Remove temporary comments --- src/_P044_P1WifiGateway.ino | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index 05de1bb4b..0bb28ebf8 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -226,7 +226,6 @@ struct P044_data_struct : public PluginTaskData_base { P1GatewayClient.write(serial_buffer.c_str(), bytes_read); P1GatewayClient.flush(); - // start: was exported addLog(LOG_LEVEL_DEBUG, F("P1 : data send!")); blinkLED(); @@ -237,7 +236,6 @@ struct P044_data_struct : public PluginTaskData_base { eventString += F("#Data"); eventQueue.add(eventString); } - // end: was exported } else { addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); From 7d877accba2afec2186ad8c6e4297c5b911dc45c Mon Sep 17 00:00:00 2001 From: sakinit Date: Mon, 25 May 2020 22:18:41 +0200 Subject: [PATCH 052/128] Use ESPeasySerial --- src/_P044_P1WifiGateway.ino | 180 ++++++++++++++++++++---------------- 1 file changed, 101 insertions(+), 79 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index 0bb28ebf8..e10f7c11c 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -62,10 +62,6 @@ struct P044_data_struct : public PluginTaskData_base { bytes_read = 0; } - bool isInit() const { - return nullptr != P1GatewayServer; - } - void addChar(char ch) { serial_buffer += ch; ++bytes_read; @@ -140,7 +136,25 @@ struct P044_data_struct : public PluginTaskData_base { return false; } - void handle_serial_in(struct EventStruct *event) { + void serialBegin(int16_t rxPin, int16_t txPin, + unsigned long baud, byte config) { + serialEnd(); + P1EasySerial = new ESPeasySerial(rxPin, txPin); +#if defined(ESP8266) + P1EasySerial->begin(baud, (SerialConfig)config); +#elif defined(ESP32) + P1EasySerial->begin(baud, config); +#endif + } + + void serialEnd() { + if (nullptr != P1EasySerial) { + delete P1EasySerial; + P1EasySerial = nullptr; + } + } + + void handleSerialIn(struct EventStruct *event) { int RXWait = PCONFIG(0); @@ -149,9 +163,9 @@ struct P044_data_struct : public PluginTaskData_base { int timeOut = RXWait; while (timeOut > 0) { - while (Serial.available() && state != P044_DONE) { + while (P1EasySerial->available() && state != P044_DONE) { if (bytes_read < P044_BUFFER_SIZE - 5) { - char ch = Serial.read(); + char ch = P1EasySerial->read(); digitalWrite(P044_STATUS_LED, 1); switch (state) { case P044_DISABLED: //ignore incoming data @@ -205,7 +219,7 @@ struct P044_data_struct : public PluginTaskData_base { } else { - Serial.read(); // when the buffer is full, just read remaining input, but do not store... + P1EasySerial->read(); // when the buffer is full, just read remaining input, but do not store... clearBuffer(); bytes_read = 0; state = P044_WAITING; // reset @@ -246,16 +260,37 @@ struct P044_data_struct : public PluginTaskData_base { } // state == P044_DONE } + void discardSerialIn() { + while (P1EasySerial->available()) { + P1EasySerial->read(); + } + } + + bool isInit() const { + return nullptr != P1GatewayServer && nullptr != P1EasySerial; + } + + inline static void init(taskIndex_t taskIndex) { + initPluginTaskData(taskIndex, new P044_data_struct()); + } + + inline static P044_data_struct *get(taskIndex_t taskIndex, bool checkInit = true) { + P044_data_struct * task = static_cast(getPluginTaskData(taskIndex)); + if (!checkInit) return task; + return (nullptr != task && task->isInit()) ? task : nullptr; + } + WiFiServer *P1GatewayServer = nullptr; WiFiClient P1GatewayClient; + byte connectionState = 0; String serial_buffer; unsigned int bytes_read = 0; unsigned int currCRC = 0; int state = P044_DISABLED; int checkI = 0; - byte connectionState = 0; boolean serialdebug = false; boolean CRCcheck = false; + ESPeasySerial *P1EasySerial = nullptr; }; boolean Plugin_044(byte function, struct EventStruct *event, String& string) @@ -328,28 +363,21 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) break; } - #if defined(ESP8266) - byte serialconfig = 0; - #elif defined(ESP32) - uint32_t serialconfig = 0x8000000; - #endif - serialconfig |= serialHelper_convertOldSerialConfig(PCONFIG(1)); - #if defined(ESP8266) - Serial.begin(ExtraTaskSettings.TaskDevicePluginConfigLong[1], (SerialConfig)serialconfig); - #elif defined(ESP32) - Serial.begin(ExtraTaskSettings.TaskDevicePluginConfigLong[1], serialconfig); - #endif - - initPluginTaskData(event->TaskIndex, new P044_data_struct()); - P044_data_struct *P044_data = - static_cast(getPluginTaskData(event->TaskIndex)); + P044_data_struct::init(event->TaskIndex); + P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex, false); if (nullptr == P044_data) { break; } + int rxPin; + int txPin; + ESPeasySerialType::getSerialTypePins(ESPeasySerialType::serial0, rxPin, txPin); + byte serialconfig = serialHelper_convertOldSerialConfig(PCONFIG(1)); + P044_data->serialBegin(rxPin, txPin, ExtraTaskSettings.TaskDevicePluginConfigLong[1], serialconfig); P044_data->startServer(ExtraTaskSettings.TaskDevicePluginConfigLong[0]); if (!P044_data->isInit()) { + clearPluginTaskData(event->TaskIndex); break; } @@ -385,77 +413,71 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) case PLUGIN_TEN_PER_SECOND: { - P044_data_struct *P044_data = - static_cast(getPluginTaskData(event->TaskIndex)); + P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex); if (nullptr == P044_data) { break; } - if (P044_data->isInit()) + if (P044_data->P1GatewayServer->hasClient()) { - if (P044_data->P1GatewayServer->hasClient()) - { - if (P044_data->P1GatewayClient) P044_data->P1GatewayClient.stop(); - P044_data->P1GatewayClient = P044_data->P1GatewayServer->available(); - P044_data->P1GatewayClient.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT); - addLog(LOG_LEVEL_ERROR, F("P1 : Client connected!")); - } - - if (P044_data->P1GatewayClient.connected()) - { - P044_data->connectionState = 1; - uint8_t net_buf[P044_NETBUF_SIZE]; - int count = P044_data->P1GatewayClient.available(); - if (count > 0) - { - size_t net_bytes_read; - if (count > P044_NETBUF_SIZE) - count = P044_NETBUF_SIZE; - net_bytes_read = P044_data->P1GatewayClient.read(net_buf, count); - Serial.write(net_buf, net_bytes_read); - Serial.flush(); // Waits for the transmission of outgoing serial data to complete - - if (count == P044_NETBUF_SIZE) // if we have a full buffer, drop the last position to stuff with string end marker - { - count--; - // and log buffer full situation - addLog(LOG_LEVEL_ERROR, F("P1 : Error: network buffer full!")); - } - net_buf[count] = 0; // before logging as a char array, zero terminate the last position to be safe. - char log[P044_NETBUF_SIZE + 40] = {0}; - sprintf_P(log, PSTR("P1 : Error: N>: %s"), (char*)net_buf); - ZERO_TERMINATE(log); - addLog(LOG_LEVEL_DEBUG, log); - } - } - else - { - if (P044_data->connectionState == 1) // there was a client connected before... - { - P044_data->connectionState = 0; - addLog(LOG_LEVEL_ERROR, F("P1 : Client disconnected!")); - } - - while (Serial.available()) - Serial.read(); - } - - success = true; + if (P044_data->P1GatewayClient) P044_data->P1GatewayClient.stop(); + P044_data->P1GatewayClient = P044_data->P1GatewayServer->available(); + P044_data->P1GatewayClient.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT); + addLog(LOG_LEVEL_ERROR, F("P1 : Client connected!")); } + + if (P044_data->P1GatewayClient.connected()) + { + P044_data->connectionState = 1; + uint8_t net_buf[P044_NETBUF_SIZE]; + int count = P044_data->P1GatewayClient.available(); + if (count > 0) + { + size_t net_bytes_read; + if (count > P044_NETBUF_SIZE) + count = P044_NETBUF_SIZE; + net_bytes_read = P044_data->P1GatewayClient.read(net_buf, count); + P044_data->P1EasySerial->write(net_buf, net_bytes_read); + P044_data->P1EasySerial->flush(); // Waits for the transmission of outgoing serial data to complete + + if (count == P044_NETBUF_SIZE) // if we have a full buffer, drop the last position to stuff with string end marker + { + count--; + // and log buffer full situation + addLog(LOG_LEVEL_ERROR, F("P1 : Error: network buffer full!")); + } + net_buf[count] = 0; // before logging as a char array, zero terminate the last position to be safe. + char log[P044_NETBUF_SIZE + 40] = {0}; + sprintf_P(log, PSTR("P1 : Error: N>: %s"), (char*)net_buf); + ZERO_TERMINATE(log); + addLog(LOG_LEVEL_DEBUG, log); + } + } + else + { + if (P044_data->connectionState == 1) // there was a client connected before... + { + P044_data->connectionState = 0; + addLog(LOG_LEVEL_ERROR, F("P1 : Client disconnected!")); + } + } + + success = true; break; } case PLUGIN_SERIAL_IN: { - P044_data_struct *P044_data = - static_cast(getPluginTaskData(event->TaskIndex)); - if (nullptr == P044_data || !P044_data->isInit()) { + P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex); + if (nullptr == P044_data) { break; } if (P044_data->P1GatewayClient.connected()) { - P044_data->handle_serial_in(event); + P044_data->handleSerialIn(event); + } else { + P044_data->discardSerialIn(); } success = true; break; From 86de58403e7747328e6ace77640096fc2109fa09 Mon Sep 17 00:00:00 2001 From: sakinit Date: Mon, 25 May 2020 22:30:59 +0200 Subject: [PATCH 053/128] Restart P1WifiGateway if webserver start failed Needed for ESP32 as the WiFiServer needs to time-out before it can reuse the address as its platform implementation does not use REUSEADDR --- src/_P044_P1WifiGateway.ino | 51 ++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index e10f7c11c..c6a66ff17 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -37,20 +37,49 @@ struct P044_data_struct : public PluginTaskData_base { stopServer(); } + inline static bool serverActive(WiFiServer * server) { +#if defined(ESP8266) + return nullptr != server && server->status() != CLOSED; +#elif defined(ESP32) + return nullptr != server && *server; +#endif + } + void startServer(unsigned int portnumber) { + if (gatewayPort == portnumber && serverActive(P1GatewayServer)) { + // server is already listening on this port + return; + } stopServer(); + gatewayPort = portnumber; P1GatewayServer = new WiFiServer(portnumber); if (nullptr != P1GatewayServer) { P1GatewayServer->begin(); - addLog(LOG_LEVEL_DEBUG, String(F("P1 : WiFi server started at port ")) + portnumber); + if(serverActive(P1GatewayServer)) { + addLog(LOG_LEVEL_INFO, String(F("P1 : WiFi server started at port ")) + portnumber); + } else { + addLog(LOG_LEVEL_ERROR, String(F("P1 : WiFi server start failed at port ")) + + portnumber + String(F(", retrying..."))); + } + } + } + + inline void checkServer() { + if (!serverActive(P1GatewayServer)) { + P1GatewayServer->close(); + P1GatewayServer->begin(); + if(serverActive(P1GatewayServer)) { + addLog(LOG_LEVEL_INFO, F("P1 : WiFi server started")); + } } } void stopServer() { clearBuffer(); if (nullptr != P1GatewayServer) { + if (P1GatewayClient) P1GatewayClient.stop(); P1GatewayServer->close(); - addLog(LOG_LEVEL_DEBUG, F("P1 : WiFi server closed")); + addLog(LOG_LEVEL_INFO, F("P1 : WiFi server closed")); delete P1GatewayServer; P1GatewayServer = nullptr; } @@ -281,6 +310,7 @@ struct P044_data_struct : public PluginTaskData_base { } WiFiServer *P1GatewayServer = nullptr; + unsigned int gatewayPort = 0; WiFiClient P1GatewayClient; byte connectionState = 0; String serial_buffer; @@ -363,8 +393,12 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) break; } - P044_data_struct::init(event->TaskIndex); + // try to reuse to keep webserver running P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex, false); + if (nullptr == P044_data) { + P044_data_struct::init(event->TaskIndex); + P044_data = P044_data_struct::get(event->TaskIndex, false); + } if (nullptr == P044_data) { break; } @@ -411,6 +445,17 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) break; } + case PLUGIN_ONCE_A_SECOND: + { + P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex); + if (nullptr == P044_data) { + break; + } + P044_data->checkServer(); + success = true; + break; + } + case PLUGIN_TEN_PER_SECOND: { P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex); From 5d8f6f4924ef10ecbd8ab809b75aae005f324759 Mon Sep 17 00:00:00 2001 From: sakinit Date: Thu, 28 May 2020 18:46:47 +0200 Subject: [PATCH 054/128] Optimize serial reading algorithm and move client from plugin into task --- src/_P044_P1WifiGateway.ino | 574 ++++++++++++++++++------------------ 1 file changed, 279 insertions(+), 295 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index c6a66ff17..ef4c8227d 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -5,8 +5,8 @@ // // designed for combo // Wemos D1 mini (see http://wemos.cc) and -// P1 wifi gateway shield (see https://circuits.io/circuits/2460082) -// see http://romix.macuser.nl for kits +// P1 wifi gateway shield (see http://www.esp8266thingies.nl for print design and kits) +// See also http://domoticx.com/p1-poort-slimme-meter-hardware/ //####################################################################################################### #include "_Plugin_Helper.h" @@ -14,30 +14,42 @@ #define PLUGIN_044 #define PLUGIN_ID_044 44 #define PLUGIN_NAME_044 "Communication - P1 Wifi Gateway" -#define PLUGIN_VALUENAME1_044 "P1WifiGateway" + +#ifndef PLUGIN_044_DEBUG + #define PLUGIN_044_DEBUG false // extra logging in serial out +#endif #define P044_STATUS_LED 12 -#define P044_BUFFER_SIZE 1024 +#define P044_CHECKSUM_LENGTH 4 +#define P044_DATAGRAM_START_CHAR '/' +#define P044_DATAGRAM_END_CHAR '!' +#define P044_DATAGRAM_MAX_SIZE 1024 #define P044_NETBUF_SIZE 128 -#define P044_DISABLED 0 -#define P044_WAITING 1 -#define P044_READING 2 -#define P044_CHECKSUM 3 -#define P044_DONE 4 +#define P044_WIFI_SERVER_PORT ExtraTaskSettings.TaskDevicePluginConfigLong[0] +#define P044_BAUDRATE ExtraTaskSettings.TaskDevicePluginConfigLong[1] +#define P044_RX_WAIT PCONFIG(0) +#define P044_SERIAL_CONFIG PCONFIG(1) +#define P044_RESET_TARGET_PIN CONFIG_PIN1 + +struct P044_Task : public PluginTaskData_base { -struct P044_data_struct : public PluginTaskData_base { + enum ParserState : byte { + P044_WAITING, + P044_READING, + P044_CHECKSUM + }; - P044_data_struct() { + P044_Task() { clearBuffer(); } - ~P044_data_struct() { + ~P044_Task() { stopServer(); } - inline static bool serverActive(WiFiServer * server) { + inline static bool serverActive(WiFiServer *server) { #if defined(ESP8266) return nullptr != server && server->status() != CLOSED; #elif defined(ESP32) @@ -64,7 +76,7 @@ struct P044_data_struct : public PluginTaskData_base { } } - inline void checkServer() { + void checkServer() { if (!serverActive(P1GatewayServer)) { P1GatewayServer->close(); P1GatewayServer->begin(); @@ -75,7 +87,6 @@ struct P044_data_struct : public PluginTaskData_base { } void stopServer() { - clearBuffer(); if (nullptr != P1GatewayServer) { if (P1GatewayClient) P1GatewayClient.stop(); P1GatewayServer->close(); @@ -85,72 +96,126 @@ struct P044_data_struct : public PluginTaskData_base { } } + bool hasClientConnected() { + if (P1GatewayServer->hasClient()) + { + if (P1GatewayClient) P1GatewayClient.stop(); + P1GatewayClient = P1GatewayServer->available(); + P1GatewayClient.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT); + addLog(LOG_LEVEL_INFO, F("P1 : Client connected!")); + } + + if (P1GatewayClient.connected()) + { + clientConnected = true; + } + else + { + if (clientConnected) // there was a client connected before... + { + clientConnected = false; + addLog(LOG_LEVEL_INFO, F("P1 : Client disconnected!")); + } + } + return clientConnected; + } + + void handleClientIn() { + uint8_t net_buf[P044_NETBUF_SIZE]; + int count = P1GatewayClient.available(); + if (count > 0) + { + size_t net_bytes_read; + if (count > P044_NETBUF_SIZE) + count = P044_NETBUF_SIZE; + net_bytes_read = P1GatewayClient.read(net_buf, count); + P1EasySerial->write(net_buf, net_bytes_read); + P1EasySerial->flush(); // Waits for the transmission of outgoing serial data to complete + + if (count == P044_NETBUF_SIZE) // if we have a full buffer, drop the last position to stuff with string end marker + { + --count; + // and log buffer full situation + addLog(LOG_LEVEL_ERROR, F("P1 : Error: network buffer full!")); + } + net_buf[count] = 0; // before logging as a char array, zero terminate the last position to be safe. + char log[P044_NETBUF_SIZE + 40] = {0}; + sprintf_P(log, PSTR("P1 : Error: N>: %s"), (char*)net_buf); + ZERO_TERMINATE(log); + addLog(LOG_LEVEL_DEBUG, log); + } + } + + static void blinkLED() { + digitalWrite(P044_STATUS_LED, 1); + delay(500); + digitalWrite(P044_STATUS_LED, 0); + } + void clearBuffer() { serial_buffer = ""; - serial_buffer.reserve(P044_BUFFER_SIZE); - bytes_read = 0; + serial_buffer.reserve(P044_DATAGRAM_MAX_SIZE); } void addChar(char ch) { serial_buffer += ch; - ++bytes_read; } /* checkDatagram - checks whether the P044_CHECKSUM of the data received from P1 matches the P044_CHECKSUM attached to the - telegram - based on code written by Jan ten Hove - https://github.com/jantenhove/P1-Meter-ESP8266 + checks whether the P044_CHECKSUM of the data received from P1 matches the P044_CHECKSUM + attached to the telegram */ - bool checkDatagram(int len) { - int startChar = serial_buffer.lastIndexOf('/'); - int endChar = serial_buffer.lastIndexOf('!'); - bool validCRCFound = false; + bool checkDatagram() const { + const int checksumStartIndex = serial_buffer.length() - P044_CHECKSUM_LENGTH; + if (checksumStartIndex < 2) return false; // sanity check, should never return here - if (!CRCcheck) return true; - -/* - if (serialdebug) { - serialPrint(F("input length: ")); - serialPrintln(String(len)); - serialPrint("Start char \\ : "); - serialPrintln(String(startChar)); - serialPrint(F("End char ! : ")); - serialPrintln(String(endChar)); + if (PLUGIN_044_DEBUG) { + for (unsigned int cnt = 0; cnt < serial_buffer.length(); ++cnt) + serialPrint(serial_buffer.substring(cnt, 1)); } -*/ - if (endChar >= 0) - { - currCRC = CRC16(0x0000, serial_buffer, endChar - startChar + 1); - - char messageCRC[5]; - strncpy(messageCRC, &serial_buffer[endChar + 1], 4); - messageCRC[4] = 0; - if (serialdebug) { - for (int cnt = 0; cnt < len; cnt++) - serialPrint(serial_buffer.substring(cnt, 1)); - } - - validCRCFound = (strtoul(messageCRC, NULL, 16) == currCRC); - currCRC = 0; - } - return validCRCFound; + // calculate the CRC and check if it equals the hexadecimal one attached to the datagram + unsigned int crc = CRC16(serial_buffer, checksumStartIndex); + return (strtoul(serial_buffer.substring(checksumStartIndex).c_str(), NULL, 16) == crc); } + /* + CRC16 + based on code written by Jan ten Hove + https://github.com/jantenhove/P1-Meter-ESP8266 + */ + static unsigned int CRC16(const String& buf, int len) + { + unsigned int crc = 0; + for (int pos = 0; pos < len; pos++) + { + crc ^= static_cast(buf[pos]); // XOR byte into least sig. byte of crc + + for (int i = 8; i != 0; i--) { // Loop over each bit + if ((crc & 0x0001) != 0) { // If the LSB is set + crc >>= 1; // Shift right and XOR 0xA001 + crc ^= 0xA001; + } + else // Else LSB is not set + crc >>= 1; // Just shift right + } + } + + return crc; + } /* validP1char - checks whether the incoming character is a valid one for a P1 datagram. Returns false if not, which signals corrupt datagram + Checks if the character is valid as part of the P1 datagram contents and/or checksum. + Returns false on a datagram start ('/'), end ('!') or invalid character */ - bool validP1char(char ch) { + static bool validP1char(char ch) { if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { return true; } switch (ch) { case '.': - case '!': case ' ': case '\\': // Single backslash, but escaped in C++ case '\r': @@ -174,151 +239,156 @@ struct P044_data_struct : public PluginTaskData_base { #elif defined(ESP32) P1EasySerial->begin(baud, config); #endif + addLog(LOG_LEVEL_DEBUG, F("P1 : Serial opened")); + state = P044_WAITING; } void serialEnd() { if (nullptr != P1EasySerial) { delete P1EasySerial; P1EasySerial = nullptr; + addLog(LOG_LEVEL_DEBUG, F("P1 : Serial closed")); } } void handleSerialIn(struct EventStruct *event) { - - int RXWait = PCONFIG(0); - - if (RXWait == 0) - RXWait = 1; + int RXWait = P044_RX_WAIT; + bool done = false; int timeOut = RXWait; - while (timeOut > 0) - { - while (P1EasySerial->available() && state != P044_DONE) { - if (bytes_read < P044_BUFFER_SIZE - 5) { - char ch = P1EasySerial->read(); - digitalWrite(P044_STATUS_LED, 1); - switch (state) { - case P044_DISABLED: //ignore incoming data - break; - case P044_WAITING: - if (ch == '/') { - clearBuffer(); - addChar(ch); - state = P044_READING; - } // else ignore data - break; - case P044_READING: - if (ch == '!') { - if (CRCcheck) { - state = P044_CHECKSUM; - } else { - state = P044_DONE; - } - } - if (validP1char(ch)) { - addChar(ch); - } else if (ch=='/') { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Start detected, discarded input.")); - clearBuffer(); - addChar(ch); - } else { // input is non-ascii - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: DATA corrupt, discarded input.")); - if (serialdebug) { - serialPrint(F("faulty char>")); - serialPrint(String(ch)); - serialPrintln("<"); - } - clearBuffer(); - state = P044_WAITING; - } - break; - case P044_CHECKSUM: - ++checkI; - if (checkI == 4) { - checkI = 0; - state = P044_DONE; - } - addChar(ch); - break; - case P044_DONE: - // Plugin_044_serial_buf[bytes_read]= '\n'; - // bytes_read++; - // Plugin_044_serial_buf[bytes_read] = 0; - break; - } - } - else - { - P1EasySerial->read(); // when the buffer is full, just read remaining input, but do not store... - clearBuffer(); - bytes_read = 0; - state = P044_WAITING; // reset - } + do { + if (P1EasySerial->available()) { + digitalWrite(P044_STATUS_LED, 1); + done = handleChar(P1EasySerial->read()); digitalWrite(P044_STATUS_LED, 0); + if (done) break; timeOut = RXWait; // if serial received, reset timeout counter - } - delay(1); - timeOut--; - } - - if (state == P044_DONE) { - if (checkDatagram(bytes_read)) { - addChar('\r'); - addChar('\n'); - // No longer needed for the string to be null-terminated, since .c_str() does deliver 0-terminated char array pointer -// serial_buffer[bytes_read] = 0; - P1GatewayClient.write(serial_buffer.c_str(), bytes_read); - P1GatewayClient.flush(); - - addLog(LOG_LEVEL_DEBUG, F("P1 : data send!")); - blinkLED(); - - if (Settings.UseRules) - { - LoadTaskSettings(event->TaskIndex); - String eventString = getTaskDeviceName(event->TaskIndex); - eventString += F("#Data"); - eventQueue.add(eventString); - } - } else { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); + if (timeOut <= 0) break; + delay(1); + --timeOut; } + } while (true); - clearBuffer(); - state = P044_WAITING; - } // state == P044_DONE + if (done) { + P1GatewayClient.print(serial_buffer); + P1GatewayClient.flush(); + + addLog(LOG_LEVEL_DEBUG, F("P1 : data send!")); + blinkLED(); + + if (Settings.UseRules) + { + LoadTaskSettings(event->TaskIndex); + String eventString = getTaskDeviceName(event->TaskIndex); + eventString += F("#Data"); + eventQueue.add(eventString); + } + } // done } + bool handleChar(char ch) { + if (serial_buffer.length() >= P044_DATAGRAM_MAX_SIZE - 2) { // room for cr/lf + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Buffer overflow, discarded input.")); + state = P044_WAITING; // reset + } + + bool done = false; + bool invalid = false; + switch (state) { + case P044_WAITING: + if (ch == P044_DATAGRAM_START_CHAR) { + clearBuffer(); + addChar(ch); + state = P044_READING; + } // else ignore data + break; + case P044_READING: + if (validP1char(ch)) { + addChar(ch); + } else if (ch == P044_DATAGRAM_END_CHAR) { + addChar(ch); + if (CRCcheck) { + checkI = 0; + state = P044_CHECKSUM; + } else { + done = true; + } + } else if (ch == P044_DATAGRAM_START_CHAR) { + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Start detected, discarded input.")); + state = P044_WAITING; // reset + return handleChar(ch); + } else { + invalid = true; + } + break; + case P044_CHECKSUM: + if (validP1char(ch)) { + addChar(ch); + ++checkI; + if (checkI == P044_CHECKSUM_LENGTH) { + if (checkDatagram()) { + done = true; + } else { + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); + state = P044_WAITING; // reset + } + } + } else { + invalid = true; + } + break; + } // switch + + if (invalid) { + // input is not a datagram char + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: DATA corrupt, discarded input.")); + if (PLUGIN_044_DEBUG) { + serialPrint(F("faulty char>")); + serialPrint(String(ch)); + serialPrintln("<"); + } + state = P044_WAITING; // reset + } + + if (done) { + // add the cr/lf pair to the datagram ahead of reading both + // from serial as the datagram has already been validated + addChar('\r'); + addChar('\n'); + state = P044_WAITING; // prepare for next one + } + + return done; + } + void discardSerialIn() { while (P1EasySerial->available()) { P1EasySerial->read(); } + state = P044_WAITING; } bool isInit() const { return nullptr != P1GatewayServer && nullptr != P1EasySerial; } - inline static void init(taskIndex_t taskIndex) { - initPluginTaskData(taskIndex, new P044_data_struct()); + inline static P044_Task *init(taskIndex_t taskIndex) { + initPluginTaskData(taskIndex, new P044_Task()); + return static_cast(getPluginTaskData(taskIndex)); } - inline static P044_data_struct *get(taskIndex_t taskIndex, bool checkInit = true) { - P044_data_struct * task = static_cast(getPluginTaskData(taskIndex)); - if (!checkInit) return task; + inline static P044_Task *get(taskIndex_t taskIndex) { + P044_Task * task = static_cast(getPluginTaskData(taskIndex)); return (nullptr != task && task->isInit()) ? task : nullptr; } WiFiServer *P1GatewayServer = nullptr; unsigned int gatewayPort = 0; WiFiClient P1GatewayClient; - byte connectionState = 0; + bool clientConnected = false; String serial_buffer; - unsigned int bytes_read = 0; - unsigned int currCRC = 0; - int state = P044_DISABLED; + ParserState state = P044_WAITING; int checkI = 0; - boolean serialdebug = false; boolean CRCcheck = false; ESPeasySerial *P1EasySerial = nullptr; }; @@ -345,25 +415,19 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) break; } - case PLUGIN_GET_DEVICEVALUENAMES: - { - strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_044)); - break; - } - case PLUGIN_WEBFORM_LOAD: { LoadTaskSettings(event->TaskIndex); - addFormNumericBox(F("TCP Port"), F("p044_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0], 0); - addFormNumericBox(F("Baud Rate"), F("p044_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1], 0); + addFormNumericBox(F("TCP Port"), F("p044_port"), P044_WIFI_SERVER_PORT, 0); + addFormNumericBox(F("Baud Rate"), F("p044_baud"), P044_BAUDRATE, 0); - byte serialConfChoice = serialHelper_convertOldSerialConfig(PCONFIG(1)); + byte serialConfChoice = serialHelper_convertOldSerialConfig(P044_SERIAL_CONFIG); serialHelper_serialconfig_webformLoad(event, serialConfChoice); // FIXME TD-er: Why isn't this using the normal pin selection functions? - addFormPinSelect(F("Reset target after boot"), F("taskdevicepin1"), CONFIG_PIN1); + addFormPinSelect(F("Reset target after boot"), F("taskdevicepin1"), P044_RESET_TARGET_PIN); - addFormNumericBox(F("RX Receive Timeout (mSec)"), F("p044_rxwait"), PCONFIG(0), 0); + addFormNumericBox(F("RX Receive Timeout (mSec)"), F("p044_rxwait"), P044_RX_WAIT, 0); success = true; break; @@ -372,10 +436,10 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) case PLUGIN_WEBFORM_SAVE: { LoadTaskSettings(event->TaskIndex); - ExtraTaskSettings.TaskDevicePluginConfigLong[0] = getFormItemInt(F("p044_port")); - ExtraTaskSettings.TaskDevicePluginConfigLong[1] = getFormItemInt(F("p044_baud")); - PCONFIG(0) = getFormItemInt(F("p044_rxwait")); - PCONFIG(1) = serialHelper_serialconfig_webformSave(); + P044_WIFI_SERVER_PORT = getFormItemInt(F("p044_port")); + P044_BAUDRATE = getFormItemInt(F("p044_baud")); + P044_RX_WAIT = getFormItemInt(F("p044_rxwait")); + P044_SERIAL_CONFIG = serialHelper_serialconfig_webformSave(); success = true; break; @@ -387,53 +451,49 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) digitalWrite(P044_STATUS_LED, 0); LoadTaskSettings(event->TaskIndex); - if ((ExtraTaskSettings.TaskDevicePluginConfigLong[0] == 0) || - (ExtraTaskSettings.TaskDevicePluginConfigLong[1] == 0)) - { - break; - } + if ((P044_WIFI_SERVER_PORT == 0) || (P044_BAUDRATE == 0)) { + clearPluginTaskData(event->TaskIndex); + break; + } // try to reuse to keep webserver running - P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex, false); - if (nullptr == P044_data) { - P044_data_struct::init(event->TaskIndex); - P044_data = P044_data_struct::get(event->TaskIndex, false); + P044_Task *task = P044_Task::get(event->TaskIndex); + if (nullptr == task) { + task = P044_Task::init(event->TaskIndex); } - if (nullptr == P044_data) { + if (nullptr == task) { break; } int rxPin; int txPin; ESPeasySerialType::getSerialTypePins(ESPeasySerialType::serial0, rxPin, txPin); - byte serialconfig = serialHelper_convertOldSerialConfig(PCONFIG(1)); - P044_data->serialBegin(rxPin, txPin, ExtraTaskSettings.TaskDevicePluginConfigLong[1], serialconfig); - P044_data->startServer(ExtraTaskSettings.TaskDevicePluginConfigLong[0]); + byte serialconfig = serialHelper_convertOldSerialConfig(P044_SERIAL_CONFIG); + task->serialBegin(rxPin, txPin, P044_BAUDRATE, serialconfig); + task->startServer(P044_WIFI_SERVER_PORT); - if (!P044_data->isInit()) { + if (!task->isInit()) { clearPluginTaskData(event->TaskIndex); break; } - if (CONFIG_PIN1 != -1) - { - pinMode(CONFIG_PIN1, OUTPUT); - digitalWrite(CONFIG_PIN1, LOW); + if (P044_RESET_TARGET_PIN != -1) { + pinMode(P044_RESET_TARGET_PIN, OUTPUT); + digitalWrite(P044_RESET_TARGET_PIN, LOW); delay(500); - digitalWrite(CONFIG_PIN1, HIGH); - pinMode(CONFIG_PIN1, INPUT_PULLUP); + digitalWrite(P044_RESET_TARGET_PIN, HIGH); + pinMode(P044_RESET_TARGET_PIN, INPUT_PULLUP); } - blinkLED(); - if (ExtraTaskSettings.TaskDevicePluginConfigLong[1] == 115200) { + task->blinkLED(); + if (P044_BAUDRATE == 115200) { addLog(LOG_LEVEL_DEBUG, F("P1 : DSMR version 4 meter, CRC on")); - P044_data->CRCcheck = true; + task->CRCcheck = true; } else { addLog(LOG_LEVEL_DEBUG, F("P1 : DSMR version 4 meter, CRC off")); - P044_data->CRCcheck = false; + task->CRCcheck = false; } - P044_data->state = P044_WAITING; success = true; break; } @@ -446,83 +506,39 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) } case PLUGIN_ONCE_A_SECOND: - { - P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex); - if (nullptr == P044_data) { + { + P044_Task *task = P044_Task::get(event->TaskIndex); + if (nullptr == task) { + break; + } + task->checkServer(); + success = true; break; } - P044_data->checkServer(); - success = true; - break; - } case PLUGIN_TEN_PER_SECOND: { - P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex); - if (nullptr == P044_data) { + P044_Task *task = P044_Task::get(event->TaskIndex); + if (nullptr == task) { break; } - - if (P044_data->P1GatewayServer->hasClient()) - { - if (P044_data->P1GatewayClient) P044_data->P1GatewayClient.stop(); - P044_data->P1GatewayClient = P044_data->P1GatewayServer->available(); - P044_data->P1GatewayClient.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT); - addLog(LOG_LEVEL_ERROR, F("P1 : Client connected!")); + if (task->hasClientConnected()) { + task->handleClientIn(); } - - if (P044_data->P1GatewayClient.connected()) - { - P044_data->connectionState = 1; - uint8_t net_buf[P044_NETBUF_SIZE]; - int count = P044_data->P1GatewayClient.available(); - if (count > 0) - { - size_t net_bytes_read; - if (count > P044_NETBUF_SIZE) - count = P044_NETBUF_SIZE; - net_bytes_read = P044_data->P1GatewayClient.read(net_buf, count); - P044_data->P1EasySerial->write(net_buf, net_bytes_read); - P044_data->P1EasySerial->flush(); // Waits for the transmission of outgoing serial data to complete - - if (count == P044_NETBUF_SIZE) // if we have a full buffer, drop the last position to stuff with string end marker - { - count--; - // and log buffer full situation - addLog(LOG_LEVEL_ERROR, F("P1 : Error: network buffer full!")); - } - net_buf[count] = 0; // before logging as a char array, zero terminate the last position to be safe. - char log[P044_NETBUF_SIZE + 40] = {0}; - sprintf_P(log, PSTR("P1 : Error: N>: %s"), (char*)net_buf); - ZERO_TERMINATE(log); - addLog(LOG_LEVEL_DEBUG, log); - } - } - else - { - if (P044_data->connectionState == 1) // there was a client connected before... - { - P044_data->connectionState = 0; - addLog(LOG_LEVEL_ERROR, F("P1 : Client disconnected!")); - } - } - success = true; break; } case PLUGIN_SERIAL_IN: { - P044_data_struct *P044_data = P044_data_struct::get(event->TaskIndex); - if (nullptr == P044_data) { + P044_Task *task = P044_Task::get(event->TaskIndex); + if (nullptr == task) { break; } - - if (P044_data->P1GatewayClient.connected()) - { - P044_data->handleSerialIn(event); + if (task->hasClientConnected()) { + task->handleSerialIn(event); } else { - P044_data->discardSerialIn(); + task->discardSerialIn(); } success = true; break; @@ -531,36 +547,4 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) } return success; } -void blinkLED() { - digitalWrite(P044_STATUS_LED, 1); - delay(500); - digitalWrite(P044_STATUS_LED, 0); -} - - - -/* - CRC16 - based on code written by Jan ten Hove - https://github.com/jantenhove/P1-Meter-ESP8266 -*/ -unsigned int CRC16(unsigned int crc, const String& buf, int len) -{ - for (int pos = 0; pos < len; pos++) - { - crc ^= static_cast(buf[pos]); // XOR byte into least sig. byte of crc - - for (int i = 8; i != 0; i--) { // Loop over each bit - if ((crc & 0x0001) != 0) { // If the LSB is set - crc >>= 1; // Shift right and XOR 0xA001 - crc ^= 0xA001; - } - else // Else LSB is not set - crc >>= 1; // Just shift right - } - } - - return crc; -} - #endif // USES_P044 From 6a79dbe0dab1b7ad6a2c6a6ce32bed4ffb360191 Mon Sep 17 00:00:00 2001 From: sakinit Date: Thu, 28 May 2020 23:30:39 +0200 Subject: [PATCH 055/128] Fix ESP32 reboot cause at boot/setup --- src/_P044_P1WifiGateway.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index ef4c8227d..d4751f07a 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -65,7 +65,7 @@ struct P044_Task : public PluginTaskData_base { stopServer(); gatewayPort = portnumber; P1GatewayServer = new WiFiServer(portnumber); - if (nullptr != P1GatewayServer) { + if (nullptr != P1GatewayServer && WiFi.isConnected()) { P1GatewayServer->begin(); if(serverActive(P1GatewayServer)) { addLog(LOG_LEVEL_INFO, String(F("P1 : WiFi server started at port ")) + portnumber); @@ -77,7 +77,7 @@ struct P044_Task : public PluginTaskData_base { } void checkServer() { - if (!serverActive(P1GatewayServer)) { + if (!serverActive(P1GatewayServer) && WiFi.isConnected()) { P1GatewayServer->close(); P1GatewayServer->begin(); if(serverActive(P1GatewayServer)) { From 6fcd00252fc0e86026538118555d7f9d43768496 Mon Sep 17 00:00:00 2001 From: sakinit Date: Fri, 29 May 2020 14:09:09 +0200 Subject: [PATCH 056/128] Optimize serial in duration --- src/_P044_P1WifiGateway.ino | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index d4751f07a..4e5e791fb 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -146,10 +146,16 @@ struct P044_Task : public PluginTaskData_base { } } - static void blinkLED() { + void blinkLED() { + blinkLEDStartTime = millis(); digitalWrite(P044_STATUS_LED, 1); - delay(500); - digitalWrite(P044_STATUS_LED, 0); + } + + void checkBlinkLED() { + if (blinkLEDStartTime > 0 && millis() - blinkLEDStartTime >= 500) { + digitalWrite(P044_STATUS_LED, 0); + blinkLEDStartTime = 0; + } } void clearBuffer() { @@ -391,6 +397,7 @@ struct P044_Task : public PluginTaskData_base { int checkI = 0; boolean CRCcheck = false; ESPeasySerial *P1EasySerial = nullptr; + unsigned long blinkLEDStartTime = 0; }; boolean Plugin_044(byte function, struct EventStruct *event, String& string) @@ -525,6 +532,7 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) if (task->hasClientConnected()) { task->handleClientIn(); } + task->checkBlinkLED(); success = true; break; } From d7a91aba60d27d828d819943082040e76b197270 Mon Sep 17 00:00:00 2001 From: sakinit Date: Fri, 29 May 2020 18:51:25 +0200 Subject: [PATCH 057/128] Update due to review comments --- src/_P044_P1WifiGateway.ino | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index 4e5e791fb..cbdfd4ccd 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -35,10 +35,10 @@ struct P044_Task : public PluginTaskData_base { - enum ParserState : byte { - P044_WAITING, - P044_READING, - P044_CHECKSUM + enum class ParserState : byte { + WAITING, + READING, + CHECKSUM }; P044_Task() { @@ -152,7 +152,7 @@ struct P044_Task : public PluginTaskData_base { } void checkBlinkLED() { - if (blinkLEDStartTime > 0 && millis() - blinkLEDStartTime >= 500) { + if (blinkLEDStartTime > 0 && timePassedSince(blinkLEDStartTime) >= 500) { digitalWrite(P044_STATUS_LED, 0); blinkLEDStartTime = 0; } @@ -246,7 +246,7 @@ struct P044_Task : public PluginTaskData_base { P1EasySerial->begin(baud, config); #endif addLog(LOG_LEVEL_DEBUG, F("P1 : Serial opened")); - state = P044_WAITING; + state = ParserState::WAITING; } void serialEnd() { @@ -295,39 +295,39 @@ struct P044_Task : public PluginTaskData_base { bool handleChar(char ch) { if (serial_buffer.length() >= P044_DATAGRAM_MAX_SIZE - 2) { // room for cr/lf addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Buffer overflow, discarded input.")); - state = P044_WAITING; // reset + state = ParserState::WAITING; // reset } bool done = false; bool invalid = false; switch (state) { - case P044_WAITING: + case ParserState::WAITING: if (ch == P044_DATAGRAM_START_CHAR) { clearBuffer(); addChar(ch); - state = P044_READING; + state = ParserState::READING; } // else ignore data break; - case P044_READING: + case ParserState::READING: if (validP1char(ch)) { addChar(ch); } else if (ch == P044_DATAGRAM_END_CHAR) { addChar(ch); if (CRCcheck) { checkI = 0; - state = P044_CHECKSUM; + state = ParserState::CHECKSUM; } else { done = true; } } else if (ch == P044_DATAGRAM_START_CHAR) { addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Start detected, discarded input.")); - state = P044_WAITING; // reset + state = ParserState::WAITING; // reset return handleChar(ch); } else { invalid = true; } break; - case P044_CHECKSUM: + case ParserState::CHECKSUM: if (validP1char(ch)) { addChar(ch); ++checkI; @@ -336,7 +336,7 @@ struct P044_Task : public PluginTaskData_base { done = true; } else { addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); - state = P044_WAITING; // reset + state = ParserState::WAITING; // reset } } } else { @@ -353,7 +353,7 @@ struct P044_Task : public PluginTaskData_base { serialPrint(String(ch)); serialPrintln("<"); } - state = P044_WAITING; // reset + state = ParserState::WAITING; // reset } if (done) { @@ -361,7 +361,7 @@ struct P044_Task : public PluginTaskData_base { // from serial as the datagram has already been validated addChar('\r'); addChar('\n'); - state = P044_WAITING; // prepare for next one + state = ParserState::WAITING; // prepare for next one } return done; @@ -371,7 +371,7 @@ struct P044_Task : public PluginTaskData_base { while (P1EasySerial->available()) { P1EasySerial->read(); } - state = P044_WAITING; + state = ParserState::WAITING; } bool isInit() const { @@ -393,7 +393,7 @@ struct P044_Task : public PluginTaskData_base { WiFiClient P1GatewayClient; bool clientConnected = false; String serial_buffer; - ParserState state = P044_WAITING; + ParserState state = ParserState::WAITING; int checkI = 0; boolean CRCcheck = false; ESPeasySerial *P1EasySerial = nullptr; From a65d1a6c518a00f37c8c52904ce2d29994bf93fb Mon Sep 17 00:00:00 2001 From: sakinit Date: Sat, 30 May 2020 13:36:48 +0200 Subject: [PATCH 058/128] Add sanity checks based on review comments --- src/_P044_P1WifiGateway.ino | 61 ++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index cbdfd4ccd..d484c22de 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -57,7 +57,7 @@ struct P044_Task : public PluginTaskData_base { #endif } - void startServer(unsigned int portnumber) { + void startServer(uint16_t portnumber) { if (gatewayPort == portnumber && serverActive(P1GatewayServer)) { // server is already listening on this port return; @@ -77,7 +77,7 @@ struct P044_Task : public PluginTaskData_base { } void checkServer() { - if (!serverActive(P1GatewayServer) && WiFi.isConnected()) { + if (nullptr != P1GatewayServer && !serverActive(P1GatewayServer) && WiFi.isConnected()) { P1GatewayServer->close(); P1GatewayServer->begin(); if(serverActive(P1GatewayServer)) { @@ -89,6 +89,7 @@ struct P044_Task : public PluginTaskData_base { void stopServer() { if (nullptr != P1GatewayServer) { if (P1GatewayClient) P1GatewayClient.stop(); + clientConnected = false; P1GatewayServer->close(); addLog(LOG_LEVEL_INFO, F("P1 : WiFi server closed")); delete P1GatewayServer; @@ -97,7 +98,7 @@ struct P044_Task : public PluginTaskData_base { } bool hasClientConnected() { - if (P1GatewayServer->hasClient()) + if (nullptr != P1GatewayServer && P1GatewayServer->hasClient()) { if (P1GatewayClient) P1GatewayClient.stop(); P1GatewayClient = P1GatewayServer->available(); @@ -172,9 +173,16 @@ struct P044_Task : public PluginTaskData_base { attached to the telegram */ bool checkDatagram() const { - const int checksumStartIndex = serial_buffer.length() - P044_CHECKSUM_LENGTH; - if (checksumStartIndex < 2) return false; // sanity check, should never return here + int endChar = serial_buffer.length() - 1; + if (CRCcheck) { + endChar -= P044_CHECKSUM_LENGTH; + } + if (endChar < 0 || serial_buffer[0] != P044_DATAGRAM_START_CHAR || + serial_buffer[endChar] != P044_DATAGRAM_END_CHAR) return false; + if (!CRCcheck) return true; + + const int checksumStartIndex = endChar + 1; if (PLUGIN_044_DEBUG) { for (unsigned int cnt = 0; cnt < serial_buffer.length(); ++cnt) serialPrint(serial_buffer.substring(cnt, 1)); @@ -239,13 +247,17 @@ struct P044_Task : public PluginTaskData_base { void serialBegin(int16_t rxPin, int16_t txPin, unsigned long baud, byte config) { serialEnd(); - P1EasySerial = new ESPeasySerial(rxPin, txPin); + if (rxPin >= 0) { + P1EasySerial = new ESPeasySerial(rxPin, txPin); + if (nullptr != P1EasySerial) { #if defined(ESP8266) - P1EasySerial->begin(baud, (SerialConfig)config); + P1EasySerial->begin(baud, (SerialConfig)config); #elif defined(ESP32) - P1EasySerial->begin(baud, config); + P1EasySerial->begin(baud, config); #endif - addLog(LOG_LEVEL_DEBUG, F("P1 : Serial opened")); + addLog(LOG_LEVEL_DEBUG, F("P1 : Serial opened")); + } + } state = ParserState::WAITING; } @@ -258,6 +270,7 @@ struct P044_Task : public PluginTaskData_base { } void handleSerialIn(struct EventStruct *event) { + if (nullptr == P1EasySerial) return; int RXWait = P044_RX_WAIT; bool done = false; int timeOut = RXWait; @@ -332,12 +345,7 @@ struct P044_Task : public PluginTaskData_base { addChar(ch); ++checkI; if (checkI == P044_CHECKSUM_LENGTH) { - if (checkDatagram()) { - done = true; - } else { - addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); - state = ParserState::WAITING; // reset - } + done = true; } } else { invalid = true; @@ -357,10 +365,17 @@ struct P044_Task : public PluginTaskData_base { } if (done) { - // add the cr/lf pair to the datagram ahead of reading both - // from serial as the datagram has already been validated - addChar('\r'); - addChar('\n'); + done = checkDatagram(); + if (done) { + // add the cr/lf pair to the datagram ahead of reading both + // from serial as the datagram has already been validated + addChar('\r'); + addChar('\n'); + } else if (CRCcheck) { + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid CRC, dropped data")); + } else { + addLog(LOG_LEVEL_DEBUG, F("P1 : Error: Invalid datagram, dropped data")); + } state = ParserState::WAITING; // prepare for next one } @@ -368,8 +383,10 @@ struct P044_Task : public PluginTaskData_base { } void discardSerialIn() { - while (P1EasySerial->available()) { - P1EasySerial->read(); + if (nullptr != P1EasySerial) { + while (P1EasySerial->available()) { + P1EasySerial->read(); + } } state = ParserState::WAITING; } @@ -389,7 +406,7 @@ struct P044_Task : public PluginTaskData_base { } WiFiServer *P1GatewayServer = nullptr; - unsigned int gatewayPort = 0; + uint16_t gatewayPort = 0; WiFiClient P1GatewayClient; bool clientConnected = false; String serial_buffer; From e96c3772e86f39f94f4a4ea27fd1447ac1bb4e9a Mon Sep 17 00:00:00 2001 From: sakinit Date: Sat, 30 May 2020 13:38:21 +0200 Subject: [PATCH 059/128] Discard data received from WiFi client due to review comment --- src/_P044_P1WifiGateway.ino | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index d484c22de..be84249e7 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -24,7 +24,6 @@ #define P044_DATAGRAM_START_CHAR '/' #define P044_DATAGRAM_END_CHAR '!' #define P044_DATAGRAM_MAX_SIZE 1024 -#define P044_NETBUF_SIZE 128 #define P044_WIFI_SERVER_PORT ExtraTaskSettings.TaskDevicePluginConfigLong[0] #define P044_BAUDRATE ExtraTaskSettings.TaskDevicePluginConfigLong[1] @@ -121,29 +120,11 @@ struct P044_Task : public PluginTaskData_base { return clientConnected; } - void handleClientIn() { - uint8_t net_buf[P044_NETBUF_SIZE]; - int count = P1GatewayClient.available(); - if (count > 0) - { - size_t net_bytes_read; - if (count > P044_NETBUF_SIZE) - count = P044_NETBUF_SIZE; - net_bytes_read = P1GatewayClient.read(net_buf, count); - P1EasySerial->write(net_buf, net_bytes_read); - P1EasySerial->flush(); // Waits for the transmission of outgoing serial data to complete - - if (count == P044_NETBUF_SIZE) // if we have a full buffer, drop the last position to stuff with string end marker - { - --count; - // and log buffer full situation - addLog(LOG_LEVEL_ERROR, F("P1 : Error: network buffer full!")); - } - net_buf[count] = 0; // before logging as a char array, zero terminate the last position to be safe. - char log[P044_NETBUF_SIZE + 40] = {0}; - sprintf_P(log, PSTR("P1 : Error: N>: %s"), (char*)net_buf); - ZERO_TERMINATE(log); - addLog(LOG_LEVEL_DEBUG, log); + void discardClientIn() { + // flush all data received from the WiFi gateway + // as a P1 meter does not receive data + while(P1GatewayClient.available()) { + P1GatewayClient.read(); } } @@ -547,7 +528,7 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string) break; } if (task->hasClientConnected()) { - task->handleClientIn(); + task->discardClientIn(); } task->checkBlinkLED(); success = true; From c4182026e86de0a88b60b59d967a327b514c641b Mon Sep 17 00:00:00 2001 From: sakinit Date: Sat, 30 May 2020 16:40:49 +0200 Subject: [PATCH 060/128] Update based on review comments --- src/_P044_P1WifiGateway.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index be84249e7..4efd832f6 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -64,7 +64,7 @@ struct P044_Task : public PluginTaskData_base { stopServer(); gatewayPort = portnumber; P1GatewayServer = new WiFiServer(portnumber); - if (nullptr != P1GatewayServer && WiFi.isConnected()) { + if (nullptr != P1GatewayServer && WiFiConnected()) { P1GatewayServer->begin(); if(serverActive(P1GatewayServer)) { addLog(LOG_LEVEL_INFO, String(F("P1 : WiFi server started at port ")) + portnumber); @@ -76,7 +76,7 @@ struct P044_Task : public PluginTaskData_base { } void checkServer() { - if (nullptr != P1GatewayServer && !serverActive(P1GatewayServer) && WiFi.isConnected()) { + if (nullptr != P1GatewayServer && !serverActive(P1GatewayServer) && WiFiConnected()) { P1GatewayServer->close(); P1GatewayServer->begin(); if(serverActive(P1GatewayServer)) { From 4c7e1b9926571640c78b9dafbd8ddd76a4ee0ccf Mon Sep 17 00:00:00 2001 From: TD-er Date: Sun, 31 May 2020 21:40:35 +0200 Subject: [PATCH 061/128] [Bug] ControllerIndex not set when calling CPLUGIN calls As reported by @sakinit --- src/src/Globals/CPlugins.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/src/Globals/CPlugins.cpp b/src/src/Globals/CPlugins.cpp index bc0a131f0..979404e28 100644 --- a/src/src/Globals/CPlugins.cpp +++ b/src/src/Globals/CPlugins.cpp @@ -77,6 +77,7 @@ bool CPluginCall(CPlugin::Function Function, struct EventStruct *event, String& for (controllerIndex_t x = 0; x < CONTROLLER_MAX; x++) { if ((Settings.Protocol[x] != 0) && Settings.ControllerEnabled[x]) { protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(x); + event->ControllerIndex = x; String dummy; CPluginCall(ProtocolIndex, Function, event, dummy); } From 5eb94adedcde3b0ab27b4b56caa0c9c6e8e73085 Mon Sep 17 00:00:00 2001 From: Saverio Cisternino Date: Mon, 1 Jun 2020 15:46:45 +0200 Subject: [PATCH 062/128] Fix parse_uint ref https://github.com/staticlibs/ccronexpr/pull/30 --- lib/ccronexpr/ccronexpr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ccronexpr/ccronexpr.c b/lib/ccronexpr/ccronexpr.c index 826d95536..1933eb144 100644 --- a/lib/ccronexpr/ccronexpr.c +++ b/lib/ccronexpr/ccronexpr.c @@ -595,7 +595,7 @@ static char* str_replace(char *orig, const char *rep, const char *with) { static unsigned int parse_uint(const char* str, int* errcode) { char* endptr; errno = 0; - long int l = strtol(str, &endptr, 0); + long int l = strtol(str, &endptr, 10); if (errno == ERANGE || *endptr != '\0' || l < 0 || l > INT_MAX) { *errcode = 1; return 0; From d485a5b785b9424cfa933cccde77afa40f116eda Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Tue, 12 May 2020 18:04:36 +0200 Subject: [PATCH 063/128] [PIO] Hide deprecated warning for SPIFFS --- platformio_core_defs.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platformio_core_defs.ini b/platformio_core_defs.ini index b735b1686..064f377da 100644 --- a/platformio_core_defs.ini +++ b/platformio_core_defs.ini @@ -105,6 +105,7 @@ platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#2.7.1 build_flags = ${esp82xx_2_6_x.build_flags} -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703 + -Wno-deprecated-declarations [core_2_7_1_sdk3] @@ -120,6 +121,7 @@ extends = esp82xx_2_6_x platform = https://github.com/platformio/platform-espressif8266.git build_flags = ${esp82xx_2_6_x.build_flags} -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191122 + -Wno-deprecated-declarations platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git From 7cd26bdf90c761f04d871fbe03df523b4994e3f4 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sat, 6 Jun 2020 12:46:35 +0200 Subject: [PATCH 064/128] [Vagrant] Fix vagrant build installing all required Python packages --- tools/vagrant/Vagrantfile | 4 +++- tools/vagrant/bootstrap.sh | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/vagrant/Vagrantfile b/tools/vagrant/Vagrantfile index 28f97fb00..20d8b4fee 100644 --- a/tools/vagrant/Vagrantfile +++ b/tools/vagrant/Vagrantfile @@ -17,6 +17,8 @@ Vagrant.configure("2") do |config| # Every Vagrant development environment requires a box. You can search for # boxes at https://vagrantcloud.com/search. config.vm.box = "bento/ubuntu-18.04" + # TD-er: No hyperv version for "bento/ubuntu-20.04" available yet. + #config.vm.box = "bento/ubuntu-20.04" # Disable automatic box update checking. If you disable this, then # boxes will only be checked for updates when the user runs @@ -69,7 +71,7 @@ Vagrant.configure("2") do |config| # documentation for more information about their specific syntax and use. config.vm.provision "shell", inline: <<-SHELL apt-get update - apt-get install -y python-minimal virtualenv build-essential zip binutils software-properties-common + apt-get install -y python3-minimal virtualenv build-essential zip binutils software-properties-common apt-get update DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade add-apt-repository ppa:deadsnakes/ppa diff --git a/tools/vagrant/bootstrap.sh b/tools/vagrant/bootstrap.sh index b60b003f2..0c545fad3 100644 --- a/tools/vagrant/bootstrap.sh +++ b/tools/vagrant/bootstrap.sh @@ -41,9 +41,9 @@ fi # Activate Python virtual environment and install/upgrade packages source ${VENV}/bin/activate -pip install -U platformio #pip install -r ${SRC}/docs/requirements.txt - +pip install -r ${SRC}/requirements.txt +pip install -U platformio # Update platformio cd ${SRC} From fd35ce7bf3ad880f22f90573532c3c3db06e2a6f Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sat, 6 Jun 2020 13:58:39 +0200 Subject: [PATCH 065/128] [Notifications] Make sure all custom defines are set at compile time --- src/ESPEasy_checks.ino | 2 ++ src/Misc.ino | 2 ++ src/WebServer.ino | 1 + src/WebServer_NotificationPage.ino | 2 ++ src/__NPlugin.ino | 2 ++ 5 files changed, 9 insertions(+) diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index 964b03f77..6e7bc38f0 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -1,3 +1,5 @@ +#include "ESPEasy_common.h" + #include "src/DataStructs/NodeStruct.h" #include "src/DataStructs/CRCStruct.h" #include "src/DataStructs/SettingsStruct.h" diff --git a/src/Misc.ino b/src/Misc.ino index 50a0cf0a9..80ad5287c 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -1,3 +1,5 @@ +#include "ESPEasy_common.h" + #include "src/DataStructs/Caches.h" #include "src/DataStructs/NodeStruct.h" #include "src/DataStructs/PinMode.h" diff --git a/src/WebServer.ino b/src/WebServer.ino index 41bbd36c6..d8865f90e 100644 --- a/src/WebServer.ino +++ b/src/WebServer.ino @@ -4,6 +4,7 @@ #include +#include "ESPEasy_common.h" #include "src/Globals/CPlugins.h" #include "src/Globals/Device.h" #include "src/Globals/TXBuffer.h" diff --git a/src/WebServer_NotificationPage.ino b/src/WebServer_NotificationPage.ino index 31d64132a..b1a2b35c6 100644 --- a/src/WebServer_NotificationPage.ino +++ b/src/WebServer_NotificationPage.ino @@ -2,6 +2,8 @@ // ******************************************************************************** // Web Interface notifcations page // ******************************************************************************** +#include "ESPEasy_common.h" + #ifndef NOTIFIER_SET_NONE #include "src/Globals/NPlugins.h" diff --git a/src/__NPlugin.ino b/src/__NPlugin.ino index 77caa603d..cd3dba727 100644 --- a/src/__NPlugin.ino +++ b/src/__NPlugin.ino @@ -1,3 +1,5 @@ +#include "ESPEasy_common.h" + #ifndef NOTIFIER_SET_NONE #include "src/Globals/NPlugins.h" From 6a8156e8543188b60c1defc5b77b78bee60179f3 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sat, 6 Jun 2020 14:37:39 +0200 Subject: [PATCH 066/128] [Travis] Fix deploy multiple ZIP files + split ESP82xx and ESP32 files --- .travis.yml | 3 +-- before_deploy | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index e9d9d4ee7..0f7cc0ca2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -77,7 +77,6 @@ script: before_deploy: - ./before_deploy - - export RELEASE_FILE=$(ls ESPEasy*.zip) deploy: provider: releases @@ -85,7 +84,7 @@ deploy: api_key: secure: bZeuKI7evXeZYmGayfcvIC1fThBGcksAyOrCbZ8kAGeTbHGJqFLBBy8to5UpNBSZVfeDWo25Iqy8Pfbyb7p2c1hg6fG9jS0UzQkLnoUNMxpUM1dJACkZxvFdP4Br3Y3vUPWtrWUbo8rN/b3E6tjSNLE7vQiwsarj+eWTO2V6BGcsN0eHc04/UCM2+DcHvJ4y7Ec36yIUaClNAWMal1osBYaViruylOdBKT/WDs1ZMoJMceXCfxMQ/8J2moYvymKfSkXSmoMGmzlTuq8v5N4AweutjpC4Zba2BbxIJv+PwWjhfIgTviHFggSU90UPTKVWYv13vms92VVKz1CDVrUQNn+YQes9+ROPUnrMc9bJ+q7E1lWJRZeDMqGECB+8BjUtUk6H81K+XhOnW1mtZiMnvMCwkmE0OT1eBObGMcpR962/DUBoQDmulMs2IieB0dLobmUBhpc1syrKEPKxjY7yhhQMr6In82jODVLR3qDkNQ8xtIfevzCo/ocUjiOrXW4b/pDMy28Yh109DMb/KSWEsjjkkpXhsT1YVy2MwOa7FRhHFW+SNKX4Us8T75H+pO4mQ4afnPEtjYKodj7XD92zqNxKfMx3elEx5RK6HKekHjpXdYtuXzGONB9StA+2T43/2llt3n5fzv4BRfCumBEJ77/ufB0U/uhsCe6lVwJf34U= file_glob: true - file: "${RELEASE_FILE}" + file: ESPEasy*.zip skip_cleanup: true on: diff --git a/before_deploy b/before_deploy index ea9bda889..26caaf7b6 100755 --- a/before_deploy +++ b/before_deploy @@ -47,8 +47,6 @@ if [ -d "docs/build" ]; then echo "### Created ESPEasy_docs_$VERSION.zip" fi -cp -r build_output/bin/* ${TMP_DIST}/bin - #create a source structure that is the same as the original ESPEasy project (and works with the howto on the wiki) #rm -rf dist/Source 2>/dev/null @@ -63,13 +61,28 @@ cp *.txt ${TMP_DIST}/source/ cp *.csv ${TMP_DIST}/source/ cp README* ${TMP_DIST}/source/ +cp -r build_output/bin/* ${TMP_DIST}/bin +rm -f ${TMP_DIST}/bin/*ESP32* cd ${TMP_DIST} -echo -zip -qq ${CURPATH}/ESPEasy_$VERSION.zip -r . -echo "### Created ESPEasy_$VERSION.zip" +if [ "$(ls -A ${TMP_DIST}/bin/)" ]; then + echo + zip -qq ${CURPATH}/ESPEasy_ESP82xx_$VERSION.zip -r . + echo "### Created ESPEasy_ESP82xx_$VERSION.zip" +fi +cd ${CURPATH} +rm -f ${TMP_DIST}/bin/* +cp -r build_output/bin/*ESP32* ${TMP_DIST}/bin + +cd ${TMP_DIST} + +if [ "$(ls -A ${TMP_DIST}/bin/)" ]; then + echo + zip -qq ${CURPATH}/ESPEasy_ESP32_$VERSION.zip -r . + echo "### Created ESPEasy_ESP32_$VERSION.zip" +fi rm -Rf ${TMP_DIST}/* 2>/dev/null rmdir ${TMP_DIST} From 39a10b0741d43e4996a40a0819947f376927f06d Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sat, 6 Jun 2020 15:37:06 +0200 Subject: [PATCH 067/128] [Build] Fix Python 3.8 build when no .git dir or pygit2 not installed --- dist/README.txt | 5 +++++ tools/pio/generate-compiletime-defines.py | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dist/README.txt b/dist/README.txt index 9b84b2196..02af8582d 100644 --- a/dist/README.txt +++ b/dist/README.txt @@ -95,6 +95,11 @@ do that. More information about the tool is found here: https://github.com/Grovkillen/ESP_Easy_Flasher You can also have custom serial commands entered in a txt file. One command per line. + +For flashing ESP32 you need Espressif's own Flash Download Tools. +The latest version can be downloaded from: https://www.espressif.com/en/support/download/other-tools + + Further reading: For more information, see: https://github.com/letscontrolit/ESPEasy Or our forum: https://www.letscontrolit.com/forum/ diff --git a/tools/pio/generate-compiletime-defines.py b/tools/pio/generate-compiletime-defines.py index bcfc89ad0..ca38139a4 100644 --- a/tools/pio/generate-compiletime-defines.py +++ b/tools/pio/generate-compiletime-defines.py @@ -4,7 +4,6 @@ import os import platform import shutil from datetime import date -from pygit2 import Repository import json @@ -15,7 +14,14 @@ def create_binary_filename(): def get_git_description(): - return Repository('.').head.shorthand + try: + from pygit2 import Repository + try: + return Repository('.').head.shorthand + except: + return 'No_.git_dir' + except ImportError: + return 'pygit2_not_installed' # needed to wrap in a number of double quotes. From b0a7825a2e2964af074dd1f0cc5379237773a517 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sat, 6 Jun 2020 16:17:54 +0200 Subject: [PATCH 068/128] [GPS] Add GPS#travelled=... event (#3099) Fixes: #3099 --- docs/source/Plugin/P082_events.repl | 18 ++++++++++++++++++ src/_P082_GPS.ino | 3 +++ 2 files changed, 21 insertions(+) diff --git a/docs/source/Plugin/P082_events.repl b/docs/source/Plugin/P082_events.repl index eb915ee79..cf3a256be 100644 --- a/docs/source/Plugin/P082_events.repl +++ b/docs/source/Plugin/P082_events.repl @@ -26,3 +26,21 @@ endon " + " + ``GPS#travelled`` + When configured to update every N meters travelled, this event will be triggered if the GPS moved more than N meters away from the last position this trigger was given. + This means the total travel distance can be more if the GPS does not move in a straight line. + "," + + .. code-block:: html + + on GPS#travelled do + LogEntry,'Travelled %eventvalue% meter' + endon + + " + + + + + \ No newline at end of file diff --git a/src/_P082_GPS.ino b/src/_P082_GPS.ino index 8dd0bc0d5..7d35c7315 100644 --- a/src/_P082_GPS.ino +++ b/src/_P082_GPS.ino @@ -499,6 +499,9 @@ boolean Plugin_082(byte function, struct EventStruct *event, String& string) { if (distance > static_cast(P082_DISTANCE)) { if (P082_data->storeCurPos(P082_TIMEOUT)) { distance_passed = true; + String eventString = F("GPS#travelled="); + eventString += distance; + eventQueue.add(eventString); if (loglevelActiveFor(LOG_LEVEL_INFO)) { String log = F("GPS: Distance trigger : "); From ac3c46c2271eb63457ff6389f690304e0aebb179 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sat, 6 Jun 2020 16:53:46 +0200 Subject: [PATCH 069/128] [Build] Add ina219 and mpu6050 to custom build (#3100) Fixes: #3100 --- tools/pio/pre_custom_esp32.py | 3 +++ tools/pio/pre_custom_esp82xx.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/tools/pio/pre_custom_esp32.py b/tools/pio/pre_custom_esp32.py index 52f93239e..72c301729 100644 --- a/tools/pio/pre_custom_esp32.py +++ b/tools/pio/pre_custom_esp32.py @@ -25,12 +25,15 @@ else: "USES_P001", # Switch "USES_P002", # ADC "USES_P004", # Dallas DS18b20 + "USES_P027", # INA219 "USES_P028", # BME280 "USES_P036", # FrameOLED + "USES_P045", # MPU6050 "USES_P049", # MHZ19 "USES_P052", # SenseAir "USES_P056", # SDS011-Dust "USES_P059", # Encoder + "USES_P081", # Cron "USES_P082", # GPS "USES_P087", # Serial Proxy "USES_P097", # Touch (ESP32) diff --git a/tools/pio/pre_custom_esp82xx.py b/tools/pio/pre_custom_esp82xx.py index bebeda382..e3527d3ce 100644 --- a/tools/pio/pre_custom_esp82xx.py +++ b/tools/pio/pre_custom_esp82xx.py @@ -26,8 +26,10 @@ else: "USES_P001", # Switch "USES_P002", # ADC "USES_P004", # Dallas DS18b20 + "USES_P027", # INA219 "USES_P028", # BME280 "USES_P036", # FrameOLED + "USES_P045", # MPU6050 "USES_P049", # MHZ19 "USES_P052", # SenseAir "USES_P056", # SDS011-Dust From ea7713dd794cbba4f41b9e6462b6a027c41e20d3 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sat, 6 Jun 2020 20:18:02 +0200 Subject: [PATCH 070/128] [Build] Disable diagnostics code for test_ESP8266_4M1M_VCC to fit size --- src/define_plugin_sets.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/define_plugin_sets.h b/src/define_plugin_sets.h index c93e7e0aa..3f27b6071 100644 --- a/src/define_plugin_sets.h +++ b/src/define_plugin_sets.h @@ -336,6 +336,11 @@ To create/register a plugin, you have to : #undef WEBSERVER_WIFI_SCANNER #endif #endif // WEBSERVER_CUSTOM_BUILD_DEFINED + + #ifndef LIMIT_BUILD_SIZE + #define LIMIT_BUILD_SIZE + #endif + #ifdef USES_SSDP #undef USES_SSDP #endif @@ -1036,15 +1041,33 @@ To create/register a plugin, you have to : #undef USES_C014 #endif +// VCC builds need a bit more, disable timing stats to make it fit. +#ifdef FEATURE_ADC_VCC + #ifndef LIMIT_BUILD_SIZE + #define LIMIT_BUILD_SIZE + #endif +#endif + // Due to size restrictions, disable a few plugins/controllers for 1M builds #ifdef SIZE_1M #ifdef USES_C003 #undef USES_C003 #endif + #ifndef LIMIT_BUILD_SIZE + #define LIMIT_BUILD_SIZE + #endif #endif - +// Disable some diagnostic parts to make builds fit. +#ifdef LIMIT_BUILD_SIZE + #ifdef WEBSERVER_TIMINGSTATS + #undef WEBSERVER_TIMINGSTATS + #endif + #ifndef BUILD_NO_DEBUG + #define BUILD_NO_DEBUG + #endif +#endif // Timing stats page needs timing stats #if defined(WEBSERVER_TIMINGSTATS) && !defined(USES_TIMING_STATS) From 73df4a8295d553fc3db8c92379964aea0f031eb3 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sun, 7 Jun 2020 00:43:45 +0200 Subject: [PATCH 071/128] [Build] Disabling timing stats results in build errors for ESP32 Still something that needs to be investigated further. Probably something related to how .ino files (Webserver code) are compiled --- src/WebServer_TimingStats.ino | 4 +++- src/define_plugin_sets.h | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/WebServer_TimingStats.ino b/src/WebServer_TimingStats.ino index 0f75c08f3..cb38bafa7 100644 --- a/src/WebServer_TimingStats.ino +++ b/src/WebServer_TimingStats.ino @@ -1,5 +1,7 @@ +#include "ESPEasy_common.h" -#ifdef WEBSERVER_TIMINGSTATS + +#if defined(WEBSERVER_TIMINGSTATS) && defined(USES_TIMING_STATS) #include "src/Globals/Device.h" diff --git a/src/define_plugin_sets.h b/src/define_plugin_sets.h index 3f27b6071..3fc0c1d4e 100644 --- a/src/define_plugin_sets.h +++ b/src/define_plugin_sets.h @@ -1061,9 +1061,16 @@ To create/register a plugin, you have to : // Disable some diagnostic parts to make builds fit. #ifdef LIMIT_BUILD_SIZE - #ifdef WEBSERVER_TIMINGSTATS - #undef WEBSERVER_TIMINGSTATS + // FIXME TD-er: When setting these undefs a lot of linker errors occur on ESP32 build => .ino compile issue? + #ifdef ESP8266 + #ifdef WEBSERVER_TIMINGSTATS + #undef WEBSERVER_TIMINGSTATS + #endif + #ifdef USES_TIMING_STATS + #undef USES_TIMING_STATS + #endif #endif + #ifndef BUILD_NO_DEBUG #define BUILD_NO_DEBUG #endif From 5a5045c2999b1cb435af0ccad9d7e0d06164bcc2 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sun, 7 Jun 2020 02:39:35 +0200 Subject: [PATCH 072/128] [Commands] Split commands.ino to .h/.cpp to overcome build/link issues --- platformio_esp82xx_envs.ini | 1 + src/ESPEasy.ino | 24 --- src/ESPEasyRules.ino | 1 + src/ESPEasyStatistics.ino | 2 +- src/ESPEasy_fdwdecl.h | 6 + src/Misc.ino | 1 + src/Networking.ino | 1 + src/Serial.ino | 2 + src/WebServer_ControlPage.ino | 2 + src/WebServer_CustomPage.ino | 1 + src/WebServer_RootPage.ino | 1 + src/WebServer_SysInfoPage.ino | 4 + src/WebServer_ToolsPage.ino | 2 + src/_C002.ino | 1 + src/_C012.ino | 82 +-------- src/define_plugin_sets.h | 10 +- src/src/Commands/Blynk.cpp | 158 ++++++++++++++++++ src/src/Commands/Blynk.h | 51 ++---- src/src/Commands/Blynk_c015.h | 2 +- src/src/Commands/Diagnostic.cpp | 1 - src/src/Commands/Diagnostic.h | 2 +- .../Commands/InternalCommands.cpp} | 96 ++++------- src/src/Commands/InternalCommands.h | 38 +++++ src/src/Commands/MQTT.cpp | 3 +- src/src/Commands/SDCARD.cpp | 28 ++++ src/src/Commands/SDCARD.h | 8 +- src/src/ControllerQueue/DelayQueueElements.h | 3 - src/src/DataStructs/TimingStats.h | 2 +- src/src/Globals/MQTT.h | 2 +- src/src/Globals/RamTracker.h | 2 +- src/src/Static/WebStaticData.h | 2 +- 31 files changed, 314 insertions(+), 225 deletions(-) create mode 100644 src/src/Commands/Blynk.cpp rename src/{Command.ino => src/Commands/InternalCommands.cpp} (89%) create mode 100644 src/src/Commands/InternalCommands.h diff --git a/platformio_esp82xx_envs.ini b/platformio_esp82xx_envs.ini index 869939508..342232065 100644 --- a/platformio_esp82xx_envs.ini +++ b/platformio_esp82xx_envs.ini @@ -342,6 +342,7 @@ build_flags = ${testing.build_flags} -DFEATURE_ADC_VCC=true -DFEATURE_MDNS -DFEATURE_SD + -DBUILD_NO_DEBUG lib_ignore = ESP32_ping, ESP32WebServer, ESP32HTTPUpdateServer, , IRremoteESP8266, HeatpumpIR diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index b5f103ac8..042be3501 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -129,13 +129,6 @@ ADC_MODE(ADC_VCC); float& getUserVar(unsigned int varIndex) {return UserVar[varIndex]; } -#ifdef USES_BLYNK -// Blynk_get prototype -boolean Blynk_get(const String& command, controllerIndex_t controllerIndex,float *data = NULL ); - -controllerIndex_t firstEnabledBlynk_ControllerIndex(); -#endif - //void checkRAM( const __FlashStringHelper* flashString); #ifdef CORE_POST_2_5_0 @@ -707,23 +700,6 @@ controllerIndex_t firstEnabledMQTT_ControllerIndex() { #endif //USES_MQTT -#ifdef USES_BLYNK -// Blynk_get prototype -//boolean Blynk_get(const String& command, controllerIndex_t controllerIndex,float *data = NULL ); - -controllerIndex_t firstEnabledBlynk_ControllerIndex() { - for (controllerIndex_t i = 0; i < CONTROLLER_MAX; ++i) { - protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(i); - if (validProtocolIndex(ProtocolIndex)) { - if (Protocol[ProtocolIndex].Number == 12 && Settings.ControllerEnabled[i]) { - return i; - } - } - } - return INVALID_CONTROLLER_INDEX; -} -#endif - /*********************************************************************************************\ * Tasks that run 50 times per second diff --git a/src/ESPEasyRules.ino b/src/ESPEasyRules.ino index a45d20e19..a367a4599 100644 --- a/src/ESPEasyRules.ino +++ b/src/ESPEasyRules.ino @@ -1,6 +1,7 @@ #define RULE_FILE_SEPARAROR '/' #define RULE_MAX_FILENAME_LENGTH 24 +#include "src/Commands/InternalCommands.h" #include "src/DataStructs/EventValueSource.h" #include "src/Globals/Device.h" #include "src/Globals/Plugins.h" diff --git a/src/ESPEasyStatistics.ino b/src/ESPEasyStatistics.ino index 1105ca6a0..d02bb94a6 100644 --- a/src/ESPEasyStatistics.ino +++ b/src/ESPEasyStatistics.ino @@ -1,4 +1,4 @@ -#include "define_plugin_sets.h" +#include "ESPEasy_common.h" #ifdef USES_TIMING_STATS diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index 3174b43da..77b2111ac 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -170,6 +170,12 @@ String LoadStringArray(SettingsType::Enum settingsType, int index, String string String SaveStringArray(SettingsType::Enum settingsType, int index, const String strings[], uint16_t nrStrings, uint16_t maxStringLength); +void SendStatus(byte source, const String& status); + +String parseTemplate(String& tmpString); +String parseTemplate(String& tmpString, bool useURLencode); +void parseCommandString(struct EventStruct *event, const String& string); + String parseString(const String& string, byte indexFind); String parseStringKeepCase(const String& string, byte indexFind); String parseStringToEnd(const String& string, byte indexFind); diff --git a/src/Misc.ino b/src/Misc.ino index 2edcdea4d..9f5c855bb 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -14,6 +14,7 @@ #include "src/Globals/RTC.h" #include "src/Globals/ResetFactoryDefaultPref.h" #include "src/Globals/Services.h" +#include "src/Globals/Settings.h" #ifdef ESP32 diff --git a/src/Networking.ino b/src/Networking.ino index 8baf6bbad..013ea28f7 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -1,3 +1,4 @@ +#include "src/Commands/InternalCommands.h" #include "src/Globals/Nodes.h" #include "src/Globals/ESPEasyWiFiEvent.h" diff --git a/src/Serial.ino b/src/Serial.ino index 1f1f2c676..2c74b9b90 100644 --- a/src/Serial.ino +++ b/src/Serial.ino @@ -1,3 +1,5 @@ +#include "src/Commands/InternalCommands.h" + /********************************************************************************************\ * Get data from Serial Interface \*********************************************************************************************/ diff --git a/src/WebServer_ControlPage.ino b/src/WebServer_ControlPage.ino index 6bfb42266..9f0034335 100644 --- a/src/WebServer_ControlPage.ino +++ b/src/WebServer_ControlPage.ino @@ -1,6 +1,8 @@ #ifdef WEBSERVER_CONTROL +#include "src/Commands/InternalCommands.h" + // ******************************************************************************** // Web Interface control page (no password!) // ******************************************************************************** diff --git a/src/WebServer_CustomPage.ino b/src/WebServer_CustomPage.ino index a0257e52a..d35e42f04 100644 --- a/src/WebServer_CustomPage.ino +++ b/src/WebServer_CustomPage.ino @@ -1,3 +1,4 @@ +#include "src/Commands/InternalCommands.h" #include "src/Globals/Nodes.h" #include "src/Globals/Device.h" #include "src/Globals/Plugins.h" diff --git a/src/WebServer_RootPage.ino b/src/WebServer_RootPage.ino index fc11de2d8..fcc6dea0c 100644 --- a/src/WebServer_RootPage.ino +++ b/src/WebServer_RootPage.ino @@ -1,5 +1,6 @@ #ifdef WEBSERVER_ROOT +#include "src/Commands/InternalCommands.h" #include "src/Globals/Nodes.h" // ******************************************************************************** diff --git a/src/WebServer_SysInfoPage.ino b/src/WebServer_SysInfoPage.ino index fdb317be0..2e9f85796 100644 --- a/src/WebServer_SysInfoPage.ino +++ b/src/WebServer_SysInfoPage.ino @@ -2,6 +2,10 @@ #include "src/DataStructs/RTCStruct.h" #include "src/Globals/CRCValues.h" #include "src/Static/WebStaticData.h" +#include "ESPEasy_common.h" + +#include "src/Commands/Diagnostic.h" + #ifdef WEBSERVER_NEW_UI diff --git a/src/WebServer_ToolsPage.ino b/src/WebServer_ToolsPage.ino index 3d1824e58..d6b374d5d 100644 --- a/src/WebServer_ToolsPage.ino +++ b/src/WebServer_ToolsPage.ino @@ -1,5 +1,7 @@ #ifdef WEBSERVER_TOOLS +#include "src/Commands/InternalCommands.h" + // ******************************************************************************** // Web Interface Tools page // ******************************************************************************** diff --git a/src/_C002.ino b/src/_C002.ino index f49d2c64c..4dac505ef 100644 --- a/src/_C002.ino +++ b/src/_C002.ino @@ -8,6 +8,7 @@ #define CPLUGIN_ID_002 2 #define CPLUGIN_NAME_002 "Domoticz MQTT" +#include "src/Commands/InternalCommands.h" #include bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String& string) diff --git a/src/_C012.ino b/src/_C012.ino index 35ba99aeb..00c0c8715 100644 --- a/src/_C012.ino +++ b/src/_C012.ino @@ -5,6 +5,8 @@ // #ifdef PLUGIN_BUILD_TESTING +#include "src/Commands/Blynk.h" + #define CPLUGIN_012 #define CPLUGIN_ID_012 12 #define CPLUGIN_NAME_012 "Blynk HTTP [TESTING]" @@ -99,85 +101,5 @@ bool do_process_c012_delay_queue(int controller_number, const C012_queue_element return element.checkDone(Blynk_get(element.txt[element.valuesSent], element.controller_idx)); } -boolean Blynk_get(const String& command, controllerIndex_t controllerIndex, float *data ) -{ - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(controllerIndex, ControllerSettings); - if ((getControllerPass(controllerIndex, ControllerSettings).length() == 0)) { - addLog(LOG_LEVEL_ERROR, F("Blynk : No password set")); - return false; - } - - WiFiClient client; - if (!try_connect_host(CPLUGIN_ID_012, client, ControllerSettings)) - return false; - - - // We now create a URI for the request - char request[300] = {0}; - sprintf_P(request, - PSTR("GET /%s/%s HTTP/1.1\r\n Host: %s \r\n Connection: close\r\n\r\n"), - getControllerPass(controllerIndex, ControllerSettings).c_str(), - command.c_str(), - ControllerSettings.getHost().c_str()); - addLog(LOG_LEVEL_DEBUG, request); - client.print(request); - bool success = !ControllerSettings.MustCheckReply; - if (ControllerSettings.MustCheckReply || data) { - unsigned long timer = millis() + 200; - while (!client_available(client) && !timeOutReached(timer)) - delay(1); - - char log[80] = {0}; - timer = millis() + 1500; - // Read all the lines of the reply from server and log them - while (client_available(client) && !success && !timeOutReached(timer)) { - String line; - safeReadStringUntil(client, line, '\n'); - addLog(LOG_LEVEL_DEBUG_MORE, line); - // success ? - if (line.substring(0, 15) == F("HTTP/1.1 200 OK")) { - strcpy_P(log, PSTR("HTTP : Success")); - if (!data) success = true; - } - else if (line.substring(0, 24) == F("HTTP/1.1 400 Bad Request")) { - strcpy_P(log, PSTR("HTTP : Unauthorized")); - } - else if (line.substring(0, 25) == F("HTTP/1.1 401 Unauthorized")) { - strcpy_P(log, PSTR("HTTP : Unauthorized")); - } - addLog(LOG_LEVEL_DEBUG, log); - - // data only - if (data && line.startsWith("[")) - { - String strValue = line; - byte pos = strValue.indexOf('"',2); - strValue = strValue.substring(2, pos); - strValue.trim(); - float value = strValue.toFloat(); - *data = value; - success = true; - - char value_char[5] = {0}; - strValue.toCharArray(value_char, 5); - sprintf_P(log, PSTR("Blynk get - %s => %s"),command.c_str(), value_char ); - addLog(LOG_LEVEL_DEBUG, log); - } - delay(0); - } - } - addLog(LOG_LEVEL_DEBUG, F("HTTP : closing connection (012)")); - - client.flush(); - client.stop(); - - // important - backgroundtasks - free mem - unsigned long timer = millis() + ControllerSettings.ClientTimeout; - while (!timeOutReached(timer)) - backgroundtasks(); - - return success; -} #endif diff --git a/src/define_plugin_sets.h b/src/define_plugin_sets.h index 3fc0c1d4e..1dbde81aa 100644 --- a/src/define_plugin_sets.h +++ b/src/define_plugin_sets.h @@ -1061,14 +1061,8 @@ To create/register a plugin, you have to : // Disable some diagnostic parts to make builds fit. #ifdef LIMIT_BUILD_SIZE - // FIXME TD-er: When setting these undefs a lot of linker errors occur on ESP32 build => .ino compile issue? - #ifdef ESP8266 - #ifdef WEBSERVER_TIMINGSTATS - #undef WEBSERVER_TIMINGSTATS - #endif - #ifdef USES_TIMING_STATS - #undef USES_TIMING_STATS - #endif + #ifdef WEBSERVER_TIMINGSTATS + #undef WEBSERVER_TIMINGSTATS #endif #ifndef BUILD_NO_DEBUG diff --git a/src/src/Commands/Blynk.cpp b/src/src/Commands/Blynk.cpp new file mode 100644 index 000000000..fb3ac62bb --- /dev/null +++ b/src/src/Commands/Blynk.cpp @@ -0,0 +1,158 @@ +#include "../Commands/Blynk.h" + + +#include "../Commands/Common.h" +#include "../DataStructs/ESPEasy_EventStruct.h" +#include "../Globals/Protocol.h" +#include "../Globals/Settings.h" +#include "../Helpers/ESPEasy_time_calc.h" +#include "../../_CPlugin_Helper.h" +#include "../../ESPEasy_fdwdecl.h" +#include "../../ESPEasy_Log.h" + + +#ifdef USES_C012 + +controllerIndex_t firstEnabledBlynk_ControllerIndex() { + for (controllerIndex_t i = 0; i < CONTROLLER_MAX; ++i) { + protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(i); + + if (validProtocolIndex(ProtocolIndex)) { + if ((Protocol[ProtocolIndex].Number == 12) && Settings.ControllerEnabled[i]) { + return i; + } + } + } + return INVALID_CONTROLLER_INDEX; +} + +String Command_Blynk_Get(struct EventStruct *event, const char *Line) +{ + controllerIndex_t first_enabled_blynk_controller = firstEnabledBlynk_ControllerIndex(); + + if (!validControllerIndex(first_enabled_blynk_controller)) { + return F("Controller not enabled"); + } else { + // FIXME TD-er: This one is not using parseString* function + String strLine = Line; + strLine = strLine.substring(9); + int index = strLine.indexOf(','); + + if (index > 0) + { + int index = strLine.lastIndexOf(','); + String blynkcommand = strLine.substring(index + 1); + float value = 0; + + if (Blynk_get(blynkcommand, first_enabled_blynk_controller, &value)) + { + UserVar[(VARS_PER_TASK * (event->Par1 - 1)) + event->Par2 - 1] = value; + } + else { + return F("Error getting data"); + } + } + else + { + if (!Blynk_get(strLine, first_enabled_blynk_controller, nullptr)) + { + return F("Error getting data"); + } + } + } + return return_command_success(); +} + +bool Blynk_get(const String& command, controllerIndex_t controllerIndex, float *data) +{ + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(controllerIndex, ControllerSettings); + + if ((getControllerPass(controllerIndex, ControllerSettings).length() == 0)) { + addLog(LOG_LEVEL_ERROR, F("Blynk : No password set")); + return false; + } + + WiFiClient client; + + if (!try_connect_host(/* CPLUGIN_ID_012 */ 12, client, ControllerSettings)) { + return false; + } + + + // We now create a URI for the request + char request[300] = { 0 }; + sprintf_P(request, + PSTR("GET /%s/%s HTTP/1.1\r\n Host: %s \r\n Connection: close\r\n\r\n"), + getControllerPass(controllerIndex, ControllerSettings).c_str(), + command.c_str(), + ControllerSettings.getHost().c_str()); + addLog(LOG_LEVEL_DEBUG, request); + client.print(request); + bool success = !ControllerSettings.MustCheckReply; + + if (ControllerSettings.MustCheckReply || data) { + unsigned long timer = millis() + 200; + + while (!client_available(client) && !timeOutReached(timer)) { + delay(1); + } + + char log[80] = { 0 }; + timer = millis() + 1500; + + // Read all the lines of the reply from server and log them + while (client_available(client) && !success && !timeOutReached(timer)) { + String line; + safeReadStringUntil(client, line, '\n'); + addLog(LOG_LEVEL_DEBUG_MORE, line); + + // success ? + if (line.substring(0, 15) == F("HTTP/1.1 200 OK")) { + strcpy_P(log, PSTR("HTTP : Success")); + + if (!data) { success = true; } + } + else if (line.substring(0, 24) == F("HTTP/1.1 400 Bad Request")) { + strcpy_P(log, PSTR("HTTP : Unauthorized")); + } + else if (line.substring(0, 25) == F("HTTP/1.1 401 Unauthorized")) { + strcpy_P(log, PSTR("HTTP : Unauthorized")); + } + addLog(LOG_LEVEL_DEBUG, log); + + // data only + if (data && line.startsWith("[")) + { + String strValue = line; + byte pos = strValue.indexOf('"', 2); + strValue = strValue.substring(2, pos); + strValue.trim(); + float value = strValue.toFloat(); + *data = value; + success = true; + + char value_char[5] = { 0 }; + strValue.toCharArray(value_char, 5); + sprintf_P(log, PSTR("Blynk get - %s => %s"), command.c_str(), value_char); + addLog(LOG_LEVEL_DEBUG, log); + } + delay(0); + } + } + addLog(LOG_LEVEL_DEBUG, F("HTTP : closing connection (012)")); + + client.flush(); + client.stop(); + + // important - backgroundtasks - free mem + unsigned long timer = millis() + ControllerSettings.ClientTimeout; + + while (!timeOutReached(timer)) { + backgroundtasks(); + } + + return success; +} + +#endif // ifdef USES_C012 diff --git a/src/src/Commands/Blynk.h b/src/src/Commands/Blynk.h index ec8530b8b..6cfd9432d 100644 --- a/src/src/Commands/Blynk.h +++ b/src/src/Commands/Blynk.h @@ -1,46 +1,23 @@ #ifndef COMMAND_BLYNK_H #define COMMAND_BLYNK_H -#include "../../define_plugin_sets.h" +#include "../../ESPEasy_common.h" +#include "../Globals/CPlugins.h" -#include "../DataStructs/ESPEasy_EventStruct.h" -#include "../../ESPEasy_fdwdecl.h" #ifdef USES_C012 - //FIXME: this should go to PLUGIN_WRITE in _C012.ino -String Command_Blynk_Get(struct EventStruct *event, const char* Line) -{ - controllerIndex_t first_enabled_blynk_controller = firstEnabledBlynk_ControllerIndex(); - if (!validControllerIndex(first_enabled_blynk_controller)) { - return F("Controller not enabled"); - } else { - // FIXME TD-er: This one is not using parseString* function - String strLine = Line; - strLine = strLine.substring(9); - int index = strLine.indexOf(','); - if (index > 0) - { - int index = strLine.lastIndexOf(','); - String blynkcommand = strLine.substring(index+1); - float value = 0; - if (Blynk_get(blynkcommand, first_enabled_blynk_controller, &value)) - { - UserVar[(VARS_PER_TASK * (event->Par1 - 1)) + event->Par2 - 1] = value; - } - else - return F("Error getting data"); - } - else - { - if (!Blynk_get(strLine, first_enabled_blynk_controller)) - { - return F("Error getting data"); - } - } - } - return return_command_success(); -} -#endif + +controllerIndex_t firstEnabledBlynk_ControllerIndex(); + +// FIXME: this should go to PLUGIN_WRITE in _C012.ino +String Command_Blynk_Get(struct EventStruct *event, + const char *Line); + +bool Blynk_get(const String & command, + controllerIndex_t controllerIndex, + float *data = nullptr); + +#endif // ifdef USES_C012 #endif // COMMAND_BLYNK_H diff --git a/src/src/Commands/Blynk_c015.h b/src/src/Commands/Blynk_c015.h index f936889e0..977837a69 100644 --- a/src/src/Commands/Blynk_c015.h +++ b/src/src/Commands/Blynk_c015.h @@ -1,7 +1,7 @@ #ifndef COMMAND_BLYNK_C015_H #define COMMAND_BLYNK_C015_H -#include "../../define_plugin_sets.h" +#include "../../ESPEasy_common.h" #ifdef USES_C015 diff --git a/src/src/Commands/Diagnostic.cpp b/src/src/Commands/Diagnostic.cpp index 1b5496af4..dd37c7a52 100644 --- a/src/src/Commands/Diagnostic.cpp +++ b/src/src/Commands/Diagnostic.cpp @@ -12,7 +12,6 @@ #include #include -#include "../../ESPEasy_common.h" #include "../Commands/Common.h" #include "../Globals/Settings.h" #include "../Globals/SecuritySettings.h" diff --git a/src/src/Commands/Diagnostic.h b/src/src/Commands/Diagnostic.h index 435fdfd35..f69fe00af 100644 --- a/src/src/Commands/Diagnostic.h +++ b/src/src/Commands/Diagnostic.h @@ -4,7 +4,7 @@ #include #include -#include "../../define_plugin_sets.h" +#include "../../ESPEasy_common.h" class String; struct portStatusStruct; diff --git a/src/Command.ino b/src/src/Commands/InternalCommands.cpp similarity index 89% rename from src/Command.ino rename to src/src/Commands/InternalCommands.cpp index d43feabfd..b2a21b3ba 100644 --- a/src/Command.ino +++ b/src/src/Commands/InternalCommands.cpp @@ -1,31 +1,38 @@ +#include "InternalCommands.h" + +#include "../../ESPEasy_common.h" +#include "../../ESPEasy_fdwdecl.h" +#include "../../ESPEasy_Log.h" +#include "../Globals/Settings.h" -#include "src/Commands/Common.h" #ifdef USES_BLYNK -# include "src/Commands/Blynk.h" -# include "src/Commands/Blynk_c015.h" +# include "../Commands/Blynk.h" +# include "../Commands/Blynk_c015.h" #endif // ifdef USES_BLYNK -#include "src/Commands/Controller.h" -#include "src/Commands/Diagnostic.h" -#include "src/Commands/HTTP.h" -#include "src/Commands/i2c.h" -#ifdef USES_MQTT -# include "src/Commands/MQTT.h" -#endif // USES_MQTT -#include "src/Commands/Networks.h" -#include "src/Commands/Notifications.h" -#include "src/Commands/RTC.h" -#include "src/Commands/Rules.h" -#include "src/Commands/SDCARD.h" -#include "src/Commands/Settings.h" -#include "src/Commands/System.h" -#include "src/Commands/Tasks.h" -#include "src/Commands/Time.h" -#include "src/Commands/Timer.h" -#include "src/Commands/UPD.h" -#include "src/Commands/wd.h" -#include "src/Commands/WiFi.h" -#include "ESPEasy_common.h" +#include "../Commands/Common.h" +#include "../Commands/Controller.h" +#include "../Commands/Diagnostic.h" +#include "../Commands/HTTP.h" +#include "../Commands/i2c.h" + +#ifdef USES_MQTT +# include "../Commands/MQTT.h" +#endif // USES_MQTT + +#include "../Commands/Networks.h" +#include "../Commands/Notifications.h" +#include "../Commands/RTC.h" +#include "../Commands/Rules.h" +#include "../Commands/SDCARD.h" +#include "../Commands/Settings.h" +#include "../Commands/System.h" +#include "../Commands/Tasks.h" +#include "../Commands/Time.h" +#include "../Commands/Timer.h" +#include "../Commands/UPD.h" +#include "../Commands/wd.h" +#include "../Commands/WiFi.h" bool checkNrArguments(const char *cmd, const char *Line, int nrArguments) { @@ -94,9 +101,6 @@ bool checkNrArguments(const char *cmd, const char *Line, int nrArguments) { return true; } -typedef String (*command_function)(struct EventStruct *, const char *); -bool do_command_case(const String& cmd_lc, const char *cmd, struct EventStruct *event, const char *line, String& status, const String& cmd_test, command_function pFunc, int nrArguments, bool& retval); - bool do_command_case(const String& cmd_lc, const char *cmd, struct EventStruct *event, const char *line, String& status, const String& cmd_test, command_function pFunc, int nrArguments, bool& retval) { if (cmd_lc.equals(cmd_test)) { @@ -112,9 +116,7 @@ bool do_command_case(const String& cmd_lc, const char *cmd, struct EventStruct * return false; } -/*********************************************************************************************\ -* Registers command -\*********************************************************************************************/ + bool executeInternalCommand(const char *cmd, struct EventStruct *event, const char *line, String& status) { String cmd_lc; @@ -303,6 +305,8 @@ bool executeInternalCommand(const char *cmd, struct EventStruct *event, const ch return false; } + + // Execute command which may be plugin or internal commands bool ExecuteCommand_all(byte source, const char *Line) { @@ -452,34 +456,4 @@ bool ExecuteCommand(taskIndex_t taskIndex, byte source, const char *Line, bool t SendStatus(source, errorUnknown); delay(0); return false; -} - -#ifdef FEATURE_SD -void printDirectory(File dir, int numTabs) -{ - while (true) { - File entry = dir.openNextFile(); - - if (!entry) { - // no more files - break; - } - - for (uint8_t i = 0; i < numTabs; i++) { - serialPrint("\t"); - } - serialPrint(entry.name()); - - if (entry.isDirectory()) { - serialPrintln("/"); - printDirectory(entry, numTabs + 1); - } else { - // files have sizes, directories do not - serialPrint("\t\t"); - serialPrintln(String(entry.size(), DEC)); - } - entry.close(); - } -} - -#endif // ifdef FEATURE_SD +} \ No newline at end of file diff --git a/src/src/Commands/InternalCommands.h b/src/src/Commands/InternalCommands.h new file mode 100644 index 000000000..56e3b98b3 --- /dev/null +++ b/src/src/Commands/InternalCommands.h @@ -0,0 +1,38 @@ +#ifndef COMMANDS_INTERNALCOMMANDS_H +#define COMMANDS_INTERNALCOMMANDS_H + +#include "../DataStructs/ESPEasy_EventStruct.h" +#include "../Globals/Plugins.h" + + +bool checkNrArguments(const char *cmd, const char *Line, int nrArguments); + +typedef String (*command_function)(struct EventStruct *, const char *); +bool do_command_case(const String& cmd_lc, const char *cmd, struct EventStruct *event, const char *line, String& status, const String& cmd_test, command_function pFunc, int nrArguments, bool& retval); + + +/*********************************************************************************************\ +* Registers command +\*********************************************************************************************/ +bool executeInternalCommand(const char *cmd, struct EventStruct *event, const char *line, String& status); + + +// Execute command which may be plugin or internal commands +bool ExecuteCommand_all(byte source, const char *Line); + +bool ExecuteCommand_all_config(byte source, const char *Line); + +bool ExecuteCommand_plugin_config(byte source, const char *Line); + +bool ExecuteCommand_all_config_eventOnly(byte source, const char *Line); + +bool ExecuteCommand_internal(byte source, const char *Line); + +bool ExecuteCommand_plugin(byte source, const char *Line); + +bool ExecuteCommand_plugin(taskIndex_t taskIndex, byte source, const char *Line); + +bool ExecuteCommand(taskIndex_t taskIndex, byte source, const char *Line, bool tryPlugin, bool tryInternal, bool tryRemoteConfig); + + +#endif // COMMANDS_INTERNALCOMMANDS_H \ No newline at end of file diff --git a/src/src/Commands/MQTT.cpp b/src/src/Commands/MQTT.cpp index 321fb15da..7231413b7 100644 --- a/src/src/Commands/MQTT.cpp +++ b/src/src/Commands/MQTT.cpp @@ -1,11 +1,10 @@ -#include "../../define_plugin_sets.h" +#include "../../ESPEasy_common.h" #include "../Globals/MQTT.h" #include "../DataStructs/SchedulerTimers.h" #ifdef USES_MQTT #include "../Commands/MQTT.h" -#include "../../ESPEasy_common.h" #include "../Commands/Common.h" #include "../Globals/Settings.h" #include "../Globals/CPlugins.h" diff --git a/src/src/Commands/SDCARD.cpp b/src/src/Commands/SDCARD.cpp index 47b36dbf1..36fdc456c 100644 --- a/src/src/Commands/SDCARD.cpp +++ b/src/src/Commands/SDCARD.cpp @@ -13,6 +13,34 @@ #include +void printDirectory(File dir, int numTabs) +{ + while (true) { + File entry = dir.openNextFile(); + + if (!entry) { + // no more files + break; + } + + for (uint8_t i = 0; i < numTabs; i++) { + serialPrint("\t"); + } + serialPrint(entry.name()); + + if (entry.isDirectory()) { + serialPrintln("/"); + printDirectory(entry, numTabs + 1); + } else { + // files have sizes, directories do not + serialPrint("\t\t"); + serialPrintln(String(entry.size(), DEC)); + } + entry.close(); + } +} + + String Command_SD_LS(struct EventStruct *event, const char* Line) { File root = SD.open("/"); diff --git a/src/src/Commands/SDCARD.h b/src/src/Commands/SDCARD.h index f31bdf9db..a5816e365 100644 --- a/src/src/Commands/SDCARD.h +++ b/src/src/Commands/SDCARD.h @@ -1,10 +1,14 @@ #ifndef COMMAND_SDCARD_H #define COMMAND_SDCARD_H -class String; - +#include "../../ESPEasy_common.h" #ifdef FEATURE_SD +#include + +class String; + +void printDirectory(File dir, int numTabs); String Command_SD_LS(struct EventStruct *event, const char* Line); String Command_SD_Remove(struct EventStruct *event, const char* Line); diff --git a/src/src/ControllerQueue/DelayQueueElements.h b/src/src/ControllerQueue/DelayQueueElements.h index f03838bb6..7034a5e2f 100644 --- a/src/src/ControllerQueue/DelayQueueElements.h +++ b/src/src/ControllerQueue/DelayQueueElements.h @@ -5,9 +5,6 @@ #include "../DataStructs/ControllerSettingsStruct.h" #include "../../ESPEasy_fdwdecl.h" -#include "../../define_plugin_sets.h" // For USES_xxx - - #include "../ControllerQueue/ControllerDelayHandlerStruct.h" #include "../ControllerQueue/SimpleQueueElement_string_only.h" #include "../ControllerQueue/queue_element_single_value_base.h" diff --git a/src/src/DataStructs/TimingStats.h b/src/src/DataStructs/TimingStats.h index 920734ac6..f32fde618 100644 --- a/src/src/DataStructs/TimingStats.h +++ b/src/src/DataStructs/TimingStats.h @@ -1,7 +1,7 @@ #ifndef DATASTRUCTS_TIMINGSTATS_H #define DATASTRUCTS_TIMINGSTATS_H -#include "../../define_plugin_sets.h" +#include "../../ESPEasy_common.h" #include "../../ESPEasy_plugindefs.h" #include "../../ESPEasy_fdwdecl.h" diff --git a/src/src/Globals/MQTT.h b/src/src/Globals/MQTT.h index 50c47e424..85b64f3eb 100644 --- a/src/src/Globals/MQTT.h +++ b/src/src/Globals/MQTT.h @@ -1,7 +1,7 @@ #ifndef GLOBALS_MQTT_H #define GLOBALS_MQTT_H -#include "../../define_plugin_sets.h" +#include "../../ESPEasy_common.h" #ifdef USES_MQTT diff --git a/src/src/Globals/RamTracker.h b/src/src/Globals/RamTracker.h index 5fac63841..9b0241f26 100644 --- a/src/src/Globals/RamTracker.h +++ b/src/src/Globals/RamTracker.h @@ -6,7 +6,7 @@ #define TRACEENTRIES 15 // entries per trace #include -#include "../../define_plugin_sets.h" +#include "../../ESPEasy_common.h" /********************************************************************************************\ RamTracker class diff --git a/src/src/Static/WebStaticData.h b/src/src/Static/WebStaticData.h index b2a1c52fe..e5993e3aa 100644 --- a/src/src/Static/WebStaticData.h +++ b/src/src/Static/WebStaticData.h @@ -1,7 +1,7 @@ #ifndef WEBSTATICDATA_h #define WEBSTATICDATA_h -#include "../../define_plugin_sets.h" +#include "../../ESPEasy_common.h" #define PGMT( pgm_ptr ) ( reinterpret_cast< const __FlashStringHelper * >( pgm_ptr ) ) From 4b756a5b35205a9ce7e89dfd4a447cfa1ca08a54 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sun, 7 Jun 2020 12:25:53 +0200 Subject: [PATCH 073/128] [Build] Limit build size (no diagnostics) for test_beta_ESP8266_4M1M --- platformio_esp82xx_envs.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platformio_esp82xx_envs.ini b/platformio_esp82xx_envs.ini index 342232065..075ca2d2c 100644 --- a/platformio_esp82xx_envs.ini +++ b/platformio_esp82xx_envs.ini @@ -342,7 +342,7 @@ build_flags = ${testing.build_flags} -DFEATURE_ADC_VCC=true -DFEATURE_MDNS -DFEATURE_SD - -DBUILD_NO_DEBUG + -DLIMIT_BUILD_SIZE lib_ignore = ESP32_ping, ESP32WebServer, ESP32HTTPUpdateServer, , IRremoteESP8266, HeatpumpIR @@ -352,6 +352,7 @@ platform = ${testing_beta.platform} platform_packages = ${testing_beta.platform_packages} build_flags = ${testing_beta.build_flags} ${esp8266_4M1M.build_flags} + -DLIMIT_BUILD_SIZE ; Test: 16M version -- LittleFS -------------- ; LittleFS is determined by using "LittleFS" in the pio env name From e633cf81b270c5f0439e17f076e848a61f1357b7 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 8 Jun 2020 10:45:59 +0200 Subject: [PATCH 074/128] [Notifications] Show notification tab when notifiers set via Custom.h --- src/define_plugin_sets.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/define_plugin_sets.h b/src/define_plugin_sets.h index 1dbde81aa..e59c88823 100644 --- a/src/define_plugin_sets.h +++ b/src/define_plugin_sets.h @@ -1026,6 +1026,13 @@ To create/register a plugin, you have to : #define USES_BLYNK #endif +// Specific notifier plugins may be enabled via Custom.h +// Make sure the NOTIFIER_SET_NONE is not defined then. +#if defined(USES_N001) || defined(USES_N002) + #ifdef NOTIFIER_SET_NONE + #undef NOTIFIER_SET_NONE + #endif +#endif #ifdef USES_MQTT From 4aeb76263485dd67bdf0ff683660f048ff415020 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 8 Jun 2020 11:19:06 +0200 Subject: [PATCH 075/128] [Notifiers] switch from NOTIFIER_SET_NONE to USES_NOTIFIER in code `NOTIFIER_SET_NONE` should only be used for not adding default selection of plugins. The positive define (USES_NOTIFIER) should be used in the code to determine whether the notifier page should be displayed. (and included in the code) --- src/ESPEasy-Globals.h | 2 +- src/ESPEasy.ino | 2 +- src/ESPEasy_checks.ino | 4 ++-- src/Misc.ino | 2 +- src/WebServer.ino | 8 ++++---- src/WebServer_NotificationPage.ino | 4 ++-- src/_N001_Email.ino | 2 +- src/__NPlugin.ino | 2 +- src/define_plugin_sets.h | 8 ++++---- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/ESPEasy-Globals.h b/src/ESPEasy-Globals.h index 7d85fc9ab..9639e3679 100644 --- a/src/ESPEasy-Globals.h +++ b/src/ESPEasy-Globals.h @@ -96,7 +96,7 @@ #include "src/DataStructs/NotificationSettingsStruct.h" #include "src/DataStructs/NotificationStruct.h" -#ifndef NOTIFIER_SET_NONE +#ifdef USES_NOTIFIER extern NotificationStruct Notification[NPLUGIN_MAX]; #endif diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index a35f2f5c4..50055e4f3 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -344,7 +344,7 @@ void setup() timermqtt_interval = 250; // Interval for checking MQTT timerAwakeFromDeepSleep = millis(); CPluginInit(); - #ifndef NOTIFIER_SET_NONE + #ifdef USES_NOTIFIER NPluginInit(); #endif PluginInit(); diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index 6e7bc38f0..db97b1873 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -39,7 +39,7 @@ void run_compiletime_checks() { const unsigned int SettingsStructSize = (252 + 82 * TASKS_MAX); check_size(); check_size(); - #ifndef NOTIFIER_SET_NONE + #ifdef USES_NOTIFIER check_size(); #endif check_size(); @@ -51,7 +51,7 @@ void run_compiletime_checks() { check_size(); // Is not stored check_size(); check_size(); - #ifndef NOTIFIER_SET_NONE + #ifdef USES_NOTIFIER check_size(); #endif check_size(); diff --git a/src/Misc.ino b/src/Misc.ino index 9f5c855bb..b033c4f5b 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -1193,7 +1193,7 @@ void ResetFactory() fname=FILE_SECURITY; InitFile(fname.c_str(), 4096); - #ifndef NOTIFIER_SET_NONE + #ifdef USES_NOTIFIER fname=FILE_NOTIFICATION; InitFile(fname.c_str(), 4096); #endif diff --git a/src/WebServer.ino b/src/WebServer.ino index 947e5e7cf..ecaa8d3a1 100644 --- a/src/WebServer.ino +++ b/src/WebServer.ino @@ -224,9 +224,9 @@ void WebServerInit() web_server.on(F("/log"), handle_log); web_server.on(F("/login"), handle_login); web_server.on(F("/logjson"), handle_log_JSON); // Also part of WEBSERVER_NEW_UI -#ifndef NOTIFIER_SET_NONE +#ifdef USES_NOTIFIER web_server.on(F("/notifications"), handle_notifications); -#endif // ifndef NOTIFIER_SET_NONE +#endif #ifdef WEBSERVER_PINSTATES web_server.on(F("/pinstates"), handle_pinstates); #endif @@ -544,12 +544,12 @@ void getWebPageTemplateVar(const String& varName) if ((i == MENU_INDEX_RULES) && !Settings.UseRules) { // hide rules menu item continue; } -#ifdef NOTIFIER_SET_NONE +#ifndef USES_NOTIFIER if (i == MENU_INDEX_NOTIFICATIONS) { // hide notifications menu item continue; } -#endif // ifdef NOTIFIER_SET_NONE +#endif addHtml(F(" -#include +#include #endif /********************************************************************************************\ diff --git a/src/WebServer.ino b/src/WebServer.ino index 83b2799eb..056b83a00 100644 --- a/src/WebServer.ino +++ b/src/WebServer.ino @@ -1117,7 +1117,7 @@ void getStorageTableSVG(SettingsType::Enum settingsType) { #ifdef ESP32 -#include +#include int getPartionCount(byte pType) { esp_partition_type_t partitionType = static_cast(pType); From b59bcee79b970650252058237c73680965eea188 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 8 Jun 2020 13:02:53 +0200 Subject: [PATCH 078/128] [ESP32] Update to platform-espressif32@1.12.2 --- platformio_core_defs.ini | 8 ++++++-- platformio_esp32_envs.ini | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/platformio_core_defs.ini b/platformio_core_defs.ini index 064f377da..134c356e4 100644 --- a/platformio_core_defs.ini +++ b/platformio_core_defs.ini @@ -126,8 +126,12 @@ platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git -[core_esp32_1_11_2] -platform = espressif32@1.11.2 + +; Updated ESP-IDF to the latest stable 4.0.1 +; See: https://github.com/platformio/platform-espressif32/releases +[core_esp32_1_12_2] +platform = espressif32@1.12.2 + [core_esp32_stage] platform = https://github.com/platformio/platform-espressif32.git#feature/stage diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 48f91c6b9..1a355a9d5 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -8,7 +8,7 @@ [esp32_common] extends = common -platform = ${core_esp32_1_11_2.platform} +platform = ${core_esp32_1_12_2.platform} lib_ignore = AS_BH1750, ESP8266WiFi, ESP8266Ping, ESP8266WebServer, ESP8266HTTPUpdateServer, ESP8266mDNS, IRremoteESP8266, ESPEasy_ESP8266Ping, ESP32_ping, HeatpumpIR lib_deps = https://github.com/TD-er/ESPEasySerial.git#v2.0.3, Adafruit ILI9341, Adafruit GFX Library board_build.f_flash = 80000000L From 87c01363858ee16786a5b27cdb5a155945ee2772 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 8 Jun 2020 13:03:49 +0200 Subject: [PATCH 079/128] [PIO] Add exception_decoder as serial monitor filter --- platformio_esp32_envs.ini | 2 ++ platformio_esp82xx_base.ini | 2 ++ 2 files changed, 4 insertions(+) diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 1a355a9d5..0e1dc2ffe 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -23,6 +23,8 @@ build_flags = ${mqtt_flags.build_flags} -DCONFIG_FREERTOS_ASSERT_DISABLE -DCONFIG_LWIP_ESP_GRATUITOUS_ARP -DCONFIG_LWIP_GARP_TMR_INTERVAL=30 +monitor_filters = esp32_exception_decoder + diff --git a/platformio_esp82xx_base.ini b/platformio_esp82xx_base.ini index 4cb149678..f4d244b1c 100644 --- a/platformio_esp82xx_base.ini +++ b/platformio_esp82xx_base.ini @@ -36,6 +36,8 @@ build_unflags = -DDEBUG_ESP_PORT lib_deps = https://github.com/TD-er/ESPEasySerial.git#v2.0.3, Adafruit ILI9341, Adafruit GFX Library lib_ignore = ${esp82xx_defaults.lib_ignore}, IRremoteESP8266, HeatpumpIR, SD(esp8266), SDFS board = esp12e +monitor_filters = esp8266_exception_decoder + From deb6128e2606d459feb3b1b6fac6162327cdea4b Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 8 Jun 2020 13:05:10 +0200 Subject: [PATCH 080/128] [WiFi] Reduce excessive logs WIFI : Disconnected: WiFi.status() Only report it when something has to be reported. --- src/ESPEasyWifi_ProcessEvent.ino | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ESPEasyWifi_ProcessEvent.ino b/src/ESPEasyWifi_ProcessEvent.ino index 3f8e563d5..288f50875 100644 --- a/src/ESPEasyWifi_ProcessEvent.ino +++ b/src/ESPEasyWifi_ProcessEvent.ino @@ -99,10 +99,18 @@ void handle_unprocessedWiFiEvents() #ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { - String wifilog = F("WIFI : Disconnected: WiFi.status() = "); - wifilog += String(WiFi.status()); + static unsigned long lastDisconnectMoment_log = 0; + static uint8_t lastWiFiStatus_log = 0; + uint8_t cur_wifi_status = WiFi.status(); + if (lastDisconnectMoment != lastDisconnectMoment_log || + lastWiFiStatus_log != cur_wifi_status) { + lastDisconnectMoment_log = lastDisconnectMoment; + lastWiFiStatus_log = cur_wifi_status; + String wifilog = F("WIFI : Disconnected: WiFi.status() = "); + wifilog += String(cur_wifi_status); - addLog(LOG_LEVEL_DEBUG, wifilog); + addLog(LOG_LEVEL_DEBUG, wifilog); + } } #endif // ifndef BUILD_NO_DEBUG From ff6a918b7cae26eaf1506d81ddbb7af98cc3d036 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 8 Jun 2020 13:41:12 +0200 Subject: [PATCH 081/128] [GPS] Add sanity check for reporting distance travelled event --- src/_P082_GPS.ino | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/_P082_GPS.ino b/src/_P082_GPS.ino index 7d35c7315..dbe2398e5 100644 --- a/src/_P082_GPS.ino +++ b/src/_P082_GPS.ino @@ -150,6 +150,9 @@ struct P082_data_struct : public PluginTaskData_base { if (!hasFix(maxAge_msec)) { return -1.0; } + if ((last_lat < 0.0001 && last_lat > -0.0001) || (last_lng < 0.0001 && last_lng > -0.0001)) { + return -1.0; + } return gps->distanceBetween(last_lat, last_lng, gps->location.lat(), gps->location.lng()); } @@ -496,18 +499,22 @@ boolean Plugin_082(byte function, struct EventStruct *event, String& string) { if (P082_DISTANCE > 0) { // Check travelled distance. - if (distance > static_cast(P082_DISTANCE)) { + if (distance > static_cast(P082_DISTANCE) || distance < 0.0) { if (P082_data->storeCurPos(P082_TIMEOUT)) { distance_passed = true; - String eventString = F("GPS#travelled="); - eventString += distance; - eventQueue.add(eventString); - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("GPS: Distance trigger : "); - log += distance; - log += F(" m"); - addLog(LOG_LEVEL_INFO, log); + // Add sanity check for distance travelled + if (distance > static_cast(P082_DISTANCE)) { + String eventString = F("GPS#travelled="); + eventString += distance; + eventQueue.add(eventString); + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("GPS: Distance trigger : "); + log += distance; + log += F(" m"); + addLog(LOG_LEVEL_INFO, log); + } } } } From 94abb74c25b3c199857cc08d2d42e6a30070ebb9 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 8 Jun 2020 14:10:32 +0200 Subject: [PATCH 082/128] Transform defines in EventValueSource into enum --- docs/source/Controller/C013.rst | 2 +- src/Controller.ino | 28 +++++++++------ src/ESPEasyRules.ino | 2 +- src/ESPEasy_fdwdecl.h | 6 ++-- src/Networking.ino | 2 +- src/Scheduler.ino | 4 +-- src/Serial.ino | 2 +- src/WebServer_ControlPage.ino | 4 +-- src/WebServer_CustomPage.ino | 2 +- src/WebServer_RootPage.ino | 4 +-- src/WebServer_ToolsPage.ino | 2 +- src/_C002.ino | 2 +- src/_C005.ino | 2 +- src/_C014.ino | 2 +- src/src/Commands/Common.cpp | 4 +-- src/src/Commands/InternalCommands.cpp | 16 ++++----- src/src/Commands/InternalCommands.h | 16 ++++----- src/src/Commands/Rules.cpp | 2 +- src/src/DataStructs/DeviceStruct.h | 2 +- src/src/DataStructs/ESPEasy_EventStruct.cpp | 7 +++- src/src/DataStructs/ESPEasy_EventStruct.h | 38 ++++++++++----------- src/src/DataStructs/EventValueSource.h | 26 +++++++++----- 22 files changed, 99 insertions(+), 76 deletions(-) diff --git a/docs/source/Controller/C013.rst b/docs/source/Controller/C013.rst index 5d1461f24..ed3a7bb23 100644 --- a/docs/source/Controller/C013.rst +++ b/docs/source/Controller/C013.rst @@ -175,7 +175,7 @@ The entire message processed as a command like this: .. code-block:: C++ packetBuffer[len] = 0; - ExecuteCommand_all(VALUE_SOURCE_SYSTEM, &packetBuffer[0]); + ExecuteCommand_all(EventValueSource::Enum::VALUE_SOURCE_SYSTEM, &packetBuffer[0]); As can be seen, no checks for size, and it is just expected to be a valid ESPeasy command. Also no check to see if the command is supported by the receiving end and no feedback to the sender. diff --git a/src/Controller.ino b/src/Controller.ino index 7f89c968d..3e854aab1 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -365,43 +365,49 @@ String getLWT_messageDisconnect(const ControllerSettingsStruct& ControllerSettin /*********************************************************************************************\ * Send status info to request source \*********************************************************************************************/ -void SendStatusOnlyIfNeeded(byte eventSource, bool param1, uint32_t key, const String& param2, int16_t param3) { +void SendStatusOnlyIfNeeded(EventValueSource::Enum eventSource, bool param1, uint32_t key, const String& param2, int16_t param3) { if (SourceNeedsStatusUpdate(eventSource)) { SendStatus(eventSource, getPinStateJSON(param1, key, param2, param3)); } } -bool SourceNeedsStatusUpdate(byte eventSource) +bool SourceNeedsStatusUpdate(EventValueSource::Enum eventSource) { switch (eventSource) { - case VALUE_SOURCE_HTTP: - case VALUE_SOURCE_SERIAL: - case VALUE_SOURCE_MQTT: - case VALUE_SOURCE_WEB_FRONTEND: + case EventValueSource::Enum::VALUE_SOURCE_HTTP: + case EventValueSource::Enum::VALUE_SOURCE_SERIAL: + case EventValueSource::Enum::VALUE_SOURCE_MQTT: + case EventValueSource::Enum::VALUE_SOURCE_WEB_FRONTEND: return true; + + default: + break; } return false; } -void SendStatus(byte source, const String& status) +void SendStatus(EventValueSource::Enum source, const String& status) { switch (source) { - case VALUE_SOURCE_HTTP: - case VALUE_SOURCE_WEB_FRONTEND: + case EventValueSource::Enum::VALUE_SOURCE_HTTP: + case EventValueSource::Enum::VALUE_SOURCE_WEB_FRONTEND: if (printToWeb) { printWebString += status; } break; #ifdef USES_MQTT - case VALUE_SOURCE_MQTT: + case EventValueSource::Enum::VALUE_SOURCE_MQTT: MQTTStatus(status); break; #endif //USES_MQTT - case VALUE_SOURCE_SERIAL: + case EventValueSource::Enum::VALUE_SOURCE_SERIAL: serialPrintln(status); break; + + default: + break; } } diff --git a/src/ESPEasyRules.ino b/src/ESPEasyRules.ino index a367a4599..cabd48e38 100644 --- a/src/ESPEasyRules.ino +++ b/src/ESPEasyRules.ino @@ -757,7 +757,7 @@ void processMatchedRule(String& action, String& event, addLog(LOG_LEVEL_INFO, log); } - ExecuteCommand_all(VALUE_SOURCE_RULES, action.c_str()); + ExecuteCommand_all(EventValueSource::Enum::VALUE_SOURCE_RULES, action.c_str()); delay(0); } } diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index 77b2111ac..72d7262b8 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -170,7 +170,7 @@ String LoadStringArray(SettingsType::Enum settingsType, int index, String string String SaveStringArray(SettingsType::Enum settingsType, int index, const String strings[], uint16_t nrStrings, uint16_t maxStringLength); -void SendStatus(byte source, const String& status); +void SendStatus(EventValueSource::Enum source, const String& status); String parseTemplate(String& tmpString); String parseTemplate(String& tmpString, bool useURLencode); @@ -189,7 +189,9 @@ String describeAllowedIPrange(); void clearAccessBlock(); String rulesProcessingFile(const String& fileName, String& event); int Calculate(const char *input, float* result); -bool SourceNeedsStatusUpdate(byte eventSource); +bool SourceNeedsStatusUpdate(EventValueSource::Enum eventSource); +void SendStatus(EventValueSource::Enum source, const String& status); +bool ExecuteCommand(taskIndex_t taskIndex, EventValueSource::Enum source, const char *Line, bool tryPlugin, bool tryInternal, bool tryRemoteConfig); void WifiScan(bool async, bool quick = false); void WifiScan(); diff --git a/src/Networking.ino b/src/Networking.ino index 013ea28f7..838bf0d05 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -140,7 +140,7 @@ void checkUDP() { packetBuffer[len] = 0; addLog(LOG_LEVEL_DEBUG, &packetBuffer[0]); - ExecuteCommand_all(VALUE_SOURCE_SYSTEM, &packetBuffer[0]); + ExecuteCommand_all(EventValueSource::Enum::VALUE_SOURCE_SYSTEM, &packetBuffer[0]); } else { diff --git a/src/Scheduler.ino b/src/Scheduler.ino index 34df9c05e..4930a2b1c 100644 --- a/src/Scheduler.ino +++ b/src/Scheduler.ino @@ -427,7 +427,7 @@ void process_plugin_task_timer(unsigned long id) { TempEvent.Par5 = timer_data.Par5; // TD-er: Not sure if we have to keep original source for notifications. - TempEvent.Source = VALUE_SOURCE_SYSTEM; + TempEvent.Source = EventValueSource::Enum::VALUE_SOURCE_SYSTEM; const deviceIndex_t deviceIndex = getDeviceIndex_from_TaskIndex(timer_data.TaskIndex); /* @@ -502,7 +502,7 @@ void process_plugin_timer(unsigned long id) { TempEvent.Par5 = timer_data.Par5; // TD-er: Not sure if we have to keep original source for notifications. - TempEvent.Source = VALUE_SOURCE_SYSTEM; + TempEvent.Source = EventValueSource::Enum::VALUE_SOURCE_SYSTEM; // const deviceIndex_t deviceIndex = getDeviceIndex_from_TaskIndex(timer_data.TaskIndex); /* diff --git a/src/Serial.ino b/src/Serial.ino index 2c74b9b90..ab9219eef 100644 --- a/src/Serial.ino +++ b/src/Serial.ino @@ -37,7 +37,7 @@ void serial() InputBuffer_Serial[SerialInByteCounter] = 0; // serial data completed Serial.write('>'); serialPrintln(InputBuffer_Serial); - ExecuteCommand_all(VALUE_SOURCE_SERIAL, InputBuffer_Serial); + ExecuteCommand_all(EventValueSource::Enum::VALUE_SOURCE_SERIAL, InputBuffer_Serial); SerialInByteCounter = 0; InputBuffer_Serial[0] = 0; // serial data processed, clear buffer } diff --git a/src/WebServer_ControlPage.ino b/src/WebServer_ControlPage.ino index 9f0034335..1049a72e2 100644 --- a/src/WebServer_ControlPage.ino +++ b/src/WebServer_ControlPage.ino @@ -37,7 +37,7 @@ void handle_control() { command.equalsIgnoreCase(F("logPortStatus")) || command.equalsIgnoreCase(F("jsonportstatus")) || command.equalsIgnoreCase(F("rules"))) { - ExecuteCommand_internal(VALUE_SOURCE_HTTP, webrequest.c_str()); + ExecuteCommand_internal(EventValueSource::Enum::VALUE_SOURCE_HTTP, webrequest.c_str()); handledCmd = true; } @@ -49,7 +49,7 @@ void handle_control() { } printToWeb = true; printWebString = ""; - bool unknownCmd = !ExecuteCommand_plugin_config(VALUE_SOURCE_HTTP, webrequest.c_str()); + bool unknownCmd = !ExecuteCommand_plugin_config(EventValueSource::Enum::VALUE_SOURCE_HTTP, webrequest.c_str()); if (printToWebJSON) { // it is setted in PLUGIN_WRITE (SendStatus) TXBuffer.startJsonStream(); diff --git a/src/WebServer_CustomPage.ino b/src/WebServer_CustomPage.ino index d35e42f04..ac7a1c02b 100644 --- a/src/WebServer_CustomPage.ino +++ b/src/WebServer_CustomPage.ino @@ -112,7 +112,7 @@ boolean handle_custom(String path) { String webrequest = web_server.arg(F("cmd")); if (webrequest.length() > 0) { - ExecuteCommand_all_config_eventOnly(VALUE_SOURCE_HTTP, webrequest.c_str()); + ExecuteCommand_all_config_eventOnly(EventValueSource::Enum::VALUE_SOURCE_HTTP, webrequest.c_str()); // handle some update processes first, before returning page update... String dummy; diff --git a/src/WebServer_RootPage.ino b/src/WebServer_RootPage.ino index fcc6dea0c..1ddc50d5c 100644 --- a/src/WebServer_RootPage.ino +++ b/src/WebServer_RootPage.ino @@ -43,7 +43,7 @@ void handle_root() { printWebString = ""; if (sCommand.length() > 0) { - ExecuteCommand_internal(VALUE_SOURCE_HTTP, sCommand.c_str()); + ExecuteCommand_internal(EventValueSource::Enum::VALUE_SOURCE_HTTP, sCommand.c_str()); } // IPAddress ip = WiFi.localIP(); @@ -237,7 +237,7 @@ void handle_root() { addHtml(F( "OK. Please wait > 1 min and connect to Acces point.

PW=configesp
URL=
192.168.4.1")); TXBuffer.endStream(); - ExecuteCommand_internal(VALUE_SOURCE_HTTP, sCommand.c_str()); + ExecuteCommand_internal(EventValueSource::Enum::VALUE_SOURCE_HTTP, sCommand.c_str()); } addHtml(F("OK")); diff --git a/src/WebServer_ToolsPage.ino b/src/WebServer_ToolsPage.ino index d6b374d5d..c24b2ba56 100644 --- a/src/WebServer_ToolsPage.ino +++ b/src/WebServer_ToolsPage.ino @@ -33,7 +33,7 @@ void handle_tools() { if (webrequest.length() > 0) { - ExecuteCommand_all(VALUE_SOURCE_WEB_FRONTEND, webrequest.c_str()); + ExecuteCommand_all(EventValueSource::Enum::VALUE_SOURCE_WEB_FRONTEND, webrequest.c_str()); } if (printWebString.length() > 0) diff --git a/src/_C002.ino b/src/_C002.ino index 4dac505ef..f04072819 100644 --- a/src/_C002.ino +++ b/src/_C002.ino @@ -150,7 +150,7 @@ bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String& } if (action.length() > 0) { - ExecuteCommand_plugin(x, VALUE_SOURCE_MQTT, action.c_str()); + ExecuteCommand_plugin(x, EventValueSource::Enum::VALUE_SOURCE_MQTT, action.c_str()); // trigger rulesprocessing if (Settings.UseRules) { diff --git a/src/_C005.ino b/src/_C005.ino index b5906b2bd..3824689b1 100644 --- a/src/_C005.ino +++ b/src/_C005.ino @@ -64,7 +64,7 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String& if (lastPartTopic == F("cmd")) { cmd = event->String2; parseCommandString(&TempEvent, cmd); - TempEvent.Source = VALUE_SOURCE_MQTT; + TempEvent.Source = EventValueSource::Enum::VALUE_SOURCE_MQTT; validTopic = true; } else { if (lastindex > 0) { diff --git a/src/_C014.ino b/src/_C014.ino index 966d6d65e..24a946909 100644 --- a/src/_C014.ino +++ b/src/_C014.ino @@ -533,7 +533,7 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& taskIndex_t taskIndex = INVALID_TASK_INDEX; struct EventStruct TempEvent; TempEvent.TaskIndex = event->TaskIndex; - TempEvent.Source = VALUE_SOURCE_MQTT; // to trigger the correct acknowledgment + TempEvent.Source = EventValueSource::Enum::VALUE_SOURCE_MQTT; // to trigger the correct acknowledgment int lastindex = event->String1.lastIndexOf('/'); errorCounter = 0; if (event->String1.substring(lastindex + 1) == F("set")) diff --git a/src/src/Commands/Common.cpp b/src/src/Commands/Common.cpp index 0df55f0ab..af86da75a 100644 --- a/src/src/Commands/Common.cpp +++ b/src/src/Commands/Common.cpp @@ -33,7 +33,7 @@ String return_result(struct EventStruct *event, const String& result) { serialPrintln(result); - if (event->Source == VALUE_SOURCE_SERIAL) { + if (event->Source == EventValueSource::Enum::VALUE_SOURCE_SERIAL) { return return_command_success(); } return result; @@ -41,7 +41,7 @@ String return_result(struct EventStruct *event, const String& result) String return_see_serial(struct EventStruct *event) { - if (event->Source == VALUE_SOURCE_SERIAL) { + if (event->Source == EventValueSource::Enum::VALUE_SOURCE_SERIAL) { return return_command_success(); } return F("Output sent to serial"); diff --git a/src/src/Commands/InternalCommands.cpp b/src/src/Commands/InternalCommands.cpp index b2a21b3ba..4fadb2e64 100644 --- a/src/src/Commands/InternalCommands.cpp +++ b/src/src/Commands/InternalCommands.cpp @@ -308,22 +308,22 @@ bool executeInternalCommand(const char *cmd, struct EventStruct *event, const ch // Execute command which may be plugin or internal commands -bool ExecuteCommand_all(byte source, const char *Line) +bool ExecuteCommand_all(EventValueSource::Enum source, const char *Line) { return ExecuteCommand(INVALID_TASK_INDEX, source, Line, true, true, false); } -bool ExecuteCommand_all_config(byte source, const char *Line) +bool ExecuteCommand_all_config(EventValueSource::Enum source, const char *Line) { return ExecuteCommand(INVALID_TASK_INDEX, source, Line, true, true, true); } -bool ExecuteCommand_plugin_config(byte source, const char *Line) +bool ExecuteCommand_plugin_config(EventValueSource::Enum source, const char *Line) { return ExecuteCommand(INVALID_TASK_INDEX, source, Line, true, false, true); } -bool ExecuteCommand_all_config_eventOnly(byte source, const char *Line) +bool ExecuteCommand_all_config_eventOnly(EventValueSource::Enum source, const char *Line) { bool tryInternal = false; { @@ -335,22 +335,22 @@ bool ExecuteCommand_all_config_eventOnly(byte source, const char *Line) return ExecuteCommand(INVALID_TASK_INDEX, source, Line, true, tryInternal, true); } -bool ExecuteCommand_internal(byte source, const char *Line) +bool ExecuteCommand_internal(EventValueSource::Enum source, const char *Line) { return ExecuteCommand(INVALID_TASK_INDEX, source, Line, false, true, false); } -bool ExecuteCommand_plugin(byte source, const char *Line) +bool ExecuteCommand_plugin(EventValueSource::Enum source, const char *Line) { return ExecuteCommand(INVALID_TASK_INDEX, source, Line, true, false, false); } -bool ExecuteCommand_plugin(taskIndex_t taskIndex, byte source, const char *Line) +bool ExecuteCommand_plugin(taskIndex_t taskIndex, EventValueSource::Enum source, const char *Line) { return ExecuteCommand(taskIndex, source, Line, true, false, false); } -bool ExecuteCommand(taskIndex_t taskIndex, byte source, const char *Line, bool tryPlugin, bool tryInternal, bool tryRemoteConfig) +bool ExecuteCommand(taskIndex_t taskIndex, EventValueSource::Enum source, const char *Line, bool tryPlugin, bool tryInternal, bool tryRemoteConfig) { checkRAM(F("ExecuteCommand")); String cmd; diff --git a/src/src/Commands/InternalCommands.h b/src/src/Commands/InternalCommands.h index 56e3b98b3..12f0c5fab 100644 --- a/src/src/Commands/InternalCommands.h +++ b/src/src/Commands/InternalCommands.h @@ -18,21 +18,21 @@ bool executeInternalCommand(const char *cmd, struct EventStruct *event, const ch // Execute command which may be plugin or internal commands -bool ExecuteCommand_all(byte source, const char *Line); +bool ExecuteCommand_all(EventValueSource::Enum source, const char *Line); -bool ExecuteCommand_all_config(byte source, const char *Line); +bool ExecuteCommand_all_config(EventValueSource::Enum source, const char *Line); -bool ExecuteCommand_plugin_config(byte source, const char *Line); +bool ExecuteCommand_plugin_config(EventValueSource::Enum source, const char *Line); -bool ExecuteCommand_all_config_eventOnly(byte source, const char *Line); +bool ExecuteCommand_all_config_eventOnly(EventValueSource::Enum source, const char *Line); -bool ExecuteCommand_internal(byte source, const char *Line); +bool ExecuteCommand_internal(EventValueSource::Enum source, const char *Line); -bool ExecuteCommand_plugin(byte source, const char *Line); +bool ExecuteCommand_plugin(EventValueSource::Enum source, const char *Line); -bool ExecuteCommand_plugin(taskIndex_t taskIndex, byte source, const char *Line); +bool ExecuteCommand_plugin(taskIndex_t taskIndex, EventValueSource::Enum source, const char *Line); -bool ExecuteCommand(taskIndex_t taskIndex, byte source, const char *Line, bool tryPlugin, bool tryInternal, bool tryRemoteConfig); +bool ExecuteCommand(taskIndex_t taskIndex, EventValueSource::Enum source, const char *Line, bool tryPlugin, bool tryInternal, bool tryRemoteConfig); #endif // COMMANDS_INTERNALCOMMANDS_H \ No newline at end of file diff --git a/src/src/Commands/Rules.cpp b/src/src/Commands/Rules.cpp index f4d215f42..d9b93f359 100644 --- a/src/src/Commands/Rules.cpp +++ b/src/src/Commands/Rules.cpp @@ -47,7 +47,7 @@ String Command_Rules_Events(struct EventStruct *event, const char *Line) if (Settings.UseRules) { const bool executeImmediately = SourceNeedsStatusUpdate(event->Source) || - event->Source == VALUE_SOURCE_RULES; + event->Source == EventValueSource::Enum::VALUE_SOURCE_RULES; if (executeImmediately) { rulesProcessing(eventName); // TD-er: Process right now } else { diff --git a/src/src/DataStructs/DeviceStruct.h b/src/src/DataStructs/DeviceStruct.h index 9747431dc..be977ef74 100644 --- a/src/src/DataStructs/DeviceStruct.h +++ b/src/src/DataStructs/DeviceStruct.h @@ -44,7 +44,7 @@ struct DeviceStruct byte Number; // Plugin ID number. (PLUGIN_ID_xxx) byte Type; // How the device is connected. e.g. DEVICE_TYPE_SINGLE => connected through 1 datapin - byte VType; // Type of value the plugin will return, used only for Domoticz + byte VType; // Type of value the plugin will return. e.g. SENSOR_TYPE_STRING byte Ports; // Port to use when device has multiple I/O pins (N.B. not used much) byte ValueCount; // The number of output values of a plugin. The value should match the number of keys PLUGIN_VALUENAME1_xxx bool PullUpOption : 1; // Allow to set internal pull-up resistors. diff --git a/src/src/DataStructs/ESPEasy_EventStruct.cpp b/src/src/DataStructs/ESPEasy_EventStruct.cpp index 58c395626..15d0849af 100644 --- a/src/src/DataStructs/ESPEasy_EventStruct.cpp +++ b/src/src/DataStructs/ESPEasy_EventStruct.cpp @@ -1,10 +1,15 @@ #include "../DataStructs/ESPEasy_EventStruct.h" #include "../DataStructs/ESPEasyLimits.h" +#include "../DataStructs/EventValueSource.h" +#include "../Globals/Plugins.h" +#include "../Globals/CPlugins.h" +#include "../Globals/NPlugins.h" EventStruct::EventStruct() : Data(nullptr), idx(0), Par1(0), Par2(0), Par3(0), Par4(0), Par5(0), - Source(0), TaskIndex(INVALID_TASK_INDEX), ControllerIndex(INVALID_CONTROLLER_INDEX), + Source(EventValueSource::Enum::VALUE_SOURCE_NOT_SET), + TaskIndex(INVALID_TASK_INDEX), ControllerIndex(INVALID_CONTROLLER_INDEX), NotificationIndex(INVALID_NOTIFIER_INDEX), BaseVarIndex(0), sensorType(0), OriginTaskIndex(0) {} diff --git a/src/src/DataStructs/ESPEasy_EventStruct.h b/src/src/DataStructs/ESPEasy_EventStruct.h index 27d3bfef7..54607f4fc 100644 --- a/src/src/DataStructs/ESPEasy_EventStruct.h +++ b/src/src/DataStructs/ESPEasy_EventStruct.h @@ -16,25 +16,25 @@ struct EventStruct EventStruct(const struct EventStruct& event); EventStruct& operator=(const struct EventStruct& other); - String String1; - String String2; - String String3; - String String4; - String String5; - byte *Data; - int idx; - int Par1; - int Par2; - int Par3; - int Par4; - int Par5; - byte Source; // The origin of the values in the event. See EventValueSource.h - taskIndex_t TaskIndex; // index position in TaskSettings array, 0-11 - controllerIndex_t ControllerIndex; // index position in Settings.Controller, 0-3 - notifierIndex_t NotificationIndex; // index position in Settings.Notification, 0-3 - byte BaseVarIndex; - byte sensorType; - byte OriginTaskIndex; + String String1; + String String2; + String String3; + String String4; + String String5; + byte *Data; + int idx; + int Par1; + int Par2; + int Par3; + int Par4; + int Par5; + EventValueSource::Enum Source; // The origin of the values in the event. See EventValueSource.h + taskIndex_t TaskIndex; // index position in TaskSettings array, 0-11 + controllerIndex_t ControllerIndex; // index position in Settings.Controller, 0-3 + notifierIndex_t NotificationIndex; // index position in Settings.Notification, 0-3 + byte BaseVarIndex; + byte sensorType; + byte OriginTaskIndex; }; #endif // ESPEASY_EVENTSTRUCT_H diff --git a/src/src/DataStructs/EventValueSource.h b/src/src/DataStructs/EventValueSource.h index c5187a033..181cb7856 100644 --- a/src/src/DataStructs/EventValueSource.h +++ b/src/src/DataStructs/EventValueSource.h @@ -1,12 +1,22 @@ #ifndef DATASTRUCTS_EVENT_VALUE_SOURCE_H #define DATASTRUCTS_EVENT_VALUE_SOURCE_H -#define VALUE_SOURCE_SYSTEM 1 -#define VALUE_SOURCE_SERIAL 2 -#define VALUE_SOURCE_HTTP 3 -#define VALUE_SOURCE_MQTT 4 -#define VALUE_SOURCE_UDP 5 -#define VALUE_SOURCE_WEB_FRONTEND 6 -#define VALUE_SOURCE_RULES 7 +class EventValueSource { +public: -#endif // DATASTRUCTS_EVENT_VALUE_SOURCE_H \ No newline at end of file + // Keep the values as they can be used by other/older builds to communicate with ESPEasy + enum class Enum : byte { + VALUE_SOURCE_NOT_SET = 0, + VALUE_SOURCE_SYSTEM = 1, + VALUE_SOURCE_SERIAL = 2, + VALUE_SOURCE_HTTP = 3, + VALUE_SOURCE_MQTT = 4, + VALUE_SOURCE_UDP = 5, + VALUE_SOURCE_WEB_FRONTEND = 6, + VALUE_SOURCE_RULES = 7, + + VALUE_SOURCE_NR_VALUES + }; +}; + +#endif // DATASTRUCTS_EVENT_VALUE_SOURCE_H From 92f01e6a2650f79ab4e050df01efac226de38280 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 8 Jun 2020 20:49:13 +0200 Subject: [PATCH 083/128] [Build] Disable diagnostics in test/dev build to reduce build size --- src/define_plugin_sets.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/define_plugin_sets.h b/src/define_plugin_sets.h index 1c34e0122..571ec5428 100644 --- a/src/define_plugin_sets.h +++ b/src/define_plugin_sets.h @@ -802,6 +802,11 @@ To create/register a plugin, you have to : // TESTING ##################################### #ifdef PLUGIN_SET_TESTING + #ifndef LIMIT_BUILD_SIZE + #define LIMIT_BUILD_SIZE + #endif + + #define USES_P045 // MPU6050 #define USES_P047 // I2C_soil_misture #define USES_P048 // Motoshield_v2 From 7fa3ffa10594a5144787fbd6acd01973ddd95cdb Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 8 Jun 2020 22:51:44 +0200 Subject: [PATCH 084/128] automatically updated release notes for mega-20200608 --- dist/Release_notes.txt | 107 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/dist/Release_notes.txt b/dist/Release_notes.txt index 9e86b3ae5..f6bf54739 100644 --- a/dist/Release_notes.txt +++ b/dist/Release_notes.txt @@ -1,3 +1,110 @@ +------------------------------------------------- +Changes in release mega-20200608 (since mega-20200515) +------------------------------------------------- + +Release date: ma 8 jun 2020 22:51:44 CEST + +Bartlomiej Zimon (11): + rfid events update for P008/P017/P040, plus send event after log line. + PN532: remove hardcoded scl/sda pins reading and use hardware configuration instead + PN532: update comment + Webserver - add port number setting into Advanced options, resolves #3031 and #573 + P2P: send and receive webserver port number, add port to link on rootpage #2252 + NodeStruct: init webgui_portnumber value + p2p infopacket - use low/highByte + Webserver - increase BUILD number and set default value for port number + Webserver port setting - add reboot note + MDNS - send service with actual webserver port + P2P: respect also build number in condition + +Florin (7): + Adding buzzer capabilities back to ESP32. + Allow to set the Latitude and longitude when resetting the firmware from custom.h or using the build_flags + clean up code and variables when NOTIFIER_SET_NONE is defined. + ESP32: Allow to select one of the two available SPI ports + clean up code and variables when NOTIFIER_SET_NONE is defined. + Fix for allowing negative timeOffset from UTC in constructor + rename the tone to toneESP32 to be more specific + +Gijs Noorlander (27): + [MQTT] Process publish LWT connect message asynchronous + [MQTT] Stop trying to send LWT connected when client disconnects + [LittleFS] Make switching between SPIFFS and LittleFS easy to do + [ESPEasySerial] Update to v2.0.3 adding I2C UART to ESP32 + fix bug ESP32 + [Build] Fix merge error + [PIO] Move to esp8266/Arduino core 2.7.1 + [PIO] Hide deprecated warning for SPIFFS + [Vagrant] Fix vagrant build installing all required Python packages + [Notifications] Make sure all custom defines are set at compile time + [Travis] Fix deploy multiple ZIP files + split ESP82xx and ESP32 files + [Build] Fix Python 3.8 build when no .git dir or pygit2 not installed + [GPS] Add GPS#travelled=... event (#3099) + [Build] Add ina219 and mpu6050 to custom build (#3100) + [Build] Disable diagnostics code for test_ESP8266_4M1M_VCC to fit size + [Build] Disabling timing stats results in build errors for ESP32 + [Commands] Split commands.ino to .h/.cpp to overcome build/link issues + [Build] Limit build size (no diagnostics) for test_beta_ESP8266_4M1M + [Notifications] Show notification tab when notifiers set via Custom.h + [Notifiers] switch from NOTIFIER_SET_NONE to USES_NOTIFIER in code + [ESP32] Fix Disabling ARDUINO_OTA fails the build (#3083) + [ESP32 build] Fix capitalization error in #include + [ESP32] Update to platform-espressif32@1.12.2 + [PIO] Add exception_decoder as serial monitor filter + [WiFi] Reduce excessive logs WIFI : Disconnected: WiFi.status() + [GPS] Add sanity check for reporting distance travelled event + Transform defines in EventValueSource into enum + [Build] Disable diagnostics in test/dev build to reduce build size + +Michał Obrembski (2): + Added /raw endpoint which gives an easy access to raw value of sensor + Changed format of RAW to CSV, added ability to filter values + +Michał Obrembski (3): + Fixed invalid check of valnr validity in CSV output mode + Renamed RAW to CSV, added printing of header + Removed usage of String.clear() + +Saverio Cisternino (1): + Fix parse_uint ref https://github.com/staticlibs/ccronexpr/pull/30 + +TD-er (1): + [Bug] ControllerIndex not set when calling CPLUGIN calls + +denisfrench (1): + [MQTT] Connect message honors LWT settings (#3006) + +jimmys01 (1): + [IR] Update Library + +sakinit (18): + Show for ESP32 also the first rule on the webserver rules page + Fix ESP32 undefined pin initialisation + Don't repeat the last rule on the next webserver page + Revert P1WifiGateway to 30cbb4c to bugfix this more generic code + Cherry-pick relevant P1WifiGateway updates since 30cbb4c + Fix the datagram check to be able to send valid messages again + Fix the serial reading algorithm + Fix P1WifiGateway webserver start + Remove temporary comments + Use ESPeasySerial + Restart P1WifiGateway if webserver start failed + Optimize serial reading algorithm and move client from plugin into task + Fix ESP32 reboot cause at boot/setup + Optimize serial in duration + Update due to review comments + Add sanity checks based on review comments + Discard data received from WiFi client due to review comment + Update based on review comments + +tonhuisman (6): + [Rules page] Add RTD help button and fix page layout issue ('Old Engine') + [Transformation] Add R/r transformations (LEFT/RIGHT and L/R) + [Transformations] Adjusted R/r to L/l and added c + [Justifications] Add 'C' (Capitalize, OPEN -> Open) option + [Justifications] Added u/l for upper/lowercasing the value, removed dash-check from C justificaion + [Docs] Describe 'elseif' with some examples + + ------------------------------------------------- Changes in release mega-20200515 (since mega-20200426) ------------------------------------------------- From 58413c219bb519801fb6702e1ef79359264f16af Mon Sep 17 00:00:00 2001 From: bccrew <8138958+bccrew@users.noreply.github.com> Date: Tue, 9 Jun 2020 20:41:21 +0200 Subject: [PATCH 085/128] Change FormSubHeader to clarify difference between IP settings of LAN or WiFi --- src/WebServer_ConfigPage.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/WebServer_ConfigPage.ino b/src/WebServer_ConfigPage.ino index 471ab92ff..aea5bfe9f 100644 --- a/src/WebServer_ConfigPage.ino +++ b/src/WebServer_ConfigPage.ino @@ -149,12 +149,12 @@ void handle_config() { addFormIPBox(F("Access IP upper range"), F("iprangehigh"), iphigh); } - addFormSubHeader(F("IP Settings")); + addFormSubHeader(F("WiFi IP Settings")); - addFormIPBox(F("ESP IP"), F("espip"), Settings.IP); - addFormIPBox(F("ESP GW"), F("espgateway"), Settings.Gateway); - addFormIPBox(F("ESP Subnetmask"), F("espsubnet"), Settings.Subnet); - addFormIPBox(F("ESP DNS"), F("espdns"), Settings.DNS); + addFormIPBox(F("ESP WiFi IP"), F("espip"), Settings.IP); + addFormIPBox(F("ESP WiFi GW"), F("espgateway"), Settings.Gateway); + addFormIPBox(F("ESP WiFi Subnetmask"), F("espsubnet"), Settings.Subnet); + addFormIPBox(F("ESP WiFi DNS"), F("espdns"), Settings.DNS); addFormNote(F("Leave empty for DHCP")); #ifdef HAS_ETHERNET From 5b93121a207379243be60d248271ab291595d97b Mon Sep 17 00:00:00 2001 From: tonhuisman Date: Wed, 17 Jun 2020 20:58:10 +0200 Subject: [PATCH 086/128] [Tasks] Call PLUGIN_INIT/PLUGIN_EXIT using TaskEnable/TaskDisable from rules --- src/src/Commands/Tasks.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/src/Commands/Tasks.cpp b/src/src/Commands/Tasks.cpp index 51e923eb8..d28d7ae07 100644 --- a/src/src/Commands/Tasks.cpp +++ b/src/src/Commands/Tasks.cpp @@ -48,8 +48,9 @@ String Command_Task_Disable(struct EventStruct *event, const char *Line) { taskIndex_t taskIndex; unsigned int varNr; + String dummy; - if (validTaskVars(event, taskIndex, varNr) && setTaskEnableStatus(taskIndex, false)) { + if (validTaskVars(event, taskIndex, varNr) && PluginCall(PLUGIN_EXIT, event, dummy) && setTaskEnableStatus(taskIndex, false)) { return return_command_success(); } return return_command_failed(); @@ -59,8 +60,9 @@ String Command_Task_Enable(struct EventStruct *event, const char *Line) { taskIndex_t taskIndex; unsigned int varNr; + String dummy; - if (validTaskVars(event, taskIndex, varNr) && setTaskEnableStatus(taskIndex, true)) { + if (validTaskVars(event, taskIndex, varNr) && setTaskEnableStatus(taskIndex, true) && PluginCall(PLUGIN_INIT, event, dummy)) { return return_command_success(); } return return_command_failed(); From 9a17df2aebe4793f615f87c5239e2ada9013a1aa Mon Sep 17 00:00:00 2001 From: tonhuisman Date: Sun, 21 Jun 2020 18:42:06 +0200 Subject: [PATCH 087/128] [Transformation] Add P/p (Password display) --- docs/source/Rules/Rules.rst | 8 ++++++++ src/Misc.ino | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/docs/source/Rules/Rules.rst b/docs/source/Rules/Rules.rst index 50a74ee43..71a40dfc8 100644 --- a/docs/source/Rules/Rules.rst +++ b/docs/source/Rules/Rules.rst @@ -388,6 +388,7 @@ Transformation * A "binary" transformation can be "inverted" by adding a leading ``!``. * A "binary" value is considered 0 when its string value is "0" or empty, otherwise it is an 1. (float values are rounded) * A "binary" value can also be used to detect presence of a string, as it is 0 on an empty string or 1 otherwise. +* If the transformation contains ``R``, under certain circumstances, the value will be right-aligned. Binary transformations: @@ -417,9 +418,16 @@ Floating point transformations: * ``F``: Floor (round down) * ``E``: cEiling (round up) +Other transformations: + +* ``p``: Password display, replacing all value characters by asterisks ``*``. If the value is "0", nothing will be displayed. +* ``Pc``: Password display with custom character ``c``. For example P- will display value "123" as "---". If the value is "0", nothing will be displayed. + Justification ^^^^^^^^^^^^^ +To apply a justification, a transformation must also be used. If no transformation is needed, use the ``V`` (value) transformation. + * ``Pn``: Prefix Fill with n spaces. * ``Sn``: Suffix Fill with n spaces. * ``Ln``: Left part of the string, n characters. diff --git a/src/Misc.ino b/src/Misc.ino index b033c4f5b..cc26bab5d 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -1980,6 +1980,33 @@ void transformValue( { case 'V': //value = value without transformations break; + case 'P': // Password hide using a custom password character: Pc + if (tempValueFormatLength > 1) + { + if (value == F("0")) { + value = ""; + } else { + const int valueLength = value.length(); + for (int i = 0; i < valueLength; i++) { + value[i] = tempValueFormat[1]; + } + } + } else { + value = F("ERR"); + } + break; + case 'p': // Password hide using asterisks + { + if (value == F("0")) { + value = ""; + } else { + const int valueLength = value.length(); + for (int i = 0; i < valueLength; i++) { + value[i] = '*'; + } + } + } + break; case 'O': value = logicVal == 0 ? F("OFF") : F(" ON"); //(equivalent to XOR operator) break; From 1b55ddc84a6a5a598c4b4bc17860542b1e262b48 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 22 Jun 2020 12:02:37 +0200 Subject: [PATCH 088/128] [ESP32] Only define FEATURE_ARDUINO_OTA in build config, not in .h files --- platformio_esp32_envs.ini | 8 ++++++-- tools/pio/pre_custom_esp32.py | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 0e1dc2ffe..f566fa1f6 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -40,7 +40,9 @@ extra_scripts = ${esp32_common.extra_scripts} [env:test_ESP32_4M316k] extends = esp32_common platform = ${esp32_common.platform} -build_flags = ${esp32_common.build_flags} -DPLUGIN_SET_TEST_ESP32 +build_flags = ${esp32_common.build_flags} + -DFEATURE_ARDUINO_OTA + -DPLUGIN_SET_TEST_ESP32 board = esp32dev extra_scripts = ${esp32_common.extra_scripts} @@ -48,7 +50,9 @@ extra_scripts = ${esp32_common.extra_scripts} [env:test_ESP32-wrover-kit_4M316k] extends = esp32_common platform = ${esp32_common.platform} -build_flags = ${esp32_common.build_flags} -DPLUGIN_SET_TEST_ESP32 +build_flags = ${esp32_common.build_flags} + -DFEATURE_ARDUINO_OTA + -DPLUGIN_SET_TEST_ESP32 board = esp-wrover-kit upload_protocol = ftdi debug_tool = ftdi diff --git a/tools/pio/pre_custom_esp32.py b/tools/pio/pre_custom_esp32.py index 72c301729..7f6b4ed02 100644 --- a/tools/pio/pre_custom_esp32.py +++ b/tools/pio/pre_custom_esp32.py @@ -38,7 +38,8 @@ else: "USES_P087", # Serial Proxy "USES_P097", # Touch (ESP32) - "USE_SETTINGS_ARCHIVE" + "USE_SETTINGS_ARCHIVE", + "FEATURE_ARDUINO_OTA" ]) print(env['CPPDEFINES']) From 70ffd6bb4a82620d3b79c809bbdf2674a42a71fb Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 22 Jun 2020 12:09:54 +0200 Subject: [PATCH 089/128] [Build] Disable test_beta_ESP8266_4M1M for now as it is too big --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 393fdeefd..c33d680d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -73,7 +73,7 @@ script: - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_ESP8266_4M1M_VCC #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_ESP8266_4M1M_VCC_MDNS_SD #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_beta_ESP8266_16M_LittleFS - - PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_beta_ESP8266_4M1M + #- PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e test_beta_ESP8266_4M1M before_deploy: - ./before_deploy From 124a9976b6f2e45732339350bcc9510dd0a4a0d7 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Thu, 11 Jun 2020 13:18:26 +0200 Subject: [PATCH 090/128] [PIO] Use espressif8266@2.5.2 with fixed esp8266_stack_decoder --- platformio_core_defs.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio_core_defs.ini b/platformio_core_defs.ini index 134c356e4..ef03ad73b 100644 --- a/platformio_core_defs.ini +++ b/platformio_core_defs.ini @@ -100,7 +100,7 @@ lib_ignore = ${esp82xx_defaults.lib_ignore}, IRremoteESP8266, Hea [core_2_7_1] extends = esp82xx_2_6_x -platform = espressif8266@2.5.1 +platform = espressif8266@2.5.2 platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#2.7.1 build_flags = ${esp82xx_2_6_x.build_flags} @@ -110,7 +110,7 @@ build_flags = ${esp82xx_2_6_x.build_flags} [core_2_7_1_sdk3] extends = esp82xx_2_6_x -platform = espressif8266@2.5.1 +platform = espressif8266@2.5.2 platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#2.7.1 build_flags = ${esp82xx_2_6_x.build_flags} From af4843677075cea003be5c21fa62671abba8b85e Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Wed, 10 Jun 2020 15:26:54 +0200 Subject: [PATCH 091/128] [Controller] Memory optimization for sending SENSOR_TYPE_STRING String was copied before sending to the MQTT publish. Plus copied another time for the log if LOG_LEVEL_DEBUG was active. --- src/Controller.ino | 48 ++++++++++++++++++++++++---------------------- src/_C005.ino | 25 +++++++++++++++--------- src/_C006.ino | 10 +++++++--- src/_C014.ino | 10 ++++++++-- 4 files changed, 56 insertions(+), 37 deletions(-) diff --git a/src/Controller.ino b/src/Controller.ino index ebc0f0f18..4845ff5c5 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -28,6 +28,12 @@ void sendData(struct EventStruct *event) } LoadTaskSettings(event->TaskIndex); // could have changed during background tasks. + if (event->sensorType == SENSOR_TYPE_NONE) { + const deviceIndex_t DeviceIndex = getDeviceIndex_from_TaskIndex(event->TaskIndex); + if (validDeviceIndex(DeviceIndex)) { + event->sensorType = Device[DeviceIndex].VType; + } + } for (controllerIndex_t x = 0; x < CONTROLLER_MAX; x++) { @@ -66,11 +72,7 @@ void sendData(struct EventStruct *event) } bool validUserVar(struct EventStruct *event) { - const deviceIndex_t DeviceIndex = getDeviceIndex_from_TaskIndex(event->TaskIndex); - - if (!validDeviceIndex(DeviceIndex)) { return false; } - - switch (Device[DeviceIndex].VType) { + switch (event->sensorType) { case SENSOR_TYPE_LONG: return true; case SENSOR_TYPE_STRING: return true; // FIXME TD-er: Must look at length of event->String2 ? default: @@ -287,25 +289,25 @@ bool MQTTCheck(controllerIndex_t controller_idx) if (MQTTclient_should_reconnect || !MQTTclient.connected()) { if (MQTTclient_should_reconnect) { - addLog(LOG_LEVEL_ERROR, F("MQTT : Intentional reconnect")); - } - return MQTTConnect(controller_idx); - } - - if (MQTTclient_must_send_LWT_connected) { - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(controller_idx, ControllerSettings); - - if (ControllerSettings.mqtt_sendLWT()) { - String LWTTopic = getLWT_topic(ControllerSettings); - String LWTMessageConnect = getLWT_messageConnect(ControllerSettings); - bool willRetain = ControllerSettings.mqtt_willRetain(); - - if (MQTTclient.publish(LWTTopic.c_str(), LWTMessageConnect.c_str(), willRetain)) { - MQTTclient_must_send_LWT_connected = false; + addLog(LOG_LEVEL_ERROR, F("MQTT : Intentional reconnect")); } - } else { - MQTTclient_must_send_LWT_connected = false; + return MQTTConnect(controller_idx); + } + + if (MQTTclient_must_send_LWT_connected) { + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(controller_idx, ControllerSettings); + + if (ControllerSettings.mqtt_sendLWT()) { + String LWTTopic = getLWT_topic(ControllerSettings); + String LWTMessageConnect = getLWT_messageConnect(ControllerSettings); + bool willRetain = ControllerSettings.mqtt_willRetain(); + + if (MQTTclient.publish(LWTTopic.c_str(), LWTMessageConnect.c_str(), willRetain)) { + MQTTclient_must_send_LWT_connected = false; + } + } else { + MQTTclient_must_send_LWT_connected = false; } } } diff --git a/src/_C005.ino b/src/_C005.ino index 3824689b1..9096f5440 100644 --- a/src/_C005.ino +++ b/src/_C005.ino @@ -110,7 +110,6 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String& String pubname = ControllerSettings.Publish; parseControllerVariables(pubname, event, false); - String value = ""; byte valueCount = getValueCountFromSensorType(event->sensorType); for (byte x = 0; x < valueCount; x++) { @@ -120,15 +119,23 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String& String tmppubname = pubname; tmppubname.replace(F("%valname%"), ExtraTaskSettings.TaskDeviceValueNames[x]); - value = formatUserVarNoCheck(event, x); - - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + String value = ""; + // Small optimization so we don't try to copy potentially large strings + if (event->sensorType == SENSOR_TYPE_STRING) { + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), ControllerSettings.mqtt_retainFlag()); + value = event->String2.substring(0, 20); // For the log + } else { + value = formatUserVarNoCheck(event, x); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + } #ifndef BUILD_NO_DEBUG - String log = F("MQTT : "); - log += tmppubname; - log += ' '; - log += value; - addLog(LOG_LEVEL_DEBUG, log); + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { + String log = F("MQTT : "); + log += tmppubname; + log += ' '; + log += value; + addLog(LOG_LEVEL_DEBUG, log); + } #endif } break; diff --git a/src/_C006.ino b/src/_C006.ino index 453cccf1d..3c124b8d3 100644 --- a/src/_C006.ino +++ b/src/_C006.ino @@ -104,14 +104,18 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& String pubname = ControllerSettings.Publish; parseControllerVariables(pubname, event, false); - String value = ""; byte valueCount = getValueCountFromSensorType(event->sensorType); for (byte x = 0; x < valueCount; x++) { String tmppubname = pubname; tmppubname.replace(F("%valname%"), ExtraTaskSettings.TaskDeviceValueNames[x]); - value = formatUserVarNoCheck(event, x); - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + // Small optimization so we don't try to copy potentially large strings + if (event->sensorType == SENSOR_TYPE_STRING) { + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), ControllerSettings.mqtt_retainFlag()); + } else { + String value = formatUserVarNoCheck(event, x); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + } } break; } diff --git a/src/_C014.ino b/src/_C014.ino index 674143c32..b39acdbeb 100644 --- a/src/_C014.ino +++ b/src/_C014.ino @@ -708,9 +708,15 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& { String tmppubname = pubname; tmppubname.replace(F("%valname%"), ExtraTaskSettings.TaskDeviceValueNames[x]); - value = formatUserVarNoCheck(event, x); - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + // Small optimization so we don't try to copy potentially large strings + if (event->sensorType == SENSOR_TYPE_STRING) { + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), ControllerSettings.mqtt_retainFlag()); + value = event->String2.substring(0, 20); // For the log + } else { + value = formatUserVarNoCheck(event, x); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + } if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { String log = F("C014 : Sent to "); log += tmppubname; From affd20418dfbaad28b4fd1ff50c81cea03b8953c Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 22 Jun 2020 10:25:02 +0200 Subject: [PATCH 092/128] [Controller] Check if controller host/IP is set before MQTT connect --- src/Controller.ino | 1 + src/Networking.ino | 3 ++ src/_CPlugin_Helper.cpp | 2 +- src/_P033_Dummy.ino | 1 + .../DataStructs/ControllerSettingsStruct.cpp | 40 ++++++++++--------- .../DataStructs/ControllerSettingsStruct.h | 19 ++++----- 6 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/Controller.ino b/src/Controller.ino index 4845ff5c5..d1f3084da 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -308,6 +308,7 @@ bool MQTTCheck(controllerIndex_t controller_idx) } } else { MQTTclient_must_send_LWT_connected = false; + } } } } diff --git a/src/Networking.ino b/src/Networking.ino index dcf92e43c..29119f7ce 100644 --- a/src/Networking.ino +++ b/src/Networking.ino @@ -878,6 +878,9 @@ bool connectClient(WiFiClient& client, IPAddress ip, uint16_t port) if (!NetworkConnected()) { return false; } + // In case of domain name resolution error result can be negative. + // https://github.com/esp8266/Arduino/blob/18f643c7e2d6a0da9d26ff2b14c94e6536ab78c1/libraries/Ethernet/src/Dns.cpp#L44 + // Thus must match the result with 1. bool connected = (client.connect(ip, port) == 1); yield(); diff --git a/src/_CPlugin_Helper.cpp b/src/_CPlugin_Helper.cpp index fc92c2e45..3764deac6 100644 --- a/src/_CPlugin_Helper.cpp +++ b/src/_CPlugin_Helper.cpp @@ -277,7 +277,7 @@ bool try_connect_host(int controller_number, WiFiUDP& client, ControllerSettings #ifndef BUILD_NO_DEBUG log_connecting_to(F("UDP : "), controller_number, ControllerSettings); #endif // ifndef BUILD_NO_DEBUG - bool success = ControllerSettings.beginPacket(client) != 0; + bool success = ControllerSettings.beginPacket(client); const bool result = count_connection_results( success, F("UDP : "), controller_number, ControllerSettings); diff --git a/src/_P033_Dummy.ino b/src/_P033_Dummy.ino index 6db1ed13c..4d402dc8a 100644 --- a/src/_P033_Dummy.ino +++ b/src/_P033_Dummy.ino @@ -41,6 +41,7 @@ boolean Plugin_033(byte function, struct EventStruct *event, String& string) case PLUGIN_GET_DEVICEVALUENAMES: { + // FIXME TD-er: Copy names as done in P026_Sysinfo.ino. strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_033)); break; } diff --git a/src/src/DataStructs/ControllerSettingsStruct.cpp b/src/src/DataStructs/ControllerSettingsStruct.cpp index af5c88ceb..cc6ccbed2 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.cpp +++ b/src/src/DataStructs/ControllerSettingsStruct.cpp @@ -40,6 +40,13 @@ void ControllerSettingsStruct::reset() { safe_strncpy(ClientID, F(CONTROLLER_DEFAULT_CLIENTID), sizeof(ClientID)); } +bool ControllerSettingsStruct::isSet() const { + if (UseDNS) { + return HostName[0] != 0; + } + return ipSet(); +} + void ControllerSettingsStruct::validate() { if (Port > 65535) { Port = 0; } @@ -84,7 +91,11 @@ void ControllerSettingsStruct::setHostname(const String& controllerhostname) { updateIPcache(); } -boolean ControllerSettingsStruct::checkHostReachable(bool quick) { +bool ControllerSettingsStruct::checkHostReachable(bool quick) { + if (!isSet()) { + // No IP/hostname set + return false; + } if (!NetworkConnected(10)) { return false; // Not connected, so no use in wasting time to connect to a host. } @@ -100,7 +111,7 @@ boolean ControllerSettingsStruct::checkHostReachable(bool quick) { return hostReachable(getIP()); } -boolean ControllerSettingsStruct::connectToHost(WiFiClient& client) { +bool ControllerSettingsStruct::connectToHost(WiFiClient& client) { if (!checkHostReachable(true)) { return false; // Host not reachable } @@ -109,10 +120,6 @@ boolean ControllerSettingsStruct::connectToHost(WiFiClient& client) { while (retry > 0 && !connected) { --retry; - - // In case of domain name resolution error result can be negative. - // https://github.com/esp8266/Arduino/blob/18f643c7e2d6a0da9d26ff2b14c94e6536ab78c1/libraries/Ethernet/src/Dns.cpp#L44 - // Thus must match the result with 1. connected = connectClient(client, getIP(), Port); if (connected) { return true; } @@ -124,26 +131,23 @@ boolean ControllerSettingsStruct::connectToHost(WiFiClient& client) { return false; } -// Returns 1 if successful, 0 if there was a problem resolving the hostname or port -int ControllerSettingsStruct::beginPacket(WiFiUDP& client) { +bool ControllerSettingsStruct::beginPacket(WiFiUDP& client) { if (!checkHostReachable(true)) { - return 0; // Host not reachable + return false; // Host not reachable } byte retry = 2; - int connected = 0; - - while (retry > 0 && connected == 0) { + while (retry > 0) { --retry; - connected = client.beginPacket(getIP(), Port); - - if (connected != 0) { return connected; } + if (client.beginPacket(getIP(), Port) == 1) { + return true; + } if (!checkHostReachable(false)) { - return 0; + return false; } delay(10); } - return 0; + return false; } String ControllerSettingsStruct::getHostPortString() const { @@ -154,7 +158,7 @@ String ControllerSettingsStruct::getHostPortString() const { return result; } -bool ControllerSettingsStruct::ipSet() { +bool ControllerSettingsStruct::ipSet() const { for (byte i = 0; i < 4; ++i) { if (IP[i] != 0) { return true; } } diff --git a/src/src/DataStructs/ControllerSettingsStruct.h b/src/src/DataStructs/ControllerSettingsStruct.h index 67f27f208..c562f3956 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.h +++ b/src/src/DataStructs/ControllerSettingsStruct.h @@ -57,8 +57,8 @@ struct ControllerSettingsStruct // IDs of controller settings, used to generate web forms // ******************************************************************************** enum VarType { - CONTROLLER_USE_DNS = 0, // PLace this before HOSTNAME/IP - CONTROLLER_USE_EXTENDED_CREDENTIALS = 1, // Place this before USER/PASS + CONTROLLER_USE_DNS = 0, // PLace this before HOSTNAME/IP + CONTROLLER_USE_EXTENDED_CREDENTIALS = 1, // Place this before USER/PASS CONTROLLER_HOSTNAME, CONTROLLER_IP, CONTROLLER_PORT, @@ -92,6 +92,8 @@ struct ControllerSettingsStruct void reset(); + bool isSet() const; + void validate(); IPAddress getIP() const; @@ -100,12 +102,11 @@ struct ControllerSettingsStruct void setHostname(const String& controllerhostname); - boolean checkHostReachable(bool quick); + bool checkHostReachable(bool quick); - boolean connectToHost(WiFiClient& client); + bool connectToHost(WiFiClient& client); - // Returns 1 if successful, 0 if there was a problem resolving the hostname or port - int beginPacket(WiFiUDP& client); + bool beginPacket(WiFiUDP& client); String getHostPortString() const; @@ -140,16 +141,16 @@ struct ControllerSettingsStruct unsigned int MinimalTimeBetweenMessages; unsigned int MaxQueueDepth; unsigned int MaxRetry; - boolean DeleteOldest; // Action to perform when buffer full, delete oldest, or ignore newest. + bool DeleteOldest; // Action to perform when buffer full, delete oldest, or ignore newest. unsigned int ClientTimeout; - boolean MustCheckReply; // When set to false, a sent message is considered always successful. + bool MustCheckReply; // When set to false, a sent message is considered always successful. taskIndex_t SampleSetInitiator; // The first task to start a sample set. uint32_t MQTT_flags; // Various flags for MQTT controllers char ClientID[65]; // Used to define the Client ID used by the controller private: - bool ipSet(); + bool ipSet() const; bool updateIPcache(); }; From c03329228f88612809967d5cc00a91162f6e576a Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 22 Jun 2020 10:27:12 +0200 Subject: [PATCH 093/128] [MQTT] Add function to check MQTT queue full state --- src/Controller.ino | 21 ++++++++++++++------- src/ESPEasy_fdwdecl.h | 1 + 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Controller.ino b/src/Controller.ino index d1f3084da..085577cb2 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -415,15 +415,22 @@ void SendStatus(EventValueSource::Enum source, const String& status) } #ifdef USES_MQTT +bool MQTT_queueFull(controllerIndex_t controller_idx) { + MQTT_queue_element dummy_element; + dummy_element.controller_idx = controller_idx; + if (MQTTDelayHandler.queueFull(dummy_element)) { + // The queue is full, try to make some room first. + addLog(LOG_LEVEL_DEBUG, F("MQTT : Extra processMQTTdelayQueue()")); + processMQTTdelayQueue(); + return MQTTDelayHandler.queueFull(dummy_element); + } + return false; +} + bool MQTTpublish(controllerIndex_t controller_idx, const char *topic, const char *payload, bool retained) { - { - MQTT_queue_element dummy_element(MQTT_queue_element(controller_idx, "", "", retained)); - if (MQTTDelayHandler.queueFull(dummy_element)) { - // The queue is full, try to make some room first. - addLog(LOG_LEVEL_DEBUG, F("MQTT : Extra processMQTTdelayQueue()")); - processMQTTdelayQueue(); - } + if (MQTT_queueFull(controller_idx)) { + return false; } const bool success = MQTTDelayHandler.addToQueue(MQTT_queue_element(controller_idx, topic, payload, retained)); scheduleNextMQTTdelayQueue(); diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index 5f149502e..df12acd1b 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -124,6 +124,7 @@ void MQTTDisconnect(); bool MQTTConnect(controllerIndex_t controller_idx); bool MQTTCheck(controllerIndex_t controller_idx); void schedule_all_tasks_using_MQTT_controller(); +bool MQTT_queueFull(controllerIndex_t controller_idx); bool MQTTpublish(controllerIndex_t controller_idx, const char *topic, const char *payload, bool retained); #endif // ifdef USES_MQTT From 08dc4a81df00433a512478813c691bd0e2a96689 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 22 Jun 2020 10:30:31 +0200 Subject: [PATCH 094/128] [Cleanup] Free ControllerSettings as soon as possible to free memory Quote often the ControllerSettings are only used to get one or two values. No need to keep this ~800 bytes large object allocated for more than absolutely needed. --- src/Controller.ino | 19 ++++++++------ src/Misc.ino | 31 ++++++++++++----------- src/WebServer_ControllerPage.ino | 43 +++++++++++++++++--------------- src/_C005.ino | 19 +++++++------- src/_C006.ino | 16 ++++++++---- src/_C008.ino | 11 +++++--- src/_C014.ino | 25 ++++++++----------- src/src/Commands/MQTT.cpp | 25 +++++++++++++------ 8 files changed, 109 insertions(+), 80 deletions(-) diff --git a/src/Controller.ino b/src/Controller.ino index 085577cb2..94cc14627 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -295,9 +295,6 @@ bool MQTTCheck(controllerIndex_t controller_idx) } if (MQTTclient_must_send_LWT_connected) { - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(controller_idx, ControllerSettings); - if (ControllerSettings.mqtt_sendLWT()) { String LWTTopic = getLWT_topic(ControllerSettings); String LWTMessageConnect = getLWT_messageConnect(ControllerSettings); @@ -420,7 +417,6 @@ bool MQTT_queueFull(controllerIndex_t controller_idx) { dummy_element.controller_idx = controller_idx; if (MQTTDelayHandler.queueFull(dummy_element)) { // The queue is full, try to make some room first. - addLog(LOG_LEVEL_DEBUG, F("MQTT : Extra processMQTTdelayQueue()")); processMQTTdelayQueue(); return MQTTDelayHandler.queueFull(dummy_element); } @@ -477,12 +473,19 @@ void MQTTStatus(const String& status) controllerIndex_t enabledMqttController = firstEnabledMQTT_ControllerIndex(); if (validControllerIndex(enabledMqttController)) { - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(enabledMqttController, ControllerSettings); - String pubname = ControllerSettings.Subscribe; + String pubname; + bool mqtt_retainFlag; + { + // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(enabledMqttController, ControllerSettings); + pubname = ControllerSettings.Publish; + mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); + } + pubname.replace(F("/#"), F("/status")); parseSystemVariables(pubname, false); - MQTTpublish(enabledMqttController, pubname.c_str(), status.c_str(), ControllerSettings.mqtt_retainFlag()); + MQTTpublish(enabledMqttController, pubname.c_str(), status.c_str(), mqtt_retainFlag); } } #endif //USES_MQTT diff --git a/src/Misc.ino b/src/Misc.ino index 8700c0109..27ba4bb93 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -1330,21 +1330,24 @@ void ResetFactory() addPredefinedRules(gpio_settings); #if DEFAULT_CONTROLLER - MakeControllerSettings(ControllerSettings); - safe_strncpy(ControllerSettings.Subscribe, F(DEFAULT_SUB), sizeof(ControllerSettings.Subscribe)); - safe_strncpy(ControllerSettings.Publish, F(DEFAULT_PUB), sizeof(ControllerSettings.Publish)); - safe_strncpy(ControllerSettings.MQTTLwtTopic, F(DEFAULT_MQTT_LWT_TOPIC), sizeof(ControllerSettings.MQTTLwtTopic)); - safe_strncpy(ControllerSettings.LWTMessageConnect, F(DEFAULT_MQTT_LWT_CONNECT_MESSAGE), sizeof(ControllerSettings.LWTMessageConnect)); - safe_strncpy(ControllerSettings.LWTMessageDisconnect, F(DEFAULT_MQTT_LWT_DISCONNECT_MESSAGE), sizeof(ControllerSettings.LWTMessageDisconnect)); - str2ip((char*)DEFAULT_SERVER, ControllerSettings.IP); - ControllerSettings.setHostname(F(DEFAULT_SERVER_HOST)); - ControllerSettings.UseDNS = DEFAULT_SERVER_USEDNS; - ControllerSettings.useExtendedCredentials(DEFAULT_USE_EXTD_CONTROLLER_CREDENTIALS); - ControllerSettings.Port = DEFAULT_PORT; - setControllerUser(0, ControllerSettings, F(DEFAULT_CONTROLLER_USER)); - setControllerPass(0, ControllerSettings, F(DEFAULT_CONTROLLER_PASS)); + { + // Place in a scope to have its memory freed ASAP + MakeControllerSettings(ControllerSettings); + safe_strncpy(ControllerSettings.Subscribe, F(DEFAULT_SUB), sizeof(ControllerSettings.Subscribe)); + safe_strncpy(ControllerSettings.Publish, F(DEFAULT_PUB), sizeof(ControllerSettings.Publish)); + safe_strncpy(ControllerSettings.MQTTLwtTopic, F(DEFAULT_MQTT_LWT_TOPIC), sizeof(ControllerSettings.MQTTLwtTopic)); + safe_strncpy(ControllerSettings.LWTMessageConnect, F(DEFAULT_MQTT_LWT_CONNECT_MESSAGE), sizeof(ControllerSettings.LWTMessageConnect)); + safe_strncpy(ControllerSettings.LWTMessageDisconnect, F(DEFAULT_MQTT_LWT_DISCONNECT_MESSAGE), sizeof(ControllerSettings.LWTMessageDisconnect)); + str2ip((char*)DEFAULT_SERVER, ControllerSettings.IP); + ControllerSettings.setHostname(F(DEFAULT_SERVER_HOST)); + ControllerSettings.UseDNS = DEFAULT_SERVER_USEDNS; + ControllerSettings.useExtendedCredentials(DEFAULT_USE_EXTD_CONTROLLER_CREDENTIALS); + ControllerSettings.Port = DEFAULT_PORT; + setControllerUser(0, ControllerSettings, F(DEFAULT_CONTROLLER_USER)); + setControllerPass(0, ControllerSettings, F(DEFAULT_CONTROLLER_PASS)); - SaveControllerSettings(0, ControllerSettings); + SaveControllerSettings(0, ControllerSettings); + } #endif SaveSettings(); diff --git a/src/WebServer_ControllerPage.ino b/src/WebServer_ControllerPage.ino index 7cb0ccc86..fc8eede2b 100644 --- a/src/WebServer_ControllerPage.ino +++ b/src/WebServer_ControllerPage.ino @@ -22,33 +22,36 @@ void handle_controllers() { // submitted data if ((protocol != -1) && !controllerNotSet) { - MakeControllerSettings(ControllerSettings); bool mustInit = false; - - if (Settings.Protocol[controllerindex] != protocol) { - // Protocol has changed. - Settings.Protocol[controllerindex] = protocol; + // Place in a scope to free ControllerSettings memory ASAP + MakeControllerSettings(ControllerSettings); - // there is a protocol selected? - if (protocol != 0) + if (Settings.Protocol[controllerindex] != protocol) { - mustInit = true; - handle_controllers_clearLoadDefaults(controllerindex, ControllerSettings); - } - } + // Protocol has changed. + Settings.Protocol[controllerindex] = protocol; - // subitted same protocol - else - { - // there is a protocol selected - if (protocol != 0) - { - mustInit = true; - handle_controllers_CopySubmittedSettings(controllerindex, ControllerSettings); + // there is a protocol selected? + if (protocol != 0) + { + mustInit = true; + handle_controllers_clearLoadDefaults(controllerindex, ControllerSettings); + } } + + // subitted same protocol + else + { + // there is a protocol selected + if (protocol != 0) + { + mustInit = true; + handle_controllers_CopySubmittedSettings(controllerindex, ControllerSettings); + } + } + addHtmlError(SaveControllerSettings(controllerindex, ControllerSettings)); } - addHtmlError(SaveControllerSettings(controllerindex, ControllerSettings)); addHtmlError(SaveSettings()); if (mustInit) { diff --git a/src/_C005.ino b/src/_C005.ino index 9096f5440..a27ec8a28 100644 --- a/src/_C005.ino +++ b/src/_C005.ino @@ -94,20 +94,21 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_SEND: { - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); - if (!ControllerSettings.checkHostReachable(true)) { - success = false; - break; + String pubname; + bool mqtt_retainFlag; + { + // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(event->ControllerIndex, ControllerSettings); + pubname = ControllerSettings.Publish; + mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); } - statusLED(true); if (ExtraTaskSettings.TaskIndex != event->TaskIndex) { String dummy; PluginCall(PLUGIN_GET_DEVICEVALUENAMES, event, dummy); } - String pubname = ControllerSettings.Publish; parseControllerVariables(pubname, event, false); byte valueCount = getValueCountFromSensorType(event->sensorType); @@ -122,11 +123,11 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String& String value = ""; // Small optimization so we don't try to copy potentially large strings if (event->sensorType == SENSOR_TYPE_STRING) { - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), ControllerSettings.mqtt_retainFlag()); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), mqtt_retainFlag); value = event->String2.substring(0, 20); // For the log } else { value = formatUserVarNoCheck(event, x); - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), mqtt_retainFlag); } #ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { diff --git a/src/_C006.ino b/src/_C006.ino index 3c124b8d3..d448003f8 100644 --- a/src/_C006.ino +++ b/src/_C006.ino @@ -91,8 +91,15 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& success = false; break; } - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); + String pubname; + bool mqtt_retainFlag; + { + // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(event->ControllerIndex, ControllerSettings); + pubname = ControllerSettings.Publish; + mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); + } statusLED(true); @@ -101,7 +108,6 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& PluginCall(PLUGIN_GET_DEVICEVALUENAMES, event, dummy); } - String pubname = ControllerSettings.Publish; parseControllerVariables(pubname, event, false); byte valueCount = getValueCountFromSensorType(event->sensorType); @@ -111,10 +117,10 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& tmppubname.replace(F("%valname%"), ExtraTaskSettings.TaskDeviceValueNames[x]); // Small optimization so we don't try to copy potentially large strings if (event->sensorType == SENSOR_TYPE_STRING) { - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), ControllerSettings.mqtt_retainFlag()); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), mqtt_retainFlag); } else { String value = formatUserVarNoCheck(event, x); - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), mqtt_retainFlag); } } break; diff --git a/src/_C008.ino b/src/_C008.ino index 88bed66e5..164df6775 100644 --- a/src/_C008.ino +++ b/src/_C008.ino @@ -58,8 +58,13 @@ bool CPlugin_008(CPlugin::Function function, struct EventStruct *event, String& PluginCall(PLUGIN_GET_DEVICEVALUENAMES, event, dummy); } - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); + String pubname; + { + // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(event->ControllerIndex, ControllerSettings); + pubname = ControllerSettings.Publish; + } for (byte x = 0; x < valueCount; x++) { @@ -67,7 +72,7 @@ bool CPlugin_008(CPlugin::Function function, struct EventStruct *event, String& String formattedValue = formatUserVar(event, x, isvalid); if (isvalid) { element.txt[x] = "/"; - element.txt[x] += ControllerSettings.Publish; + element.txt[x] += pubname; element.txt[x].replace(F("%valname%"), ExtraTaskSettings.TaskDeviceValueNames[x]); element.txt[x].replace(F("%value%"), formattedValue); parseControllerVariables(element.txt[x], event, true); diff --git a/src/_C014.ino b/src/_C014.ino index b39acdbeb..881dda91d 100644 --- a/src/_C014.ino +++ b/src/_C014.ino @@ -207,12 +207,6 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_GOT_CONNECTED: //// call after connected to mqtt server to publich device autodicover features { - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); - if (!ControllerSettings.checkHostReachable(true)) { - success = false; - break; - } statusLED(true); // send autodiscover header @@ -686,12 +680,16 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_SEND: { - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); - if (!ControllerSettings.checkHostReachable(true)) { - success = false; - break; + String pubname; + bool mqtt_retainFlag; + { + // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(event->ControllerIndex, ControllerSettings); + pubname = ControllerSettings.Publish; + mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); } + statusLED(true); if (ExtraTaskSettings.TaskIndex != event->TaskIndex) { @@ -699,7 +697,6 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& PluginCall(PLUGIN_GET_DEVICEVALUENAMES, event, dummy); } - String pubname = ControllerSettings.Publish; parseControllerVariables(pubname, event, false); String value = ""; @@ -711,11 +708,11 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& // Small optimization so we don't try to copy potentially large strings if (event->sensorType == SENSOR_TYPE_STRING) { - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), ControllerSettings.mqtt_retainFlag()); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), mqtt_retainFlag); value = event->String2.substring(0, 20); // For the log } else { value = formatUserVarNoCheck(event, x); - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), mqtt_retainFlag); } if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { String log = F("C014 : Sent to "); diff --git a/src/src/Commands/MQTT.cpp b/src/src/Commands/MQTT.cpp index 7231413b7..1b47995b5 100644 --- a/src/src/Commands/MQTT.cpp +++ b/src/src/Commands/MQTT.cpp @@ -29,8 +29,14 @@ String Command_MQTT_Publish(struct EventStruct *event, const char *Line) addLog(LOG_LEVEL_DEBUG, String(F("Publish: ")) + topic + value); if ((topic.length() > 0) && (value.length() > 0)) { - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(enabledMqttController, ControllerSettings); + + bool mqtt_retainFlag; + { + // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(event->ControllerIndex, ControllerSettings); + mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); + } // @giig1967g: if payload starts with '=' then treat it as a Formula and evaluate accordingly @@ -40,10 +46,10 @@ String Command_MQTT_Publish(struct EventStruct *event, const char *Line) bool success = false; if (value[0] != '=') { - success = MQTTpublish(enabledMqttController, topic.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); + success = MQTTpublish(enabledMqttController, topic.c_str(), value.c_str(), mqtt_retainFlag); } else { - success = MQTTpublish(enabledMqttController, topic.c_str(), String(event->Par2).c_str(), ControllerSettings.mqtt_retainFlag()); + success = MQTTpublish(enabledMqttController, topic.c_str(), String(event->Par2).c_str(), mqtt_retainFlag); } if (success) { return return_command_success(); @@ -71,12 +77,17 @@ String Command_MQTT_Subscribe(struct EventStruct *event, const char* Line) // ToDo TD-er: Not sure about this function, but at least it sends to an existing MQTTclient controllerIndex_t enabledMqttController = firstEnabledMQTT_ControllerIndex(); if (validControllerIndex(enabledMqttController)) { - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(enabledMqttController, ControllerSettings); + bool mqtt_retainFlag; + { + // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(event->ControllerIndex, ControllerSettings); + mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); + } String eventName = Line; String topic = eventName.substring(10); - if (!MQTTsubscribe(enabledMqttController, topic.c_str(), ControllerSettings.mqtt_retainFlag())) + if (!MQTTsubscribe(enabledMqttController, topic.c_str(), mqtt_retainFlag)) return_command_failed(); return_command_success(); } From 33291eac11b1c5dd36ea3459a0e0b58fef974699 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Fri, 12 Jun 2020 01:11:14 +0200 Subject: [PATCH 095/128] [Cleanup] Try to use move constructor when adding to controller queue Still to do: create a proper move operator for queue_element_single_value_base --- src/_C008.ino | 3 ++- src/_C009.ino | 3 ++- src/_C010.ino | 3 ++- src/_C012.ino | 3 ++- src/_C017.ino | 3 ++- .../ControllerQueue/ControllerDelayHandlerStruct.h | 2 +- .../queue_element_single_value_base.cpp | 13 +++++++++++++ .../queue_element_single_value_base.h | 2 ++ 8 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/_C008.ino b/src/_C008.ino index 164df6775..19ddac2ca 100644 --- a/src/_C008.ino +++ b/src/_C008.ino @@ -81,7 +81,8 @@ bool CPlugin_008(CPlugin::Function function, struct EventStruct *event, String& #endif } } - success = C008_DelayHandler.addToQueue(element); + // FIXME TD-er must define a proper move operator + success = C008_DelayHandler.addToQueue(C008_queue_element(element)); scheduleNextDelayQueue(TIMER_C008_DELAY_QUEUE, C008_DelayHandler.getNextScheduleTime()); break; } diff --git a/src/_C009.ino b/src/_C009.ino index af1f77fd2..ddca63a64 100644 --- a/src/_C009.ino +++ b/src/_C009.ino @@ -68,7 +68,8 @@ bool CPlugin_009(CPlugin::Function function, struct EventStruct *event, String& { element.txt[x] = formatUserVarNoCheck(event, x); } - success = C009_DelayHandler.addToQueue(element); + // FIXME TD-er must define a proper move operator + success = C009_DelayHandler.addToQueue(C009_queue_element(element)); scheduleNextDelayQueue(TIMER_C009_DELAY_QUEUE, C009_DelayHandler.getNextScheduleTime()); break; } diff --git a/src/_C010.ino b/src/_C010.ino index 549971049..6ebe6bc03 100644 --- a/src/_C010.ino +++ b/src/_C010.ino @@ -63,7 +63,8 @@ bool CPlugin_010(CPlugin::Function function, struct EventStruct *event, String& addLog(LOG_LEVEL_DEBUG_MORE, element.txt[x]); } } - success = C010_DelayHandler.addToQueue(element); + // FIXME TD-er must define a proper move operator + success = C010_DelayHandler.addToQueue(C010_queue_element(element)); scheduleNextDelayQueue(TIMER_C010_DELAY_QUEUE, C010_DelayHandler.getNextScheduleTime()); break; } diff --git a/src/_C012.ino b/src/_C012.ino index ce1f10439..d5a639831 100644 --- a/src/_C012.ino +++ b/src/_C012.ino @@ -60,7 +60,8 @@ bool CPlugin_012(CPlugin::Function function, struct EventStruct *event, String& addLog(LOG_LEVEL_DEBUG_MORE, element.txt[x]); } } - success = C012_DelayHandler.addToQueue(element); + // FIXME TD-er must define a proper move operator + success = C012_DelayHandler.addToQueue(C012_queue_element(element)); scheduleNextDelayQueue(TIMER_C012_DELAY_QUEUE, C012_DelayHandler.getNextScheduleTime()); break; } diff --git a/src/_C017.ino b/src/_C017.ino index 0ba051f5f..a4282ee27 100644 --- a/src/_C017.ino +++ b/src/_C017.ino @@ -56,7 +56,8 @@ bool CPlugin_017(CPlugin::Function function, struct EventStruct *event, String & { element.txt[x] = formatUserVarNoCheck(event, x); } - success = C017_DelayHandler.addToQueue(element); + // FIXME TD-er must define a proper move operator + success = C017_DelayHandler.addToQueue(C017_queue_element(element)); scheduleNextDelayQueue(TIMER_C017_DELAY_QUEUE, C017_DelayHandler.getNextScheduleTime()); break; } diff --git a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h index 20095a336..ae216dec1 100644 --- a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h +++ b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h @@ -82,7 +82,7 @@ struct ControllerDelayHandlerStruct { // Try to add to the queue, if permitted by "delete_oldest" // Return false when no item was added. - bool addToQueue(const T& element) { + bool addToQueue(T&& element) { if (delete_oldest) { // Force add to the queue. // If max buffer is reached, the oldest in the queue (first to be served) will be removed. diff --git a/src/src/ControllerQueue/queue_element_single_value_base.cpp b/src/src/ControllerQueue/queue_element_single_value_base.cpp index 08ac41324..ec0704e99 100644 --- a/src/src/ControllerQueue/queue_element_single_value_base.cpp +++ b/src/src/ControllerQueue/queue_element_single_value_base.cpp @@ -11,6 +11,19 @@ queue_element_single_value_base::queue_element_single_value_base(const struct Ev valuesSent(0), valueCount(value_count) {} +/* +queue_element_single_value_base::queue_element_single_value_base(queue_element_single_value_base &&rval) +: idx(rval.idx), TaskIndex(rval.TaskIndex), + controller_idx(rval.controller_idx), + valuesSent(rval.valuesSent), valueCount(rval.valueCount) +{ + for (byte i = 0; i < VARS_PER_TASK; ++i) { + String tmp(std::move(rval.txt[i])); + txt[i] = tmp; + } +} +*/ + bool queue_element_single_value_base::checkDone(bool succesfull) const { if (succesfull) { ++valuesSent; } return valuesSent >= valueCount || valuesSent >= VARS_PER_TASK; diff --git a/src/src/ControllerQueue/queue_element_single_value_base.h b/src/src/ControllerQueue/queue_element_single_value_base.h index cd01ffbb7..c041c14f3 100644 --- a/src/src/ControllerQueue/queue_element_single_value_base.h +++ b/src/src/ControllerQueue/queue_element_single_value_base.h @@ -21,6 +21,8 @@ public: queue_element_single_value_base(const struct EventStruct *event, byte value_count); +// queue_element_single_value_base(queue_element_single_value_base &&rval); + bool checkDone(bool succesfull) const; size_t getSize() const; From 15af201bb9e5569c65637129736807f7700c2eaa Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 22 Jun 2020 10:31:28 +0200 Subject: [PATCH 096/128] [Controller] Cache needed controller info to reduce memory usage --- src/_C002.ino | 19 +++++++------------ src/_C005.ino | 17 ++++++++--------- src/_C006.ino | 17 ++++++++--------- src/_C014.ino | 16 +++++++--------- 4 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/_C002.ino b/src/_C002.ino index f04072819..1c8c9b97b 100644 --- a/src/_C002.ino +++ b/src/_C002.ino @@ -11,6 +11,9 @@ #include "src/Commands/InternalCommands.h" #include +String CPlugin_002_pubname; +bool CPlugin_002_retain = false; + bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String& string) { bool success = false; @@ -41,6 +44,8 @@ bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String& MakeControllerSettings(ControllerSettings); LoadControllerSettings(event->ControllerIndex, ControllerSettings); MQTTDelayHandler.configureControllerSettings(ControllerSettings); + CPlugin_002_pubname = ControllerSettings.Publish; + CPlugin_002_retain = ControllerSettings.mqtt_retainFlag(); break; } @@ -172,16 +177,6 @@ bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String& { if (event->idx != 0) { - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); - - /* - if (!ControllerSettings.checkHostReachable(true)) { - success = false; - break; - } - */ - DynamicJsonDocument root(200); root[F("idx")] = event->idx; root[F("RSSI")] = mapRSSItoDomoticz(); @@ -237,10 +232,10 @@ bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String& addLog(LOG_LEVEL_DEBUG, log); #endif // ifndef BUILD_NO_DEBUG - String pubname = ControllerSettings.Publish; + String pubname = CPlugin_002_pubname; parseControllerVariables(pubname, event, false); - success = MQTTpublish(event->ControllerIndex, pubname.c_str(), json.c_str(), ControllerSettings.mqtt_retainFlag()); + success = MQTTpublish(event->ControllerIndex, pubname.c_str(), json.c_str(), CPlugin_002_retain); } // if ixd !=0 else { diff --git a/src/_C005.ino b/src/_C005.ino index a27ec8a28..95211674d 100644 --- a/src/_C005.ino +++ b/src/_C005.ino @@ -7,6 +7,10 @@ #define CPLUGIN_ID_005 5 #define CPLUGIN_NAME_005 "Home Assistant (openHAB) MQTT" +String CPlugin_005_pubname; +bool CPlugin_005_mqtt_retainFlag; + + bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String& string) { bool success = false; @@ -37,6 +41,8 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String& MakeControllerSettings(ControllerSettings); LoadControllerSettings(event->ControllerIndex, ControllerSettings); MQTTDelayHandler.configureControllerSettings(ControllerSettings); + CPlugin_005_pubname = ControllerSettings.Publish; + CPlugin_005_mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); break; } @@ -94,15 +100,8 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_SEND: { - String pubname; - bool mqtt_retainFlag; - { - // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); - pubname = ControllerSettings.Publish; - mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); - } + String pubname = CPlugin_005_pubname; + bool mqtt_retainFlag = CPlugin_005_mqtt_retainFlag; if (ExtraTaskSettings.TaskIndex != event->TaskIndex) { String dummy; diff --git a/src/_C006.ino b/src/_C006.ino index d448003f8..0b13d7e95 100644 --- a/src/_C006.ino +++ b/src/_C006.ino @@ -7,6 +7,10 @@ #define CPLUGIN_ID_006 6 #define CPLUGIN_NAME_006 "PiDome MQTT" +String CPlugin_006_pubname; +bool CPlugin_006_mqtt_retainFlag; + + bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& string) { bool success = false; @@ -37,6 +41,8 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& MakeControllerSettings(ControllerSettings); LoadControllerSettings(event->ControllerIndex, ControllerSettings); MQTTDelayHandler.configureControllerSettings(ControllerSettings); + CPlugin_006_pubname = ControllerSettings.Publish; + CPlugin_006_mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); break; } @@ -91,15 +97,8 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& success = false; break; } - String pubname; - bool mqtt_retainFlag; - { - // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); - pubname = ControllerSettings.Publish; - mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); - } + String pubname = CPlugin_006_pubname; + bool mqtt_retainFlag = CPlugin_006_mqtt_retainFlag; statusLED(true); diff --git a/src/_C014.ino b/src/_C014.ino index 881dda91d..825c60a45 100644 --- a/src/_C014.ino +++ b/src/_C014.ino @@ -37,6 +37,9 @@ byte msgCounter=0; // counter for send Messages (currently for information / log only! +String CPlugin_014_pubname; +bool CPlugin_014_mqtt_retainFlag; + // send MQTT Message with complete Topic / Payload bool CPlugin_014_sendMQTTmsg(String& topic, const char* payload, int& errorCounter) { @@ -157,6 +160,8 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& MakeControllerSettings(ControllerSettings); LoadControllerSettings(event->ControllerIndex, ControllerSettings); MQTTDelayHandler.configureControllerSettings(ControllerSettings); + CPlugin_014_pubname = ControllerSettings.Publish; + CPlugin_014_mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); break; } @@ -680,15 +685,8 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_SEND: { - String pubname; - bool mqtt_retainFlag; - { - // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); - pubname = ControllerSettings.Publish; - mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); - } + String pubname = CPlugin_014_pubname; + bool mqtt_retainFlag = CPlugin_014_mqtt_retainFlag; statusLED(true); From 6fc8642e045d3417477a9730b6e92d9110819b8b Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Sat, 20 Jun 2020 18:24:23 +0200 Subject: [PATCH 097/128] [MQTT] More efficient MQTT copy incoming messages --- src/Controller.ino | 28 ++++------------------------ src/Scheduler.ino | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/Controller.ino b/src/Controller.ino index 94cc14627..d38d78eb3 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -109,32 +109,12 @@ void callback(char *c_topic, byte *b_payload, unsigned int length) { return; } - struct EventStruct TempEvent; - // TD-er: This one cannot set the TaskIndex, but that may seem to work out.... hopefully. - TempEvent.String1 = c_topic; - TempEvent.String2.reserve(length); - - for (unsigned int i = 0; i < length; ++i) { - char c = static_cast(*(b_payload + i)); - TempEvent.String2 += c; - } - - /* - if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) { - String log; - log=F("MQTT : Topic: "); - log+=c_topic; - addLog(LOG_LEVEL_DEBUG_MORE, log); - - log=F("MQTT : Payload: "); - log+=TempEvent.String2; - addLog(LOG_LEVEL_DEBUG_MORE, log); - } - */ - protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(enabledMqttController); - schedule_controller_event_timer(ProtocolIndex, CPlugin::Function::CPLUGIN_PROTOCOL_RECV, &TempEvent); + schedule_mqtt_controller_event_timer( + ProtocolIndex, + CPlugin::Function::CPLUGIN_PROTOCOL_RECV, + c_topic, b_payload, length); } /*********************************************************************************************\ diff --git a/src/Scheduler.ino b/src/Scheduler.ino index 4930a2b1c..9d55b52a6 100644 --- a/src/Scheduler.ino +++ b/src/Scheduler.ino @@ -1,5 +1,6 @@ #include "src/Globals/RTC.h" #include "src/DataStructs/RTCStruct.h" +#include "src/DataStructs/ESPEasy_EventStruct.h" #include "src/DataStructs/EventValueSource.h" #include "src/Globals/Device.h" #include "src/Globals/CPlugins.h" @@ -8,6 +9,7 @@ #include "src/Helpers/ESPEasy_time_calc.h" #include "ESPEasy_plugindefs.h" +#include "ESPEasy-Globals.h" #define TIMER_ID_SHIFT 28 @@ -658,6 +660,22 @@ void schedule_controller_event_timer(protocolIndex_t ProtocolIndex, byte Functio } } +void schedule_mqtt_controller_event_timer(protocolIndex_t ProtocolIndex, byte Function, char *c_topic, byte *b_payload, unsigned int length) { + if (validProtocolIndex(ProtocolIndex)) { + const unsigned long mixedId = createSystemEventMixedId(ControllerPluginEnum, ProtocolIndex, Function); + EventQueue.emplace_back(mixedId, EventStruct()); + EventQueue.back().event.String1 = c_topic; + + String& payload = EventQueue.back().event.String2; + payload.reserve(length); + + for (unsigned int i = 0; i < length; ++i) { + char c = static_cast(*(b_payload + i)); + payload += c; + } + } +} + void schedule_notification_event_timer(byte NotificationProtocolIndex, byte Function, struct EventStruct *event) { schedule_event_timer(NotificationPluginEnum, NotificationProtocolIndex, Function, event); } From 21f0cb7fe95508c06184908209010881aee83af7 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 22 Jun 2020 10:32:17 +0200 Subject: [PATCH 098/128] [Controller] Check if MakeControllerSettings failed due to low RAM Add checks to see if allocating the relative large ControllerSettingsStruct failed. This can be caused by either running out of memory or when memory gets fragmented. --- src/Controller.ino | 35 +++++++++++++++++-- src/_C008.ino | 20 +++++++---- src/src/Commands/Blynk.cpp | 5 +++ src/src/Commands/MQTT.cpp | 11 ++++++ .../DataStructs/ControllerSettingsStruct.h | 3 ++ 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/Controller.ino b/src/Controller.ino index d38d78eb3..576a014af 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -136,6 +136,10 @@ bool MQTTConnect(controllerIndex_t controller_idx) { ++mqtt_reconnect_count; MakeControllerSettings(ControllerSettings); + if (!AllocatedControllerSettings()) { + addLog(LOG_LEVEL_ERROR, F("MQTT : Cannot connect, out of RAM")); + return false; + } LoadControllerSettings(controller_idx, ControllerSettings); if (!ControllerSettings.checkHostReachable(true)) { @@ -266,9 +270,29 @@ bool MQTTCheck(controllerIndex_t controller_idx) if (Protocol[ProtocolIndex].usesMQTT) { - if (MQTTclient_should_reconnect || !MQTTclient.connected()) - { - if (MQTTclient_should_reconnect) { + MakeControllerSettings(ControllerSettings); + if (!AllocatedControllerSettings()) { + addLog(LOG_LEVEL_ERROR, F("MQTT : Cannot check, out of RAM")); + return false; + } + + LoadControllerSettings(controller_idx, ControllerSettings); + + // FIXME TD-er: Is this still needed? + /* + #ifdef USES_ESPEASY_NOW + if (!MQTTclient.connected()) { + if (ControllerSettings.enableESPEasyNowFallback()) { + return true; + } + } + #endif + */ + + if (ControllerSettings.isSet()) { + if (MQTTclient_should_reconnect || !MQTTclient.connected()) + { + if (MQTTclient_should_reconnect) { addLog(LOG_LEVEL_ERROR, F("MQTT : Intentional reconnect")); } return MQTTConnect(controller_idx); @@ -458,6 +482,11 @@ void MQTTStatus(const String& status) { // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. MakeControllerSettings(ControllerSettings); + if (!AllocatedControllerSettings()) { + addLog(LOG_LEVEL_ERROR, F("MQTT : Cannot send status, out of RAM")); + return; + } + LoadControllerSettings(enabledMqttController, ControllerSettings); pubname = ControllerSettings.Publish; mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); diff --git a/src/_C008.ino b/src/_C008.ino index 19ddac2ca..7da7d45f9 100644 --- a/src/_C008.ino +++ b/src/_C008.ino @@ -50,6 +50,19 @@ bool CPlugin_008(CPlugin::Function function, struct EventStruct *event, String& case CPlugin::Function::CPLUGIN_PROTOCOL_SEND: { + String pubname; + { + // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. + MakeControllerSettings(ControllerSettings); + if (!AllocatedControllerSettings()) { + addLog(LOG_LEVEL_ERROR, F("C008 : Generic HTTP - Cannot send, out of RAM")); + break; + } + LoadControllerSettings(event->ControllerIndex, ControllerSettings); + pubname = ControllerSettings.Publish; + } + + // Collect the values at the same run, to make sure all are from the same sample byte valueCount = getValueCountFromSensorType(event->sensorType); C008_queue_element element(event, valueCount); @@ -58,13 +71,6 @@ bool CPlugin_008(CPlugin::Function function, struct EventStruct *event, String& PluginCall(PLUGIN_GET_DEVICEVALUENAMES, event, dummy); } - String pubname; - { - // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. - MakeControllerSettings(ControllerSettings); - LoadControllerSettings(event->ControllerIndex, ControllerSettings); - pubname = ControllerSettings.Publish; - } for (byte x = 0; x < valueCount; x++) { diff --git a/src/src/Commands/Blynk.cpp b/src/src/Commands/Blynk.cpp index fb3ac62bb..e91f616f6 100644 --- a/src/src/Commands/Blynk.cpp +++ b/src/src/Commands/Blynk.cpp @@ -66,6 +66,11 @@ String Command_Blynk_Get(struct EventStruct *event, const char *Line) bool Blynk_get(const String& command, controllerIndex_t controllerIndex, float *data) { MakeControllerSettings(ControllerSettings); + if (!AllocatedControllerSettings()) { + addLog(LOG_LEVEL_ERROR, F("Blynk : Cannot run GET, out of RAM")); + return false; + } + LoadControllerSettings(controllerIndex, ControllerSettings); if ((getControllerPass(controllerIndex, ControllerSettings).length() == 0)) { diff --git a/src/src/Commands/MQTT.cpp b/src/src/Commands/MQTT.cpp index 1b47995b5..a487e25d5 100644 --- a/src/src/Commands/MQTT.cpp +++ b/src/src/Commands/MQTT.cpp @@ -34,6 +34,12 @@ String Command_MQTT_Publish(struct EventStruct *event, const char *Line) { // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. MakeControllerSettings(ControllerSettings); + if (!AllocatedControllerSettings()) { + String error = F("MQTT : Cannot publish, out of RAM"); + addLog(LOG_LEVEL_ERROR, error); + return error; + } + LoadControllerSettings(event->ControllerIndex, ControllerSettings); mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); } @@ -81,6 +87,11 @@ String Command_MQTT_Subscribe(struct EventStruct *event, const char* Line) { // Place the ControllerSettings in a scope to free the memory as soon as we got all relevant information. MakeControllerSettings(ControllerSettings); + if (!AllocatedControllerSettings()) { + String error = F("MQTT : Cannot subscribe, out of RAM"); + addLog(LOG_LEVEL_ERROR, error); + return error; + } LoadControllerSettings(event->ControllerIndex, ControllerSettings); mqtt_retainFlag = ControllerSettings.mqtt_retainFlag(); } diff --git a/src/src/DataStructs/ControllerSettingsStruct.h b/src/src/DataStructs/ControllerSettingsStruct.h index c562f3956..53d0e4547 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.h +++ b/src/src/DataStructs/ControllerSettingsStruct.h @@ -159,4 +159,7 @@ typedef std::shared_ptr ControllerSettingsStruct_ptr_t #define MakeControllerSettings(T) ControllerSettingsStruct_ptr_type ControllerSettingsStruct_ptr(new ControllerSettingsStruct()); \ ControllerSettingsStruct& (T) = *ControllerSettingsStruct_ptr; +// Check to see if MakeControllerSettings was successful +#define AllocatedControllerSettings() (ControllerSettingsStruct_ptr.get() != nullptr) + #endif // DATASTRUCTS_CONTROLLERSETTINGSSTRUCT_H From b3574a7706234f762fd8f663b5c8304932934643 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 22 Jun 2020 10:22:43 +0200 Subject: [PATCH 099/128] [MQTT import] Check if MakeControllerSettings failed due to out of RAM --- src/_P037_MQTTImport.ino | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/_P037_MQTTImport.ino b/src/_P037_MQTTImport.ino index 31ffa64f9..9ae62f2fa 100644 --- a/src/_P037_MQTTImport.ino +++ b/src/_P037_MQTTImport.ino @@ -377,19 +377,17 @@ void mqttcallback_037(char* c_topic, byte* b_payload, unsigned int length) return; } - // We generate a temp event structure to pass to the plugins - - struct EventStruct TempEvent; - - TempEvent.String1 = topic; // This is the topic of the message - TempEvent.String2 = payload; // This is the payload - // Here we loop over all tasks and call each 037 plugin with function PLUGIN_IMPORT for (taskIndex_t y = 0; y < TASKS_MAX; y++) { if (Settings.TaskDeviceNumber[y] == PLUGIN_ID_037) // if we have found a 037 device, then give it something to think about! { + // We generate a temp event structure to pass to the plugins + struct EventStruct TempEvent; + + TempEvent.String1 = topic; // This is the topic of the message + TempEvent.String2 = payload; // This is the payload TempEvent.TaskIndex = y; LoadTaskSettings(TempEvent.TaskIndex); TempEvent.BaseVarIndex = y * VARS_PER_TASK; // This is the index in Uservar where values for this task are stored @@ -423,6 +421,11 @@ boolean MQTTConnect_037() return false; // Not connected, so no use in wasting time to connect to a host. } MakeControllerSettings(ControllerSettings); + if (!AllocatedControllerSettings()) { + addLog(LOG_LEVEL_ERROR, F("IMPT : Cannot load controller settings, out of RAM")); + return false; + } + LoadControllerSettings(enabledMqttController, ControllerSettings); if (ControllerSettings.UseDNS) { MQTTclient_037->setServer(ControllerSettings.getHost().c_str(), ControllerSettings.Port); From 2fe22afd3b5f305f5175229daad3789abad01320 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Mon, 22 Jun 2020 13:38:19 +0200 Subject: [PATCH 100/128] Fix merge issue WiFiConnected changed to NetworkConnected --- src/_P044_P1WifiGateway.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_P044_P1WifiGateway.ino b/src/_P044_P1WifiGateway.ino index 4efd832f6..2c4f47a5c 100644 --- a/src/_P044_P1WifiGateway.ino +++ b/src/_P044_P1WifiGateway.ino @@ -64,7 +64,7 @@ struct P044_Task : public PluginTaskData_base { stopServer(); gatewayPort = portnumber; P1GatewayServer = new WiFiServer(portnumber); - if (nullptr != P1GatewayServer && WiFiConnected()) { + if (nullptr != P1GatewayServer && NetworkConnected()) { P1GatewayServer->begin(); if(serverActive(P1GatewayServer)) { addLog(LOG_LEVEL_INFO, String(F("P1 : WiFi server started at port ")) + portnumber); @@ -76,7 +76,7 @@ struct P044_Task : public PluginTaskData_base { } void checkServer() { - if (nullptr != P1GatewayServer && !serverActive(P1GatewayServer) && WiFiConnected()) { + if (nullptr != P1GatewayServer && !serverActive(P1GatewayServer) && NetworkConnected()) { P1GatewayServer->close(); P1GatewayServer->begin(); if(serverActive(P1GatewayServer)) { From 71dc108eda3eef9ddbae4f19cfa4291df732ccbf Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Tue, 23 Jun 2020 00:55:05 +0200 Subject: [PATCH 101/128] [P001 Switch] Reduce stack usage on PLUGIN_WEBFORM_LOAD --- src/_P001_Switch.ino | 76 ++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/src/_P001_Switch.ino b/src/_P001_Switch.ino index 6f963c708..c2cf32533 100644 --- a/src/_P001_Switch.ino +++ b/src/_P001_Switch.ino @@ -164,26 +164,30 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string) globalMapPortStatus[key].previousTask = event->TaskIndex; } - String options[2]; - options[0] = F("Switch"); - options[1] = F("Dimmer"); - int optionValues[2] = { PLUGIN_001_TYPE_SWITCH, PLUGIN_001_TYPE_DIMMER }; - const byte switchtype = P001_getSwitchType(event); - addFormSelector(F("Switch Type"), F("p001_type"), 2, options, optionValues, switchtype); - - if (switchtype == PLUGIN_001_TYPE_DIMMER) { - addFormNumericBox(F("Dim value"), F("p001_dimvalue"), PCONFIG(1), 0, 255); + String options[2]; + options[0] = F("Switch"); + options[1] = F("Dimmer"); + int optionValues[2] = { PLUGIN_001_TYPE_SWITCH, PLUGIN_001_TYPE_DIMMER }; + const byte switchtype = P001_getSwitchType(event); + addFormSelector(F("Switch Type"), F("p001_type"), 2, options, optionValues, switchtype); + + if (switchtype == PLUGIN_001_TYPE_DIMMER) + { + addFormNumericBox(F("Dim value"), F("p001_dimvalue"), PCONFIG(1), 0, 255); + } } - byte choice = PCONFIG(2); - String buttonOptions[3]; - buttonOptions[0] = F("Normal Switch"); - buttonOptions[1] = F("Push Button Active Low"); - buttonOptions[2] = F("Push Button Active High"); - int buttonOptionValues[3] = - { PLUGIN_001_BUTTON_TYPE_NORMAL_SWITCH, PLUGIN_001_BUTTON_TYPE_PUSH_ACTIVE_LOW, PLUGIN_001_BUTTON_TYPE_PUSH_ACTIVE_HIGH }; - addFormSelector(F("Switch Button Type"), F("p001_button"), 3, buttonOptions, buttonOptionValues, choice); + { + byte choice = PCONFIG(2); + String buttonOptions[3]; + buttonOptions[0] = F("Normal Switch"); + buttonOptions[1] = F("Push Button Active Low"); + buttonOptions[2] = F("Push Button Active High"); + int buttonOptionValues[3] = + { PLUGIN_001_BUTTON_TYPE_NORMAL_SWITCH, PLUGIN_001_BUTTON_TYPE_PUSH_ACTIVE_LOW, PLUGIN_001_BUTTON_TYPE_PUSH_ACTIVE_HIGH }; + addFormSelector(F("Switch Button Type"), F("p001_button"), 3, buttonOptions, buttonOptionValues, choice); + } addFormCheckBox(F("Send Boot state"), F("p001_boot"), PCONFIG(3)); @@ -197,15 +201,17 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string) PCONFIG_FLOAT(1) = PLUGIN_001_DOUBLECLICK_MIN_INTERVAL; } - byte choiceDC = PCONFIG(4); - String buttonDC[4]; - buttonDC[0] = F("Disabled"); - buttonDC[1] = F("Active only on LOW (EVENT=3)"); - buttonDC[2] = F("Active only on HIGH (EVENT=3)"); - buttonDC[3] = F("Active on LOW & HIGH (EVENT=3)"); - int buttonDCValues[4] = { PLUGIN_001_DC_DISABLED, PLUGIN_001_DC_LOW, PLUGIN_001_DC_HIGH, PLUGIN_001_DC_BOTH }; + { + byte choiceDC = PCONFIG(4); + String buttonDC[4]; + buttonDC[0] = F("Disabled"); + buttonDC[1] = F("Active only on LOW (EVENT=3)"); + buttonDC[2] = F("Active only on HIGH (EVENT=3)"); + buttonDC[3] = F("Active on LOW & HIGH (EVENT=3)"); + int buttonDCValues[4] = { PLUGIN_001_DC_DISABLED, PLUGIN_001_DC_LOW, PLUGIN_001_DC_HIGH, PLUGIN_001_DC_BOTH }; - addFormSelector(F("Doubleclick event"), F("p001_dc"), 4, buttonDC, buttonDCValues, choiceDC); + addFormSelector(F("Doubleclick event"), F("p001_dc"), 4, buttonDC, buttonDCValues, choiceDC); + } addFormNumericBox(F("Doubleclick max. interval (ms)"), F("p001_dcmaxinterval"), @@ -218,15 +224,17 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string) PCONFIG_FLOAT(2) = PLUGIN_001_LONGPRESS_MIN_INTERVAL; } - byte choiceLP = PCONFIG(5); - String buttonLP[4]; - buttonLP[0] = F("Disabled"); - buttonLP[1] = F("Active only on LOW (EVENT= 10 [NORMAL] or 11 [INVERSED])"); - buttonLP[2] = F("Active only on HIGH (EVENT= 11 [NORMAL] or 10 [INVERSED])"); - buttonLP[3] = F("Active on LOW & HIGH (EVENT= 10 or 11)"); - int buttonLPValues[4] = - { PLUGIN_001_LONGPRESS_DISABLED, PLUGIN_001_LONGPRESS_LOW, PLUGIN_001_LONGPRESS_HIGH, PLUGIN_001_LONGPRESS_BOTH }; - addFormSelector(F("Longpress event"), F("p001_lp"), 4, buttonLP, buttonLPValues, choiceLP); + { + byte choiceLP = PCONFIG(5); + String buttonLP[4]; + buttonLP[0] = F("Disabled"); + buttonLP[1] = F("Active only on LOW (EVENT= 10 [NORMAL] or 11 [INVERSED])"); + buttonLP[2] = F("Active only on HIGH (EVENT= 11 [NORMAL] or 10 [INVERSED])"); + buttonLP[3] = F("Active on LOW & HIGH (EVENT= 10 or 11)"); + int buttonLPValues[4] = + { PLUGIN_001_LONGPRESS_DISABLED, PLUGIN_001_LONGPRESS_LOW, PLUGIN_001_LONGPRESS_HIGH, PLUGIN_001_LONGPRESS_BOTH }; + addFormSelector(F("Longpress event"), F("p001_lp"), 4, buttonLP, buttonLPValues, choiceLP); + } addFormNumericBox(F("Longpress min. interval (ms)"), F("p001_lpmininterval"), From 6408849967e39de6ab4726325c2e7171fc4be2e4 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Tue, 23 Jun 2020 00:56:57 +0200 Subject: [PATCH 102/128] [Blynk] Reduce stack usage on Blynk_get There is still room for improvement as we still try to create the entire string in a fixed size buffer. Maybe we can also send out the data in chunks? Or determine the needed array size at runtime. --- src/src/Commands/Blynk.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/src/Commands/Blynk.cpp b/src/src/Commands/Blynk.cpp index e91f616f6..bd07ce5c0 100644 --- a/src/src/Commands/Blynk.cpp +++ b/src/src/Commands/Blynk.cpp @@ -86,14 +86,17 @@ bool Blynk_get(const String& command, controllerIndex_t controllerIndex, float * // We now create a URI for the request - char request[300] = { 0 }; - sprintf_P(request, - PSTR("GET /%s/%s HTTP/1.1\r\n Host: %s \r\n Connection: close\r\n\r\n"), - getControllerPass(controllerIndex, ControllerSettings).c_str(), - command.c_str(), - ControllerSettings.getHost().c_str()); - addLog(LOG_LEVEL_DEBUG, request); - client.print(request); + { + // Place this stack allocated array in its own scope, as it is quite big. + char request[300] = { 0 }; + sprintf_P(request, + PSTR("GET /%s/%s HTTP/1.1\r\n Host: %s \r\n Connection: close\r\n\r\n"), + getControllerPass(controllerIndex, ControllerSettings).c_str(), + command.c_str(), + ControllerSettings.getHost().c_str()); + addLog(LOG_LEVEL_DEBUG, request); + client.print(request); + } bool success = !ControllerSettings.MustCheckReply; if (ControllerSettings.MustCheckReply || data) { From 41666156d687bd2ba5c35947f89b3e7b954bb2a6 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Tue, 23 Jun 2020 00:57:43 +0200 Subject: [PATCH 103/128] [Web Frontend] Reduce stack usage on DST configuration --- src/WebServer_AdvancedConfigPage.ino | 56 ++++++++++++++++------------ 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/WebServer_AdvancedConfigPage.ino b/src/WebServer_AdvancedConfigPage.ino index a8d48a157..b9bd090f5 100644 --- a/src/WebServer_AdvancedConfigPage.ino +++ b/src/WebServer_AdvancedConfigPage.ino @@ -211,22 +211,6 @@ void handle_advanced() { } void addFormDstSelect(bool isStart, uint16_t choice) { - String weekid = isStart ? F("dststartweek") : F("dstendweek"); - String dowid = isStart ? F("dststartdow") : F("dstenddow"); - String monthid = isStart ? F("dststartmonth") : F("dstendmonth"); - String hourid = isStart ? F("dststarthour") : F("dstendhour"); - - String weeklabel = isStart ? F("Start (week, dow, month)") : F("End (week, dow, month)"); - String hourlabel = isStart ? F("Start (localtime, e.g. 2h→3h)") : F("End (localtime, e.g. 3h→2h)"); - - String week[5] = { F("Last"), F("1st"), F("2nd"), F("3rd"), F("4th") }; - int weekValues[5] = { 0, 1, 2, 3, 4 }; - String dow[7] = { F("Sun"), F("Mon"), F("Tue"), F("Wed"), F("Thu"), F("Fri"), F("Sat") }; - int dowValues[7] = { 1, 2, 3, 4, 5, 6, 7 }; - String month[12] = { F("Jan"), F("Feb"), F("Mar"), F("Apr"), F("May"), F("Jun"), F("Jul"), F("Aug"), F("Sep"), F("Oct"), F("Nov"), F( - "Dec") }; - int monthValues[12] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; - uint16_t tmpstart(choice); uint16_t tmpend(choice); @@ -234,15 +218,39 @@ void addFormDstSelect(bool isStart, uint16_t choice) { time_zone.getDefaultDst_flash_values(tmpstart, tmpend); } TimeChangeRule rule(isStart ? tmpstart : tmpend, 0); - addRowLabel(weeklabel); - addSelector(weekid, 5, week, weekValues, NULL, rule.week); - html_BR(); - addSelector(dowid, 7, dow, dowValues, NULL, rule.dow); - html_BR(); - addSelector(monthid, 12, month, monthValues, NULL, rule.month); + { + String weeklabel = isStart ? F("Start (week, dow, month)") : F("End (week, dow, month)"); + String weekid = isStart ? F("dststartweek") : F("dstendweek"); + String week[5] = { F("Last"), F("1st"), F("2nd"), F("3rd"), F("4th") }; + int weekValues[5] = { 0, 1, 2, 3, 4 }; - addFormNumericBox(hourlabel, hourid, rule.hour, 0, 23); - addUnit(isStart ? F("hour ↷") : F("hour ↶")); + addRowLabel(weeklabel); + addSelector(weekid, 5, week, weekValues, NULL, rule.week); + } + html_BR(); + { + String dowid = isStart ? F("dststartdow") : F("dstenddow"); + String dow[7] = { F("Sun"), F("Mon"), F("Tue"), F("Wed"), F("Thu"), F("Fri"), F("Sat") }; + int dowValues[7] = { 1, 2, 3, 4, 5, 6, 7 }; + + addSelector(dowid, 7, dow, dowValues, NULL, rule.dow); + } + html_BR(); + { + String monthid = isStart ? F("dststartmonth") : F("dstendmonth"); + String month[12] = { F("Jan"), F("Feb"), F("Mar"), F("Apr"), F("May"), F("Jun"), F("Jul"), F("Aug"), F("Sep"), F("Oct"), F("Nov"), F( + "Dec") }; + int monthValues[12] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + + addSelector(monthid, 12, month, monthValues, NULL, rule.month); + } + { + String hourid = isStart ? F("dststarthour") : F("dstendhour"); + String hourlabel = isStart ? F("Start (localtime, e.g. 2h→3h)") : F("End (localtime, e.g. 3h→2h)"); + + addFormNumericBox(hourlabel, hourid, rule.hour, 0, 23); + addUnit(isStart ? F("hour ↷") : F("hour ↶")); + } } void addFormLogLevelSelect(const String& label, const String& id, int choice) From 586d956ab8187886342fa9a42fdd8ddc0cd1e02e Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Tue, 23 Jun 2020 09:11:38 +0200 Subject: [PATCH 104/128] [Python] Update package versions in requirements.txt --- docs/requirements.txt | 4 ++-- requirements.txt | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index d25555bac..d04a885ce 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ recommonmark==0.6.0 -Sphinx==3.0.3 +Sphinx==3.1.1 sphinx-autobuild==0.7.1 sphinx-bootstrap-theme==0.7.1 sphinxcontrib-applehelp==1.0.2 @@ -8,4 +8,4 @@ sphinxcontrib-htmlhelp==1.0.3 sphinxcontrib-jsmath==1.0.1 sphinxcontrib-qthelp==1.0.3 sphinxcontrib-serializinghtml==1.1.4 -sphinxcontrib-websupport==1.2.2 +sphinxcontrib-websupport==1.2.2 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 4d31c39c5..b7fbab683 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ argh==0.26.2 Babel==2.8.0 bottle==0.12.18 cached-property==1.5.1 -certifi==2020.4.5.1 +certifi==2020.6.20 cffi==1.14.0 chardet==3.0.4 click==7.1.2 @@ -13,12 +13,12 @@ docutils==0.16 idna==2.9 imagesize==1.2.0 Jinja2==2.11.2 -livereload==2.6.1 +livereload==2.6.2 MarkupSafe==1.1.1 -marshmallow==3.5.2 +marshmallow==3.6.1 packaging==20.3 pathtools==0.1.2 -platformio>=4.3.3 +platformio>=4.3.4 port-for==0.3.1 pycparser==2.20 pyelftools==0.26 @@ -29,9 +29,9 @@ pyserial==3.4 pytz==2020.1 PyYAML==5.3.1 recommonmark==0.6.0 -requests==2.23.0 +requests==2.24.0 semantic-version==2.8.5 -six==1.14.0 +six==1.15.0 snowballstemmer==2.0.0 tabulate==0.8.7 tornado==6.0.4 From 50b032881f8c201c6bfcde2266b68115c8cea4a2 Mon Sep 17 00:00:00 2001 From: Gijs Noorlander Date: Wed, 24 Jun 2020 13:37:17 +0200 Subject: [PATCH 105/128] addFormSelectorI2C Fix high stack usage (#3130) Fixes: #3130 --- src/WebServer_Markup.ino | 41 +++++++++++++++++++++------------- src/WebServer_Markup_Forms.ino | 10 +++++---- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/WebServer_Markup.ino b/src/WebServer_Markup.ino index ea8308db6..eee1aab8d 100644 --- a/src/WebServer_Markup.ino +++ b/src/WebServer_Markup.ino @@ -57,27 +57,38 @@ void addSelector_options(int optionCount, const String options[], const int indi else { index = x; } - String html; - html.reserve(64); - html += F("