Merge remote-tracking branch 'upstream/development' into development

This commit is contained in:
Laurent 2019-02-22 22:53:01 -05:00
commit 2cc15a8c34
12 changed files with 230 additions and 185 deletions

View File

@ -65,8 +65,9 @@ build_flags = ${esp82xx_defaults.build_flags}
-DVTABLES_IN_FLASH
[core_2_5_0]
; *** Esp8266 core for Arduino version 2.5.0 release (still not available via platformio)
; *** Esp8266 core for Arduino version 2.5.0 (since version from platformio is faulty)
platform = https://github.com/Jason2866/platform-espressif8266.git#Tasmota
;platform = espressif8266@2.0.0
build_flags = ${esp82xx_defaults.build_flags}
-Wl,-Teagle.flash.1m.ld
; lwIP 1.4 (Default)

View File

@ -1,4 +1,11 @@
/* 6.4.1.17 20190214
/* 6.4.1.18 20191221
* Fix some exceptions and watchdogs due to lack of stack space - part 1 (#5215)
* Fix some exceptions and watchdogs due to lack of stack space - part 2
* Add command SetOption62 0/1 to disable retain on Button or Swith hold messages (#5299)
* Add option WifiConfig 7 to allow reset of device in AP mode without admin password (#5297)
* Fix command WebSend when using a port number as regression from 6.4.1.17 (#5304)
*
* 6.4.1.17 20190214
* Change template update by removing possibility to add user module config keeping template as defined (#5222)
* Fix regression from 6.4.1.16 where GPIO9 and GPIO10 connected devices did not work (#5197)
* Fix GUI wifi password acception starting with asteriks (*) (#5231, #5242)

View File

@ -248,6 +248,7 @@
#define D_WCFG_4_RETRY "Retry"
#define D_WCFG_5_WAIT "Wait"
#define D_WCFG_6_SERIAL "Serial"
#define D_WCFG_7_WIFIMANAGER_RESET_ONLY "ManagerRst"
#define D_CMND_FRIENDLYNAME "FriendlyName"
#define D_CMND_SWITCHMODE "SwitchMode"
#define D_CMND_INTERLOCK "Interlock"
@ -540,7 +541,8 @@ const char kWifiConfig[MAX_WIFI_OPTION][WCFG_MAX_STRING_LENGTH] PROGMEM = {
D_WCFG_3_WPSCONFIG,
D_WCFG_4_RETRY,
D_WCFG_5_WAIT,
D_WCFG_6_SERIAL };
D_WCFG_6_SERIAL,
D_WCFG_7_WIFIMANAGER_RESET_ONLY };
const char kPrefixes[3][PRFX_MAX_STRING_LENGTH] PROGMEM = {
D_CMND,
D_STAT,

View File

@ -75,7 +75,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t hass_tele_on_power : 1; // bit 9 (v6.3.0.13)
uint32_t sleep_normal : 1; // bit 10 (v6.3.0.15) - SetOption60 - Enable normal sleep instead of dynamic sleep
uint32_t button_switch_force_local : 1;// bit 11 (v6.3.0.16) - SetOption61 - Force local operation when button/switch topic is set
uint32_t spare12 : 1;
uint32_t no_hold_retain : 1; // bit 12 (v6.4.1.19) - SetOption62 - Don't use retain flag on HOLD messages
uint32_t spare13 : 1;
uint32_t spare14 : 1;
uint32_t spare15 : 1;

View File

@ -212,7 +212,7 @@ enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART, DT_ENERGY };
enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
enum WifiConfigOptions {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, MAX_WIFI_OPTION};
enum WifiConfigOptions {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, WIFI_MANAGER_RESET_ONLY, MAX_WIFI_OPTION};
enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, MAX_SWITCH_OPTION};

View File

@ -866,9 +866,7 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
}
restart_flag = 2;
}
uint8_t module = Settings.module;
if (USER_MODULE == Settings.module) { module = 0; } else { module++; }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_SVALUE, command, module, ModuleName().c_str());
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_SVALUE, command, ModuleNr(), ModuleName().c_str());
}
else if (CMND_MODULES == command_code) {
for (uint8_t i = 0; i <= MAXMODULE; i++) {
@ -964,40 +962,11 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
}
}
else if (data_len > 9) { // Workaround exception if empty JSON like {} - Needs checks
StaticJsonBuffer<350> jb; // 331 from https://arduinojson.org/v5/assistant/
JsonObject& obj = jb.parseObject(dataBuf);
if (!obj.success()) {
if (JsonTemplate(dataBuf)) { // Free 336 bytes StaticJsonBuffer stack space by moving code to function
if (USER_MODULE == Settings.module) { restart_flag = 2; }
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON);
error = true;
} else {
// All parameters are optional allowing for partial changes
const char* name = obj[D_JSON_NAME];
if (name != nullptr) {
strlcpy(Settings.user_template.name, name, sizeof(Settings.user_template.name));
}
if (obj[D_JSON_GPIO].success()) {
for (uint8_t i = 0; i < sizeof(mycfgio); i++) {
Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0;
}
}
if (obj[D_JSON_FLAG].success()) {
uint8_t flag = obj[D_JSON_FLAG] | 0;
memcpy(&Settings.user_template.flag, &flag, sizeof(gpio_flag));
}
if (obj[D_JSON_BASE].success()) {
uint8_t base = obj[D_JSON_BASE];
if ((0 == base) || (base >= MAXMODULE)) { base = 17; } else { base--; }
Settings.user_template_base = base; // Default WEMOS
}
// Validate GPIO
// for (uint8_t i = 0; i < sizeof(mycfgio); i++) {
// For now do not allow non-user configurable GPIO
// if ((Settings.user_template.gp.io[i] > GPIO_FIX_START) && (Settings.user_template.gp.io[i] < GPIO_USER)) {
// Settings.user_template.gp.io[i] = GPIO_NONE;
// };
// }
if (USER_MODULE == Settings.module) { restart_flag = 2; }
}
}
if (!error) { TemplateJson(); }
@ -1173,7 +1142,7 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.sta_ssid[index -1]);
}
else if ((CMND_PASSWORD == command_code) && (index > 0) && (index <= 2)) {
if ((data_len > 0) && (data_len < sizeof(Settings.sta_pwd[0]))) {
if ((data_len > 4 || SC_CLEAR == Shortcut(dataBuf) || SC_DEFAULT == Shortcut(dataBuf)) && (data_len < sizeof(Settings.sta_pwd[0]))) {
strlcpy(Settings.sta_pwd[index -1], (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? (1 == index) ? STA_PASS1 : STA_PASS2 : dataBuf, sizeof(Settings.sta_pwd[0]));
Settings.sta_active = index -1;
restart_flag = 2;
@ -1463,10 +1432,10 @@ bool SendKey(uint8_t key, uint8_t device, uint8_t state)
}
#ifdef USE_DOMOTICZ
if (!(DomoticzSendKey(key, device, state, strlen(mqtt_data)))) {
MqttPublishDirect(stopic, (key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain);
MqttPublishDirect(stopic, ((key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain) && (state != 3 || !Settings.flag3.no_hold_retain));
}
#else
MqttPublishDirect(stopic, (key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain);
MqttPublishDirect(stopic, ((key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain) && (state != 3 || !Settings.flag3.no_hold_retain));
#endif // USE_DOMOTICZ
result = !Settings.flag3.button_switch_force_local;
} else {
@ -1595,8 +1564,6 @@ void StopAllPowerBlink(void)
void ExecuteCommand(char *cmnd, int source)
{
char stopic[CMDSZ];
char svalue[INPUT_BUFFER_SIZE];
char *start;
char *token;
@ -1608,9 +1575,13 @@ void ExecuteCommand(char *cmnd, int source)
start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble
if (start) { token = start +1; }
}
uint16_t size = (token != NULL) ? strlen(token) : 0;
char stopic[size +2]; // / + \0
snprintf_P(stopic, sizeof(stopic), PSTR("/%s"), (token == NULL) ? "" : token);
token = strtok(NULL, "");
// snprintf_P(svalue, sizeof(svalue), (token == NULL) ? "" : token); // Fails with command FullTopic home/%prefix%/%topic% as it processes %p of %prefix%
size = (token != NULL) ? strlen(token) : 0;
char svalue[size +1];
strlcpy(svalue, (token == NULL) ? "" : token, sizeof(svalue)); // Fixed 5.8.0b
MqttDataHandler(stopic, (uint8_t*)svalue, strlen(svalue));
}
@ -1639,7 +1610,7 @@ void PublishStatus(uint8_t payload)
snprintf_P(stemp2, sizeof(stemp2), PSTR("%s%s%d" ), stemp2, (i > 0 ? "," : ""), Settings.switchmode[i]);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_SWITCHTOPIC "\":\"%s\",\"" D_CMND_SWITCHMODE "\":[%s],\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_SWITCHRETAIN "\":%d,\"" D_CMND_SENSORRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"),
(USER_MODULE == Settings.module)?0:Settings.module +1, stemp, mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.switch_topic, stemp2, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_switch_retain, Settings.flag.mqtt_sensor_retain, Settings.flag.mqtt_power_retain);
ModuleNr(), stemp, mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.switch_topic, stemp2, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_switch_retain, Settings.flag.mqtt_sensor_retain, Settings.flag.mqtt_power_retain);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS));
}
@ -2223,7 +2194,8 @@ void ArduinoOTAInit(void)
void SerialInput(void)
{
while (Serial.available()) {
yield();
// yield();
delay(0);
serial_in_byte = Serial.read();
/*-------------------------------------------------------------------------------------------*\

View File

@ -20,7 +20,7 @@
#ifndef _SONOFF_VERSION_H_
#define _SONOFF_VERSION_H_
#define VERSION 0x06040111
#define VERSION 0x06040112
#define D_PROGRAMNAME "Sonoff-Tasmota"
#define D_AUTHOR "Theo Arends"

View File

@ -699,6 +699,13 @@ void ShowSource(int source)
* GPIO Module and Template management
\*********************************************************************************************/
uint8_t ModuleNr()
{
// 0 = User module (255)
// 1 up = Template module 0 up
return (USER_MODULE == Settings.module) ? 0 : Settings.module +1;
}
String AnyModuleName(uint8_t index)
{
if (USER_MODULE == index) {
@ -720,7 +727,6 @@ void ModuleGpios(myio *gp)
uint8_t src[sizeof(mycfgio)];
if (USER_MODULE == Settings.module) {
// src = Settings.user_template.gp;
memcpy(&src, &Settings.user_template.gp, sizeof(mycfgio));
} else {
memcpy_P(&src, &kModules[Settings.module].gp, sizeof(mycfgio));
@ -845,14 +851,40 @@ bool GetUsedInModule(uint8_t val, uint8_t *arr)
return false;
}
bool JsonTemplate(const char* dataBuf)
{
StaticJsonBuffer<350> jb; // 331 from https://arduinojson.org/v5/assistant/
JsonObject& obj = jb.parseObject(dataBuf);
if (!obj.success()) { return false; }
// All parameters are optional allowing for partial changes
const char* name = obj[D_JSON_NAME];
if (name != nullptr) {
strlcpy(Settings.user_template.name, name, sizeof(Settings.user_template.name));
}
if (obj[D_JSON_GPIO].success()) {
for (uint8_t i = 0; i < sizeof(mycfgio); i++) {
Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0;
}
}
if (obj[D_JSON_FLAG].success()) {
uint8_t flag = obj[D_JSON_FLAG] | 0;
memcpy(&Settings.user_template.flag, &flag, sizeof(gpio_flag));
}
if (obj[D_JSON_BASE].success()) {
uint8_t base = obj[D_JSON_BASE];
if ((0 == base) || (base >= MAXMODULE)) { base = 17; } else { base--; }
Settings.user_template_base = base; // Default WEMOS
}
return true;
}
void TemplateJson()
{
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), Settings.user_template.name);
for (uint8_t i = 0; i < sizeof(Settings.user_template.gp); i++) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d"), mqtt_data, (i>0)?",":"", Settings.user_template.gp.io[i]);
}
// snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":\"%d (%s)\"}"),
// mqtt_data, Settings.user_template.flag, Settings.user_template_base +1, AnyModuleName(Settings.user_template_base).c_str());
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"),
mqtt_data, Settings.user_template.flag, Settings.user_template_base +1);
}

