diff --git a/docs/source/Plugin/P016_DeviceConfiguration.png b/docs/source/Plugin/P016_DeviceConfiguration.png index a33895fc9..35b1b4bbc 100644 Binary files a/docs/source/Plugin/P016_DeviceConfiguration.png and b/docs/source/Plugin/P016_DeviceConfiguration.png differ diff --git a/docs/source/Plugin/P016_TSOP4838.rst b/docs/source/Plugin/P016_TSOP4838.rst index b0aa06010..9d582dd63 100644 --- a/docs/source/Plugin/P016_TSOP4838.rst +++ b/docs/source/Plugin/P016_TSOP4838.rst @@ -39,6 +39,8 @@ Sensor * **Receiver buffer size**: For receiving and decoding the data from the sensor, a buffer is needed. For more complex protocols, like often used for Air Conditioner remote controls, a larger buffer may be needed. By default this buffer is dimensioned at 300 bytes (will be rounded up to the next even number when stored), and needs to be enlarged if a message of this intent is shown in the log at INFO level (Either Web or serial log). +* **Event on boffer overflow**: When enabled, will generate an event ``#Overflow=`` when the buffer overflows, so this can be used as a way to handle this exception, f.e. by lighting up a LED or activating a buzzer. The received data won't be processed further, and discarded, when this error occurs. + Content ^^^^^^^ @@ -71,10 +73,7 @@ Code - command map .. note:: Using compile-time options, the **Code - command map** and related options can be disabled. -Data acquisition -~~~~~~~~~~~~~~~~ - -This group of settings, **Single event with all values** settings are standard available configuration items. +.. include:: DataAcquisition.repl Values ~~~~~~ diff --git a/lib/ESPEasySerial/ESPEasySerialPort.h b/lib/ESPEasySerial/ESPEasySerialPort.h index a2b5c2df6..38ec4b840 100644 --- a/lib/ESPEasySerial/ESPEasySerialPort.h +++ b/lib/ESPEasySerial/ESPEasySerialPort.h @@ -20,15 +20,6 @@ enum class ESPEasySerialPort : uint8_t { #if USABLE_SOC_UART_NUM > 2 serial2 = 5, #endif // if USABLE_SOC_UART_NUM > 2 -#if USABLE_SOC_UART_NUM > 3 - serial3 = 10, -#endif -#if USABLE_SOC_UART_NUM > 4 - serial4 = 11, -#endif -#if USABLE_SOC_UART_NUM > 5 - serial5 = 12, -#endif #if USES_SW_SERIAL software = 6, @@ -41,8 +32,17 @@ enum class ESPEasySerialPort : uint8_t { usb_cdc_0 = 8, // usb_cdc_1 = 9, // TD-er: Disable 2nd USB CDC port as it doesn't seem to work well #endif // if USES_USBCDC +#if USABLE_SOC_UART_NUM > 3 + serial3 = 10, +#endif +#if USABLE_SOC_UART_NUM > 4 + serial4 = 11, +#endif +#if USABLE_SOC_UART_NUM > 5 + serial5 = 12, +#endif - MAX_SERIAL_TYPE + MAX_SERIAL_TYPE // Keep enum values in numerical order so MAX_SERIAL_TYPE has a useable value }; diff --git a/src/_P016_IR.ino b/src/_P016_IR.ino index 9e48b0791..c9524b7f6 100644 --- a/src/_P016_IR.ino +++ b/src/_P016_IR.ino @@ -23,6 +23,10 @@ // IRSENDAC,'{"protocol":"COOLIX","power":"on","mode":"dry","fanspeed":"auto","temp":22,"swingv":"max","swingh":"off"}' /** Changelog: + * 2026-06-22 tonhuisman: Add Event on buffer overflow option, guarded with P016_EVENT_ON_ERROR (enabled by default) Event includes the raw + * command length (for what it's worth) + * Deprecate History section in favor of Changelog + * 2025-01-12 tonhuisman: Add support for MQTT AutoDiscovery (not supported for IR receive) * 2024-01-26 uwekaditz: Decode type UNKNOWN was not added to the web settings * Decode types UNKNOWN and UNUSED were mixed up * Workaround for decode type UNKNOWN is not necessary @@ -69,9 +73,7 @@ # define P016_SEND_IR_TO_CONTROLLER false # endif // ifndef P016_SEND_IR_TO_CONTROLLER -// History -// @tonhuisman: 2025-01-12 -// ADD: support for MQTT AutoDiscovery (not supported for IR receive) +// History (deprecated, use Changelog, above) // @uwekaditz: 2024-01-23 // CHG: Use the new property addToQueue in ExecuteCommand_all() due to the lack of resources // NEW: Heap and memory can be reported (P016_CHECK_HEAP) @@ -183,6 +185,7 @@ boolean displayRawToReadableB32Hex(String& outputStr, decode_results results); # endif // ifdef P016_P035_USE_RAW_RAW2 # ifdef PLUGIN_016_DEBUG + void P016_infoLogMemory(const __FlashStringHelper *text) { if (loglevelActiveFor(LOG_LEVEL_INFO)) { addLogMove(LOG_LEVEL_INFO, strformat( @@ -202,8 +205,8 @@ boolean Plugin_016(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_DEVICE_ADD: { auto& dev = Device[++deviceCount]; - dev.Number = PLUGIN_ID_016; - dev.Type = DEVICE_TYPE_SINGLE; + dev.Number = PLUGIN_ID_016; + dev.Type = DEVICE_TYPE_SINGLE; # if P016_SEND_IR_TO_CONTROLLER dev.VType = Sensor_VType::SENSOR_TYPE_STRING; # else // if P016_SEND_IR_TO_CONTROLLER @@ -357,6 +360,9 @@ boolean Plugin_016(uint8_t function, struct EventStruct *event, String& string) addUnit(unit); addFormNote(F("Increase buffer size if IR commands are received incomplete.")); + # if P016_EVENT_ON_ERROR + addFormCheckBox(F("Event on buffer overflow"), F("pErrEvt"), bitRead(PCONFIG_LONG(0), P016_EventOnError)); + # endif addFormSubHeader(F("Content")); @@ -441,7 +447,7 @@ boolean Plugin_016(uint8_t function, struct EventStruct *event, String& string) FormSelectorOptions selector(protocolCount, &decodeTypes[0], &decodeTypeOptions[0]); selector.clearClassName(); selector.addSelector( - getPluginCustomArgName(rowCnt + 0), + getPluginCustomArgName(rowCnt + 0), static_cast(line.CodeDecodeType)); } html_TD(); @@ -460,7 +466,7 @@ boolean Plugin_016(uint8_t function, struct EventStruct *event, String& string) selector.clearClassName(); selector.addSelector( - getPluginCustomArgName(rowCnt + 3), + getPluginCustomArgName(rowCnt + 3), static_cast(line.AlternativeCodeDecodeType)); } html_TD(); @@ -521,6 +527,9 @@ boolean Plugin_016(uint8_t function, struct EventStruct *event, String& string) bitWrite(lSettings, P016_BitExecuteCmd, isFormItemChecked(F("pExecuteCmd"))); # endif // if P016_FEATURE_COMMAND_HANDLING bitWrite(lSettings, P016_BitAcceptUnknownType, isFormItemChecked(F("pAcceptUnknownType"))); + # if P016_EVENT_ON_ERROR + bitWrite(lSettings, P016_EventOnError, isFormItemChecked(F("pErrEvt"))); + # endif bEnableIRcodeAdding = true; PCONFIG_LONG(0) = lSettings; @@ -644,8 +653,15 @@ boolean Plugin_016(uint8_t function, struct EventStruct *event, String& string) if (results.overflow) { - addLog(LOG_LEVEL_ERROR, F("IR: WARNING, IR code is too big for buffer. Try pressing the transmiter button only momenteraly")); + addLog(LOG_LEVEL_ERROR, F("IR: WARNING, IR code is too big for buffer. Try pressing the transmitter button only momentarily")); success = false; + + # if P016_EVENT_ON_ERROR + + if (bitRead(PCONFIG_LONG(0), P016_EventOnError)) { + eventQueue.add(event->TaskIndex, F("Overflow"), results.rawlen); + } + # endif // if P016_EVENT_ON_ERROR break; // Do not continue and risk hanging the ESP } diff --git a/src/_P020_Ser2Net.ino b/src/_P020_Ser2Net.ino index a7b73e0f9..5c302a6cf 100644 --- a/src/_P020_Ser2Net.ino +++ b/src/_P020_Ser2Net.ino @@ -8,6 +8,7 @@ /************ * Changelog: + * 2026-07-11 tonhuisman: Send also Derived values when sending the event with received data, when enabled and available * 2025-03-26 tonhuisman: Add optional receiving (relaying) of UDP data to Serial. Uses the same port as configured for the (default) TCP * connection. Available on ESP32 only. * Can be enabled for ESP8266 in a Custom build by adding #define P020_USE_PROTOCOL 1 diff --git a/src/src/Controller_config/C018_config.cpp b/src/src/Controller_config/C018_config.cpp index 77369d084..d36d17888 100644 --- a/src/src/Controller_config/C018_config.cpp +++ b/src/src/Controller_config/C018_config.cpp @@ -115,13 +115,13 @@ void C018_ConfigStruct::webform_load(C018_data_struct *C018_data) { addTableSeparator(F("Serial Port Configuration"), 2, 3); - serialHelper_webformLoad(port, rxpin, txpin, true); + serialHelper_webformLoad(port, rxpin, txpin); // Show serial port selection addFormPinSelect(PinSelectPurpose::Generic_input, formatGpioName_serialRX(false), F("taskdevicepin1"), rxpin); addFormPinSelect(PinSelectPurpose::Generic_output, formatGpioName_serialTX(false), F("taskdevicepin2"), txpin); - html_add_script(F("document.getElementById('serPort').onchange();"), false); + html_add_script(F("elId('serPort').onchange();"), false); addFormNumericBox(F("Baudrate"), F(C018_BAUDRATE_LABEL), baudrate, 2400, 115200); addUnit(F("baud")); diff --git a/src/src/Controller_config/C023_config.cpp b/src/src/Controller_config/C023_config.cpp index 9c04994dd..069002ab1 100644 --- a/src/src/Controller_config/C023_config.cpp +++ b/src/src/Controller_config/C023_config.cpp @@ -121,13 +121,13 @@ void C023_ConfigStruct::webform_load(C023_data_struct *C023_data) { addTableSeparator(F("Serial Port Configuration"), 2, 3); - serialHelper_webformLoad(port, rxpin, txpin, true); + serialHelper_webformLoad(port, rxpin, txpin); // Show serial port selection addFormPinSelect(PinSelectPurpose::Generic_input, formatGpioName_serialRX(false), F("taskdevicepin1"), rxpin); addFormPinSelect(PinSelectPurpose::Generic_output, formatGpioName_serialTX(false), F("taskdevicepin2"), txpin); - html_add_script(F("document.getElementById('serPort').onchange();"), false); + html_add_script(F("elId('serPort').onchange();"), false); addFormNumericBox(F("Baudrate"), F(C023_BAUDRATE_LABEL), baudrate, 2400, 115200); addUnit(F("baud")); diff --git a/src/src/Helpers/_Plugin_Helper_serial.cpp b/src/src/Helpers/_Plugin_Helper_serial.cpp index 7ab423bac..556435a55 100644 --- a/src/src/Helpers/_Plugin_Helper_serial.cpp +++ b/src/src/Helpers/_Plugin_Helper_serial.cpp @@ -120,14 +120,17 @@ String serialHelper_getSerialTypeLabel(struct EventStruct *event) { } #ifndef DISABLE_SC16IS752_Serial -void serialHelper_addI2CuartSelectors(int address, int channel) { +void serialHelper_addI2CuartSelectors(int address, int channel, String id, String uid) { # define SC16IS752_I2C_ADDRESSES 16 # define SC16IS752_I2C_BASE_ADDR (0x90 >> 1) # define SC16IS752_CHANNELS 2 # define SC16IS752_CHANNEL_A 0x00 # define SC16IS752_CHANNEL_B 0x01 { - String id = F("i2cuart_addr"); + if (id.isEmpty()) { + id = F("i2cuart_addr"); + } + addRowLabel_tr_id(F("I2C Address"), id); do_addSelector_Head(id, F(""), EMPTY_STRING, false); @@ -163,28 +166,53 @@ void serialHelper_addI2CuartSelectors(int address, int channel) { SC16IS752_CHANNEL_B, }; */ + if (uid.isEmpty()) { + uid = F("i2cuart_ch"); + } + const FormSelectorOptions selector(NR_ELEMENTS(chOptions), chOptions); - selector.addFormSelector(F("Channel"), F("i2cuart_ch"), channel); + selector.addFormSelector(F("Channel"), uid, channel); } } #endif // ifndef DISABLE_SC16IS752_Serial void serialHelper_webformLoad(struct EventStruct *event) { - serialHelper_webformLoad(event, true); + serialHelper_webformLoad(event, INCLUDE_DEFAULT_SERIAL); } // These helper functions were made to create a generic interface to setup serial port config. // See issue #2343 and Pull request https://github.com/letscontrolit/ESPEasy/pull/2352 // For now P020 and P044 have been reverted to make them work again. -void serialHelper_webformLoad(struct EventStruct *event, bool allowSoftwareSerial) { +void serialHelper_webformLoad(struct EventStruct *event, uint8_t allowedSerial) { serialHelper_webformLoad(static_cast(CONFIG_PORT), serialHelper_getRxPin(event), serialHelper_getTxPin(event), - allowSoftwareSerial); + allowedSerial); } -void serialHelper_webformLoad(ESPEasySerialPort port, int rxPinDef, int txPinDef, bool allowSoftwareSerial) { +void serialHelper_webformLoad(ESPEasySerialPort port, int rxPinDef, int txPinDef, uint8_t allowedSerial) { + serialHelper_webformLoad(port, + rxPinDef, + txPinDef, + allowedSerial, + F("Serial Port"), + F("serPort"), + EMPTY_STRING, + EMPTY_STRING, + EMPTY_STRING, + EMPTY_STRING); +} +void serialHelper_webformLoad(ESPEasySerialPort port, + int rxPinDef, + int txPinDef, + uint8_t allowedSerial, + String label, + String id, + String pin1Var, + String pin2Var, + String i2c1Var, + String i2c2Var) { // Field for I2C addr & RX are shared // Field for channel and TX are shared #ifdef ESP8266 @@ -194,11 +222,19 @@ void serialHelper_webformLoad(ESPEasySerialPort port, int rxPinDef, int txPinDef // 'none';document.getElementById('tr_taskdevicepin1').style.display = style;document.getElementById('tr_taskdevicepin2').style.display = // style;document.getElementById('tr_i2cuart_addr').style.display = i2cstyle;document.getElementById('tr_i2cuart_ch').style.display = // i2cstyle;}"), - html_add_script(F("function serialPortChanged(e){var t=6==e.value?'':'none',l=1==e.value?'':'none';" - "document.getElementById('tr_taskdevicepin1').style.display=t," - "document.getElementById('tr_taskdevicepin2').style.display=t," - "document.getElementById('tr_i2cuart_addr').style.display=l," - "document.getElementById('tr_i2cuart_ch').style.display=l}"), + html_add_script(F("function elId(e){return document.getElementById(e)}\n" + "function serialPortChanged(e,p1=\"taskdevicepin1\",p2=\"taskdevicepin2\",ia=\"i2cuart_addr\",ic=\"i2cuart_ch\")" + "{var t=6==e.value?'':'none'" + #if USES_I2C_SC16IS752 + ",l=1==e.value?'':'none';" + #endif // if USES_I2C_SC16IS752 + "elId('tr_'+p1).style.display=t," + "elId('tr_'+p2).style.display=t," + #if USES_I2C_SC16IS752 + "elId('tr_'+ia).style.display=l," + "elId('tr_'+ic).style.display=l}" + #endif // if USES_I2C_SC16IS752 + ), false); #endif // ifdef ESP8266 #ifdef ESP32 @@ -208,47 +244,53 @@ void serialHelper_webformLoad(ESPEasySerialPort port, int rxPinDef, int txPinDef // elem.value == 1 ? '' : 'none';document.getElementById('tr_taskdevicepin1').style.display = // style;document.getElementById('tr_taskdevicepin2').style.display = style;document.getElementById('tr_i2cuart_addr').style.display = // i2cstyle;document.getElementById('tr_i2cuart_ch').style.display = i2cstyle;}"), - html_add_script(F("function serialPortChanged(elem) {" -" var style = 'none';" -" var i2cstyle = elem.value == 1 ? '' : 'none';" -" if (elem.value == 2) {" -//" document.querySelector('#taskdevicepin1').value =" STRINGIFY(SOC_RX0) ";" -//" document.querySelector('#taskdevicepin2').value =" STRINGIFY(SOC_TX0) ";" -" style = '';" -# if USABLE_SOC_UART_NUM > 1 -" } else if (elem.value == 4) {" -//" document.querySelector('#taskdevicepin1').value =" STRINGIFY(SOC_RX1) ";" -//" document.querySelector('#taskdevicepin2').value =" STRINGIFY(SOC_TX1) ";" -" style = '';" -#endif -# if USABLE_SOC_UART_NUM > 2 -" } else if (elem.value == 5) {" -//" document.querySelector('#taskdevicepin1').value =" STRINGIFY(SOC_RX2) ";" -//" document.querySelector('#taskdevicepin2').value =" STRINGIFY(SOC_TX2) ";" -" style = '';" -#endif -# if USABLE_SOC_UART_NUM > 3 -" } else if (elem.value == 10) {" -" style = '';" -#endif -# if USABLE_SOC_UART_NUM > 4 -" } else if (elem.value == 11) {" -" style = '';" -#endif -# if USABLE_SOC_UART_NUM > 5 -" } else if (elem.value == 12) {" -" style = '';" -#endif -#if USES_SW_SERIAL -" } else if (elem.value == 6) {" -" style = '';" -#endif -" }" -" document.getElementById('tr_taskdevicepin1').style.display = style;" -" document.getElementById('tr_taskdevicepin2').style.display = style;" -" document.getElementById('tr_i2cuart_addr').style.display = i2cstyle;" -" document.getElementById('tr_i2cuart_ch').style.display = i2cstyle;" -"}"), + html_add_script(F("function elId(e){return document.getElementById(e)}\n" + "function serialPortChanged(elem,p1=\"taskdevicepin1\",p2=\"taskdevicepin2\",ia=\"i2cuart_addr\",ic=\"i2cuart_ch\") {" + "var v=elem.value;" + "var st='none';" + #if USES_I2C_SC16IS752 + "var i2cst=v==1?'':'none';" + #endif // if USES_I2C_SC16IS752 + "if (v==2) {" + // "document.querySelector('#'+p1).value =" STRINGIFY(SOC_RX0) ";" + // "document.querySelector('#'+p2).value =" STRINGIFY(SOC_TX0) ";" + "st='';" + # if USABLE_SOC_UART_NUM > 1 + "} else if (v==4) {" + // "document.querySelector('#'+p1).value =" STRINGIFY(SOC_RX1) ";" + // "document.querySelector('#'+p2).value =" STRINGIFY(SOC_TX1) ";" + "st='';" + #endif + # if USABLE_SOC_UART_NUM > 2 + "} else if (v==5) {" + //"document.querySelector('#'+p1).value =" STRINGIFY(SOC_RX2) ";" + //"document.querySelector('#'+p2).value =" STRINGIFY(SOC_TX2) ";" + "st='';" + #endif + # if USABLE_SOC_UART_NUM > 3 + "} else if (v==10) {" + "st='';" + #endif + # if USABLE_SOC_UART_NUM > 4 + "} else if (v==11) {" + "st='';" + #endif + # if USABLE_SOC_UART_NUM > 5 + "} else if (v==12) {" + "st='';" + #endif + #if USES_SW_SERIAL + " } else if (v==6) {" + "st='';" + #endif + "}" + "elId('tr_'+p1).style.display=st;" + "elId('tr_'+p2).style.display=st;" + #if USES_I2C_SC16IS752 + "elId('tr_'+ia).style.display=i2cst;" + "elId('tr_'+ic).style.display=i2cst;" + #endif // if USES_I2C_SC16IS752 + "}"), true); #endif // ifdef ESP32 @@ -296,7 +338,7 @@ void serialHelper_webformLoad(ESPEasySerialPort port, int rxPinDef, int txPinDef constexpr int NR_ESPEASY_SERIAL_TYPES = NR_ELEMENTS(ids); String options[NR_ESPEASY_SERIAL_TYPES]; -// String attr[NR_ESPEASY_SERIAL_TYPES]; + String attr[NR_ESPEASY_SERIAL_TYPES]; for (int i = 0; (i < NR_ESPEASY_SERIAL_TYPES); ++i) { ESPEasySerialPort serType = static_cast(ids[i]); @@ -324,16 +366,47 @@ void serialHelper_webformLoad(ESPEasySerialPort port, int rxPinDef, int txPinDef } #endif options[i] = option; + if (!(allowedSerial & INCLUDE_HW_SERIAL) && isHWserial(serType)) { + attr[i] = F("disabled"); + } + if (!(allowedSerial & INCLUDE_SW_SERIAL) && (serType == ESPEasySerialPort::software)) { + attr[i] = F("disabled"); + } + #if USES_I2C_SC16IS752 + if (!(allowedSerial & INCLUDE_I2C_SERIAL) && (serType == ESPEasySerialPort::sc16is752)) { + attr[i] = F("disabled"); + } + #endif // if USES_I2C_SC16IS752 + #if USES_HWCDC || USES_USBCDC + if (!(allowedSerial & INCLUDE_CDC_SERIAL) + #if USES_HWCDC + && (serType == ESPEasySerialPort::usb_hw_cdc) + #endif // if USES_HWCDC + #if USES_USBCDC + && (serType == ESPEasySerialPort::usb_cdc_0) + #endif // if USES_USBCDC + ) { + attr[i] = F("disabled"); + } + #endif // if USES_HWCDC || USES_USBCDC } - FormSelectorOptions selector(NR_ESPEASY_SERIAL_TYPES, options, ids); + FormSelectorOptions selector(NR_ESPEASY_SERIAL_TYPES, options, ids, attr); // Script to toggle GPIO visibility when changing selection. - selector.onChangeCall = F("serialPortChanged(this)"); + if (pin1Var.isEmpty() && pin2Var.isEmpty() && i2c1Var.isEmpty() && i2c2Var.isEmpty()) { + selector.onChangeCall = F("serialPortChanged(this)"); + } else { + selector.onChangeCall = strformat(F("serialPortChanged(this,\"%s\",\"%s\",\"%s\",\"%s\")"), + pin1Var.c_str(), pin2Var.c_str(), i2c1Var.c_str(), i2c2Var.c_str()); + } selector.addFormSelector( - F("Serial Port"), F("serPort"), - static_cast(ESPeasySerialType::getSerialType(port, rxPinDef, txPinDef))); + label, id, + // static_cast(ESPeasySerialType::getSerialType(port, rxPinDef, txPinDef))); + static_cast(port)); #if USES_I2C_SC16IS752 - serialHelper_addI2CuartSelectors(rxPinDef, txPinDef); + if (allowedSerial & INCLUDE_I2C_SERIAL) { + serialHelper_addI2CuartSelectors(rxPinDef, txPinDef, i2c1Var, i2c2Var); + } #endif // ifndef DISABLE_SC16IS752_Serial #ifdef ESP8266 diff --git a/src/src/Helpers/_Plugin_Helper_serial.h b/src/src/Helpers/_Plugin_Helper_serial.h index c889331ef..acc5e5ac2 100644 --- a/src/src/Helpers/_Plugin_Helper_serial.h +++ b/src/src/Helpers/_Plugin_Helper_serial.h @@ -8,6 +8,13 @@ #include +constexpr uint8_t INCLUDE_SW_SERIAL = (1 << 0); +constexpr uint8_t INCLUDE_HW_SERIAL = (1 << 1); // Ignored for now, always enabled +constexpr uint8_t INCLUDE_I2C_SERIAL = (1 << 2); +constexpr uint8_t INCLUDE_CDC_SERIAL = (1 << 3); +constexpr uint8_t INCLUDE_ALL_SERIAL = (INCLUDE_SW_SERIAL | INCLUDE_HW_SERIAL | INCLUDE_I2C_SERIAL | INCLUDE_CDC_SERIAL); +constexpr uint8_t INCLUDE_DEFAULT_SERIAL = INCLUDE_ALL_SERIAL; +constexpr uint8_t INCLUDE_NOT_CDC_SERIAL = (INCLUDE_SW_SERIAL | INCLUDE_HW_SERIAL | INCLUDE_I2C_SERIAL); struct ESPeasySerialType; @@ -41,8 +48,10 @@ ESPEasySerialPort serialHelper_getSerialType(struct EventStruct *event); String serialHelper_getSerialTypeLabel(struct EventStruct *event); #ifndef DISABLE_SC16IS752_Serial -void serialHelper_addI2CuartSelectors(int address, - int channel); +void serialHelper_addI2CuartSelectors(int address, + int channel, + String id = "", + String uid = ""); #endif // ifndef DISABLE_SC16IS752_Serial void serialHelper_webformLoad(struct EventStruct *event); @@ -51,12 +60,23 @@ void serialHelper_webformLoad(struct EventStruct *event); // See issue #2343 and Pull request https://github.com/letscontrolit/ESPEasy/pull/2352 // For now P020 and P044 have been reverted to make them work again. void serialHelper_webformLoad(struct EventStruct *event, - bool allowSoftwareSerial); + uint8_t allowedSerial); void serialHelper_webformLoad(ESPEasySerialPort port, int rxPinDef, int txPinDef, - bool allowSoftwareSerial); + uint8_t allowedSerial = INCLUDE_DEFAULT_SERIAL); + +void serialHelper_webformLoad(ESPEasySerialPort port, + int rxPinDef, + int txPinDef, + uint8_t allowedSerial, + String label, + String id, + String pin1Var, + String pin2Var, + String i2c1Var, + String i2c2Var); void serialHelper_webformSave(uint8_t& port, int8_t & rxPin, diff --git a/src/src/PluginStructs/P016_data_struct.h b/src/src/PluginStructs/P016_data_struct.h index 10f84acc3..d87ac8b6b 100644 --- a/src/src/PluginStructs/P016_data_struct.h +++ b/src/src/PluginStructs/P016_data_struct.h @@ -19,10 +19,15 @@ # endif // if defined(P016_CHECK_HEAP) # endif // if defined(LIMIT_BUILD_SIZE) +# ifndef P016_EVENT_ON_ERROR +# define P016_EVENT_ON_ERROR 1 +# endif // ifndef P016_EVENT_ON_ERROR + // bit definition in PCONFIG_LONG(0) # define P016_BitAddNewCode 0 // Add automatically new code into Code of the command structure # define P016_BitExecuteCmd 1 // Execute command if received code matches Code or AlternativeCode of the command structure # define P016_BitAcceptUnknownType 2 // Accept unknown DecodeType as valid IR code (UNKNOWH is only the result of DECODE_HASH) +# define P016_EventOnError 3 // Generate #Overflow event on buffer overflow # define P16_Nlines 10 // The number of different lines which can be displayed - each line is 64 chars max # define P16_Nchars 64 // max chars per command line @@ -57,6 +62,7 @@ typedef struct { char Command[P16_Nchars] = { 0 }; uint32_t Code = 0; // received code (can be added automatically) uint32_t AlternativeCode = 0; // alternative code fpr the same command + } tCommandLinesV1; # endif // ifdef P16_SETTINGS_V1 @@ -75,7 +81,9 @@ struct tCommandLinesV2 { decode_type_t AlternativeCodeDecodeType = decode_type_t::UNUSED; uint16_t CodeFlags = 0; uint16_t AlternativeCodeFlags = 0; + }; + # endif // if P016_FEATURE_COMMAND_HANDLING struct P016_data_struct : public PluginTaskData_base { @@ -132,6 +140,7 @@ private: # ifdef P016_CHECK_HEAP void CheckHeap(String dbgtxt); # endif // ifdef P016_CHECK_HEAP + }; #endif // ifdef USES_P016 diff --git a/src/src/PluginStructs/P020_data_struct.cpp b/src/src/PluginStructs/P020_data_struct.cpp index d30b6b708..becf5a6d8 100644 --- a/src/src/PluginStructs/P020_data_struct.cpp +++ b/src/src/PluginStructs/P020_data_struct.cpp @@ -297,7 +297,8 @@ void P020_Task::handleSerialIn(struct EventStruct *event) { bool done = false; char ch; - do { + do + { if (ser2netSerial->available()) { if ((serial_processing != P020_Events::P1WiFiGateway) // P1 handling without this check && (serial_buffer.length() > static_cast(P020_RX_BUFFER))) { @@ -357,7 +358,7 @@ void P020_Task::handleSerialIn(struct EventStruct *event) { blinkLED(); - rulesEngine(serial_buffer); + rulesEngine(serial_buffer, event); ser2netClient.PR_9453_FLUSH_TO_CLEAR(); clearBuffer(); # ifndef BUILD_NO_DEBUG @@ -375,14 +376,16 @@ void P020_Task::discardSerialIn() { } // We can also use the rules engine for local control! -void P020_Task::rulesEngine(const String& message) { +void P020_Task::rulesEngine(const String& message, struct EventStruct *event) { if (!Settings.UseRules || message.isEmpty() || (P020_Events::None == serial_processing)) { return; } - int NewLinePos = 0; - uint16_t StartPos = 0; + int NewLinePos = 0; + uint16_t StartPos = 0; + bool eventSent = false; NewLinePos = handleMultiLine ? message.indexOf('\n', StartPos) : message.length(); - do { + do + { if (NewLinePos < 0) { NewLinePos = message.length(); } @@ -394,11 +397,14 @@ void P020_Task::rulesEngine(const String& message) { NewLinePos--; } - switch (serial_processing) { - case P020_Events::None: { break; } - case P020_Events::Generic: { // Generic + switch (serial_processing) + { + case P020_Events::None: + break; + case P020_Events::Generic: // Generic + { if (NewLinePos > StartPos) { - eventString = '!'; // F("!Serial"); + eventString = '!'; // F("!Serial"); if (_serialId) { eventString += ESPEasySerialPort_toString(_port, true); @@ -421,8 +427,9 @@ void P020_Task::rulesEngine(const String& message) { } break; } - case P020_Events::RFLink: { // RFLink - StartPos += 6; // RFLink, strip 20;xx; from incoming message + case P020_Events::RFLink: // RFLink + { + StartPos += 6; // RFLink, strip 20;xx; from incoming message if (((NewLinePos - StartPos) >= 8) && message.substring(StartPos, StartPos + 8) @@ -442,6 +449,7 @@ void P020_Task::rulesEngine(const String& message) { eventString += message.substring(StartPos, NewLinePos); } eventQueue.addMove(std::move(eventString)); + eventSent = true; break; } case P020_Events::P1WiFiGateway: // P1 WiFi Gateway @@ -466,6 +474,7 @@ void P020_Task::rulesEngine(const String& message) { if (!eventString.isEmpty()) { eventQueue.add(eventString); + eventSent = true; } NewLinePos = message.indexOf('\n', StartPos); @@ -473,6 +482,13 @@ void P020_Task::rulesEngine(const String& message) { NewLinePos = message.length(); } } while (handleMultiLine && NewLinePos > StartPos); + + # if FEATURE_STRING_VARIABLES + + if (eventSent) { + sendData(event); // Send derived values + } + # endif // if FEATURE_STRING_VARIABLES } bool P020_Task::isInit() const { @@ -483,10 +499,7 @@ bool P020_Task::isInit() const { ) && nullptr != ser2netSerial; } -void P020_Task::sendConnectedEvent(bool connected) -{ - eventQueue.add(_taskIndex, F("Client"), (connected ? 1 : 0)); -} +void P020_Task::sendConnectedEvent(bool connected) { eventQueue.add(_taskIndex, F("Client"), (connected ? 1 : 0)); } void P020_Task::blinkLED() { if (_ledEnabled) { @@ -605,7 +618,8 @@ bool P020_Task::handleP1Char(char ch) { bool done = false; bool invalid = false; - switch (_state) { + switch (_state) + { case ParserState::WAITING: if (ch == P020_DATAGRAM_START_CHAR) { diff --git a/src/src/PluginStructs/P020_data_struct.h b/src/src/PluginStructs/P020_data_struct.h index c322f927c..8c3f2784c 100644 --- a/src/src/PluginStructs/P020_data_struct.h +++ b/src/src/PluginStructs/P020_data_struct.h @@ -79,6 +79,7 @@ enum class P020_Events : uint8_t { Generic = 1u, RFLink = 2u, P1WiFiGateway = 3u, + }; # if P020_USE_PROTOCOL @@ -86,7 +87,9 @@ enum class P020_Protocol_e : uint8_t { TCP = 0u, UDP = 1u, TCP_UDP = 2u, + }; + # endif // if P020_USE_PROTOCOL struct P020_Task : public PluginTaskData_base { @@ -94,6 +97,7 @@ struct P020_Task : public PluginTaskData_base { WAITING, READING, CHECKSUM + }; P020_Task(struct EventStruct *event); @@ -120,7 +124,8 @@ struct P020_Task : public PluginTaskData_base { void handleSerialIn(struct EventStruct *event); void handleClientIn(struct EventStruct *event); void discardSerialIn(); - void rulesEngine(const String& message); + void rulesEngine(const String & message, + struct EventStruct *event); bool isInit() const; @@ -187,6 +192,7 @@ struct P020_Task : public PluginTaskData_base { bool _eventAsHex = false; ESPEasySerialPort _port; + }; #endif // ifdef USES_P020 diff --git a/src/src/PluginStructs/P129_data_struct.cpp b/src/src/PluginStructs/P129_data_struct.cpp index 8d67c3e90..66e6dcdfd 100644 --- a/src/src/PluginStructs/P129_data_struct.cpp +++ b/src/src/PluginStructs/P129_data_struct.cpp @@ -13,7 +13,6 @@ P129_data_struct::P129_data_struct(int8_t dataPin, uint8_t chipCount) : _dataPin(dataPin), _clockPin(clockPin), _enablePin(enablePin), _loadPin(loadPin), _chipCount(chipCount) {} - bool P129_data_struct::plugin_init(struct EventStruct *event) { if (isInitialized()) { for (uint8_t i = 0; i < P129_MAX_CHIP_COUNT; ++i) { // Clear entire buffer @@ -29,6 +28,7 @@ bool P129_data_struct::plugin_init(struct EventStruct *event) { if (validGpio(_enablePin)) { DIRECT_pinWrite(_enablePin, HIGH); } + plugin_read(event); // Prime data return true; } return false; @@ -74,6 +74,7 @@ enum class p129_subcommands_e { setchipcount, samplefrequency, eventperpin + }; bool P129_data_struct::plugin_write(struct EventStruct *event, @@ -91,7 +92,8 @@ bool P129_data_struct::plugin_write(struct EventStruct *event, return false; } - switch (static_cast(command_i)) { + switch (static_cast(command_i)) + { case p129_subcommands_e::pinevent: { // ShiftIn,pinevent,,<0|1> const uint8_t pin = event->Par2 - 1; diff --git a/src/src/WebServer/AdvancedConfigPage.cpp b/src/src/WebServer/AdvancedConfigPage.cpp index 95f0d9631..cf5ffa115 100644 --- a/src/src/WebServer/AdvancedConfigPage.cpp +++ b/src/src/WebServer/AdvancedConfigPage.cpp @@ -253,8 +253,7 @@ void handle_advanced() { serialHelper_webformLoad( static_cast(Settings.console_serial_port), Settings.console_serial_rxpin, - Settings.console_serial_txpin, - true); + Settings.console_serial_txpin); // Show serial port selection addFormPinSelect( @@ -268,7 +267,7 @@ void handle_advanced() { F("taskdevicepin2"), Settings.console_serial_txpin); - html_add_script(F("document.getElementById('serPort').onchange();"), false); + html_add_script(F("elId('serPort').onchange();"), false); #if USES_ESPEASY_CONSOLE_FALLBACK_PORT addFormCheckBox(LabelType::CONSOLE_FALLBACK_TO_SERIAL0); #endif