Merge pull request #5580 from TD-er/bugfix/Webserver_dedup_stdtmpl

[Webserver] Deduplicate & simplify code handling begin/end of web pages
This commit is contained in:
TD-er
2026-07-13 21:47:45 +02:00
committed by GitHub
31 changed files with 305 additions and 249 deletions
+107
View File
@@ -25,19 +25,126 @@ Maintainer: |NW005_maintainer|
Description
-----------
The PPP network interface allows to use one of many available GSM/GPRS/WCDMA/HSDPA/HSUPA/PSPA/LTE/4g modem modules to allow an ESPEasy node to be used literally "in the field".
When connected, a module offers a direct connection to the internet. Keep in mind this connection is like any other device behind a NAT router, thus no connection possible from the internet to the device itself.
N.B. There are exceptions to this, for example when using a custom service with your own SIM cards. These kinds of configurations are not tested, but also not actively disabled in ESPEasy.
All supported modules need to have an UART interface over which the ESP communicates using AT-commands.
Currently supported PPP modules (others may also work):
* SIMCOM A76xx
* SIMCOM A7070/A7000
* BG96
* SIM800 (obsolete)
* Generic
The "Generic" option likely does work on most modules, however some specifics may not work.
Configuration
-------------
PPP modems need to communicate via a serial port.
It is strongly adviced to use flow control where possible and use hardware serial (not software serial).
Most SIMCOM modules use 115200 as default baudrate, unless it is configured otherwise.
Make sure to have at least the reset pin of the PPP modem connected, or at the very least have the option to power cycle the modem. But this should be used only as last resort as the modem may take minutes to find a network after a power cycle.
LTE modules can draw a significant high current while connecting to the provider network.
This can be upto 2 Ampere. So make sure either the module has ample capacitors (e.g. 330 uF ... 470 uF) and preferrably also a soft-start circuit when enable power to the PPP modem.
.. note:: Never run these PPP modem modules without an antenna connected!
Device Settings
^^^^^^^^^^^^^^^
.. image:: NW005_DeviceSettings.png
DTR pin
-------
For SIMCOM A76xx modems, there is an emergency fallback option possible to regain access to the modem while the modem is in 'data' mode and not in 'console' mode.
ESPEasy does send the required AT-command ``AT&D1`` right before starting the network connection to enable this fallback in the modem settings.
These PPP modems do have a console/command mode and a data mode.
When entering AT commands, the modem must be pulled out of the data mode. However when the connection between the ESP and the modem got interrupted while the modem is still in data mode, it is impossible to regain access to the modem unless it is reset or power cycled.
This may occur when the ESP crashes or reboots without properly terminating the PPP network connection, or when the serial link between the ESP and the modem is not using flow control (which is strongly suggested to use!).
Not all modem boards do have the DTR pin exposed. So make sure to either have the reset pin available, or as a last resort, have the option to power cycle the modem board.
Power cycling should be considered as last resort to regain access to the modem, as it may take several minutes for a modem to get connected again after a power cycle.
Connection Settings
^^^^^^^^^^^^^^^^^^^
These settings are optional.
.. note:: These specific settings are stored in the file ``devsecurity.dat`` as these are specific to this device.
Access Point Name (APN)
-----------------------
The APN is like a default gateway for your device to connect to another network.
Typically the default APN as stored in the SIM card, or sent by the provider when setting up the connection, is just fine.
For some use cases, it may be required to set a specific APN, to override the pre-configured one stored in the SIM card.
A provider may offer several APNs, for example to connect to a specific customer network or to handle the traffic differently.
Whether or not this is even useful to change depends on the use case and the specific provider.
SIM Card Pin
------------
A SIM card often has some 4-digit pin, which must be entered when powering up the device.
If needed, the Pin number can be entered here.
Modem State
^^^^^^^^^^^
.. image:: NW005_ModemState.png
UE System Information
^^^^^^^^^^^^^^^^^^^^^
.. image:: NW005_UE_SystemInformation.png
Useful AT commands
^^^^^^^^^^^^^^^^^^
The command ``ppp,write,<AT-command>`` can be used to interact directly with the modem.
.. note:: The displayed output on the web interface often also includes the ``OK`` at the end. This is not part of the reply, but was originally printed on a separate line. However the way how these outputs are shown on the "Command Output" window, the extra newlines have been stripped from the response. The log on the serial port will output these on separate lines.
* ``ppp,write,ATI`` Example output: ``+GCAP: +CGSM,+FCLASS,+DS``
* ``ppp,write,AT+IPR=?`` Listing supported baud rates: ``+IPR: (300,600,1200,2400,4800,9600,19200,38400,57600,115200,230400,460800,921600,1842000,3686400)``
* ``ppp,write,AT+CSPN?`` Show the SIM card carrier string: ``+CSPN: "Lebara",0``
* ``ppp,write,AT+CCLK?`` Show local time as known by the modem: ``+CCLK: "70/01/01,00:53:53+00"``
Example Devices
^^^^^^^^^^^^^^^
* `A7670E <https://nl.aliexpress.com/item/1005005220505235.html>`_ (DTR pin exposed, no RST pin)
* `A7670G <https://nl.aliexpress.com/item/1005008748473438.html>`_ (DTR pin exposed, no RST pin)
* `LilyGO T-PCIE V1.2 - AXP2101 - ESP32-WROVER - 16MB <https://www.tinytronics.nl/nl/development-boards/microcontroller-boards/met-wi-fi/lilygo-t-pcie-v1.2-axp2101-esp32-wrover-16mb>`_ with modem: `LilyGO TTGO T-PCIE A7670G <https://www.tinytronics.nl/nl/communicatie-en-signalen/draadloos/telecom/modules/lilygo-ttgo-t-pcie-a7670g-uitbreidingsmodule>`_
To use the last LilyGo T-PCIe v1.2 along with their A7670G modem combination as network interface #3, this config import can be used to get started:
.. code-block::
networkimportconfig,3,`{"nwpluginID":5,"enabled":"true","route_prio":200,"fallback":"false","sn_block":"true","start_delay":1000,"en_ipv6":"false","serPort":4,"RX":26,"TX":27,"RTS":-1,"CTS":-1,"rst":4,"rst_act_low":"false","rst_delay":500,"baudrate":115200,"flowctrl":0,"phytype":2,"DTR":-1}`
Change log
----------
Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 72 KiB

