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:
Theo Arends 2018-09-05 10:58:56 +02:00
parent 45ffd2cdc3
commit 28e3773113
15 changed files with 101 additions and 44 deletions

View File

@ -104,6 +104,12 @@ See [Tasmota ESP/Arduino library version related issues](https://github.com/aren
| USE_RF_FLASH | - | - | x | x | x | | USE_RF_FLASH | - | - | x | x | x |
## Changelog ## 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 Version 6.2.0 20180901
* Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561) * 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) * 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)

View File

@ -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) * 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) * 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 * Change DS18B20 driver to provide better instant results

View File

@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele. * 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) //#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_BLINKOFF "Мигане изкл."
#define D_BOOT_COUNT "Брой на стартиранията" #define D_BOOT_COUNT "Брой на стартиранията"
#define D_BRIGHTLIGHT "Яркост" #define D_BRIGHTLIGHT "Яркост"
#define D_BSSID "BSSId"
#define D_BUTTON "Бутон" #define D_BUTTON "Бутон"
#define D_BY "от" // Written by me #define D_BY "от" // Written by me
#define D_BYTES "Байта" #define D_BYTES "Байта"
#define D_CELSIUS "Целзий" #define D_CELSIUS "Целзий"
#define D_CHANNEL "Канал"
#define D_CO2 "Въглероден диоксид" #define D_CO2 "Въглероден диоксид"
#define D_CODE "код" // Button code #define D_CODE "код" // Button code
#define D_COLDLIGHT "Хладна" #define D_COLDLIGHT "Хладна"
@ -438,12 +440,12 @@
#define D_PARTICALS_BEYOND "Частици" #define D_PARTICALS_BEYOND "Частици"
// xsns_32_mpu6050.ino // xsns_32_mpu6050.ino
#define D_AX_AXIS "Accel. X-Axis" #define D_AX_AXIS "Ускорение - ос X"
#define D_AY_AXIS "Accel. Y-Axis" #define D_AY_AXIS "Ускорение - ос Y"
#define D_AZ_AXIS "Accel. Z-Axis" #define D_AZ_AXIS "Ускорение - ос Z"
#define D_GX_AXIS "Gyro X-Axis" #define D_GX_AXIS "Жироскоп - ос X"
#define D_GY_AXIS "Gyro Y-Axis" #define D_GY_AXIS "Жироскоп - ос Y"
#define D_GZ_AXIS "Gyro Z-Axis" #define D_GZ_AXIS "Жироскоп - ос Z"
// sonoff_template.h // sonoff_template.h
#define D_SENSOR_NONE "Няма" #define D_SENSOR_NONE "Няма"

View File

@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele. * 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) #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_BLINKOFF "BlinkOff"
#define D_BOOT_COUNT "Conteo Reinicios" #define D_BOOT_COUNT "Conteo Reinicios"
#define D_BRIGHTLIGHT "Brillante" #define D_BRIGHTLIGHT "Brillante"
#define D_BSSID "BSSId"
#define D_BUTTON "Botón" #define D_BUTTON "Botón"
#define D_BY "por" // Written by me #define D_BY "por" // Written by me
#define D_BYTES "Bytes" #define D_BYTES "Bytes"
#define D_CELSIUS "Celsius" #define D_CELSIUS "Celsius"
#define D_CHANNEL "Canal"
#define D_CO2 "CO2" #define D_CO2 "CO2"
#define D_CODE "código" // Button code #define D_CODE "código" // Button code
#define D_COLDLIGHT "Fría" #define D_COLDLIGHT "Fría"
@ -460,7 +462,7 @@
#define D_SENSOR_RELAY "Relé" // Suffix "1i" #define D_SENSOR_RELAY "Relé" // Suffix "1i"
#define D_SENSOR_LED "Led" // Suffix "1i" #define D_SENSOR_LED "Led" // Suffix "1i"
#define D_SENSOR_PWM "PWM" // Suffix "1" #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_IRRECV "IR RX"
#define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx" #define D_SENSOR_MHZ_TX "MHZ Tx"

View File

