3.9.13 20170210
* Add FlashChipSize to Status 4
* Removed redundant DHT2 option and code
* Add Sonoff SV GPIO pin 05 configuration (#40)
* Add configuration file backup and restore via web page
* Fix latency due to light_sleep mode even if sleep was set to zero
(#50)
This commit is contained in:
arendst 2017-02-10 17:03:34 +01:00
parent 971ffef4a9
commit cbd1904b42
9 changed files with 231 additions and 266 deletions

View File

@ -1,7 +1,7 @@
## Sonoff-Tasmota ## Sonoff-Tasmota
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
Current version is **3.9.12** - See ```sonoff/_releasenotes.ino``` for change information. Current version is **3.9.13** - See ```sonoff/_releasenotes.ino``` for change information.
- This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic. - This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic.
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```. - Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.

Binary file not shown.

View File

@ -1,4 +1,11 @@
/* 3.9.12 20170208 /* 3.9.13 20170210
* Add FlashChipSize to Status 4
* Removed redundant DHT2 option and code
* Add Sonoff SV GPIO pin 05 configuration (#40)
* Add configuration file backup and restore via web page
* Fix latency due to light_sleep mode even if sleep was set to zero (#50)
*
* 3.9.12 20170208
* Fix compile error when webserver is disabled (#30) * Fix compile error when webserver is disabled (#30)
* Fix possible ESP8285 flash problem by updating Flash Chip Mode to DOUT during OTA upload * Fix possible ESP8285 flash problem by updating Flash Chip Mode to DOUT during OTA upload
* Fix hostname issues by not allowing user entry of string formatting and removing from user_config.h (#36) * Fix hostname issues by not allowing user entry of string formatting and removing from user_config.h (#36)

View File

@ -10,7 +10,7 @@
* ==================================================== * ====================================================
*/ */
#define VERSION 0x03090C00 // 3.9.12 #define VERSION 0x03090D00 // 3.9.13
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
enum week_t {Last, First, Second, Third, Fourth}; enum week_t {Last, First, Second, Third, Fourth};
@ -59,6 +59,8 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#endif #endif
#define WIFI_HOSTNAME "%s-%04d" // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address> #define WIFI_HOSTNAME "%s-%04d" // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address>
#define CONFIG_FILE_SIGN 0xA5 // Configuration file signature
#define CONFIG_FILE_XOR 0x5A // Configuration file xor (0 = No Xor)
#define HLW_PREF_PULSE 12530 // was 4975us = 201Hz = 1000W #define HLW_PREF_PULSE 12530 // was 4975us = 201Hz = 1000W
#define HLW_UREF_PULSE 1950 // was 1666us = 600Hz = 220V #define HLW_UREF_PULSE 1950 // was 1666us = 600Hz = 220V
@ -93,7 +95,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#endif #endif
#define APP_BAUDRATE 115200 // Default serial baudrate #define APP_BAUDRATE 115200 // Default serial baudrate
#define MAX_STATUS 10 #define MAX_STATUS 10 // Max number of status lines
enum butt_t {PRESSED, NOT_PRESSED}; enum butt_t {PRESSED, NOT_PRESSED};
@ -410,7 +412,7 @@ boolean mDNSbegun = false;
/********************************************************************************************/ /********************************************************************************************/
void CFG_DefaultSet() void CFG_DefaultSet1()
{ {
memset(&sysCfg, 0x00, sizeof(SYSCFG)); memset(&sysCfg, 0x00, sizeof(SYSCFG));
@ -418,7 +420,11 @@ void CFG_DefaultSet()
sysCfg.saveFlag = 0; sysCfg.saveFlag = 0;
sysCfg.version = VERSION; sysCfg.version = VERSION;
sysCfg.bootcount = 0; sysCfg.bootcount = 0;
sysCfg.migflg = 0; }
void CFG_DefaultSet2()
{
sysCfg.migflg = 0xA5;
sysCfg.savedata = SAVE_DATA; sysCfg.savedata = SAVE_DATA;
sysCfg.savestate = SAVE_STATE; sysCfg.savestate = SAVE_STATE;
sysCfg.module = MODULE; sysCfg.module = MODULE;
@ -537,14 +543,16 @@ void CFG_DefaultSet()
void CFG_Default() void CFG_Default()
{ {
addLog_P(LOG_LEVEL_NONE, PSTR("Config: Use default configuration")); addLog_P(LOG_LEVEL_NONE, PSTR("Config: Use default configuration"));
CFG_DefaultSet(); CFG_DefaultSet1();
CFG_DefaultSet2();
CFG_Save(); CFG_Save();
} }
void CFG_Migrate_Part2() void CFG_Migrate_Part2()
{ {
addLog_P(LOG_LEVEL_NONE, PSTR("Config: Migrating configuration")); addLog_P(LOG_LEVEL_NONE, PSTR("Config: Migrating configuration"));
CFG_DefaultSet(); CFG_DefaultSet1();
CFG_DefaultSet2();
sysCfg.seriallog_level = sysCfg2.seriallog_level; sysCfg.seriallog_level = sysCfg2.seriallog_level;
sysCfg.syslog_level = sysCfg2.syslog_level; sysCfg.syslog_level = sysCfg2.syslog_level;
@ -1300,6 +1308,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
} }
else if (!strcmp(type,"SLEEP")) { else if (!strcmp(type,"SLEEP")) {
if ((data_len > 0) && (payload >= 0) && (payload < 251)) { if ((data_len > 0) && (payload >= 0) && (payload < 251)) {
if ((!sysCfg.sleep && payload) || (sysCfg.sleep && !payload)) restartflag = 2;
sysCfg.sleep = payload; sysCfg.sleep = payload;
sleep = payload; sleep = payload;
// restartflag = 2; // restartflag = 2;
@ -1877,9 +1886,9 @@ void publish_status(uint8_t payload)
} }
if ((payload == 0) || (payload == 4)) { if ((payload == 0) || (payload == 4)) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMEM\":{\"ProgramSize\":%d, \"Free\":%d, \"Heap\":%d, \"SpiffsStart\":%d, \"SpiffsSize\":%d, \"FlashSize\":%d, \"ProgramFlashSize\":%d}}"), snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMEM\":{\"ProgramSize\":%d, \"Free\":%d, \"Heap\":%d, \"SpiffsStart\":%d, \"SpiffsSize\":%d, \"FlashSize\":%d, \"ProgramFlashSize\":%d, \"FlashChipMode\",%d}}"),
ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ((uint32_t)&_SPIFFS_start - 0x40200000)/1024, ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ((uint32_t)&_SPIFFS_start - 0x40200000)/1024,
(((uint32_t)&_SPIFFS_end - 0x40200000) - ((uint32_t)&_SPIFFS_start - 0x40200000))/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipSize()/1024); (((uint32_t)&_SPIFFS_end - 0x40200000) - ((uint32_t)&_SPIFFS_start - 0x40200000))/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipSize()/1024, ESP.getFlashChipMode());
mqtt_publish_topic_P(option, PSTR("STATUS4"), svalue); mqtt_publish_topic_P(option, PSTR("STATUS4"), svalue);
} }

View File

@ -17,41 +17,41 @@
#define GPIO_SWT1 8 // User connected external switches #define GPIO_SWT1 8 // User connected external switches
#define GPIO_SENSOR_END 9 #define GPIO_SENSOR_END 9
#define GPIO_SWT2 9 #define GPIO_SWT2 GPIO_SENSOR_END
#define GPIO_SWT3 10 #define GPIO_SWT3 GPIO_SENSOR_END +1
#define GPIO_SWT4 11 #define GPIO_SWT4 GPIO_SENSOR_END +2
#define GPIO_KEY1 12 // Button usually connected to GPIO0 #define GPIO_KEY1 GPIO_SENSOR_END +3 // Button usually connected to GPIO0
#define GPIO_KEY2 13 #define GPIO_KEY2 GPIO_SENSOR_END +4
#define GPIO_KEY3 14 #define GPIO_KEY3 GPIO_SENSOR_END +5
#define GPIO_KEY4 15 #define GPIO_KEY4 GPIO_SENSOR_END +6
#define GPIO_REL1 16 // Relays #define GPIO_REL1 GPIO_SENSOR_END +7 // Relays
#define GPIO_REL2 17 #define GPIO_REL2 GPIO_SENSOR_END +8
#define GPIO_REL3 18 #define GPIO_REL3 GPIO_SENSOR_END +9
#define GPIO_REL4 19 #define GPIO_REL4 GPIO_SENSOR_END +10
#define GPIO_REL1_INV 20 #define GPIO_REL1_INV GPIO_SENSOR_END +11
#define GPIO_REL2_INV 21 #define GPIO_REL2_INV GPIO_SENSOR_END +12
#define GPIO_REL3_INV 22 #define GPIO_REL3_INV GPIO_SENSOR_END +13
#define GPIO_REL4_INV 23 #define GPIO_REL4_INV GPIO_SENSOR_END +14
#define GPIO_LED1 24 // Leds #define GPIO_LED1 GPIO_SENSOR_END +15 // Leds
#define GPIO_LED2 25 #define GPIO_LED2 GPIO_SENSOR_END +16
#define GPIO_LED3 26 #define GPIO_LED3 GPIO_SENSOR_END +17
#define GPIO_LED4 27 #define GPIO_LED4 GPIO_SENSOR_END +18
#define GPIO_LED1_INV 28 #define GPIO_LED1_INV GPIO_SENSOR_END +19
#define GPIO_LED2_INV 29 #define GPIO_LED2_INV GPIO_SENSOR_END +20
#define GPIO_LED3_INV 30 #define GPIO_LED3_INV GPIO_SENSOR_END +21
#define GPIO_LED4_INV 31 #define GPIO_LED4_INV GPIO_SENSOR_END +22
#define GPIO_PWM0 32 // Cold #define GPIO_PWM0 GPIO_SENSOR_END +23 // Cold
#define GPIO_PWM1 33 // Warm #define GPIO_PWM1 GPIO_SENSOR_END +24 // Warm
#define GPIO_PWM2 34 // Red (swapped with Blue from original) #define GPIO_PWM2 GPIO_SENSOR_END +25 // Red (swapped with Blue from original)
#define GPIO_PWM3 35 // Green #define GPIO_PWM3 GPIO_SENSOR_END +26 // Green
#define GPIO_PWM4 36 // Blue (swapped with Red from original) #define GPIO_PWM4 GPIO_SENSOR_END +27 // Blue (swapped with Red from original)
#define GPIO_RXD 37 // Serial interface #define GPIO_RXD GPIO_SENSOR_END +28 // Serial interface
#define GPIO_TXD 38 // Serial interface #define GPIO_TXD GPIO_SENSOR_END +29 // Serial interface
#define GPIO_HLW_SEL 39 // HLW8012 Sel output (Sonoff Pow) #define GPIO_HLW_SEL GPIO_SENSOR_END +30 // HLW8012 Sel output (Sonoff Pow)
#define GPIO_HLW_CF1 40 // HLW8012 CF1 voltage / current (Sonoff Pow) #define GPIO_HLW_CF1 GPIO_SENSOR_END +31 // HLW8012 CF1 voltage / current (Sonoff Pow)
#define GPIO_HLW_CF 41 // HLW8012 CF power (Sonoff Pow) #define GPIO_HLW_CF GPIO_SENSOR_END +32 // HLW8012 CF power (Sonoff Pow)
#define GPIO_USER 42 // User configurable #define GPIO_USER GPIO_SENSOR_END +33 // User configurable
#define GPIO_MAX 43 #define GPIO_MAX GPIO_SENSOR_END +34
/********************************************************************************************/ /********************************************************************************************/
@ -108,7 +108,8 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
0, 0, 0, 0,
GPIO_USER, // GPIO03 Serial TXD and Optional sensor GPIO_USER, // GPIO03 Serial TXD and Optional sensor
GPIO_USER, // GPIO04 Optional sensor GPIO_USER, // GPIO04 Optional sensor
0, 0, 0, 0, 0, 0, 0, GPIO_USER, // GPIO05 Optional sensor
0, 0, 0, 0, 0, 0,
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off)
GPIO_USER, // GPIO14 Optional sensor GPIO_USER, // GPIO14 Optional sensor
@ -237,7 +238,8 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
GPIO_USER, // GPIO02 Optional sensor GPIO_USER, // GPIO02 Optional sensor
GPIO_USER, // GPIO03 Serial TXD and Optional sensor GPIO_USER, // GPIO03 Serial TXD and Optional sensor
GPIO_USER, // GPIO04 Optional sensor GPIO_USER, // GPIO04 Optional sensor
0, 0, 0, 0, 0, 0, 0, GPIO_USER, // GPIO05 Optional sensor
0, 0, 0, 0, 0, 0,
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off)
GPIO_USER, // GPIO14 Optional sensor GPIO_USER, // GPIO14 Optional sensor

View File

@ -436,7 +436,8 @@ void WIFI_begin(uint8_t flag)
WiFi.disconnect(); WiFi.disconnect();
WiFi.mode(WIFI_STA); // Disable AP mode WiFi.mode(WIFI_STA); // Disable AP mode
// if (sysCfg.sleep) wifi_set_sleep_type(LIGHT_SLEEP_T); // Allow light sleep during idle times // if (sysCfg.sleep) wifi_set_sleep_type(LIGHT_SLEEP_T); // Allow light sleep during idle times
WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times if (sysCfg.sleep) WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
// WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) WiFi.setPhyMode(WIFI_PHY_MODE_11N); // if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) WiFi.setPhyMode(WIFI_PHY_MODE_11N);
if (!WiFi.getAutoConnect()) WiFi.setAutoConnect(true); if (!WiFi.getAutoConnect()) WiFi.setAutoConnect(true);
// WiFi.setAutoReconnect(true); // WiFi.setAutoReconnect(true);

View File

@ -117,7 +117,6 @@
#define PRESSURE_RESOLUTION 1 // Maximum number of decimals (0 - 3) showing sensor Pressure #define PRESSURE_RESOLUTION 1 // Maximum number of decimals (0 - 3) showing sensor Pressure
// -- Sensor code selection ----------------------- // -- Sensor code selection -----------------------
//#define USE_DHT2 // Optional using Adafruit DHT library
//#define USE_DS18x20 // Optional using OneWire library for multiple DS18B20 and/or DS18S20 //#define USE_DS18x20 // Optional using OneWire library for multiple DS18B20 and/or DS18S20
#define USE_I2C // I2C using library wire (+10k code, 0.2k mem) - Disable by // #define USE_I2C // I2C using library wire (+10k code, 0.2k mem) - Disable by //

View File

@ -110,7 +110,9 @@ const char HTTP_BTN_MENU3[] PROGMEM =
const char HTTP_BTN_MENU4[] PROGMEM = const char HTTP_BTN_MENU4[] PROGMEM =
"<br/><form action='/lg' method='post'><button>Configure Logging</button></form>" "<br/><form action='/lg' method='post'><button>Configure Logging</button></form>"
"<br/><form action='/co' method='post'><button>Configure Other</button></form>" "<br/><form action='/co' method='post'><button>Configure Other</button></form>"
"<br/><form action='/rt' method='post' onsubmit='return confirm(\"Confirm Reset Configuration\");'><button>Reset Configuration</button></form>"; "<br/><form action='/rt' method='post' onsubmit='return confirm(\"Confirm Reset Configuration\");'><button>Reset Configuration</button></form>"
"<br/><form action='/dl' method='post'><button>Backup Configuration</button></form>"
"<br/><form action='/rs' method='post'><button>Restore Configuration</button></form>";
const char HTTP_BTN_MAIN[] PROGMEM = const char HTTP_BTN_MAIN[] PROGMEM =
"<br/><br/><form action='/' method='post'><button>Main menu</button></form>"; "<br/><br/><form action='/' method='post'><button>Main menu</button></form>";
const char HTTP_BTN_CONF[] PROGMEM = const char HTTP_BTN_CONF[] PROGMEM =
@ -170,6 +172,15 @@ const char HTTP_FORM_OTHER3[] PROGMEM =
#endif // USE_EMULATION #endif // USE_EMULATION
const char HTTP_FORM_END[] PROGMEM = const char HTTP_FORM_END[] PROGMEM =
"<br/><button type='submit'>Save</button></form></fieldset>"; "<br/><button type='submit'>Save</button></form></fieldset>";
const char HTTP_FORM_RST[] PROGMEM =
"<div id='f1' name='f1' style='display:block;'>"
"<fieldset><legend><b>&nbsp;Restore configuration&nbsp;</b></legend>"
"<form method='post' action='u2' enctype='multipart/form-data'>"
"<br/><input type='file' name='u2'><br/>"
"<br/><button type='submit' onclick='document.getElementById(\"f1\").style.display=\"none\";document.getElementById(\"f2\").style.display=\"block\";this.form.submit();'>Start restore</button></form>"
"</fieldset>"
"</div>"
"<div id='f2' name='f2' style='display:none;text-align:center;'><b>Restore started ...</b></div>";
const char HTTP_FORM_UPG[] PROGMEM = const char HTTP_FORM_UPG[] PROGMEM =
"<div id='f1' name='f1' style='display:block;'>" "<div id='f1' name='f1' style='display:block;'>"
"<fieldset><legend><b>&nbsp;Upgrade by web server&nbsp;</b></legend>" "<fieldset><legend><b>&nbsp;Upgrade by web server&nbsp;</b></legend>"
@ -319,7 +330,8 @@ DNSServer *dnsServer;
ESP8266WebServer *webServer; ESP8266WebServer *webServer;
boolean _removeDuplicateAPs = true; boolean _removeDuplicateAPs = true;
int _minimumQuality = -1, _httpflag = HTTP_OFF, _uploaderror = 0, _colcount; int _minimumQuality = -1;
uint8_t _httpflag = HTTP_OFF, _uploaderror = 0, _uploadfiletype, _colcount;
void startWebserver(int type, IPAddress ipweb) void startWebserver(int type, IPAddress ipweb)
{ {
@ -341,10 +353,12 @@ void startWebserver(int type, IPAddress ipweb)
} }
webServer->on("/lg", handleLog); webServer->on("/lg", handleLog);
webServer->on("/co", handleOther); webServer->on("/co", handleOther);
webServer->on("/dl", handleDownload);
webServer->on("/sv", handleSave); webServer->on("/sv", handleSave);
webServer->on("/rs", handleRestore);
webServer->on("/rt", handleReset); webServer->on("/rt", handleReset);
webServer->on("/up", handleUpgrade); webServer->on("/up", handleUpgrade);
webServer->on("/u1", handleUpgradeStart); webServer->on("/u1", handleUpgradeStart); // OTA
webServer->on("/u2", HTTP_POST, handleUploadDone, handleUploadLoop); webServer->on("/u2", HTTP_POST, handleUploadDone, handleUploadLoop);
webServer->on("/cm", handleCmnd); webServer->on("/cm", handleCmnd);
webServer->on("/cs", handleConsole); webServer->on("/cs", handleConsole);
@ -508,12 +522,16 @@ void handleRoot()
} }
} }
boolean httpUser()
{
boolean status = (_httpflag == HTTP_USER);
if (status) handleRoot();
return status;
}
void handleConfig() void handleConfig()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle config")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle config"));
String page = FPSTR(HTTP_HEAD); String page = FPSTR(HTTP_HEAD);
@ -527,11 +545,7 @@ void handleConfig()
void handleModule() void handleModule()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
char stemp[20]; char stemp[20];
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Module config")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Module config"));
@ -585,10 +599,7 @@ void handleWifi0()
void handleWifi(boolean scan) void handleWifi(boolean scan)
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
char log[LOGSZ]; char log[LOGSZ];
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Wifi config")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Wifi config"));
@ -686,10 +697,7 @@ void handleWifi(boolean scan)
void handleMqtt() void handleMqtt()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle MQTT config")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle MQTT config"));
String page = FPSTR(HTTP_HEAD); String page = FPSTR(HTTP_HEAD);
@ -711,10 +719,7 @@ void handleMqtt()
void handleLog() void handleLog()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Log config")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Log config"));
String page = FPSTR(HTTP_HEAD); String page = FPSTR(HTTP_HEAD);
@ -760,10 +765,7 @@ void handleLog()
void handleOther() void handleOther()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle other config")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle other config"));
char stemp[40]; char stemp[40];
@ -794,12 +796,33 @@ void handleOther()
showPage(page); showPage(page);
} }
void handleDownload()
{
if (httpUser()) return;
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle download config"));
uint8_t buffer[sizeof(sysCfg)];
WiFiClient myClient = webServer->client();
webServer->setContentLength(4096);
String attachment = F("attachment; filename=Config_");
attachment += sysCfg.friendlyname[0];
attachment += F("_");
attachment += Version;
attachment += F(".dmp");
webServer->sendHeader("Content-Disposition", attachment);
webServer->send(200, "application/octet-stream", "");
memcpy(buffer, &sysCfg, sizeof(sysCfg));
buffer[0] = CONFIG_FILE_SIGN;
buffer[1] = (!CONFIG_FILE_XOR)?0:1;
if (buffer[1]) for (uint16_t i = 2; i < sizeof(buffer); i++) buffer[i] ^= (CONFIG_FILE_XOR +i);
myClient.write((const char*)buffer, sizeof(buffer));
}
void handleSave() void handleSave()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
char log[LOGSZ], stemp[20]; char log[LOGSZ], stemp[20];
byte what = 0, restart; byte what = 0, restart;
String result = ""; String result = "";
@ -903,10 +926,8 @@ void handleSave()
void handleReset() void handleReset()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
char svalue[MESSZ]; char svalue[MESSZ];
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Reset parameters")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Reset parameters"));
@ -922,12 +943,24 @@ void handleReset()
do_cmnd(svalue); do_cmnd(svalue);
} }
void handleRestore()
{
if (httpUser()) return;
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle restore"));
String page = FPSTR(HTTP_HEAD);
page.replace("{v}", "Restore Configuration");
page += FPSTR(HTTP_FORM_RST);
page += FPSTR(HTTP_BTN_CONF);
showPage(page);
_uploaderror = 0;
_uploadfiletype = 1;
}
void handleUpgrade() void handleUpgrade()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle upgrade")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle upgrade"));
String page = FPSTR(HTTP_HEAD); String page = FPSTR(HTTP_HEAD);
@ -938,14 +971,12 @@ void handleUpgrade()
showPage(page); showPage(page);
_uploaderror = 0; _uploaderror = 0;
_uploadfiletype = 0;
} }
void handleUpgradeStart() void handleUpgradeStart()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
char svalue[MESSZ]; char svalue[MESSZ];
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Firmware upgrade start")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Firmware upgrade start"));
@ -969,12 +1000,10 @@ void handleUpgradeStart()
void handleUploadDone() void handleUploadDone()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot(); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: File upload done"));
return;
}
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Firmware upload done")); char log[LOGSZ];
WIFI_configCounter(); WIFI_configCounter();
restartflag = 0; restartflag = 0;
mqttcounter = 0; mqttcounter = 0;
@ -984,28 +1013,36 @@ void handleUploadDone()
page += F("<div style='text-align:center;'><b>Upload "); page += F("<div style='text-align:center;'><b>Upload ");
if (_uploaderror) { if (_uploaderror) {
page += F("<font color='red'>failed</font></b><br/><br/>"); page += F("<font color='red'>failed</font></b><br/><br/>");
String error = "";
if (_uploaderror == 1) { if (_uploaderror == 1) {
page += F("No file selected"); error = F("No file selected");
} else if (_uploaderror == 2) { } else if (_uploaderror == 2) {
page += F("File size is larger than available free space"); error = F("File size is larger than available free space");
} else if (_uploaderror == 3) { } else if (_uploaderror == 3) {
page += F("File magic header does not start with 0xE9"); error = F("File magic header does not start with 0xE9");
} else if (_uploaderror == 4) { } else if (_uploaderror == 4) {
page += F("File flash size is larger than device flash size"); error = F("File flash size is larger than device flash size");
} else if (_uploaderror == 5) { } else if (_uploaderror == 5) {
page += F("File upload buffer miscompare"); error = F("File upload buffer miscompare");
} else if (_uploaderror == 6) { } else if (_uploaderror == 6) {
page += F("Upload failed. Enable logging option 3 for more information"); error = F("Upload failed. Enable logging option 3 for more information");
} else if (_uploaderror == 7) { } else if (_uploaderror == 7) {
page += F("Upload aborted"); error = F("Upload aborted");
} else if (_uploaderror == 8) {
error = F("Invalid configuration file");
} else if (_uploaderror == 9) {
error = F("Configuration file too large");
} else { } else {
page += F("Upload error code "); error = F("Upload error code ");
page += String(_uploaderror); error += String(_uploaderror);
} }
if (Update.hasError()) { page += error;
if (!_uploadfiletype && Update.hasError()) {
page += F("<br/><br/>Update error code (see Updater.cpp) "); page += F("<br/><br/>Update error code (see Updater.cpp) ");
page += String(Update.getError()); page += String(Update.getError());
} }
snprintf_P(log, sizeof(log), PSTR("Upload: Error - %s"), error.c_str());
addLog(LOG_LEVEL_DEBUG, log);
} else { } else {
page += F("<font color='green'>successful</font></b><br/><br/>Device will restart in a few seconds"); page += F("<font color='green'>successful</font></b><br/><br/>Device will restart in a few seconds");
restartflag = 2; restartflag = 2;
@ -1023,7 +1060,7 @@ void handleUploadLoop()
if (_httpflag == HTTP_USER) return; if (_httpflag == HTTP_USER) return;
if (_uploaderror) { if (_uploaderror) {
Update.end(); if (!_uploadfiletype) Update.end();
return; return;
} }
@ -1031,82 +1068,97 @@ void handleUploadLoop()
if (upload.status == UPLOAD_FILE_START) { if (upload.status == UPLOAD_FILE_START) {
restartflag = 60; restartflag = 60;
mqttcounter = 60; if (upload.filename.c_str()[0] == 0) {
if (upload.filename.c_str()[0] == 0)
{
_uploaderror = 1; _uploaderror = 1;
return; return;
} }
#ifdef USE_EMULATION
UDP_Disconnect();
#endif // USE_EMULATION
if (sysCfg.mqtt_enabled) mqttClient.disconnect();
snprintf_P(log, sizeof(log), PSTR("Upload: File %s ..."), upload.filename.c_str()); snprintf_P(log, sizeof(log), PSTR("Upload: File %s ..."), upload.filename.c_str());
addLog(LOG_LEVEL_INFO, log); addLog(LOG_LEVEL_INFO, log);
if (!_uploadfiletype) {
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; mqttcounter = 60;
if (!Update.begin(maxSketchSpace)) { //start with max available size #ifdef USE_EMULATION
if (_serialoutput) Update.printError(Serial); UDP_Disconnect();
_uploaderror = 2; #endif // USE_EMULATION
return; if (sysCfg.mqtt_enabled) mqttClient.disconnect();
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if (!Update.begin(maxSketchSpace)) { //start with max available size
if (_serialoutput) Update.printError(Serial);
_uploaderror = 2;
return;
}
} }
_colcount = 0; _colcount = 0;
} else if (!_uploaderror && (upload.status == UPLOAD_FILE_WRITE)) { } else if (!_uploaderror && (upload.status == UPLOAD_FILE_WRITE)) {
if (upload.totalSize == 0) if (upload.totalSize == 0)
{ {
if (upload.buf[0] != 0xE9) { if (_uploadfiletype) {
addLog_P(LOG_LEVEL_DEBUG, PSTR("Upload: File magic header does not start with 0xE9")); if (upload.buf[0] != CONFIG_FILE_SIGN) {
_uploaderror = 3; _uploaderror = 8;
return;
}
if (upload.currentSize > sizeof(sysCfg)) {
_uploaderror = 9;
return;
}
} else {
if (upload.buf[0] != 0xE9) {
_uploaderror = 3;
return;
}
uint32_t bin_flash_size = ESP.magicFlashChipSize((upload.buf[3] & 0xf0) >> 4);
if(bin_flash_size > ESP.getFlashChipRealSize()) {
_uploaderror = 4;
return;
}
if ((sysCfg.module == SONOFF_TOUCH) || (sysCfg.module == SONOFF_4CH)) {
upload.buf[2] = 3; // DOUT - ESP8285
addLog_P(LOG_LEVEL_DEBUG, PSTR("FLSH: Updated Flash Chip Mode to 3"));
}
}
}
if (_uploadfiletype) { // config
if (!_uploaderror) {
if (upload.buf[1]) for (uint16_t i = 2; i < upload.currentSize; i++) upload.buf[i] ^= (CONFIG_FILE_XOR +i);
CFG_DefaultSet2();
memcpy((char*)&sysCfg +16, upload.buf +16, upload.currentSize -16);
}
} else { // firmware
if (!_uploaderror && (Update.write(upload.buf, upload.currentSize) != upload.currentSize)) {
if (_serialoutput) Update.printError(Serial);
_uploaderror = 5;
return; return;
} }
uint32_t bin_flash_size = ESP.magicFlashChipSize((upload.buf[3] & 0xf0) >> 4); if (_serialoutput) {
if(bin_flash_size > ESP.getFlashChipRealSize()) { Serial.printf(".");
addLog_P(LOG_LEVEL_DEBUG, PSTR("Upload: File flash size is larger than device flash size")); _colcount++;
_uploaderror = 4; if (!(_colcount % 80)) Serial.println();
return;
}
if ((sysCfg.module == SONOFF_TOUCH) || (sysCfg.module == SONOFF_4CH)) {
upload.buf[2] = 3; // DOUT - ESP8285
addLog_P(LOG_LEVEL_DEBUG, PSTR("FLSH: Updated Flash Chip Mode to 3"));
} }
} }
if (!_uploaderror && (Update.write(upload.buf, upload.currentSize) != upload.currentSize)) { } else if(!_uploaderror && (upload.status == UPLOAD_FILE_END)) {
if (_serialoutput) Update.printError(Serial);
_uploaderror = 5;
return;
}
if (_serialoutput) {
Serial.printf(".");
_colcount++;
if (!(_colcount % 80)) Serial.println();
}
} else if(!_uploaderror && (upload.status == UPLOAD_FILE_END)){
if (_serialoutput && (_colcount % 80)) Serial.println(); if (_serialoutput && (_colcount % 80)) Serial.println();
if (Update.end(true)) { // true to set the size to the current progress if (!_uploadfiletype) {
if (!Update.end(true)) { // true to set the size to the current progress
if (_serialoutput) Update.printError(Serial);
_uploaderror = 6;
return;
}
}
if (!_uploaderror) {
snprintf_P(log, sizeof(log), PSTR("Upload: Successful %u bytes. Restarting"), upload.totalSize); snprintf_P(log, sizeof(log), PSTR("Upload: Successful %u bytes. Restarting"), upload.totalSize);
addLog(LOG_LEVEL_INFO, log); addLog(LOG_LEVEL_INFO, log);
} else {
if (_serialoutput) Update.printError(Serial);
_uploaderror = 6;
return;
} }
} else if(upload.status == UPLOAD_FILE_ABORTED) { } else if(upload.status == UPLOAD_FILE_ABORTED) {
addLog_P(LOG_LEVEL_DEBUG, PSTR("Upload: Update was aborted"));
restartflag = 0; restartflag = 0;
mqttcounter = 0; mqttcounter = 0;
_uploaderror = 7; _uploaderror = 7;
Update.end(); if (!_uploadfiletype) Update.end();
} }
delay(0); delay(0);
} }
void handleCmnd() void handleCmnd()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
char svalue[MESSZ]; char svalue[MESSZ];
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle cmnd")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle cmnd"));
@ -1147,10 +1199,7 @@ void handleCmnd()
void handleConsole() void handleConsole()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
char svalue[MESSZ]; char svalue[MESSZ];
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle console")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle console"));
@ -1170,10 +1219,7 @@ void handleConsole()
void handleAjax() void handleAjax()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
String message = ""; String message = "";
uint16_t size = 0; uint16_t size = 0;
@ -1201,10 +1247,7 @@ void handleAjax()
void handleInfo() void handleInfo()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle info")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle info"));
int freeMem = ESP.getFreeHeap(); int freeMem = ESP.getFreeHeap();
@ -1302,10 +1345,7 @@ void handleInfo()
void handleRestart() void handleRestart()
{ {
if (_httpflag == HTTP_USER) { if (httpUser()) return;
handleRoot();
return;
}
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Restarting")); addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Restarting"));
String page = FPSTR(HTTP_HEAD); String page = FPSTR(HTTP_HEAD);

View File

@ -1,93 +0,0 @@
/*
Copyright (c) 2017 Theo Arends. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef USE_DHT2
/*********************************************************************************************\
* DHT11, DHT21 (AM2301), DHT22 (AM2302, AM2321) - Temperature and Humidy
*
* Reading temperature or humidity takes about 250 milliseconds!
* Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
\*********************************************************************************************/
// WARNING: To use this DHT library you'll need to delete files DHT_U.cpp and DHT_U.h if present
#include "DHT.h"
DHT dht2(pin[GPIO_DHT11], dht_type);
float dht2_t, dht2_h = 0;
boolean dht_readTempHum(bool S, float &t, float &h)
{
h = dht2.readHumidity();
t = dht2.readTemperature(S);
if (!isnan(t)) dht2_t = t; else if (dht2_h) t = dht2_t;
if (!isnan(h)) dht2_h = h; else if (dht2_h) h = dht2_h;
return (!isnan(t) && !isnan(h));
}
void dht_init()
{
dht2.begin();
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
{
char stemp1[10], stemp2[10];
float t, h;
if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
snprintf_P(svalue, ssvalue, PSTR("%s, \"DHT\":{\"Temperature\":\"%s\", \"Humidity\":\"%s\"}"), svalue, stemp1, stemp2);
*djson = 1;
#ifdef USE_DOMOTICZ
domoticz_sensor2(stemp1, stemp2);
#endif // USE_DOMOTICZ
}
}
#ifdef USE_WEBSERVER
String dht_webPresent()
{
char stemp[10], sconv[10];
float t, h;
String page = "";
if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature as Celsius (the default)
snprintf_P(sconv, sizeof(sconv), PSTR("&deg;%c"), (TEMP_CONVERSION) ? 'F' : 'C');
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp);
page += F("<tr><td>DHT Temperature: </td><td>"); page += stemp; page += sconv; page += F("</td></tr>");
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp);
page += F("<tr><td>DHT Humidity: </td><td>"); page += stemp; page += F("%</td></tr>");
}
return page;
}
#endif // USE_WEBSERVER
#endif // USE_DHT2