+1 -1
View File
@@ -60,7 +60,7 @@ bool NWPlugin_005(NWPlugin::Function function, EventStruct *event, String& strin
ESPEasy::net::ppp::NW005_data_struct_PPP_modem *NW_data =
static_cast<ESPEasy::net::ppp::NW005_data_struct_PPP_modem *>(getNWPluginData(event->NetworkIndex));
if (NW_data && NW_data->attached()) {
if (NW_data /*&& NW_data->attached()*/) {
event->networkInterface = &PPP;
success = event->networkInterface != nullptr;
}
+2 -6
View File
@@ -37,10 +37,7 @@ void handle_advanced() {
checkRAM(F("handle_advanced"));
#endif
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
if (!webArg(F("edit")).isEmpty())
{
@@ -405,8 +402,7 @@ void handle_advanced() {
addHtml(F("<input type='hidden' name='edit' value='1'>"));
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
void addFormDstSelect(bool isStart, uint16_t choice) {
+2 -7
View File
@@ -34,11 +34,7 @@ void handle_config() {
checkRAM(F("handle_config"));
#endif
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_CONFIG;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_CONFIG)) { return; }
if (web_server.args() != 0)
{
@@ -186,8 +182,7 @@ void handle_config() {
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
#endif // ifdef WEBSERVER_CONFIG
+5 -8
View File
@@ -36,10 +36,7 @@ void handle_controllers() {
checkRAM(F("handle_controllers"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_CONTROLLERS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_CONTROLLERS)) { return; }
// 'index' value in the URL
uint8_t controllerindex = getFormItemInt(F("index"), 0);
@@ -125,8 +122,6 @@ void handle_controllers() {
}
}
html_add_form();
if (controllerIndexSet)
{
handle_controllers_ControllerSettingsPage(controllerindex);
@@ -134,8 +129,7 @@ void handle_controllers() {
handle_controllers_ShowAllControllersTable();
}
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
// ********************************************************************************
@@ -217,6 +211,7 @@ void handle_controllers_CopySubmittedSettings_CPluginCall(uint8_t controllerinde
// ********************************************************************************
void handle_controllers_ShowAllControllersTable()
{
html_add_form();
html_table_class_multirow();
html_TR();
html_table_header(F(""), 70);
@@ -285,6 +280,8 @@ void handle_controllers_ControllerSettingsPage(controllerIndex_t controllerindex
return;
}
html_add_form();
// Show controller settings page
html_table_class_normal();
addFormHeader(F("Controller Settings"));
+2 -7
View File
@@ -48,11 +48,7 @@ void handle_devices() {
checkRAM(F("handle_devices"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_DEVICES;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_DEVICES)) { return; }
// char tmpString[41];
@@ -218,8 +214,7 @@ void handle_devices() {
addLogMove(LOG_LEVEL_DEBUG_DEV, concat(F("DEBUG: String size:"), static_cast<int>(TXBuffer.sentBytes)));
}
# endif // ifndef BUILD_NO_DEBUG
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
// ********************************************************************************
+77 -39
View File
@@ -123,45 +123,9 @@ void sendHeadandTail(const __FlashStringHelper *tmplName, bool Tail, bool reboot
STOP_TIMER(HANDLE_SERVING_WEBPAGE);
}
void sendHeadandTail_stdtemplate(bool Tail, bool rebooting) {
sendHeadandTail(F("TmplStd"), Tail, rebooting);
if (!Tail) {
// TODO TD-er: Must check clientConnectedToAP()?
if (!clientIPinSubnetDefaultNetwork() && ESPEasy::net::wifi::wifiAPmodeActivelyUsed()) {
addHtmlError(F("Warning: Connected via AP"));
}
#ifndef BUILD_NO_DEBUG
/*
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
const int nrArgs = web_server.args();
if (nrArgs > 0) {
String log = F(" Webserver ");
log += nrArgs;
log += F(" Arguments");
if (nrArgs > 20) {
log += F(" (First 20)");
}
log += ':';
for (int i = 0; i < nrArgs && i < 20; ++i) {
log += ' ';
log += i;
log += F(": '");
log += web_server.argName(i);
log += F("' length: ");
log += webArg(i).length();
}
addLogMove(LOG_LEVEL_INFO, log);
}
}
*/
#endif // ifndef BUILD_NO_DEBUG
}
void sendTail_stdtemplate(bool rebooting) {
sendHeadandTail(F("TmplStd"), _TAIL, rebooting);
TXBuffer.endStream();
// We have sent a lot of data at once.
// try to flush it to the connected client to free up some RAM
@@ -898,6 +862,69 @@ bool isLoggedIn(bool mustProvideLogin)
return true;
}
bool startStream_send_stdTemplate(uint8_t newNavIndex)
{
if (!isLoggedIn()) { return false; }
startStream_send_stdTemplate_NoLoginCheck(newNavIndex);
return true;
}
void startStream_send_stdTemplate_NoLoginCheck(uint8_t newNavIndex, bool rebooting)
{
navMenuIndex = newNavIndex;
TXBuffer.startStream();
sendHeadandTail(F("TmplStd"), _HEAD, rebooting);
// TODO TD-er: This should be the only place where sendHeadandTail_stdtemplate(_HEAD) is called
// TODO TD-er: Must check clientConnectedToAP()?
if (!clientIPinSubnetDefaultNetwork() && ESPEasy::net::wifi::wifiAPmodeActivelyUsed()) {
addHtmlError(F("Warning: Connected via AP"));
}
#ifndef BUILD_NO_DEBUG
/*
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
const int nrArgs = web_server.args();
if (nrArgs > 0) {
String log = F(" Webserver ");
log += nrArgs;
log += F(" Arguments");
if (nrArgs > 20) {
log += F(" (First 20)");
}
log += ':';
for (int i = 0; i < nrArgs && i < 20; ++i) {
log += ' ';
log += i;
log += F(": '");
log += web_server.argName(i);
log += F("' length: ");
log += webArg(i).length();
}
addLogMove(LOG_LEVEL_INFO, log);
}
}
*/
#endif // ifndef BUILD_NO_DEBUG
}
bool startJSON_Stream()
{
if (!isLoggedIn()) { return false; }
TXBuffer.startJsonStream();
return true;
}
String getControllerSymbol(uint8_t index)
{
String ret = F("<span style='font-size:20px; background: #00000000;'>&#");
@@ -907,6 +934,17 @@ String getControllerSymbol(uint8_t index)
return ret;
}
void handle_printWebString()
{
if (printWebString.isEmpty()) return;
addRowColspan(2);
addHtml(F("Command Output<BR><textarea readonly rows='10' wrap='on'>"));
addHtml(printWebString);
addHtml(F("</textarea>"));
free_string(printWebString);
printToWeb = false;
}
/*
String getValueSymbol(uint8_t index)
{
+14 -2
View File
@@ -22,8 +22,7 @@ void sendHeadandTail(const __FlashStringHelper * tmplName,
bool Tail = false,
bool rebooting = false);
void sendHeadandTail_stdtemplate(bool Tail,
bool rebooting = false);
void sendTail_stdtemplate(bool rebooting = false);
void WebServerInit();
@@ -128,8 +127,21 @@ void addTaskValueSelect(const String& name,
// ********************************************************************************
bool isLoggedIn(bool mustProvideLogin = true);
// Check isLoggedIn, set new navIndex and start serving standard template
// Thus not for non-HTML pages.
bool startStream_send_stdTemplate(uint8_t newNavIndex);
void startStream_send_stdTemplate_NoLoginCheck(uint8_t newNavIndex, bool rebooting = false);
// Check isLoggedIn and start JSON stream
// JSON can be called from anywhere, so no need to update the nav index
bool startJSON_Stream();
String getControllerSymbol(uint8_t index);
void handle_printWebString();
/*
String getValueSymbol(uint8_t index);
*/
+3 -6
View File
@@ -25,10 +25,8 @@ void handle_factoryreset() {
checkRAM(F("handle_factoryreset"));
#endif
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
html_add_form();
html_table_class_normal();
html_TR();
@@ -109,8 +107,7 @@ void handle_factoryreset() {
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
// ********************************************************************************
+4 -13
View File
@@ -140,10 +140,7 @@ void handle_filelist() {
checkRAM(F("handle_filelist"));
#endif
if (!clientIPallowed()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
if (tryDeleteFile(webArg(F("delete"))))
{
@@ -333,8 +330,7 @@ void handle_filelist_buttons(int start_prev, int start_next, bool cacheFilesPres
}
#endif
addHtml(F("<BR><BR>"));
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
#endif // ifdef WEBSERVER_FILELIST
@@ -348,11 +344,7 @@ void handle_SDfilelist() {
checkRAM(F("handle_SDfilelist"));
#endif
if (!clientIPallowed()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
String fdelete;
String ddelete;
@@ -498,8 +490,7 @@ void handle_SDfilelist() {
html_BR();
addButton(F("/uploadsd"), F("Upload"));
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
#endif // if FEATURE_SD
+2 -6
View File
@@ -30,10 +30,7 @@ void handle_hardware() {
checkRAM(F("handle_hardware"));
#endif
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_HARDWARE;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_HARDWARE)) { return; }
if (isFormItem(F("pled"))) {
String error;
@@ -125,8 +122,7 @@ void handle_hardware() {
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
#endif // ifdef WEBSERVER_HARDWARE
+4 -9
View File
@@ -109,9 +109,8 @@ void handle_i2cscanner_json() {
checkRAM(F("handle_i2cscanner"));
#endif
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startJsonStream();
if (!startJSON_Stream()) { return; }
json_init();
json_open(true);
@@ -489,10 +488,7 @@ void handle_i2cscanner() {
checkRAM(F("handle_i2cscanner"));
#endif
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
int nDevices = 0;
#if !FEATURE_I2C_MULTIPLE
@@ -561,7 +557,6 @@ void handle_i2cscanner() {
I2CSelectHighClockSpeed(0); // By default the bus is in standard speed
}
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
#endif // WEBSERVER_I2C_SCANNER
+12 -13
View File
@@ -75,26 +75,26 @@ void handle_interfaces() {
checkRAM(F("handle_interfaces"));
# endif
if (!isLoggedIn()) { return; }
if ((navMenuIndex != MENU_INDEX_INTERFACES) && (navMenuIndex <= MENU_MAX_INDEX_SHOWN)) {
uint8_t newNavIndex = navMenuIndex;
if ((newNavIndex != MENU_INDEX_INTERFACES) && (newNavIndex <= MENU_MAX_INDEX_SHOWN)) {
#if FEATURE_I2C
navMenuIndex = MENU_INDEX_INTERFACES_I2C;
newNavIndex = MENU_INDEX_INTERFACES_I2C;
#elif FEATURE_SPI
navMenuIndex = MENU_INDEX_INTERFACES_SPI;
newNavIndex = MENU_INDEX_INTERFACES_SPI;
#elif FEATURE_MODBUS && FEATURE_MODBUS_INTERFACES_TAB
navMenuIndex = MENU_INDEX_INTERFACES_MODBUS;
newNavIndex = MENU_INDEX_INTERFACES_MODBUS;
#elif FEATURE_CAN
navMenuIndex = MENU_INDEX_INTERFACES_CAN;
newNavIndex = MENU_INDEX_INTERFACES_CAN;
#elif FEATURE_WRMBUS
navMenuIndex = MENU_INDEX_INTERFACES_WRMBUS;
newNavIndex = MENU_INDEX_INTERFACES_WRMBUS;
#elif FEATURE_WIMBUS
navMenuIndex = MENU_INDEX_INTERFACES_WIMBUS;
newNavIndex = MENU_INDEX_INTERFACES_WIMBUS;
#else
navMenuIndex = MENU_INDEX_INTERFACES;
// FIXME TD-er: Should we still continue here? Why not simply return;
newNavIndex = MENU_INDEX_INTERFACES;
#endif
}
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(newNavIndex)) return;
save_interfaces();
@@ -149,8 +149,7 @@ void handle_interfaces() {
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
void save_interfaces() {
+2 -4
View File
@@ -757,8 +757,7 @@ void handle_timingstats_json() {
# if FEATURE_ESPEASY_P2P
void handle_nodes_list_json() {
if (!isLoggedIn()) { return; }
TXBuffer.startJsonStream();
if (!startJSON_Stream()) { return; }
json_init();
json_open(true);
@@ -790,8 +789,7 @@ void handle_nodes_list_json() {
# endif // if FEATURE_ESPEASY_P2P
void handle_buildinfo() {
if (!isLoggedIn()) { return; }
TXBuffer.startJsonStream();
if (!startJSON_Stream()) { return; }
json_init();
json_open();
{
+5 -8
View File
@@ -21,11 +21,8 @@
// Web Interface log page
// ********************************************************************************
void handle_log() {
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
html_table_class_normal();
#ifdef WEBSERVER_LOG
@@ -45,18 +42,16 @@ void handle_log() {
#else // ifdef WEBSERVER_LOG
addHtml(F("Not included in build"));
#endif // ifdef WEBSERVER_LOG
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
// ********************************************************************************
// Web Interface JSON log page
// ********************************************************************************
void handle_log_JSON() {
if (!isLoggedIn()) { return; }
#ifdef WEBSERVER_LOG
START_TIMER;
TXBuffer.startJsonStream();
if (!startJSON_Stream()) { return; }
{
KeyValueWriter_JSON top(true);
{
@@ -148,6 +143,8 @@ void handle_log_JSON() {
updateLogLevelCache();
#else // ifdef WEBSERVER_LOG
if (!isLoggedIn()) { return; }
handleNotFound();
#endif // ifdef WEBSERVER_LOG
}
+5 -9
View File
@@ -35,11 +35,7 @@ void handle_networks()
checkRAM(F("handle_networks"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_NETWORK;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_NETWORK)) { return; }
// 'index' value in the URL
uint8_t networkindex = getFormItemInt(F("index"), 0);
@@ -115,8 +111,6 @@ void handle_networks()
}
html_add_form();
if (networkIndexSet)
{
handle_networks_NetworkSettingsPage(networkindex);
@@ -126,8 +120,7 @@ void handle_networks()
handle_networks_ShowAllNetworksTable();
}
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
void handle_networks_clearLoadDefaults(ESPEasy::net::networkIndex_t networkindex, NetworkSettingsStruct& NetworkSettings) {
@@ -184,6 +177,7 @@ void handle_networks_CopySubmittedSettings_NWPluginCall(ESPEasy::net::networkInd
void handle_networks_ShowAllNetworksTable()
{
html_add_form();
html_table_class_multirow();
html_TR();
html_table_header(F(""), 70);
@@ -321,6 +315,8 @@ void handle_networks_NetworkSettingsPage(ESPEasy::net::networkIndex_t networkind
{
if (!validNetworkIndex(networkindex)) { return; }
html_add_form();
const networkDriverIndex_t networkDriverIndex =
getNetworkDriverIndex_from_NWPluginID(
Settings.getNWPluginID_for_network(networkindex));
+2 -6
View File
@@ -39,10 +39,7 @@ void handle_notifications() {
checkRAM(F("handle_notifications"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_NOTIFICATIONS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_NOTIFICATIONS)) { return; }
struct EventStruct TempEvent;
@@ -324,8 +321,7 @@ void handle_notifications() {
html_end_table();
html_end_form();
}
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
#endif // FEATURE_NOTIFIER
+3 -9
View File
@@ -32,9 +32,7 @@ void handle_pinstates_json() {
checkRAM(F("handle_pinstates"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startJsonStream();
if (!startJSON_Stream()) { return; }
bool first = true;
addHtml('[');
@@ -75,10 +73,7 @@ void handle_pinstates() {
checkRAM(F("handle_pinstates"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
# ifdef ESP32
html_BR();
@@ -303,8 +298,7 @@ void handle_pinstates() {
# endif // if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
# endif // ifdef ESP32
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
#endif // ifdef WEBSERVER_PINSTATES
+2 -4
View File
@@ -28,8 +28,7 @@ void handle_pluginlist() {
const int colspan = 5;
# endif // if FEATURE_MQTT_TLS || FEATURE_HTTP_TLS
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
startStream_send_stdTemplate_NoLoginCheck(MENU_INDEX_DEVICES);
// the table header
html_table_class_normal();
@@ -196,8 +195,7 @@ void handle_pluginlist() {
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
#endif // if FEATURE_PLUGIN_LIST
+10 -11
View File
@@ -79,19 +79,19 @@ void handle_root() {
const bool loggedIn = isLoggedIn(false);
navMenuIndex = 0;
navMenuIndex = MENU_INDEX_MAIN;
// if index.htm exists on FS serve that one (first check if gziped version exists)
if (loadFromFS(F("/index.htm.gz"))) { return; }
if (loadFromFS(F("/index.htm"))) { return; }
TXBuffer.startStream();
boolean rebootCmd = false;
String sCommand = webArg(F("cmd"));
rebootCmd = strcasecmp_P(sCommand.c_str(), PSTR("reboot")) == 0;
sendHeadandTail_stdtemplate(_HEAD, rebootCmd);
// Already checked for logged in state
startStream_send_stdTemplate_NoLoginCheck(MENU_INDEX_MAIN, rebootCmd);
// TODO: move this to handle_tools, from where it is actually called?
@@ -211,12 +211,8 @@ void handle_root() {
addFormHeader(F("Command Argument"));
addRowLabel(F("Command"));
addHtml(sCommand);
addRowColspan(2);
addHtml(F("Command Output<BR><textarea readonly rows='10' wrap='on'>"));
addHtml(printWebString);
addHtml(F("</textarea>"));
free_string(printWebString);
handle_printWebString();
}
}
html_end_table();
@@ -404,10 +400,13 @@ void handle_root() {
html_end_table();
# endif // if FEATURE_ESPEASY_P2P
html_end_form();
sendTail_stdtemplate();
// FIXME TD-er: Is this still needed?
free_string(printWebString);
printToWeb = false;
sendHeadandTail_stdtemplate(_TAIL);
return; // TXBuffer.endStream() was already sent
}
TXBuffer.endStream();
}
+8 -15
View File
@@ -55,8 +55,8 @@ void handle_rules() {
if (f) { f.close(); }
}
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
// Already checked for login
startStream_send_stdTemplate_NoLoginCheck(MENU_INDEX_RULES);
addHtmlError(error);
html_table_class_normal();
@@ -104,8 +104,7 @@ void handle_rules() {
addButton(fileName, F("Download to file"));
html_end_table();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
checkRuleSets();
}
@@ -127,10 +126,8 @@ void handle_rules_new() {
# ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("handle_rules"));
# endif // ifndef BUILD_NO_RAM_TRACKER
navMenuIndex = 5;
TXBuffer.startStream();
sendHeadandTail(F("TmplStd"), _HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_RULES)) { return; }
// define macro
# if defined(ESP8266)
String rootPath = F("rules");
@@ -254,8 +251,7 @@ void handle_rules_new() {
}
// TXBuffer += F("<BR><BR>");
sendHeadandTail(F("TmplStd"), _TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
# ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("handle_rules"));
# endif // ifndef BUILD_NO_RAM_TRACKER
@@ -477,9 +473,7 @@ bool handle_rules_edit(String originalUri, bool isAddNew) {
}
}
}
navMenuIndex = 5;
TXBuffer.startStream();
sendHeadandTail(F("TmplStd"));
startStream_send_stdTemplate_NoLoginCheck(MENU_INDEX_RULES);
if (error.length() > 0) {
addHtmlError(error);
@@ -529,8 +523,7 @@ bool handle_rules_edit(String originalUri, bool isAddNew) {
addHtml(F("</table></form>"));
sendHeadandTail(F("TmplStd"), true);
TXBuffer.endStream();
sendTail_stdtemplate();
# endif // WEBSERVER_NEW_RULES
}
# ifndef BUILD_NO_RAM_TRACKER
+3 -6
View File
@@ -24,10 +24,8 @@ void handle_settingsarchive() {
checkRAM(F("handle_settingsarchive"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
html_add_form();
html_table_class_normal();
html_TR();
@@ -234,8 +232,7 @@ void handle_settingsarchive() {
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
// ********************************************************************************
+5 -6
View File
@@ -43,15 +43,15 @@ void handle_setup() {
checkRAM(F("handle_setup"));
# endif // ifndef BUILD_NO_RAM_TRACKER
// Do not check client IP range allowed.
TXBuffer.startStream();
const bool connected = ESPEasy::net::NetworkConnected();
// if (connected) {
navMenuIndex = MENU_INDEX_SETUP;
sendHeadandTail_stdtemplate(_HEAD);
// TODO TD-er: Should also check for logged in state here?
// if (!startStream_send_stdTemplate(MENU_INDEX_SETUP)) { return; }
startStream_send_stdTemplate_NoLoginCheck(MENU_INDEX_SETUP);
/* } else {
sendHeadandTail(F("TmplAP"));
@@ -260,13 +260,12 @@ void handle_setup() {
}
// if (connected) {
sendHeadandTail_stdtemplate(_TAIL);
sendTail_stdtemplate();
/* } else {
sendHeadandTail(F("TmplAP"), true);
}
*/
TXBuffer.endStream();
delay(10);
if (clearWiFiCredentials) {
+3 -8
View File
@@ -56,8 +56,7 @@ void handle_sysinfo_json() {
checkRAM(F("handle_sysinfo"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
TXBuffer.startJsonStream();
if (!startJSON_Stream()) { return; }
{
KeyValueWriter_JSON mainLevelWriter(true);
{
@@ -235,13 +234,10 @@ void handle_sysinfo() {
checkRAM(F("handle_sysinfo"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
#ifdef WEBSERVER_GITHUB_COPY
html_reset_copyTextCounter();
#endif
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
addHtml(printWebString);
addHtml(F("<form>"));
@@ -295,8 +291,7 @@ void handle_sysinfo() {
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
void handle_sysinfo_basicInfo() {
+2 -5
View File
@@ -41,9 +41,7 @@ void handle_sysvars() {
checkRAM(F("handle_sysvars"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
html_BR();
addHtml(F("<p>This page may load slow.<BR>Do not load too often, since it may affect performance of the node.</p>"));
@@ -545,8 +543,7 @@ void handle_sysvars() {
}
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
void addSysVar_html(const __FlashStringHelper *input) {
+4 -5
View File
@@ -17,9 +17,9 @@ void handle_timingstats() {
#ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("handle_timingstats"));
#endif
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
startStream_send_stdTemplate_NoLoginCheck(MENU_INDEX_TOOLS);
html_table_class_multirow();
html_TR();
{
@@ -55,8 +55,7 @@ void handle_timingstats() {
addHtml(F("Duty cycle based on average < 1 msec is highly unreliable"));
html_end_table();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
// ********************************************************************************
+5 -15
View File
@@ -19,10 +19,7 @@
// Web Interface Tools page
// ********************************************************************************
void handle_tools() {
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
String webrequest = webArg(F("cmd"));
@@ -51,15 +48,7 @@ void handle_tools() {
addRTDHelpButton(F("Reference/Command.html"));
html_TR_TD();
if (printWebString.length() > 0)
{
addRowColspan(2);
addHtml(F("Command Output<BR><textarea readonly rows='10' wrap='on'>"));
addHtml(printWebString);
addHtml(F("</textarea>"));
free_string(printWebString);
}
handle_printWebString();
addFormSubHeader(F("System"));
@@ -204,8 +193,9 @@ void handle_tools() {
html_end_table();
html_end_form();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
// FIXME TD-er: Is this still needed?
free_string(printWebString);
printToWeb = false;
}
+4 -13
View File
@@ -25,15 +25,11 @@
uploadResult_e uploadResult = uploadResult_e::UploadStarted;
void handle_upload() {
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
addHtml(F(
"<form enctype='multipart/form-data' method='post'><p>Upload settings file:<br><input type='file' name='datafile' size='40'></p><div><input class='button link' type='submit' value='Upload'></div><input type='hidden' name='edit' value='1'></form>"));
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
free_string(printWebString);
printToWeb = false;
}
@@ -46,11 +42,7 @@ void handle_upload_post() {
checkRAM(F("handle_upload_post"));
# endif // ifndef BUILD_NO_RAM_TRACKER
if (!isLoggedIn()) { return; }
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
switch (uploadResult) {
case uploadResult_e::Success:
@@ -84,8 +76,7 @@ void handle_upload_post() {
}
addHtml(F("Upload finished"));
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
free_string(printWebString);
printToWeb = false;
}
+3 -3
View File
@@ -15,10 +15,10 @@
#define MENU_INDEX_INTERFACES 3
#define MENU_INDEX_INTERFACES_I2C 30
#define MENU_INDEX_INTERFACES_SPI 31
#define MENU_INDEX_INTERFACES_MODBUS 32
#define MENU_INDEX_INTERFACES_MODBUS 32 // For now Modbus-RTU, maybe later also Modbus-TCP
#define MENU_INDEX_INTERFACES_CAN 33
#define MENU_INDEX_INTERFACES_WRMBUS 34
#define MENU_INDEX_INTERFACES_WIMBUS 35
#define MENU_INDEX_INTERFACES_WRMBUS 34 // Wired M-Bus
#define MENU_INDEX_INTERFACES_WIMBUS 35 // Wireless M-Bus
#define MENU_INDEX_NETWORK 4
#define MENU_INDEX_CONTROLLERS 5
#define MENU_INDEX_BUSES 6
+4 -5
View File
@@ -61,6 +61,7 @@ void handle_wifiscanner() {
checkRAM(F("handle_wifiscanner"));
#endif
// Check for logged in state before potentially interrupting WiFi connection
if (!isLoggedIn()) { return; }
WiFiMode_t cur_wifimode = WiFi.getMode();
@@ -69,9 +70,8 @@ void handle_wifiscanner() {
int8_t scanCompleteStatus = ESPEasy::net::wifi::WiFi_AP_Candidates.scanComplete();
ESPEasy::net::wifi::setWifiMode(cur_wifimode);
navMenuIndex = MENU_INDEX_TOOLS;
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
if (!startStream_send_stdTemplate(MENU_INDEX_TOOLS)) { return; }
html_table_class_multirow();
html_TR();
html_table_header(getLabel(LabelType::SSID));
@@ -97,8 +97,7 @@ void handle_wifiscanner() {
}
html_end_table();
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
sendTail_stdtemplate();
}
#endif // ifdef WEBSERVER_WIFI_SCANNER