View File

@ -174,9 +174,9 @@ void WifiConfig(uint8_t type)
}
#endif // USE_WPS
#ifdef USE_WEBSERVER
else if (WIFI_MANAGER == wifi_config_type) {
else if (WIFI_MANAGER == wifi_config_type || WIFI_MANAGER_RESET_ONLY == wifi_config_type) {
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_2_WIFIMANAGER " " D_ACTIVE_FOR_3_MINUTES));
WifiManagerBegin();
WifiManagerBegin(WIFI_MANAGER_RESET_ONLY == wifi_config_type);
}
#endif // USE_WEBSERVER
}

View File

@ -294,12 +294,14 @@ const char HTTP_BTN_RSTRT[] PROGMEM =
const char HTTP_BTN_MENU_MODULE[] PROGMEM =
"<p><form action='md' method='get'><button>" D_CONFIGURE_MODULE "</button></form></p>"
"<p><form action='wi' method='get'><button>" D_CONFIGURE_WIFI "</button></form></p>";
const char HTTP_BTN_RESET[] PROGMEM =
"<br/>"
"<form action='rt' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESET_CONFIGURATION "\");'><button class='button bred'>" D_RESET_CONFIGURATION "</button></form>";
const char HTTP_BTN_MENU4[] PROGMEM =
"<p><form action='lg' method='get'><button>" D_CONFIGURE_LOGGING "</button></form></p>"
"<p><form action='co' method='get'><button>" D_CONFIGURE_OTHER "</button></form></p>"
"<p><form action='tp' method='get'><button>" D_CONFIGURE_TEMPLATE "</button></form></p>"
"<br/>"
"<form action='rt' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESET_CONFIGURATION "\");'><button class='button bred'>" D_RESET_CONFIGURATION "</button></form>"
"<p><form action='tp' method='get'><button>" D_CONFIGURE_TEMPLATE "</button></form></p>";
const char HTTP_BTN_MENU5[] PROGMEM =
"<p><form action='dl' method='get'><button>" D_BACKUP_CONFIGURATION "</button></form></p>"
"<p><form action='rs' method='get'><button>" D_RESTORE_CONFIGURATION "</button></form></p>";
const char HTTP_BTN_MAIN[] PROGMEM =
@ -437,7 +439,7 @@ const char HDR_CTYPE_JSON[] PROGMEM = "application/json";
const char HDR_CTYPE_STREAM[] PROGMEM = "application/octet-stream";
#define DNS_PORT 53
enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER};
enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY};
DNSServer *DnsServer;
ESP8266WebServer *WebServer;
@ -460,6 +462,10 @@ static void WebGetArg(const char* arg, char* out, size_t max)
// out[max-1] = '\0'; // Ensure terminating NUL
}
static bool WifiIsInManagerMode(){
return (HTTP_MANAGER == webserver_state || HTTP_MANAGER_RESET_ONLY == webserver_state);
}
void ShowWebSource(int source)
{
if ((source > 0) && (source < SRC_MAX)) {
@ -480,8 +486,13 @@ void StartWebserver(int type, IPAddress ipweb)
if (!Settings.web_refresh) { Settings.web_refresh = HTTP_REFRESH_TIME; }
if (!webserver_state) {
if (!WebServer) {
WebServer = new ESP8266WebServer((HTTP_MANAGER==type) ? 80 : WEB_PORT);
WebServer = new ESP8266WebServer((HTTP_MANAGER==type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT);
WebServer->on("/", HandleRoot);
WebServer->onNotFound(HandleNotFound);
#ifndef FIRMWARE_MINIMAL
WebServer->on("/rt", HandleResetConfiguration);
#endif // FIRMWARE_MINIMAL
if(HTTP_MANAGER_RESET_ONLY != type){
WebServer->on("/up", HandleUpgradeFirmware);
WebServer->on("/u1", HandleUpgradeFirmwareStart); // OTA
WebServer->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop);
@ -490,7 +501,6 @@ void StartWebserver(int type, IPAddress ipweb)
WebServer->on("/ax", HandleAjaxConsoleRefresh);
WebServer->on("/ay", HandleAjaxStatusRefresh);
WebServer->on("/cm", HandleHttpCommand);
WebServer->onNotFound(HandleNotFound);
#ifndef FIRMWARE_MINIMAL
WebServer->on("/cn", HandleConfiguration);
WebServer->on("/md", HandleModuleConfiguration);
@ -509,6 +519,7 @@ void StartWebserver(int type, IPAddress ipweb)
XsnsCall(FUNC_WEB_ADD_HANDLER);
#endif // Not FIRMWARE_MINIMAL
}
}
reset_web_log_flag = false;
WebServer->begin(); // Web server start
}
@ -529,7 +540,7 @@ void StopWebserver(void)
}
}
void WifiManagerBegin(void)
void WifiManagerBegin(bool reset_only)
{
// setup AP
if (!global_state.wifi_down) {
@ -553,7 +564,7 @@ void WifiManagerBegin(void)
DnsServer->setErrorReplyCode(DNSReplyCode::NoError);
DnsServer->start(DNS_PORT, "*", WiFi.softAPIP());
StartWebserver(HTTP_MANAGER, WiFi.softAPIP());
StartWebserver((reset_only ? HTTP_MANAGER_RESET_ONLY : HTTP_MANAGER), WiFi.softAPIP());
}
void PollDnsWebserver(void)
@ -576,7 +587,7 @@ void SetHeader(void)
bool WebAuthenticate(void)
{
if (Settings.web_password[0] != 0) {
if (Settings.web_password[0] != 0 && HTTP_MANAGER_RESET_ONLY != webserver_state) {
return WebServer->authenticate(WEB_USERNAME, Settings.web_password);
} else {
return true;
@ -611,7 +622,7 @@ void ShowPage(String &page, bool auth)
}
page.replace(F("{j}"), info);
if (HTTP_MANAGER == webserver_state) {
if (WifiIsInManagerMode()) {
if (WifiConfigCounter()) {
page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_COUNTER));
page += FPSTR(HTTP_COUNTER);
@ -655,14 +666,16 @@ void WebRestart(uint8_t type)
page.replace(F("{v}"), FPSTR(S_RESTART));
}
bool reset_only = (HTTP_MANAGER_RESET_ONLY == webserver_state);
page += FPSTR(HTTP_MSG_RSTRT);
if (HTTP_MANAGER == webserver_state) {
if (HTTP_MANAGER == webserver_state || reset_only) {
webserver_state = HTTP_ADMIN;
} else {
page += FPSTR(HTTP_BTN_MAIN);
}
page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_RELOAD));
ShowPage(page);
ShowPage(page, !reset_only);
ShowWebSource(SRC_WEBGUI);
restart_flag = 2;
@ -690,12 +703,12 @@ void HandleRoot(void)
return;
}
if (HTTP_MANAGER == webserver_state) {
if (WifiIsInManagerMode()) {
#ifndef FIRMWARE_MINIMAL
if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1"))) {
if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1")) && HTTP_MANAGER_RESET_ONLY != webserver_state) {
HandleWifiLogin();
} else {
if (!(Settings.web_password[0] != 0) || ((WebServer->arg("USER1") == WEB_USERNAME ) && (WebServer->arg("PASS1") == Settings.web_password ))) {
if (!(Settings.web_password[0] != 0) || ((WebServer->arg("USER1") == WEB_USERNAME ) && (WebServer->arg("PASS1") == Settings.web_password ) || HTTP_MANAGER_RESET_ONLY == webserver_state)) {
HandleWifiConfiguration();
} else {
// wrong user and pass
@ -874,6 +887,8 @@ void HandleConfiguration(void)
page += String(mqtt_data);
page += FPSTR(HTTP_BTN_MENU4);
page += FPSTR(HTTP_BTN_RESET);
page += FPSTR(HTTP_BTN_MENU5);
page += FPSTR(HTTP_BTN_MAIN);
ShowPage(page);
}
@ -1125,7 +1140,7 @@ void HandleWifiConfiguration(void)
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_WIFI);
if (WebServer->hasArg("save")) {
if (WebServer->hasArg("save") && HTTP_MANAGER_RESET_ONLY != webserver_state) {
WifiSaveSettings();
WebRestart(2);
return;
@ -1136,6 +1151,8 @@ void HandleWifiConfiguration(void)
page += FPSTR(HTTP_SCRIPT_WIFI);
page += FPSTR(HTTP_HEAD_STYLE);
if(HTTP_MANAGER_RESET_ONLY != webserver_state){
if (WebServer->hasArg("scan")) {
#ifdef USE_EMULATION
UdpDisconnect();
@ -1213,13 +1230,17 @@ void HandleWifiConfiguration(void)
page.replace(F("{s1"), Settings.sta_ssid[0]);
page.replace(F("{s2"), Settings.sta_ssid[1]);
page += FPSTR(HTTP_FORM_END);
if (HTTP_MANAGER == webserver_state) {
}
if (WifiIsInManagerMode()) {
page += FPSTR(HTTP_BTN_RSTRT);
#ifndef FIRMWARE_MINIMAL
page += FPSTR(HTTP_BTN_RESET);
#endif // FIRMWARE_MINIMAL
} else {
page += FPSTR(HTTP_BTN_CONF);
}
// ShowPage(page);
ShowPage(page, !(HTTP_MANAGER == webserver_state));
ShowPage(page, !(WifiIsInManagerMode()));
}
void WifiSaveSettings(void)
@ -1236,9 +1257,9 @@ void WifiSaveSettings(void)
WebGetArg("s2", tmp, sizeof(tmp));
strlcpy(Settings.sta_ssid[1], (!strlen(tmp)) ? STA_SSID2 : tmp, sizeof(Settings.sta_ssid[1]));
WebGetArg("p1", tmp, sizeof(tmp));
strlcpy(Settings.sta_pwd[0], (!strlen(tmp)) ? "" : (!strcmp(tmp,D_ASTERISK_PWD)) ? Settings.sta_pwd[0] : tmp, sizeof(Settings.sta_pwd[0]));
strlcpy(Settings.sta_pwd[0], (!strlen(tmp)) ? "" : (strlen(tmp) < 5) ? Settings.sta_pwd[0] : tmp, sizeof(Settings.sta_pwd[0]));
WebGetArg("p2", tmp, sizeof(tmp));
strlcpy(Settings.sta_pwd[1], (!strlen(tmp)) ? "" : (!strcmp(tmp,D_ASTERISK_PWD)) ? Settings.sta_pwd[1] : tmp, sizeof(Settings.sta_pwd[1]));
strlcpy(Settings.sta_pwd[1], (!strlen(tmp)) ? "" : (strlen(tmp) < 5) ? Settings.sta_pwd[1] : tmp, sizeof(Settings.sta_pwd[1]));
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_CMND_HOSTNAME " %s, " D_CMND_SSID "1 %s, " D_CMND_SSID "2 %s"),
Settings.hostname, Settings.sta_ssid[0], Settings.sta_ssid[1]);
AddLog(LOG_LEVEL_INFO);
@ -1475,7 +1496,7 @@ void HandleResetConfiguration(void)
page += F("<div style='text-align:center;'>" D_CONFIGURATION_RESET "</div>");
page += FPSTR(HTTP_MSG_RSTRT);
page += FPSTR(HTTP_BTN_MAIN);
ShowPage(page);
ShowPage(page, HTTP_MANAGER_RESET_ONLY != webserver_state);
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RESET " 1"));
ExecuteWebCommand(svalue, SRC_WEBGUI);
@ -1935,8 +1956,6 @@ void HandleHttpCommand(void)
{
if (!HttpCheckPriviledgedAccess(false)) { return; }
char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND));
uint8_t valid = 1;
@ -1951,9 +1970,9 @@ void HandleHttpCommand(void)
String message = F("{\"" D_RSLT_WARNING "\":\"");
if (valid) {
uint8_t curridx = web_log_index;
WebGetArg("cmnd", svalue, sizeof(svalue));
if (strlen(svalue)) {
ExecuteWebCommand(svalue, SRC_WEBCOMMAND);
String svalue = WebServer->arg("cmnd");
if (svalue.length() && (svalue.length() < INPUT_BUFFER_SIZE)) {
ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE);
if (web_log_index != curridx) {
uint8_t counter = curridx;
@ -1968,6 +1987,7 @@ void HandleHttpCommand(void)
if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O])
if (message.length() > 1) { message += F(","); }
size_t JSONlen = len - (JSON - tmp);
if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); }
strlcpy(mqtt_data, JSON +1, JSONlen -2);
message += mqtt_data;
}
@ -2010,19 +2030,19 @@ void HandleAjaxConsoleRefresh(void)
{
if (!HttpCheckPriviledgedAccess()) { return; }
char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog
bool cflg = true;
uint8_t counter = 0; // Initial start, should never be 0 again
WebGetArg("c1", svalue, sizeof(svalue));
if (strlen(svalue)) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue);
String svalue = WebServer->arg("c1");
if (svalue.length() && (svalue.length() < INPUT_BUFFER_SIZE)) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue.c_str());
AddLog(LOG_LEVEL_INFO);
ExecuteWebCommand(svalue, SRC_WEBCONSOLE);
ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE);
}
WebGetArg("c2", svalue, sizeof(svalue));
if (strlen(svalue)) { counter = atoi(svalue); }
char stmp[10];
WebGetArg("c2", stmp, sizeof(stmp));
if (strlen(stmp)) { counter = atoi(stmp); }
bool last_reset_web_log_flag = reset_web_log_flag;
// mqtt_data used as scratch space
@ -2047,6 +2067,7 @@ void HandleAjaxConsoleRefresh(void)
} else {
cflg = true;
}
if (len > sizeof(mqtt_data) -2) { len = sizeof(mqtt_data); }
strlcpy(mqtt_data, tmp, len);
message += mqtt_data; // mqtt_data used as scratch space
}
@ -2087,7 +2108,7 @@ void HandleNotFound(void)
/* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */
bool CaptivePortal(void)
{
if ((HTTP_MANAGER == webserver_state) && !ValidIpAddress(WebServer->hostHeader())) {
if ((WifiIsInManagerMode()) && !ValidIpAddress(WebServer->hostHeader())) {
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED));
WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true);
@ -2161,18 +2182,19 @@ int WebSend(char *buffer)
// buffer = | [ 192.168.178.86 : 80 , admin : joker ] POWER1 ON |
host = strtok_r(buffer, "]", &command); // host = | [ 192.168.178.86 : 80 , admin : joker |, command = | POWER1 ON |
if (host && command) {
String url = F("http:"); // url = |http:|
String url = F("http://"); // url = |http://|
host = Trim(host); // host = |[ 192.168.178.86 : 80 , admin : joker|
host++; // host = | 192.168.178.86 : 80 , admin : joker| - Skip [
host = strtok_r(host, ",", &user); // host = | 192.168.178.86 : 80 |, user = | admin : joker|
host = strtok_r(host, ":", &port); // host = | 192.168.178.86 |, port = | 80 |
host = Trim(host); // host = |192.168.178.86|
url += host; // url = |http://192.168.178.86|
if (port) {
port = Trim(port); // port = |80|
url += port; // url = |http:80|
url += F(":"); // url = |http://192.168.178.86:|
url += port; // url = |http://192.168.178.86:80|
}
url += F("//"); // url = |http://| or |http:80//|
url += host; // url = |http://192.168.178.86|
if (user) {
user = strtok_r(user, ":", &password); // user = | admin |, password = | joker|
@ -2197,8 +2219,14 @@ int WebSend(char *buffer)
//snprintf_P(log_data, sizeof(log_data), PSTR("DBG: Uri |%s|"), url.c_str());
//AddLog(LOG_LEVEL_DEBUG);
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
HTTPClient http;
if (http.begin(UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON|
#else
WiFiClient http_client;
HTTPClient http;
if (http.begin(http_client, UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON|
#endif
int http_code = http.GET(); // Start connection and send HTTP header
if (http_code > 0) { // http_code will be negative on error
if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) {
@ -2209,8 +2237,7 @@ int WebSend(char *buffer)
for (uint16_t i = 0; i < result.length(); i++) {
char text = result.charAt(i);
if (text > 31) { // Remove control characters like linefeed
mqtt_data[j] = result.charAt(i);
j++;
mqtt_data[j++] = text;
if (j == sizeof(mqtt_data) -2) { break; }
}
}
@ -2222,7 +2249,7 @@ int WebSend(char *buffer)
} else {
status = 2; // Connection failed
}
http.end();
http.end(); // Clean up connection data
} else {
status = 3; // Host not found or connection error
}

View File

@ -170,7 +170,7 @@ void Ws2812Clock(void)
Ws2812UpdateHand((RtcTime.second * 1000) / clksize, WS_SECOND);
Ws2812UpdateHand((RtcTime.minute * 1000) / clksize, WS_MINUTE);
Ws2812UpdateHand(((RtcTime.hour % 12) * (5000 / clksize)) + ((RtcTime.minute * 1000) / (12 * clksize)), WS_HOUR);
Ws2812UpdateHand((((RtcTime.hour % 12) * 5000) + ((RtcTime.minute * 1000) / 12 )) / clksize, WS_HOUR);
if (Settings.ws_color[WS_MARKER][WS_RED] + Settings.ws_color[WS_MARKER][WS_GREEN] + Settings.ws_color[WS_MARKER][WS_BLUE]) {
for (uint8_t i = 0; i < 12; i++) {
Ws2812UpdateHand((i * 5000) / clksize, WS_MARKER);

View File

@ -866,11 +866,15 @@ Setting_6_4_1_16.update({
'pullup': ('B', (0x73C,1,1), (None, None, ('Management', None)) ),
}, 0x73C, (None, None, ('Management', None))
),
}, 0x720, (None, None, ('Management', '"Template GPIO:{}".format(@["user_template"]["gp"][0])'))
}, 0x720, (None, None, ('Management', None))
),
})
# ======================================================================
Setting_6_4_1_17 = copy.deepcopy(Setting_6_4_1_16)
Setting_6_4_1_17['flag3'][0].pop('no_pullup',None)
# ======================================================================
Settings = [
(0x6040111, 0xe00, Setting_6_4_1_17),
(0x6040110, 0xe00, Setting_6_4_1_16),
(0x604010D, 0xe00, Setting_6_4_1_13),
(0x604010B, 0xe00, Setting_6_4_1_11),