mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-25 19:56:30 +00:00
Add command WebRun (as WebQuery extension) (#21364)
* tasmota-1m32 * ready * add code usage * clean * remove also that * remove WebQueryWithFunction in favor of default value
This commit is contained in:
parent
33b0c1d5c2
commit
60a42f015e
@ -461,6 +461,7 @@
|
|||||||
#define D_CMND_WEBTIME "WebTime"
|
#define D_CMND_WEBTIME "WebTime"
|
||||||
#define D_CMND_WEBSENSOR "WebSensor"
|
#define D_CMND_WEBSENSOR "WebSensor"
|
||||||
#define D_CMND_WEBGETCONFIG "WebGetConfig"
|
#define D_CMND_WEBGETCONFIG "WebGetConfig"
|
||||||
|
#define D_CMND_WEBRUN "WebRun"
|
||||||
#define D_CMND_EMULATION "Emulation"
|
#define D_CMND_EMULATION "Emulation"
|
||||||
#define D_CMND_SENDMAIL "Sendmail"
|
#define D_CMND_SENDMAIL "Sendmail"
|
||||||
#define D_CMND_CORS "CORS"
|
#define D_CMND_CORS "CORS"
|
||||||
|
@ -512,10 +512,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
|
|||||||
|
|
||||||
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
|
||||||
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
|
||||||
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_SO47, SRC_SENSOR, SRC_MAX };
|
SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_SO47, SRC_SENSOR, SRC_WEB, SRC_MAX };
|
||||||
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
|
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
|
||||||
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
|
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
|
||||||
"Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole|SO47|Sensor";
|
"Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole|SO47|Sensor|Web";
|
||||||
|
|
||||||
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
|
||||||
|
|
||||||
|
@ -474,6 +474,7 @@
|
|||||||
#define USE_ENHANCED_GUI_WIFI_SCAN // Enable Wi-Fi scan output with BSSID (+0k5 code)
|
#define USE_ENHANCED_GUI_WIFI_SCAN // Enable Wi-Fi scan output with BSSID (+0k5 code)
|
||||||
// #define USE_WEBSEND_RESPONSE // Enable command WebSend response message (+1k code)
|
// #define USE_WEBSEND_RESPONSE // Enable command WebSend response message (+1k code)
|
||||||
// #define USE_WEBGETCONFIG // Enable restoring config from external webserver (+0k6)
|
// #define USE_WEBGETCONFIG // Enable restoring config from external webserver (+0k6)
|
||||||
|
// #define USE_WEBRUN // Enable executing a tasmota command file from external web server (+0.4 code)
|
||||||
// #define USE_GPIO_VIEWER // Enable GPIO Viewer to see realtime GPIO states (+6k code)
|
// #define USE_GPIO_VIEWER // Enable GPIO Viewer to see realtime GPIO states (+6k code)
|
||||||
// #define GV_SAMPLING_INTERVAL 100 // [GvSampling] milliseconds - Use Tasmota Scheduler (100) or Ticker (20..99,101..1000)
|
// #define GV_SAMPLING_INTERVAL 100 // [GvSampling] milliseconds - Use Tasmota Scheduler (100) or Ticker (20..99,101..1000)
|
||||||
#define USE_EMULATION_HUE // Enable Hue Bridge emulation for Alexa (+14k code, +2k mem common)
|
#define USE_EMULATION_HUE // Enable Hue Bridge emulation for Alexa (+14k code, +2k mem common)
|
||||||
|
@ -3320,6 +3320,169 @@ bool CaptivePortal(void)
|
|||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
|
enum {QUERY_DEFAULT=0, QUERY_RUN};
|
||||||
|
int WebQuery(char *buffer, int query_function);
|
||||||
|
|
||||||
|
#ifdef USE_WEBRUN
|
||||||
|
char *WebRunBuffer = nullptr;
|
||||||
|
char *WebRunContext = nullptr;
|
||||||
|
bool WebRunMutex = false;
|
||||||
|
|
||||||
|
void WebRunLoop(void)
|
||||||
|
{
|
||||||
|
if (WebRunBuffer && !WebRunMutex && BACKLOG_EMPTY) {
|
||||||
|
WebRunMutex = true;
|
||||||
|
char *command = strtok_r(WebRunContext, "\n\r", &WebRunContext);
|
||||||
|
if (command) {
|
||||||
|
while (isspace(*command)) command++; // skip space
|
||||||
|
if (*command && ';' != *command)
|
||||||
|
ExecuteCommand(command, SRC_WEB);
|
||||||
|
} else {
|
||||||
|
free(WebRunBuffer);
|
||||||
|
WebRunBuffer = WebRunContext = nullptr;
|
||||||
|
}
|
||||||
|
WebRunMutex = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRunInit(const char *command_buffer)
|
||||||
|
{
|
||||||
|
if (!WebRunBuffer) {
|
||||||
|
int len = strlen(command_buffer);
|
||||||
|
WebRunContext = WebRunBuffer = (char*)malloc(len+1);
|
||||||
|
if (WebRunBuffer) {
|
||||||
|
memcpy(WebRunBuffer, command_buffer, len);
|
||||||
|
WebRunBuffer[len] = 0;
|
||||||
|
} else {
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("WEBRUN: not enough memory"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AddLog(LOG_LEVEL_DEBUG, PSTR("WEBRUN: previous not completed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // #ifdef USE_WEBRUN
|
||||||
|
|
||||||
|
|
||||||
|
int WebQuery(char *buffer, int query_function = 0)
|
||||||
|
{
|
||||||
|
// http://192.168.1.1/path GET -> Sends HTTP GET http://192.168.1.1/path
|
||||||
|
// http://192.168.1.1/path POST {"some":"message"} -> Sends HTTP POST to http://192.168.1.1/path with body {"some":"message"}
|
||||||
|
// http://192.168.1.1/path PUT [Autorization: Bearer abcdxyz] potato -> Sends HTTP PUT to http://192.168.1.1/path with authorization header and body "potato"
|
||||||
|
// http://192.168.1.1/path PATCH patchInfo -> Sends HTTP PATCH to http://192.168.1.1/path with body "potato"
|
||||||
|
|
||||||
|
// Valid HTTP Commands: GET, POST, PUT, and PATCH
|
||||||
|
// An unlimited number of headers can be sent per request, and a body can be sent for all command types
|
||||||
|
// The body will be ignored if sending a GET command
|
||||||
|
|
||||||
|
#if defined(ESP32) && defined(USE_WEBCLIENT_HTTPS)
|
||||||
|
HTTPClientLight http;
|
||||||
|
#else // HTTP only
|
||||||
|
WiFiClient http_client;
|
||||||
|
HTTPClient http;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int status = WEBCMND_WRONG_PARAMETERS;
|
||||||
|
|
||||||
|
char *temp;
|
||||||
|
const char *url = strtok_r(buffer, " ", &temp);
|
||||||
|
const char *method = strtok_r(temp, " ", &temp);
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
#if defined(ESP32) && defined(USE_WEBCLIENT_HTTPS)
|
||||||
|
if (http.begin(UrlEncode(url))) {
|
||||||
|
#else // HTTP only
|
||||||
|
if (http.begin(http_client, UrlEncode(url))) {
|
||||||
|
#endif
|
||||||
|
char empty_body[1] = { 0 };
|
||||||
|
char *body = empty_body;
|
||||||
|
if (temp) { // There is a body and/or header
|
||||||
|
if (temp[0] == '[') { // Header information was sent; decode it
|
||||||
|
temp += 1;
|
||||||
|
temp = strtok_r(temp, "]", &body);
|
||||||
|
bool headerFound = true;
|
||||||
|
while (headerFound) {
|
||||||
|
char *header = strtok_r(temp, ":", &temp);
|
||||||
|
if (header) {
|
||||||
|
char *headerBody = strtok_r(temp, "|", &temp);
|
||||||
|
if (headerBody) {
|
||||||
|
http.addHeader(header, headerBody);
|
||||||
|
}
|
||||||
|
else headerFound = false;
|
||||||
|
}
|
||||||
|
else headerFound = false;
|
||||||
|
}
|
||||||
|
} else { // No header information was sent, but there was a body
|
||||||
|
body = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int http_code;
|
||||||
|
if ((!method) || 0 == strcasecmp_P(method, PSTR("GET"))) { http_code = http.GET(); }
|
||||||
|
else if (0 == strcasecmp_P(method, PSTR("POST"))) { http_code = http.POST(body); }
|
||||||
|
else if (0 == strcasecmp_P(method, PSTR("PUT"))) { http_code = http.PUT(body); }
|
||||||
|
else if (0 == strcasecmp_P(method, PSTR("PATCH"))) { http_code = http.PATCH(body); }
|
||||||
|
else return status;
|
||||||
|
|
||||||
|
if (http_code > 0) { // http_code will be negative on error
|
||||||
|
#if defined(USE_WEBSEND_RESPONSE) || defined(USE_WEBRUN)
|
||||||
|
if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) {
|
||||||
|
// Return received data to the user - Adds 900+ bytes to the code
|
||||||
|
String response = http.getString(); // File found at server - may need lot of ram or trigger out of memory!
|
||||||
|
const char* read = response.c_str();
|
||||||
|
// uint32_t len = response.length() + 1;
|
||||||
|
// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Response '%*_H' = %s"), len, (uint8_t*)read, read);
|
||||||
|
#ifdef USE_WEBRUN
|
||||||
|
if (QUERY_RUN == query_function)
|
||||||
|
WebRunInit(read);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_WEBSEND_RESPONSE
|
||||||
|
char text[3] = { 0 }; // Make room foor double %
|
||||||
|
text[0] = *read++;
|
||||||
|
if (text[0] != '\0') {
|
||||||
|
Response_P(PSTR("{\"" D_CMND_WEBQUERY "\":"));
|
||||||
|
bool assume_json = (text[0] == '{') || (text[0] == '[');
|
||||||
|
if (!assume_json) { ResponseAppend_P(PSTR("\"")); }
|
||||||
|
while (text[0] != '\0') {
|
||||||
|
if (text[0] > 31) { // Remove control characters like linefeed
|
||||||
|
if ('%' == text[0]) { // Fix char string formatting for %
|
||||||
|
text[1] = '%';
|
||||||
|
}
|
||||||
|
if (assume_json) {
|
||||||
|
if (ResponseAppend_P(text) == ResponseSize()) { break; };
|
||||||
|
} else {
|
||||||
|
if (ResponseAppend_P(EscapeJSONString(text).c_str()) == ResponseSize()) { break; };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text[0] = *read++;
|
||||||
|
text[1] = '\0';
|
||||||
|
}
|
||||||
|
if (!assume_json) { ResponseAppend_P(PSTR("\"")); }
|
||||||
|
ResponseJsonEnd();
|
||||||
|
#ifdef USE_SCRIPT
|
||||||
|
// recursive call must be possible in this case
|
||||||
|
void script_setaflg(uint8_t flg);
|
||||||
|
script_setaflg(0);
|
||||||
|
#endif // USE_SCRIPT
|
||||||
|
status = WEBCMND_VALID_RESPONSE;
|
||||||
|
} else {
|
||||||
|
#endif // USE_WEBSEND_RESPONSE
|
||||||
|
status = WEBCMND_DONE;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif // USE_WEBSEND_RESPONSE || USE_WEBRUN
|
||||||
|
status = WEBCMND_DONE;
|
||||||
|
} else {
|
||||||
|
status = WEBCMND_CONNECT_FAILED;
|
||||||
|
}
|
||||||
|
http.end(); // Clean up connection data
|
||||||
|
} else {
|
||||||
|
status = WEBCMND_HOST_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int WebSend(char *buffer)
|
int WebSend(char *buffer)
|
||||||
{
|
{
|
||||||
// [tasmota] POWER1 ON --> Sends http://tasmota/cm?cmnd=POWER1 ON
|
// [tasmota] POWER1 ON --> Sends http://tasmota/cm?cmnd=POWER1 ON
|
||||||
@ -3364,120 +3527,6 @@ int WebSend(char *buffer)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebQuery(char *buffer) {
|
|
||||||
// http://192.168.1.1/path GET -> Sends HTTP GET http://192.168.1.1/path
|
|
||||||
// http://192.168.1.1/path POST {"some":"message"} -> Sends HTTP POST to http://192.168.1.1/path with body {"some":"message"}
|
|
||||||
// http://192.168.1.1/path PUT [Autorization: Bearer abcdxyz] potato -> Sends HTTP PUT to http://192.168.1.1/path with authorization header and body "potato"
|
|
||||||
// http://192.168.1.1/path PATCH patchInfo -> Sends HTTP PATCH to http://192.168.1.1/path with body "potato"
|
|
||||||
|
|
||||||
// Valid HTTP Commands: GET, POST, PUT, and PATCH
|
|
||||||
// An unlimited number of headers can be sent per request, and a body can be sent for all command types
|
|
||||||
// The body will be ignored if sending a GET command
|
|
||||||
|
|
||||||
#if defined(ESP32) && defined(USE_WEBCLIENT_HTTPS)
|
|
||||||
HTTPClientLight http;
|
|
||||||
#else // HTTP only
|
|
||||||
WiFiClient http_client;
|
|
||||||
HTTPClient http;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int status = WEBCMND_WRONG_PARAMETERS;
|
|
||||||
|
|
||||||
char *temp;
|
|
||||||
char *url = strtok_r(buffer, " ", &temp);
|
|
||||||
char *method = strtok_r(temp, " ", &temp);
|
|
||||||
|
|
||||||
if (url && method) {
|
|
||||||
#if defined(ESP32) && defined(USE_WEBCLIENT_HTTPS)
|
|
||||||
if (http.begin(UrlEncode(url))) {
|
|
||||||
#else // HTTP only
|
|
||||||
if (http.begin(http_client, UrlEncode(url))) {
|
|
||||||
#endif
|
|
||||||
char empty_body[1] = { 0 };
|
|
||||||
char *body = empty_body;
|
|
||||||
if (temp) { // There is a body and/or header
|
|
||||||
if (temp[0] == '[') { // Header information was sent; decode it
|
|
||||||
temp += 1;
|
|
||||||
temp = strtok_r(temp, "]", &body);
|
|
||||||
bool headerFound = true;
|
|
||||||
while (headerFound) {
|
|
||||||
char *header = strtok_r(temp, ":", &temp);
|
|
||||||
if (header) {
|
|
||||||
char *headerBody = strtok_r(temp, "|", &temp);
|
|
||||||
if (headerBody) {
|
|
||||||
http.addHeader(header, headerBody);
|
|
||||||
}
|
|
||||||
else headerFound = false;
|
|
||||||
}
|
|
||||||
else headerFound = false;
|
|
||||||
}
|
|
||||||
} else { // No header information was sent, but there was a body
|
|
||||||
body = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int http_code;
|
|
||||||
if (0 == strcasecmp_P(method, PSTR("GET"))) { http_code = http.GET(); }
|
|
||||||
else if (0 == strcasecmp_P(method, PSTR("POST"))) { http_code = http.POST(body); }
|
|
||||||
else if (0 == strcasecmp_P(method, PSTR("PUT"))) { http_code = http.PUT(body); }
|
|
||||||
else if (0 == strcasecmp_P(method, PSTR("PATCH"))) { http_code = http.PATCH(body); }
|
|
||||||
else return status;
|
|
||||||
|
|
||||||
if (http_code > 0) { // http_code will be negative on error
|
|
||||||
#ifdef USE_WEBSEND_RESPONSE
|
|
||||||
if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) {
|
|
||||||
// Return received data to the user - Adds 900+ bytes to the code
|
|
||||||
String response = http.getString(); // File found at server - may need lot of ram or trigger out of memory!
|
|
||||||
const char* read = response.c_str();
|
|
||||||
|
|
||||||
// uint32_t len = response.length() + 1;
|
|
||||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Response '%*_H' = %s"), len, (uint8_t*)read, read);
|
|
||||||
|
|
||||||
char text[3] = { 0 }; // Make room foor double %
|
|
||||||
text[0] = *read++;
|
|
||||||
if (text[0] != '\0') {
|
|
||||||
Response_P(PSTR("{\"" D_CMND_WEBQUERY "\":"));
|
|
||||||
bool assume_json = (text[0] == '{') || (text[0] == '[');
|
|
||||||
if (!assume_json) { ResponseAppend_P(PSTR("\"")); }
|
|
||||||
while (text[0] != '\0') {
|
|
||||||
if (text[0] > 31) { // Remove control characters like linefeed
|
|
||||||
if ('%' == text[0]) { // Fix char string formatting for %
|
|
||||||
text[1] = '%';
|
|
||||||
}
|
|
||||||
if (assume_json) {
|
|
||||||
if (ResponseAppend_P(text) == ResponseSize()) { break; };
|
|
||||||
} else {
|
|
||||||
if (ResponseAppend_P(EscapeJSONString(text).c_str()) == ResponseSize()) { break; };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text[0] = *read++;
|
|
||||||
text[1] = '\0';
|
|
||||||
}
|
|
||||||
if (!assume_json) { ResponseAppend_P(PSTR("\"")); }
|
|
||||||
ResponseJsonEnd();
|
|
||||||
#ifdef USE_SCRIPT
|
|
||||||
// recursive call must be possible in this case
|
|
||||||
void script_setaflg(uint8_t flg);
|
|
||||||
script_setaflg(0);
|
|
||||||
#endif // USE_SCRIPT
|
|
||||||
status = WEBCMND_VALID_RESPONSE;
|
|
||||||
} else {
|
|
||||||
status = WEBCMND_DONE;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
#endif // USE_WEBSEND_RESPONSE
|
|
||||||
status = WEBCMND_DONE;
|
|
||||||
} else {
|
|
||||||
status = WEBCMND_CONNECT_FAILED;
|
|
||||||
}
|
|
||||||
http.end(); // Clean up connection data
|
|
||||||
} else {
|
|
||||||
status = WEBCMND_HOST_NOT_FOUND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_WEBGETCONFIG
|
#ifdef USE_WEBGETCONFIG
|
||||||
int WebGetConfig(char *buffer) {
|
int WebGetConfig(char *buffer) {
|
||||||
// http://user:password@server:port/path/%id%.dmp : %id% will be expanded to MAC address
|
// http://user:password@server:port/path/%id%.dmp : %id% will be expanded to MAC address
|
||||||
@ -3597,6 +3646,9 @@ const char kWebCommands[] PROGMEM = "|" // No prefix
|
|||||||
#ifdef USE_WEBGETCONFIG
|
#ifdef USE_WEBGETCONFIG
|
||||||
"|" D_CMND_WEBGETCONFIG
|
"|" D_CMND_WEBGETCONFIG
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_WEBRUN
|
||||||
|
"|" D_CMND_WEBRUN
|
||||||
|
#endif
|
||||||
#ifdef USE_CORS
|
#ifdef USE_CORS
|
||||||
"|" D_CMND_CORS
|
"|" D_CMND_CORS
|
||||||
#endif
|
#endif
|
||||||
@ -3618,6 +3670,9 @@ void (* const WebCommand[])(void) PROGMEM = {
|
|||||||
#ifdef USE_WEBGETCONFIG
|
#ifdef USE_WEBGETCONFIG
|
||||||
, &CmndWebGetConfig
|
, &CmndWebGetConfig
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_WEBRUN
|
||||||
|
, &CmndWebRun
|
||||||
|
#endif
|
||||||
#ifdef USE_CORS
|
#ifdef USE_CORS
|
||||||
, &CmndCors
|
, &CmndCors
|
||||||
#endif
|
#endif
|
||||||
@ -3743,6 +3798,18 @@ void CmndWebQuery(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_WEBRUN
|
||||||
|
void CmndWebRun(void) {
|
||||||
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
uint32_t result = WebQuery(XdrvMailbox.data, QUERY_RUN);
|
||||||
|
if (result != WEBCMND_VALID_RESPONSE) {
|
||||||
|
char stemp1[20];
|
||||||
|
ResponseCmndChar(GetTextIndexed(stemp1, sizeof(stemp1), result, kWebCmndStatus));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // #ifdef USE_WEBRUN
|
||||||
|
|
||||||
#ifdef USE_WEBGETCONFIG
|
#ifdef USE_WEBGETCONFIG
|
||||||
void CmndWebGetConfig(void) {
|
void CmndWebGetConfig(void) {
|
||||||
// WebGetConfig http://myserver:8000/tasmota/conf/%id%.dmp where %id% is expanded to device mac address
|
// WebGetConfig http://myserver:8000/tasmota/conf/%id%.dmp where %id% is expanded to device mac address
|
||||||
@ -3875,6 +3942,9 @@ bool Xdrv01(uint32_t function)
|
|||||||
switch (function) {
|
switch (function) {
|
||||||
case FUNC_LOOP:
|
case FUNC_LOOP:
|
||||||
PollDnsWebserver();
|
PollDnsWebserver();
|
||||||
|
#ifdef USE_WEBRUN
|
||||||
|
WebRunLoop();
|
||||||
|
#endif // #ifdef USE_WEBRUN
|
||||||
#ifdef USE_EMULATION
|
#ifdef USE_EMULATION
|
||||||
if (Settings->flag2.emulation) { PollUdp(); }
|
if (Settings->flag2.emulation) { PollUdp(); }
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
|
Loading…
x
Reference in New Issue
Block a user