@ -333,6 +333,12 @@ struct SYSCFG {
// E00 - FFF free locations // E00 - FFF free locations
} Settings; } Settings;
struct RTCRBT {
uint16_t valid; // 000
uint8_t fast_reboot_count; // 002
uint8_t free_003[1]; // 003
} RtcReboot;
struct RTCMEM { struct RTCMEM {
uint16_t valid; // 000 uint16_t valid; // 000
byte oswatch_blocked_loop; // 002 byte oswatch_blocked_loop; // 002
@ -341,9 +347,7 @@ struct RTCMEM {
unsigned long energy_kWhtotal; // 008 unsigned long energy_kWhtotal; // 008
unsigned long pulse_counter[MAX_COUNTERS]; // 00C unsigned long pulse_counter[MAX_COUNTERS]; // 00C
power_t power; // 01C power_t power; // 01C
uint16_t extended_valid; // 020 Extended valid flag (v6.1.1.14) uint8_t free_020[60]; // 020
uint8_t fast_reboot_count; // 022
uint8_t free_023[57]; // 023
// 05C next free location (64 (=core) + 100 (=tasmota offset) + 92 (=0x5C RTCMEM struct) = 256 bytes (max = 512)) // 05C next free location (64 (=core) + 100 (=tasmota offset) + 92 (=0x5C RTCMEM struct) = 256 bytes (max = 512))
} RtcSettings; } RtcSettings;

View File

@ -84,7 +84,6 @@ void RtcSettingsSave()
{ {
if (GetRtcSettingsCrc() != rtc_settings_crc) { if (GetRtcSettingsCrc() != rtc_settings_crc) {
RtcSettings.valid = RTC_MEM_VALID; RtcSettings.valid = RTC_MEM_VALID;
RtcSettings.extended_valid = RTC_MEM_VALID;
ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
rtc_settings_crc = GetRtcSettingsCrc(); rtc_settings_crc = GetRtcSettingsCrc();
#ifdef DEBUG_THEO #ifdef DEBUG_THEO
@ -104,14 +103,12 @@ void RtcSettingsLoad()
if (RtcSettings.valid != RTC_MEM_VALID) { if (RtcSettings.valid != RTC_MEM_VALID) {
memset(&RtcSettings, 0, sizeof(RTCMEM)); memset(&RtcSettings, 0, sizeof(RTCMEM));
RtcSettings.valid = RTC_MEM_VALID; RtcSettings.valid = RTC_MEM_VALID;
RtcSettings.extended_valid = RTC_MEM_VALID;
RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday; RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday;
RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal; RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
for (byte i = 0; i < MAX_COUNTERS; i++) { for (byte i = 0; i < MAX_COUNTERS; i++) {
RtcSettings.pulse_counter[i] = Settings.pulse_counter[i]; RtcSettings.pulse_counter[i] = Settings.pulse_counter[i];
} }
RtcSettings.power = Settings.power; RtcSettings.power = Settings.power;
// RtcSettings.fast_reboot_count = 0; // Explicit by memset
RtcSettingsSave(); RtcSettingsSave();
} }
rtc_settings_crc = GetRtcSettingsCrc(); rtc_settings_crc = GetRtcSettingsCrc();
@ -122,9 +119,45 @@ boolean RtcSettingsValid()
return (RTC_MEM_VALID == RtcSettings.valid); 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);
} }
/*********************************************************************************************\ /*********************************************************************************************\

View File

@ -442,7 +442,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
ShowFreeMem(PSTR("MqttDataHandler")); ShowFreeMem(PSTR("MqttDataHandler"));
strncpy(topicBuf, topic, sizeof(topicBuf)); strlcpy(topicBuf, topic, sizeof(topicBuf));
for (i = 0; i < data_len; i++) { for (i = 0; i < data_len; i++) {
if (!isspace(data[i])) break; if (!isspace(data[i])) break;
} }
@ -1568,8 +1568,8 @@ void PerformEverySecond()
uptime++; uptime++;
if (BOOT_LOOP_TIME == uptime) { if (BOOT_LOOP_TIME == uptime) {
RtcSettings.fast_reboot_count = 0; RtcReboot.fast_reboot_count = 0;
RtcSettingsSave(); RtcRebootSave();
} }
if ((4 == uptime) && (SONOFF_IFAN02 == Settings.module)) { // Microcontroller needs 3 seconds before accepting commands if ((4 == uptime) && (SONOFF_IFAN02 == Settings.module)) { // Microcontroller needs 3 seconds before accepting commands
@ -2491,10 +2491,10 @@ void setup()
{ {
byte idx; byte idx;
RtcSettingsLoad(); RtcRebootLoad();
if (!RtcSettingsExtendedValid()) { RtcSettings.fast_reboot_count = 0; } if (!RtcRebootValid()) { RtcReboot.fast_reboot_count = 0; }
RtcSettings.fast_reboot_count++; RtcReboot.fast_reboot_count++;
RtcSettingsSave(); RtcRebootSave();
Serial.begin(baudrate); Serial.begin(baudrate);
delay(10); delay(10);
@ -2528,26 +2528,26 @@ void setup()
sleep = Settings.sleep; sleep = Settings.sleep;
// Disable functionality as possible cause of fast restart within BOOT_LOOP_TIME seconds (Exception, WDT or restarts) // 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 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++) { for (byte i = 0; i < MAX_RULE_SETS; i++) {
if (bitRead(Settings.rule_stop, i)) { if (bitRead(Settings.rule_stop, i)) {
bitWrite(Settings.rule_enabled, i, 0); // Disable rules causing boot loop 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 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.module = SONOFF_BASIC; // Reset module to Sonoff Basic
Settings.last_module = SONOFF_BASIC; Settings.last_module = SONOFF_BASIC;
for (byte i = 0; i < MAX_GPIO_PIN; i++) { for (byte i = 0; i < MAX_GPIO_PIN; i++) {
Settings.my_gp.io[i] = GPIO_NONE; // Reset user defined GPIO disabling sensors 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); AddLog(LOG_LEVEL_DEBUG);
} }

View File

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

View File

@ -143,7 +143,7 @@ char* subStr(char* dest, char* str, const char *delim, int index)
int i; int i;
// Since strtok consumes the first arg, make a copy // 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) { for (i = 1, act = dest; i <= index; i++, act = NULL) {
sub = strtok_r(act, delim, &ptr); sub = strtok_r(act, delim, &ptr);
if (sub == NULL) break; if (sub == NULL) break;
@ -157,7 +157,7 @@ double CharToDouble(char *str)
// simple ascii to double, because atof or strtod are too large // simple ascii to double, because atof or strtod are too large
char strbuf[24]; char strbuf[24];
strcpy(strbuf, str); strlcpy(strbuf, str, sizeof(strbuf));
char *pt; char *pt;
double left = atoi(strbuf); double left = atoi(strbuf);
double right = 0; double right = 0;
@ -561,13 +561,13 @@ int GetStateNumber(char *state_text)
char command[CMDSZ]; char command[CMDSZ];
int state_number = -1; 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; 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; 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; state_number = 2;
} }
else if (GetCommandCode(command, sizeof(command), state_text, kOptionBlink) >= 0) { else if (GetCommandCode(command, sizeof(command), state_text, kOptionBlink) >= 0) {

View File

@ -372,8 +372,7 @@ long ajax_token = 1;
static void WebGetArg(const char* arg, char* out, size_t max) static void WebGetArg(const char* arg, char* out, size_t max)
{ {
String s = WebServer->arg(arg); String s = WebServer->arg(arg);
strncpy(out, s.c_str(), max); strlcpy(out, s.c_str(), max);
out[max-1] = '\0'; // Ensure terminating NUL
} }
void ShowWebSource(int source) void ShowWebSource(int source)

View File

@ -386,11 +386,16 @@ void HandleUpnpEvent()
String state_xml = FPSTR(WEMO_RESPONSE_STATE_SOAP); String state_xml = FPSTR(WEMO_RESPONSE_STATE_SOAP);
//differentiate get and set state //differentiate get and set state
if (request.indexOf(F("SetBinaryState")) > 0) { if (request.indexOf(F("SetBinaryState")) > 0) {
uint8_t power = POWER_TOGGLE;
if (request.indexOf(F("State>1</Binary")) > 0) { 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) { 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){ else if(request.indexOf(F("GetBinaryState")) > 0){

View File

@ -111,7 +111,7 @@ void CounterShow(boolean json)
} }
header++; header++;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"C%d\":%s"), mqtt_data, stemp, i +1, counter); 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 #ifdef USE_DOMOTICZ
if ((0 == tele_period) && (1 == dsxflg)) { if ((0 == tele_period) && (1 == dsxflg)) {
DomoticzSensor(DZ_COUNT, RtcSettings.pulse_counter[i]); DomoticzSensor(DZ_COUNT, RtcSettings.pulse_counter[i]);

View File

@ -186,7 +186,7 @@ void Ds18x20Show(boolean json)
dsxflg++; 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}"), 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); mqtt_data, stemp, i +1, ds18x20_types, Ds18x20Addresses(i).c_str(), temperature);
strcpy(stemp, ","); strlcpy(stemp, ",", sizeof(stemp));
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
if ((0 == tele_period) && (1 == dsxflg)) { if ((0 == tele_period) && (1 == dsxflg)) {
DomoticzSensor(DZ_TEMP, temperature); DomoticzSensor(DZ_TEMP, temperature);

View File

@ -191,7 +191,7 @@ void Ads1115Show(boolean json)
} }
dsxflg++; dsxflg++;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, stemp, i, adc_value); 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 #ifdef USE_WEBSERVER
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value);

View File

@ -111,7 +111,7 @@ void Ads1115Show(boolean json)
} }
dsxflg++; dsxflg++;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"A%d\":%d"), mqtt_data, stemp, i, adc_value); 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 #ifdef USE_WEBSERVER
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ANALOG, mqtt_data, "ADS1115", i, adc_value);