mirror of https://github.com/arendst/Tasmota.git
v6.2.1
Version 6.2.1 20180905 * Fix possible ambiguity on command parameters if StateText contains numbers only (#3656) * Fix Wemo emulation to select the first relay when more than one relay is present (#3657) * Fix possible exception due to buffer overflow (#3659) * Fix lost energy today and total energy value after power cycle (#3689)
This commit is contained in:
parent
45ffd2cdc3
commit
28e3773113
|
@ -104,6 +104,12 @@ See [Tasmota ESP/Arduino library version related issues](https://github.com/aren
|
|||
| USE_RF_FLASH | - | - | x | x | x |
|
||||
|
||||
## Changelog
|
||||
Version 6.2.1 20180905
|
||||
* Fix possible ambiguity on command parameters if StateText contains numbers only (#3656)
|
||||
* Fix Wemo emulation to select the first relay when more than one relay is present (#3657)
|
||||
* Fix possible exception due to buffer overflow (#3659)
|
||||
* Fix lost energy today and total energy value after power cycle (#3689)
|
||||
|
||||
Version 6.2.0 20180901
|
||||
* Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561)
|
||||
* Disable wifi sleep for both Esp8266/Arduino core 2.4.1 and 2.4.2 to solve device freeze caused by Espressif SDK bug (#3554)
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
/* 6.2.0 20180901
|
||||
/* 6.2.1 20180905
|
||||
* Fix possible ambiguity on command parameters if StateText contains numbers only (#3656)
|
||||
* Fix Wemo emulation to select the first relay when more than one relay is present (#3657)
|
||||
* Fix possible exception due to buffer overflow (#3659)
|
||||
* Fix lost energy today and total energy value after power cycle (#3689)
|
||||
*
|
||||
* 6.2.0 20180901
|
||||
* Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561)
|
||||
* Disable wifi sleep for both Esp8266/Arduino core 2.4.1 and 2.4.2 to solve device freeze caused by Espressif SDK bug (#3554)
|
||||
* Change DS18B20 driver to provide better instant results
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||
* Use online command Prefix to translate cmnd, stat and tele.
|
||||
*
|
||||
* Updated until v6.1.1.5
|
||||
* Updated until v6.2.0.1
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
@ -60,10 +60,12 @@
|
|||
#define D_BLINKOFF "Мигане изкл."
|
||||
#define D_BOOT_COUNT "Брой на стартиранията"
|
||||
#define D_BRIGHTLIGHT "Яркост"
|
||||
#define D_BSSID "BSSId"
|
||||
#define D_BUTTON "Бутон"
|
||||
#define D_BY "от" // Written by me
|
||||
#define D_BYTES "Байта"
|
||||
#define D_CELSIUS "Целзий"
|
||||
#define D_CHANNEL "Канал"
|
||||
#define D_CO2 "Въглероден диоксид"
|
||||
#define D_CODE "код" // Button code
|
||||
#define D_COLDLIGHT "Хладна"
|
||||
|
@ -438,12 +440,12 @@
|
|||
#define D_PARTICALS_BEYOND "Частици"
|
||||
|
||||
// xsns_32_mpu6050.ino
|
||||
#define D_AX_AXIS "Accel. X-Axis"
|
||||
#define D_AY_AXIS "Accel. Y-Axis"
|
||||
#define D_AZ_AXIS "Accel. Z-Axis"
|
||||
#define D_GX_AXIS "Gyro X-Axis"
|
||||
#define D_GY_AXIS "Gyro Y-Axis"
|
||||
#define D_GZ_AXIS "Gyro Z-Axis"
|
||||
#define D_AX_AXIS "Ускорение - ос X"
|
||||
#define D_AY_AXIS "Ускорение - ос Y"
|
||||
#define D_AZ_AXIS "Ускорение - ос Z"
|
||||
#define D_GX_AXIS "Жироскоп - ос X"
|
||||
#define D_GY_AXIS "Жироскоп - ос Y"
|
||||
#define D_GZ_AXIS "Жироскоп - ос Z"
|
||||
|
||||
// sonoff_template.h
|
||||
#define D_SENSOR_NONE "Няма"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
|
||||
* Use online command Prefix to translate cmnd, stat and tele.
|
||||
*
|
||||
* Updated until v6.1.1c
|
||||
* Updated until v6.2.0.1
|
||||
\*********************************************************************/
|
||||
|
||||
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
@ -60,10 +60,12 @@
|
|||
#define D_BLINKOFF "BlinkOff"
|
||||
#define D_BOOT_COUNT "Conteo Reinicios"
|
||||
#define D_BRIGHTLIGHT "Brillante"
|
||||
#define D_BSSID "BSSId"
|
||||
#define D_BUTTON "Botón"
|
||||
#define D_BY "por" // Written by me
|
||||
#define D_BYTES "Bytes"
|
||||
#define D_CELSIUS "Celsius"
|
||||
#define D_CHANNEL "Canal"
|
||||
#define D_CO2 "CO2"
|
||||
#define D_CODE "código" // Button code
|
||||
#define D_COLDLIGHT "Fría"
|
||||
|
@ -460,7 +462,7 @@
|
|||
#define D_SENSOR_RELAY "Relé" // Suffix "1i"
|
||||
#define D_SENSOR_LED "Led" // Suffix "1i"
|
||||
#define D_SENSOR_PWM "PWM" // Suffix "1"
|
||||
#define D_SENSOR_COUNTER "Counter" // Suffix "1"
|
||||
#define D_SENSOR_COUNTER "Contador" // Suffix "1"
|
||||
#define D_SENSOR_IRRECV "IR RX"
|
||||
#define D_SENSOR_MHZ_RX "MHZ Rx"
|
||||
#define D_SENSOR_MHZ_TX "MHZ Tx"
|
||||
|
|
|
@ -333,6 +333,12 @@ struct SYSCFG {
|
|||
// E00 - FFF free locations
|
||||
} Settings;
|
||||
|
||||
struct RTCRBT {
|
||||
uint16_t valid; // 000
|
||||
uint8_t fast_reboot_count; // 002
|
||||
uint8_t free_003[1]; // 003
|
||||
} RtcReboot;
|
||||
|
||||
struct RTCMEM {
|
||||
uint16_t valid; // 000
|
||||
byte oswatch_blocked_loop; // 002
|
||||
|
@ -341,9 +347,7 @@ struct RTCMEM {
|
|||
unsigned long energy_kWhtotal; // 008
|
||||
unsigned long pulse_counter[MAX_COUNTERS]; // 00C
|
||||
power_t power; // 01C
|
||||
uint16_t extended_valid; // 020 Extended valid flag (v6.1.1.14)
|
||||
uint8_t fast_reboot_count; // 022
|
||||
uint8_t free_023[57]; // 023
|
||||
uint8_t free_020[60]; // 020
|
||||
// 05C next free location (64 (=core) + 100 (=tasmota offset) + 92 (=0x5C RTCMEM struct) = 256 bytes (max = 512))
|
||||
} RtcSettings;
|
||||
|
||||
|
|
|
@ -84,7 +84,6 @@ void RtcSettingsSave()
|
|||
{
|
||||
if (GetRtcSettingsCrc() != rtc_settings_crc) {
|
||||
RtcSettings.valid = RTC_MEM_VALID;
|
||||
RtcSettings.extended_valid = RTC_MEM_VALID;
|
||||
ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
|
||||
rtc_settings_crc = GetRtcSettingsCrc();
|
||||
#ifdef DEBUG_THEO
|
||||
|
@ -104,14 +103,12 @@ void RtcSettingsLoad()
|
|||
if (RtcSettings.valid != RTC_MEM_VALID) {
|
||||
memset(&RtcSettings, 0, sizeof(RTCMEM));
|
||||
RtcSettings.valid = RTC_MEM_VALID;
|
||||
RtcSettings.extended_valid = RTC_MEM_VALID;
|
||||
RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday;
|
||||
RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
|
||||
for (byte i = 0; i < MAX_COUNTERS; i++) {
|
||||
RtcSettings.pulse_counter[i] = Settings.pulse_counter[i];
|
||||
}
|
||||
RtcSettings.power = Settings.power;
|
||||
// RtcSettings.fast_reboot_count = 0; // Explicit by memset
|
||||
RtcSettingsSave();
|
||||
}
|
||||
rtc_settings_crc = GetRtcSettingsCrc();
|
||||
|
@ -122,9 +119,45 @@ boolean RtcSettingsValid()
|
|||
return (RTC_MEM_VALID == RtcSettings.valid);
|
||||
}
|
||||
|
||||
boolean RtcSettingsExtendedValid()
|
||||
/********************************************************************************************/
|
||||
|
||||
uint32_t rtc_reboot_crc = 0;
|
||||
|
||||
uint32_t GetRtcRebootCrc()
|
||||
{
|
||||
return (RTC_MEM_VALID == RtcSettings.extended_valid);
|
||||
uint32_t crc = 0;
|
||||
uint8_t *bytes = (uint8_t*)&RtcReboot;
|
||||
|
||||
for (uint16_t i = 0; i < sizeof(RTCRBT); i++) {
|
||||
crc += bytes[i]*(i+1);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
void RtcRebootSave()
|
||||
{
|
||||
if (GetRtcRebootCrc() != rtc_reboot_crc) {
|
||||
RtcReboot.valid = RTC_MEM_VALID;
|
||||
ESP.rtcUserMemoryWrite(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT));
|
||||
rtc_reboot_crc = GetRtcRebootCrc();
|
||||
}
|
||||
}
|
||||
|
||||
void RtcRebootLoad()
|
||||
{
|
||||
ESP.rtcUserMemoryRead(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT));
|
||||
if (RtcReboot.valid != RTC_MEM_VALID) {
|
||||
memset(&RtcReboot, 0, sizeof(RTCRBT));
|
||||
RtcReboot.valid = RTC_MEM_VALID;
|
||||
// RtcReboot.fast_reboot_count = 0; // Explicit by memset
|
||||
RtcRebootSave();
|
||||
}
|
||||
rtc_reboot_crc = GetRtcRebootCrc();
|
||||
}
|
||||
|
||||
boolean RtcRebootValid()
|
||||
{
|
||||
return (RTC_MEM_VALID == RtcReboot.valid);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
|
|
@ -442,7 +442,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||
|
||||
ShowFreeMem(PSTR("MqttDataHandler"));
|
||||
|
||||
strncpy(topicBuf, topic, sizeof(topicBuf));
|
||||
strlcpy(topicBuf, topic, sizeof(topicBuf));
|
||||
for (i = 0; i < data_len; i++) {
|
||||
if (!isspace(data[i])) break;
|
||||
}
|
||||
|
@ -1568,8 +1568,8 @@ void PerformEverySecond()
|
|||
uptime++;
|
||||
|
||||
if (BOOT_LOOP_TIME == uptime) {
|
||||
RtcSettings.fast_reboot_count = 0;
|
||||
RtcSettingsSave();
|
||||
RtcReboot.fast_reboot_count = 0;
|
||||
RtcRebootSave();
|
||||
}
|
||||
|
||||
if ((4 == uptime) && (SONOFF_IFAN02 == Settings.module)) { // Microcontroller needs 3 seconds before accepting commands
|
||||
|
@ -2491,10 +2491,10 @@ void setup()
|
|||
{
|
||||
byte idx;
|
||||
|
||||
RtcSettingsLoad();
|
||||
if (!RtcSettingsExtendedValid()) { RtcSettings.fast_reboot_count = 0; }
|
||||
RtcSettings.fast_reboot_count++;
|
||||
RtcSettingsSave();
|
||||
RtcRebootLoad();
|
||||
if (!RtcRebootValid()) { RtcReboot.fast_reboot_count = 0; }
|
||||
RtcReboot.fast_reboot_count++;
|
||||
RtcRebootSave();
|
||||
|
||||
Serial.begin(baudrate);
|
||||
delay(10);
|
||||
|
@ -2528,26 +2528,26 @@ void setup()
|
|||
sleep = Settings.sleep;
|
||||
|
||||
// Disable functionality as possible cause of fast restart within BOOT_LOOP_TIME seconds (Exception, WDT or restarts)
|
||||
if (RtcSettings.fast_reboot_count > 1) { // Restart twice
|
||||
if (RtcReboot.fast_reboot_count > 1) { // Restart twice
|
||||
Settings.flag3.user_esp8285_enable = 0; // Disable ESP8285 Generic GPIOs interfering with flash SPI
|
||||
if (RtcSettings.fast_reboot_count > 2) { // Restart 3 times
|
||||
if (RtcReboot.fast_reboot_count > 2) { // Restart 3 times
|
||||
for (byte i = 0; i < MAX_RULE_SETS; i++) {
|
||||
if (bitRead(Settings.rule_stop, i)) {
|
||||
bitWrite(Settings.rule_enabled, i, 0); // Disable rules causing boot loop
|
||||
}
|
||||
}
|
||||
}
|
||||
if (RtcSettings.fast_reboot_count > 3) { // Restarted 4 times
|
||||
if (RtcReboot.fast_reboot_count > 3) { // Restarted 4 times
|
||||
Settings.rule_enabled = 0; // Disable all rules
|
||||
}
|
||||
if (RtcSettings.fast_reboot_count > 4) { // Restarted 5 times
|
||||
if (RtcReboot.fast_reboot_count > 4) { // Restarted 5 times
|
||||
Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic
|
||||
Settings.last_module = SONOFF_BASIC;
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
Settings.my_gp.io[i] = GPIO_NONE; // Reset user defined GPIO disabling sensors
|
||||
}
|
||||
}
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcSettings.fast_reboot_count);
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef _SONOFF_VERSION_H_
|
||||
#define _SONOFF_VERSION_H_
|
||||
|
||||
#define VERSION 0x06020000
|
||||
#define VERSION 0x06020100
|
||||
|
||||
#define D_PROGRAMNAME "Sonoff-Tasmota"
|
||||
#define D_AUTHOR "Theo Arends"
|
||||
|
|
|
@ -143,7 +143,7 @@ char* subStr(char* dest, char* str, const char *delim, int index)
|
|||
int i;
|
||||
|
||||
// Since strtok consumes the first arg, make a copy
|
||||
strncpy(dest, str, strlen(str));
|
||||
strlcpy(dest, str, strlen(str));
|
||||
for (i = 1, act = dest; i <= index; i++, act = NULL) {
|
||||
sub = strtok_r(act, delim, &ptr);
|
||||
if (sub == NULL) break;
|
||||
|
@ -157,7 +157,7 @@ double CharToDouble(char *str)
|
|||
// simple ascii to double, because atof or strtod are too large
|
||||
char strbuf[24];
|
||||
|
||||
strcpy(strbuf, str);
|
||||
strlcpy(strbuf, str, sizeof(strbuf));
|
||||
char *pt;
|
||||
double left = atoi(strbuf);
|
||||
double right = 0;
|
||||
|
@ -561,13 +561,13 @@ int GetStateNumber(char *state_text)
|
|||
char command[CMDSZ];
|
||||
int state_number = -1;
|
||||
|
||||
if ((GetCommandCode(command, sizeof(command), state_text, kOptionOff) >= 0) || !strcasecmp(state_text, Settings.state_text[0])) {
|
||||
if (GetCommandCode(command, sizeof(command), state_text, kOptionOff) >= 0) {
|
||||
state_number = 0;
|
||||
}
|
||||
else if ((GetCommandCode(command, sizeof(command), state_text, kOptionOn) >= 0) || !strcasecmp(state_text, Settings.state_text[1])) {
|
||||
else if (GetCommandCode(command, sizeof(command), state_text, kOptionOn) >= 0) {
|
||||
state_number = 1;
|
||||
}
|
||||
else if ((GetCommandCode(command, sizeof(command), state_text, kOptionToggle) >= 0) || !strcasecmp(state_text, Settings.state_text[2])) {
|
||||
else if (GetCommandCode(command, sizeof(command), state_text, kOptionToggle) >= 0) {
|
||||
state_number = 2;
|
||||
}
|
||||
else if (GetCommandCode(command, sizeof(command), state_text, kOptionBlink) >= 0) {
|
||||
|
|
|
@ -372,8 +372,7 @@ long ajax_token = 1;
|
|||
static void WebGetArg(const char* arg, char* out, size_t max)
|
||||
{
|
||||
String s = WebServer->arg(arg);
|
||||
strncpy(out, s.c_str(), max);
|
||||
out[max-1] = '\0'; // Ensure terminating NUL
|
||||
strlcpy(out, s.c_str(), max);
|
||||
}
|
||||
|
||||
void ShowWebSource(int source)
|
||||
|
|
|
@ -386,11 +386,16 @@ void HandleUpnpEvent()
|
|||
String state_xml = FPSTR(WEMO_RESPONSE_STATE_SOAP);
|
||||
//differentiate get and set state
|
||||
if (request.indexOf(F("SetBinaryState")) > 0) {
|
||||
uint8_t power = POWER_TOGGLE;
|
||||
if (request.indexOf(F("State>1</Binary")) > 0) {
|
||||
ExecuteCommandPower(devices_present, POWER_ON, SRC_WEMO);
|
||||
power = POWER_ON;
|
||||
}
|
||||
else if (request.indexOf(F("State>0</Binary")) > 0) {
|
||||
ExecuteCommandPower(devices_present, POWER_OFF, SRC_WEMO);
|
||||
power = POWER_OFF;
|
||||
}
|
||||
if (power != POWER_TOGGLE) {
|
||||
uint8_t device = (light_type) ? devices_present : 1; // Select either a configured light or relay1
|
||||
ExecuteCommandPower(device, power, SRC_WEMO);
|
||||
}
|
||||
}
|
||||
else if(request.indexOf(F("GetBinaryState")) > 0){
|
||||
|
|
|
@ -111,7 +111,7 @@ void CounterShow(boolean json)
|
|||
}
|
||||
header++;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"C%d\":%s"), mqtt_data, stemp, i +1, counter);
|
||||
strcpy(stemp, ",");
|
||||
strlcpy(stemp, ",", sizeof(stemp));
|
||||
#ifdef USE_DOMOTICZ
|
||||
if ((0 == tele_period) && (1 == dsxflg)) {
|
||||
DomoticzSensor(DZ_COUNT, RtcSettings.pulse_counter[i]);
|
||||
|
|
|
@ -186,7 +186,7 @@ void Ds18x20Show(boolean json)
|
|||
dsxflg++;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"DS%d\":{\"" D_JSON_TYPE "\":\"%s\",\"" D_JSON_ADDRESS "\":\"%s\",\"" D_JSON_TEMPERATURE "\":%s}"),
|
||||
mqtt_data, stemp, i +1, ds18x20_types, Ds18x20Addresses(i).c_str(), temperature);
|
||||
strcpy(stemp, ",");
|
||||
strlcpy(stemp, ",", sizeof(stemp));
|
||||
#ifdef USE_DOMOTICZ
|
||||
if ((0 == tele_period) && (1 == dsxflg)) {
|
||||
DomoticzSensor(DZ_TEMP, temperature);
|
||||
|
|
|
@ -191,7 +191,7 @@ void Ads1115Show(boolean json)
|
|||
}
|
||||
dsxflg++;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, stemp, i, adc_value);
|
||||
strcpy(stemp, ",");
|
||||
strlcpy(stemp, ",", sizeof(stemp));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value);
|
||||
|
|
|
@ -111,7 +111,7 @@ void Ads1115Show(boolean json)
|
|||
}
|
||||
dsxflg++;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, stemp, i, adc_value);
|
||||
strcpy(stemp, ",");
|
||||
strlcpy(stemp, ",", sizeof(stemp));
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value);
|
||||
|
|
Loading…
Reference in New Issue