From af942a278c604c4158a72b7fffc78ac69575193e Mon Sep 17 00:00:00 2001 From: arendst Date: Mon, 18 Sep 2017 18:38:13 +0200 Subject: [PATCH] v5.8.0 5.8.0 20170918 * Remove the need for NeoPixelBus library for Hue support * Consolidate WS2812 into Sonoff Led for flexible future led strip library changes * Invert WS2812 fade speed to align with Sonoff led (Speed 1 = fast, Speed 8 = slow) * Remove upper case MQTT receive buffer * Reduce code and string length for output of commands Modules and GPIOs * Add Sonoff SC debug information * Change syslog service * Removed webserver syslog disable as now no longer needed * Increased default MQTT message size from 368 to 405 bytes while keeping MQTT_MAX_PACKET_SIZE = 512 (because we can) * Fix MQTT Offline or Remove MQTT retained topic code * Fix Domoticz loop when Emulation is selected * Add blink to WS2812 and Sonoff Led (#643) * Add option WIFI_WAIT (5) to command WifiConfig to allow connection retry to same AP without restart or update flash (#772, #869) * Add support for Witty Cloud (#794) * Add GPIO14 to Sonoff Dual (#797, #839) * Add support for Yunshan Wifi Relay (#802) * Add GPIO16 input pulldown (#827) * Add timeout to DHT and DS18B20 sensors (#852) * Fix watchdog timeout caused by lack of stack space by moving to heap (#853) * Allow LogPort and MqttPort up to 65535 and add LogPort tot Status 3 (#859) * Allow command SwitchTopic in group mode (#861) * Allow command SwitchMode if no switches are defined (#861) * Add optional dimmer parameter to command Wakeup for WS2812, AiLight, Sonoff B1, Led and BN-SZ01 (#867) * Fix basic On, Off, Toggle, Blink and BlinkOff commands when other language is selected (#874) --- README.md | 2 +- sonoff/_releasenotes.ino | 28 +- sonoff/i18n.h | 5 +- sonoff/language/en-GB.h | 5 +- sonoff/language/nl-NL.h | 5 +- sonoff/settings.ino | 91 +++--- sonoff/sonoff.ino | 648 ++++++++++++++++++-------------------- sonoff/sonoff_template.h | 35 +- sonoff/support.ino | 122 ++++--- sonoff/user_config.h | 4 +- sonoff/webserver.ino | 82 +++-- sonoff/xdrv_domoticz.ino | 65 ++-- sonoff/xdrv_ir_send.ino | 57 ++-- sonoff/xdrv_snfbridge.ino | 33 +- sonoff/xdrv_snfled.ino | 469 ++++++++++++++++++--------- sonoff/xdrv_snfsc.ino | 38 ++- sonoff/xdrv_wemohue.ino | 48 +-- sonoff/xdrv_ws2812.ino | 470 ++++++--------------------- sonoff/xsns_bh1750.ino | 9 +- sonoff/xsns_bmp.ino | 15 +- sonoff/xsns_counter.ino | 10 +- sonoff/xsns_dht.ino | 44 +-- sonoff/xsns_ds18b20.ino | 14 +- sonoff/xsns_ds18x20.ino | 10 +- sonoff/xsns_hlw8012.ino | 111 ++++--- sonoff/xsns_htu21.ino | 9 +- sonoff/xsns_sht1x.ino | 4 +- 27 files changed, 1161 insertions(+), 1272 deletions(-) diff --git a/README.md b/README.md index 329022ba22e3..ac06b73646bf 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## 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. -Current version is **5.7.1** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. +Current version is **5.8.0** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. ### ATTENTION All versions diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 48ce58c55606..fa341c4e9c1a 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,30 @@ -/* 5.7.1 20170909 +/* 5.8.0 20170918 + * Remove the need for NeoPixelBus library for Hue support + * Consolidate WS2812 into Sonoff Led for flexible future led strip library changes + * Invert WS2812 fade speed to align with Sonoff led (Speed 1 = fast, Speed 8 = slow) + * Remove upper case MQTT receive buffer + * Reduce code and string length for output of commands Modules and GPIOs + * Add Sonoff SC debug information + * Change syslog service + * Removed webserver syslog disable as now no longer needed + * Increased default MQTT message size from 368 to 405 bytes while keeping MQTT_MAX_PACKET_SIZE = 512 (because we can) + * Fix MQTT Offline or Remove MQTT retained topic code + * Fix Domoticz loop when Emulation is selected + * Add blink to WS2812 and Sonoff Led (#643) + * Add option WIFI_WAIT (5) to command WifiConfig to allow connection retry to same AP without restart or update flash (#772, #869) + * Add support for Witty Cloud (#794) + * Add GPIO14 to Sonoff Dual (#797, #839) + * Add support for Yunshan Wifi Relay (#802) + * Add GPIO16 input pulldown (#827) + * Add timeout to DHT and DS18B20 sensors (#852) + * Fix watchdog timeout caused by lack of stack space by moving to heap (#853) + * Allow LogPort and MqttPort up to 65535 and add LogPort tot Status 3 (#859) + * Allow command SwitchTopic in group mode (#861) + * Allow command SwitchMode if no switches are defined (#861) + * Add optional dimmer parameter to command Wakeup for WS2812, AiLight, Sonoff B1, Led and BN-SZ01 (#867) + * Fix basic On, Off, Toggle, Blink and BlinkOff commands when other language is selected (#874) + * + * 5.7.1 20170909 * Remove leading spaces from MQTT data * Fix webconsole special character entry * Allow # as prefix for color value diff --git a/sonoff/i18n.h b/sonoff/i18n.h index d716ccf55c24..c49e31c8f387 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -44,12 +44,13 @@ const char commands[MAX_BUTTON_COMMANDS][14] PROGMEM = { D_CMND_WIFICONFIG " 3", // Press button five times D_CMND_RESTART " 1", // Press button six times D_CMND_UPGRADE " 1" }; // Press button seven times -const char wificfg[5][WCFG_MAX_STRING_LENGTH] PROGMEM = { +const char wificfg[MAX_WIFI_OPTION][WCFG_MAX_STRING_LENGTH] PROGMEM = { D_WCFG_0_RESTART, D_WCFG_1_SMARTCONFIG, D_WCFG_2_WIFIMANAGER, D_WCFG_3_WPSCONFIG, - D_WCFG_4_RETRY }; + D_WCFG_4_RETRY, + D_WCFG_5_WAIT }; const char PREFIXES[3][PRFX_MAX_STRING_LENGTH] PROGMEM = { D_CMND, D_STAT, diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index dedb22a3b2bf..d5acc0fc0813 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -175,6 +175,7 @@ #define D_TOGGLE "Toggle" #define D_TOPIC "Topic" #define D_TOTAL "Total" +#define D_TRANSMIT "Transmit" #define D_TRUE "True" #define D_TYPE "Type" #define D_UNKNOWN "Unknown" @@ -478,7 +479,7 @@ #define D_LOG_APPLICATION "APP: " #define D_LOG_BRIDGE "BRG: " #define D_LOG_CONFIG "CFG: " -#define D_LOG_COMMAND "CND: " +#define D_LOG_COMMAND "CMD: " #define D_LOG_DHT "DHT: " #define D_LOG_DOMOTICZ "DOM: " #define D_LOG_DSB "DSB: " @@ -494,6 +495,7 @@ #define D_LOG_UPLOAD "UPL: " #define D_LOG_UPNP "UPP: " #define D_LOG_WIFI "WIF: " +#define D_LOG_SERIAL "SER: " // Result #define D_RSLT_RESULT "RESULT" @@ -587,6 +589,7 @@ #define D_WCFG_2_WIFIMANAGER "WifiManager" #define D_WCFG_3_WPSCONFIG "WPSConfig" #define D_WCFG_4_RETRY "Retry" + #define D_WCFG_5_WAIT "Wait" #define D_CMND_FRIENDLYNAME "FriendlyName" #define D_CMND_SWITCHMODE "SwitchMode" #define D_CMND_WEBSERVER "Webserver" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index eece900a5ff5..9e39fc2e4e96 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -175,6 +175,7 @@ #define D_TOGGLE "Toggle" // Wissel, Tuimel #define D_TOPIC "Topic" // Onderwerp #define D_TOTAL "Totaal" +#define D_TRANSMIT "Verzend" #define D_TRUE "Waar" #define D_TYPE "Soort" #define D_UNKNOWN "Onbekend" @@ -478,7 +479,7 @@ #define D_LOG_APPLICATION "APP: " #define D_LOG_BRIDGE "BRG: " #define D_LOG_CONFIG "CFG: " -#define D_LOG_COMMAND "CND: " +#define D_LOG_COMMAND "CMD: " #define D_LOG_DHT "DHT: " #define D_LOG_DOMOTICZ "DOM: " #define D_LOG_DSB "DSB: " @@ -494,6 +495,7 @@ #define D_LOG_UPLOAD "UPL: " #define D_LOG_UPNP "UPP: " #define D_LOG_WIFI "WIF: " +#define D_LOG_SERIAL "SER: " // Result #define D_RSLT_RESULT "RESULTAAT" @@ -587,6 +589,7 @@ #define D_WCFG_2_WIFIMANAGER "WifiManager" #define D_WCFG_3_WPSCONFIG "WPSConfig" #define D_WCFG_4_RETRY "Opnieuw" + #define D_WCFG_5_WAIT "Wacht" #define D_CMND_FRIENDLYNAME "FriendlyName" #define D_CMND_SWITCHMODE "SwitchMode" #define D_CMND_WEBSERVER "Webserver" diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 844a3a5956e1..1c8e4d4eb5e9 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -82,7 +82,6 @@ void RTC_Dump() { #define CFG_COLS 16 - char log[LOGSZ]; uint16_t idx; uint16_t maxrow; uint16_t row; @@ -93,22 +92,22 @@ void RTC_Dump() for (row = 0; row < maxrow; row++) { idx = row * CFG_COLS; - snprintf_P(log, sizeof(log), PSTR("%04X:"), idx); + snprintf_P(log_data, sizeof(log_data), PSTR("%04X:"), idx); for (col = 0; col < CFG_COLS; col++) { if (!(col%4)) { - snprintf_P(log, sizeof(log), PSTR("%s "), log); + snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data); } - snprintf_P(log, sizeof(log), PSTR("%s %02X"), log, buffer[idx + col]); + snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X"), log_data, buffer[idx + col]); } - snprintf_P(log, sizeof(log), PSTR("%s |"), log); + snprintf_P(log_data, sizeof(log_data), PSTR("%s |"), log_data); for (col = 0; col < CFG_COLS; col++) { // if (!(col%4)) { -// snprintf_P(log, sizeof(log), PSTR("%s "), log); +// snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data); // } - snprintf_P(log, sizeof(log), PSTR("%s%c"), log, ((buffer[idx + col] > 0x20) && (buffer[idx + col] < 0x7F)) ? (char)buffer[idx + col] : ' '); + snprintf_P(log_data, sizeof(log_data), PSTR("%s%c"), log_data, ((buffer[idx + col] > 0x20) && (buffer[idx + col] < 0x7F)) ? (char)buffer[idx + col] : ' '); } - snprintf_P(log, sizeof(log), PSTR("%s|"), log); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR("%s|"), log_data); + addLog(LOG_LEVEL_INFO); } } #endif // DEBUG_THEO @@ -193,8 +192,6 @@ void CFG_Save(byte rotate) * stop_flash_rotate 0 = Allow flash slot rotation (SetOption12 0) * stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1) */ - char log[LOGSZ]; - #ifndef BE_MINIMAL if ((getHash() != _cfgHash) || rotate) { if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade) @@ -224,9 +221,9 @@ void CFG_Save(byte rotate) delay(1); } } - snprintf_P(log, sizeof(log), PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), _cfgLocation, sysCfg.saveFlag, sizeof(SYSCFG)); - addLog(LOG_LEVEL_DEBUG, log); + addLog(LOG_LEVEL_DEBUG); _cfgHash = getHash(); } #endif // BE_MINIMAL @@ -237,8 +234,6 @@ void CFG_Load() { /* Load configuration from eeprom or one of 7 slots below if first load does not stop_flash_rotate */ - char log[LOGSZ]; - struct SYSCFGH { unsigned long cfg_holder; unsigned long saveFlag; @@ -252,17 +247,17 @@ void CFG_Load() spi_flash_read((_cfgLocation -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_sysCfgH, sizeof(SYSCFGH)); interrupts(); -// snprintf_P(log, sizeof(log), PSTR("Cnfg: Check at %X with count %d and holder %X"), _cfgLocation -1, _sysCfgH.saveFlag, _sysCfgH.cfg_holder); -// addLog(LOG_LEVEL_DEBUG, log); +// snprintf_P(log_data, sizeof(log_data), PSTR("Cnfg: Check at %X with count %d and holder %X"), _cfgLocation -1, _sysCfgH.saveFlag, _sysCfgH.cfg_holder); +// addLog(LOG_LEVEL_DEBUG); if (((sysCfg.version > 0x05000200) && sysCfg.flag.stop_flash_rotate) || (sysCfg.cfg_holder != _sysCfgH.cfg_holder) || (sysCfg.saveFlag > _sysCfgH.saveFlag)) { break; } delay(1); } - snprintf_P(log, sizeof(log), PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %d"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %d"), _cfgLocation, sysCfg.saveFlag); - addLog(LOG_LEVEL_DEBUG, log); + addLog(LOG_LEVEL_DEBUG); if (sysCfg.cfg_holder != CFG_HOLDER) { // Auto upgrade noInterrupts(); @@ -283,15 +278,14 @@ void CFG_Load() void CFG_Erase() { - char log[LOGSZ]; SpiFlashOpResult result; uint32_t _sectorStart = (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 1; uint32_t _sectorEnd = ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE; boolean _serialoutput = (LOG_LEVEL_DEBUG_MORE <= seriallog_level); - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_ERASE " %d " D_UNIT_SECTORS), _sectorEnd - _sectorStart); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_ERASE " %d " D_UNIT_SECTORS), _sectorEnd - _sectorStart); + addLog(LOG_LEVEL_DEBUG); for (uint32_t _sector = _sectorStart; _sector < _sectorEnd; _sector++) { noInterrupts(); @@ -314,7 +308,6 @@ void CFG_Dump(char* parms) { #define CFG_COLS 16 - char log[LOGSZ]; uint16_t idx; uint16_t maxrow; uint16_t row; @@ -327,8 +320,8 @@ void CFG_Dump(char* parms) uint16_t srow = strtol(parms, &p, 16) / CFG_COLS; uint16_t mrow = strtol(p, &p, 10); -// snprintf_P(log, sizeof(log), PSTR("Cnfg: Parms %s, Start row %d, rows %d"), parms, srow, mrow); -// addLog(LOG_LEVEL_DEBUG, log); +// snprintf_P(log_data, sizeof(log_data), PSTR("Cnfg: Parms %s, Start row %d, rows %d"), parms, srow, mrow); +// addLog(LOG_LEVEL_DEBUG); if (0 == mrow) { // Default only 8 lines mrow = 8; @@ -342,22 +335,22 @@ void CFG_Dump(char* parms) for (row = srow; row < maxrow; row++) { idx = row * CFG_COLS; - snprintf_P(log, sizeof(log), PSTR("%04X:"), idx); + snprintf_P(log_data, sizeof(log_data), PSTR("%04X:"), idx); for (col = 0; col < CFG_COLS; col++) { if (!(col%4)) { - snprintf_P(log, sizeof(log), PSTR("%s "), log); + snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data); } - snprintf_P(log, sizeof(log), PSTR("%s %02X"), log, buffer[idx + col]); + snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X"), log_data, buffer[idx + col]); } - snprintf_P(log, sizeof(log), PSTR("%s |"), log); + snprintf_P(log_data, sizeof(log_data), PSTR("%s |"), log_data); for (col = 0; col < CFG_COLS; col++) { // if (!(col%4)) { -// snprintf_P(log, sizeof(log), PSTR("%s "), log); +// snprintf_P(log_data, sizeof(log_data), PSTR("%s "), log_data); // } - snprintf_P(log, sizeof(log), PSTR("%s%c"), log, ((buffer[idx + col] > 0x20) && (buffer[idx + col] < 0x7F)) ? (char)buffer[idx + col] : ' '); + snprintf_P(log_data, sizeof(log_data), PSTR("%s%c"), log_data, ((buffer[idx + col] > 0x20) && (buffer[idx + col] < 0x7F)) ? (char)buffer[idx + col] : ' '); } - snprintf_P(log, sizeof(log), PSTR("%s|"), log); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR("%s|"), log_data); + addLog(LOG_LEVEL_INFO); delay(1); } } @@ -507,6 +500,8 @@ void CFG_DefaultSet2() // 5.4.1 memcpy_P(sysCfg.sfb_code[0], sfb_codeDefault, 9); + // 5.8.0 + sysCfg.led_pixels = 1; } /********************************************************************************************/ @@ -540,7 +535,7 @@ void CFG_DefaultSet_3_9_3() sysCfg.my_module.gp.io[i] = 0; } - sysCfg.led_pixels = 0; + sysCfg.led_pixels = WS2812_LEDS; for (byte i = 0; i < 5; i++) { sysCfg.led_color[i] = 255; } @@ -549,9 +544,9 @@ void CFG_DefaultSet_3_9_3() sysCfg.led_dimmer[i] = 10; } sysCfg.led_fade = 0; - sysCfg.led_speed = 0; + sysCfg.led_speed = 1; sysCfg.led_scheme = 0; - sysCfg.led_width = 0; + sysCfg.led_width = 1; sysCfg.led_wakeup = 0; } @@ -715,6 +710,30 @@ void CFG_Delta() } memcpy_P(sysCfg.sfb_code[0], sfb_codeDefault, 9); } + if (sysCfg.version < 0x05080000) { + uint8_t cfg_wsflg = 0; + for (byte i = 0; i < MAX_GPIO_PIN; i++) { + if (GPIO_WS2812 == sysCfg.my_module.gp.io[i]) { + cfg_wsflg = 1; + } + } + if (!sysCfg.led_pixels && cfg_wsflg) { + sysCfg.led_pixels = sysCfg.ws_pixels; + sysCfg.led_color[0] = sysCfg.ws_red; + sysCfg.led_color[1] = sysCfg.ws_green; + sysCfg.led_color[2] = sysCfg.ws_blue; + sysCfg.led_dimmer[0] = sysCfg.ws_dimmer; + sysCfg.led_table = sysCfg.ws_ledtable; + sysCfg.led_fade = sysCfg.ws_fade; + sysCfg.led_speed = sysCfg.ws_speed; + sysCfg.led_scheme = sysCfg.ws_scheme; + sysCfg.led_width = sysCfg.ws_width; + sysCfg.led_wakeup = sysCfg.ws_wakeup; + } else { + sysCfg.led_pixels = 1; + sysCfg.led_width = 1; + } + } sysCfg.version = VERSION; CFG_Save(1); diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 939655c85cb7..d1f74726c70d 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,13 +25,13 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x05070100 // 5.7.1 +#define VERSION 0x05080000 // 5.8.0 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 dow_t {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat}; enum month_t {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; -enum wifi_t {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, MAX_WIFI_OPTION}; +enum wifi_t {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, MAX_WIFI_OPTION}; enum swtch_t {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, MAX_SWITCH_OPTION}; enum led_t {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION}; enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; @@ -140,7 +140,6 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX}; #define INPUT_BUFFER_SIZE 250 // Max number of characters in (serial) command buffer #define CMDSZ 20 // Max number of characters in command #define TOPSZ 100 // Max number of characters in topic string -#define LOGSZ 128 // Max number of characters in log string #ifdef USE_MQTT_TLS #define MAX_LOG_LINES 10 // Max number of lines in weblog #else @@ -159,11 +158,13 @@ enum opt_t {P_HOLD_TIME, P_MAX_POWER_RETRY, P_MAX_PARAM8}; // Index in sysCf #include // MQTT #ifndef MESSZ - #define MESSZ 368 // Max number of characters in JSON message string (4 x DS18x20 sensors) + #define MESSZ 405 // Max number of characters in JSON message string (4 x DS18x20 sensors) #endif + +// Max message size calculated by PubSubClient is (MQTT_MAX_PACKET_SIZE < 5 + 2 + strlen(topic) + plength) #if (MQTT_MAX_PACKET_SIZE -TOPSZ -7) < MESSZ // If the max message size is too small, throw an error at compile time // See pubsubclient.c line 359 - #error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 475" + #error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 512" #endif #include // RTC, HLW8012, OSWatch @@ -172,7 +173,6 @@ enum opt_t {P_HOLD_TIME, P_MAX_POWER_RETRY, P_MAX_PARAM8}; // Index in sysCf #include // Ota #include // Webserver, Updater #include // WemoHue, IRremote, Domoticz -#include // Ws2812, Sonoff Led hue support #ifdef USE_WEBSERVER #include // WifiManager, Webserver #include // WifiManager @@ -216,13 +216,9 @@ TimeChangeRule mySTD = { TIME_STD }; // Standard Time int Baudrate = APP_BAUDRATE; // Serial interface baud rate byte SerialInByte; // Received byte int SerialInByteCounter = 0; // Index in receive buffer -char serialInBuf[INPUT_BUFFER_SIZE + 2]; // Receive buffer byte Hexcode = 0; // Sonoff dual input flag uint16_t ButtonCode = 0; // Sonoff dual received code int16_t savedatacounter; // Counter and flag for config save to Flash -char Version[16]; // Version string from VERSION define -char Hostname[33]; // Composed Wifi hostname -char MQTTClient[33]; // Composed MQTT Clientname uint8_t mqttcounter = 0; // MQTT connection retry counter uint8_t fallbacktopic = 0; // Use Topic or FallbackTopic unsigned long timerxs = 0; // State loop timer @@ -236,7 +232,6 @@ int wificheckflag = WIFI_RESTART; // Wifi state flag int uptime = 0; // Current uptime in hours boolean uptime_flg = true; // Signal latest uptime int tele_period = 0; // Tele period timer -String Log[MAX_LOG_LINES]; // Web log buffer byte logidx = 0; // Index in Web log buffer byte logajaxflg = 0; // Reset web console log byte Maxdevice = 0; // Max number of devices supported @@ -250,7 +245,6 @@ uint8_t blink_powersave; // Blink start power save state uint16_t mqtt_cmnd_publish = 0; // ignore flag for publish command uint8_t latching_power = 0; // Power state at latching start uint8_t latching_relay_pulse = 0; // Latching relay pulse timer -String Backlog[MAX_BACKLOG]; // Command backlog uint8_t blogidx = 0; // Command backlog index uint8_t blogptr = 0; // Command backlog pointer uint8_t blogmutex = 0; // Command backlog pending @@ -288,7 +282,6 @@ mytmplt my_module; // Active copy of GPIOs uint8_t pin[GPIO_MAX]; // Possible pin configurations uint8_t rel_inverted[4] = { 0 }; // Relay inverted flag (1 = (0 = On, 1 = Off)) uint8_t led_inverted[4] = { 0 }; // LED inverted flag (1 = (0 = On, 1 = Off)) -uint8_t swt_flg = 0; // Any external switch configured uint8_t dht_flg = 0; // DHT configured uint8_t hlw_flg = 0; // Power monitor configured uint8_t i2c_flg = 0; // I2C configured @@ -299,6 +292,15 @@ uint8_t pwm_idxoffset = 0; // Allowed PWM command offset (change for boolean mDNSbegun = false; +char Version[16]; // Version string from VERSION define +char Hostname[33]; // Composed Wifi hostname +char MQTTClient[33]; // Composed MQTT Clientname +char serialInBuf[INPUT_BUFFER_SIZE + 2]; // Receive buffer +char mqtt_data[MESSZ]; // MQTT publish buffer +char log_data[TOPSZ + MESSZ]; // Logging +String Log[MAX_LOG_LINES]; // Web log buffer +String Backlog[MAX_BACKLOG]; // Command backlog + /********************************************************************************************/ void getClient(char* output, const char* input, byte size) @@ -416,7 +418,7 @@ void setRelay(uint8_t rpower) Serial.flush(); } else if (sfl_flg) { - sl_setPower(rpower &1); + sl_setPower(rpower); } else if (EXS_RELAY == sysCfg.module) { setLatchingRelay(rpower, 1); @@ -443,28 +445,26 @@ void setLed(uint8_t state) /********************************************************************************************/ -void mqtt_publish_sec(const char* topic, const char* data, boolean retained) +void mqtt_publish_sec(const char* topic, boolean retained) { - char log[TOPSZ + MESSZ]; - if (sysCfg.flag.mqtt_enabled) { - if (mqttClient.publish(topic, data, retained)) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_MQTT "%s = %s%s"), topic, data, (retained) ? " (" D_RETAINED ")" : ""); + if (mqttClient.publish(topic, mqtt_data, retained)) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT "%s = %s%s"), topic, mqtt_data, (retained) ? " (" D_RETAINED ")" : ""); // mqttClient.loop(); // Do not use here! Will block previous publishes } else { - snprintf_P(log, sizeof(log), PSTR(D_LOG_RESULT "%s = %s"), topic, data); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_RESULT "%s = %s"), topic, mqtt_data); } } else { - snprintf_P(log, sizeof(log), PSTR(D_LOG_RESULT "%s = %s"), strrchr(topic,'/')+1, data); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_RESULT "%s = %s"), strrchr(topic,'/')+1, mqtt_data); } - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); if (sysCfg.ledstate &0x04) { blinks++; } } -void mqtt_publish(const char* topic, const char* data, boolean retained) +void mqtt_publish(const char* topic, boolean retained) { char *me; @@ -474,15 +474,15 @@ void mqtt_publish(const char* topic, const char* data, boolean retained) mqtt_cmnd_publish += 8; } } - mqtt_publish_sec(topic, data, retained); + mqtt_publish_sec(topic, retained); } -void mqtt_publish(const char* topic, const char* data) +void mqtt_publish(const char* topic) { - mqtt_publish(topic, data, false); + mqtt_publish(topic, false); } -void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data, boolean retained) +void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, boolean retained) { /* prefix 0 = cmnd using subtopic * prefix 1 = stat using subtopic @@ -500,57 +500,54 @@ void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data } prefix &= 3; getTopic_P(stopic, prefix, sysCfg.mqtt_topic, romram); - mqtt_publish(stopic, data, retained); + mqtt_publish(stopic, retained); } -void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data) +void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic) { - mqtt_publish_topic_P(prefix, subtopic, data, false); + mqtt_publish_topic_P(prefix, subtopic, false); } void mqtt_publishPowerState(byte device) { char stopic[TOPSZ]; char scommand[16]; - char svalue[64]; // was MESSZ if ((device < 1) || (device > Maxdevice)) { device = 1; } getPowerDevice(scommand, device, sizeof(scommand)); getTopic_P(stopic, 1, sysCfg.mqtt_topic, (sysCfg.flag.mqtt_response) ? scommand : S_RSLT_RESULT); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"%s\":\"%s\"}"), scommand, getStateText(bitRead(power, device -1))); - mqtt_publish(stopic, svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\"}"), scommand, getStateText(bitRead(power, device -1))); + mqtt_publish(stopic); getTopic_P(stopic, 1, sysCfg.mqtt_topic, scommand); - snprintf_P(svalue, sizeof(svalue), PSTR("%s"), getStateText(bitRead(power, device -1))); - mqtt_publish(stopic, svalue, sysCfg.flag.mqtt_power_retain); + snprintf_P(mqtt_data, sizeof(mqtt_data), getStateText(bitRead(power, device -1))); + mqtt_publish(stopic, sysCfg.flag.mqtt_power_retain); } void mqtt_publishPowerBlinkState(byte device) { char scommand[16]; - char svalue[64]; // was MESSZ if ((device < 1) || (device > Maxdevice)) { device = 1; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"%s\":\"" D_BLINK " %s\"}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"" D_BLINK " %s\"}"), getPowerDevice(scommand, device, sizeof(scommand)), getStateText(bitRead(blink_mask, device -1))); - mqtt_publish_topic_P(5, S_RSLT_POWER, svalue); + mqtt_publish_topic_P(5, S_RSLT_POWER); } void mqtt_connected() { char stopic[TOPSZ]; - char svalue[164]; // was MESSZ if (sysCfg.flag.mqtt_enabled) { // Satisfy iobroker (#299) - svalue[0] = '\0'; - mqtt_publish_topic_P(0, S_RSLT_POWER, svalue); + mqtt_data[0] = '\0'; + mqtt_publish_topic_P(0, S_RSLT_POWER); getTopic_P(stopic, 0, sysCfg.mqtt_topic, PSTR("#")); mqttClient.subscribe(stopic); @@ -571,19 +568,19 @@ void mqtt_connected() } if (mqttflag) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_MODULE "\":\"%s\", \"" D_VERSION "\":\"%s\", \"" D_FALLBACKTOPIC "\":\"%s\", \"" D_CMND_GROUPTOPIC "\":\"%s\"}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULE "\":\"%s\", \"" D_VERSION "\":\"%s\", \"" D_FALLBACKTOPIC "\":\"%s\", \"" D_CMND_GROUPTOPIC "\":\"%s\"}"), my_module.name, Version, MQTTClient, sysCfg.mqtt_grptopic); - mqtt_publish_topic_P(2, PSTR(D_RSLT_INFO "1"), svalue); + mqtt_publish_topic_P(2, PSTR(D_RSLT_INFO "1")); #ifdef USE_WEBSERVER if (sysCfg.webserver) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_WEBSERVER_MODE "\":\"%s\", \"" D_CMND_HOSTNAME "\":\"%s\", \"" D_CMND_IPADDRESS "\":\"%s\"}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_WEBSERVER_MODE "\":\"%s\", \"" D_CMND_HOSTNAME "\":\"%s\", \"" D_CMND_IPADDRESS "\":\"%s\"}"), (2 == sysCfg.webserver) ? D_ADMIN : D_USER, Hostname, WiFi.localIP().toString().c_str()); - mqtt_publish_topic_P(2, PSTR(D_RSLT_INFO "2"), svalue); + mqtt_publish_topic_P(2, PSTR(D_RSLT_INFO "2")); } #endif // USE_WEBSERVER - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_RESTARTREASON "\":\"%s\"}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_RESTARTREASON "\":\"%s\"}"), (getResetReason() == "Exception") ? ESP.getResetInfo().c_str() : getResetReason().c_str()); - mqtt_publish_topic_P(2, PSTR(D_RSLT_INFO "3"), svalue); + mqtt_publish_topic_P(2, PSTR(D_RSLT_INFO "3")); if (sysCfg.tele_period) { tele_period = sysCfg.tele_period -9; } @@ -598,8 +595,6 @@ void mqtt_connected() void mqtt_reconnect() { char stopic[TOPSZ]; - char svalue[TOPSZ]; - char log[LOGSZ]; mqttcounter = sysCfg.mqtt_retry; @@ -614,9 +609,9 @@ void mqtt_reconnect() #ifdef USE_MQTT_TLS addLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_FINGERPRINT)); if (!espClient.connect(sysCfg.mqtt_host, sysCfg.mqtt_port)) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_MQTT D_TLS_CONNECT_FAILED_TO " %s:%d. " D_RETRY_IN " %d " D_UNIT_SECOND), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_TLS_CONNECT_FAILED_TO " %s:%d. " D_RETRY_IN " %d " D_UNIT_SECOND), sysCfg.mqtt_host, sysCfg.mqtt_port, mqttcounter); - addLog(LOG_LEVEL_DEBUG, log); + addLog(LOG_LEVEL_DEBUG); return; } if (espClient.verify(sysCfg.mqtt_fingerprint, sysCfg.mqtt_host)) { @@ -642,23 +637,23 @@ void mqtt_reconnect() mqttClient.setServer(sysCfg.mqtt_host, sysCfg.mqtt_port); getTopic_P(stopic, 2, sysCfg.mqtt_topic, S_LWT); - snprintf_P(svalue, sizeof(svalue), S_OFFLINE); - if (mqttClient.connect(MQTTClient, sysCfg.mqtt_user, sysCfg.mqtt_pwd, stopic, 1, true, svalue)) { + snprintf_P(mqtt_data, sizeof(mqtt_data), S_OFFLINE); + if (mqttClient.connect(MQTTClient, sysCfg.mqtt_user, sysCfg.mqtt_pwd, stopic, 1, true, mqtt_data)) { addLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_CONNECTED)); mqttcounter = 0; - snprintf_P(svalue, sizeof(svalue), PSTR(D_ONLINE)); - mqtt_publish(stopic, svalue, true); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_ONLINE)); + mqtt_publish(stopic, true); mqtt_connected(); } else { - snprintf_P(log, sizeof(log), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d, rc %d. " D_RETRY_IN " %d " D_UNIT_SECOND), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d, rc %d. " D_RETRY_IN " %d " D_UNIT_SECOND), sysCfg.mqtt_host, sysCfg.mqtt_port, mqttClient.state(), mqttcounter); //status codes are documented here http://pubsubclient.knolleary.net/api.html#state - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); } } /********************************************************************************************/ -boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue) +boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, uint16_t payload16) { boolean serviced = true; char stemp1[TOPSZ]; @@ -671,21 +666,21 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, strlcpy(sysCfg.mqtt_host, (1 == payload) ? MQTT_HOST : dataBuf, sizeof(sysCfg.mqtt_host)); restartflag = 2; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTHOST "\":\"%s\"}"), sysCfg.mqtt_host); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MQTTHOST "\":\"%s\"}"), sysCfg.mqtt_host); } else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTPORT))) { - if ((payload > 0) && (payload < 32766)) { - sysCfg.mqtt_port = (1 == payload) ? MQTT_PORT : payload; + if (payload16 > 0) { + sysCfg.mqtt_port = (1 == payload16) ? MQTT_PORT : payload16; restartflag = 2; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTPORT "\":%d}"), sysCfg.mqtt_port); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MQTTPORT "\":%d}"), sysCfg.mqtt_port); } else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTRETRY))) { if ((payload >= MQTT_RETRY_SECS) && (payload < 32001)) { sysCfg.mqtt_retry = payload; mqttcounter = sysCfg.mqtt_retry; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTRETRY "\":%d}"), sysCfg.mqtt_retry); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MQTTRETRY "\":%d}"), sysCfg.mqtt_retry); } else if (!strcasecmp_P(type, PSTR(D_CMND_STATETEXT)) && (index > 0) && (index <= 4)) { if ((data_len > 0) && (data_len < sizeof(sysCfg.state_text[0]))) { @@ -696,7 +691,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, } strlcpy(sysCfg.state_text[index -1], dataBuf, sizeof(sysCfg.state_text[0])); } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_STATETEXT "%d\":\"%s\"}"), index, getStateText(index -1)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATETEXT "%d\":\"%s\"}"), index, getStateText(index -1)); } #ifdef USE_MQTT_TLS else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTFINGERPRINT))) { @@ -704,7 +699,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, strlcpy(sysCfg.mqtt_fingerprint, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_FINGERPRINT : dataBuf, sizeof(sysCfg.mqtt_fingerprint)); restartflag = 2; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTFINGERPRINT "\":\"%s\"}"), sysCfg.mqtt_fingerprint); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MQTTFINGERPRINT "\":\"%s\"}"), sysCfg.mqtt_fingerprint); } #endif else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_MQTTCLIENT))) { @@ -712,21 +707,21 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, strlcpy(sysCfg.mqtt_client, (1 == payload) ? MQTT_CLIENT_ID : dataBuf, sizeof(sysCfg.mqtt_client)); restartflag = 2; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTCLIENT "\":\"%s\"}"), sysCfg.mqtt_client); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MQTTCLIENT "\":\"%s\"}"), sysCfg.mqtt_client); } else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTUSER))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_user))) { strlcpy(sysCfg.mqtt_user, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_USER : dataBuf, sizeof(sysCfg.mqtt_user)); restartflag = 2; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTUSER "\":\"%s\"}"), sysCfg.mqtt_user); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MQTTUSER "\":\"%s\"}"), sysCfg.mqtt_user); } else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTPASSWORD))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_pwd))) { strlcpy(sysCfg.mqtt_pwd, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_PASS : dataBuf, sizeof(sysCfg.mqtt_pwd)); restartflag = 2; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTPASSWORD "\":\"%s\"}"), sysCfg.mqtt_pwd); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MQTTPASSWORD "\":\"%s\"}"), sysCfg.mqtt_pwd); } else if (!strcasecmp_P(type, PSTR(D_CMND_FULLTOPIC))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_fulltopic))) { @@ -736,12 +731,13 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, } strlcpy(stemp1, (1 == payload) ? MQTT_FULLTOPIC : dataBuf, sizeof(stemp1)); if (strcmp(stemp1, sysCfg.mqtt_fulltopic)) { - mqtt_publish_topic_P(2, PSTR(D_LWT), (sysCfg.flag.mqtt_offline) ? D_OFFLINE : "", true); // Offline or remove previous retained topic + snprintf_P(mqtt_data, sizeof(mqtt_data), (sysCfg.flag.mqtt_offline) ? S_OFFLINE : ""); + mqtt_publish_topic_P(2, PSTR(D_LWT), true); // Offline or remove previous retained topic strlcpy(sysCfg.mqtt_fulltopic, stemp1, sizeof(sysCfg.mqtt_fulltopic)); restartflag = 2; } } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_FULLTOPIC "\":\"%s\"}"), sysCfg.mqtt_fulltopic); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_FULLTOPIC "\":\"%s\"}"), sysCfg.mqtt_fulltopic); } else if (!strcasecmp_P(type, PSTR(D_CMND_PREFIX)) && (index > 0) && (index <= 3)) { if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_prefix[0]))) { @@ -750,7 +746,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, // if (sysCfg.mqtt_prefix[index -1][strlen(sysCfg.mqtt_prefix[index -1])] == '/') sysCfg.mqtt_prefix[index -1][strlen(sysCfg.mqtt_prefix[index -1])] = 0; restartflag = 2; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_PREFIX "%d\":\"%s\"}"), index, sysCfg.mqtt_prefix[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PREFIX "%d\":\"%s\"}"), index, sysCfg.mqtt_prefix[index -1]); } else if (!strcasecmp_P(type, PSTR(D_CMND_GROUPTOPIC))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_grptopic))) { @@ -761,7 +757,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, strlcpy(sysCfg.mqtt_grptopic, (1 == payload) ? MQTT_GRPTOPIC : dataBuf, sizeof(sysCfg.mqtt_grptopic)); restartflag = 2; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_GROUPTOPIC "\":\"%s\"}"), sysCfg.mqtt_grptopic); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_GROUPTOPIC "\":\"%s\"}"), sysCfg.mqtt_grptopic); } else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_TOPIC))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_topic))) { @@ -771,12 +767,13 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, } strlcpy(stemp1, (1 == payload) ? MQTT_TOPIC : dataBuf, sizeof(stemp1)); if (strcmp(stemp1, sysCfg.mqtt_topic)) { - mqtt_publish_topic_P(2, PSTR(D_LWT), (sysCfg.flag.mqtt_offline) ? D_OFFLINE : "", true); // Offline or remove previous retained topic + snprintf_P(mqtt_data, sizeof(mqtt_data), (sysCfg.flag.mqtt_offline) ? S_OFFLINE : ""); + mqtt_publish_topic_P(2, PSTR(D_LWT), true); // Offline or remove previous retained topic strlcpy(sysCfg.mqtt_topic, stemp1, sizeof(sysCfg.mqtt_topic)); restartflag = 2; } } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_TOPIC "\":\"%s\"}"), sysCfg.mqtt_topic); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TOPIC "\":\"%s\"}"), sysCfg.mqtt_topic); } else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_BUTTONTOPIC))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.button_topic))) { @@ -786,9 +783,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, } strlcpy(sysCfg.button_topic, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? sysCfg.mqtt_topic : dataBuf, sizeof(sysCfg.button_topic)); } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_BUTTONTOPIC "\":\"%s\"}"), sysCfg.button_topic); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_BUTTONTOPIC "\":\"%s\"}"), sysCfg.button_topic); } - else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_SWITCHTOPIC))) { + else if (!strcasecmp_P(type, PSTR(D_CMND_SWITCHTOPIC))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.switch_topic))) { mqttfy(0, dataBuf); if (!strcmp(dataBuf, MQTTClient)) { @@ -796,7 +793,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, } strlcpy(sysCfg.switch_topic, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? sysCfg.mqtt_topic : dataBuf, sizeof(sysCfg.switch_topic)); } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SWITCHTOPIC "\":\"%s\"}"), sysCfg.switch_topic); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SWITCHTOPIC "\":\"%s\"}"), sysCfg.switch_topic); } else if (!strcasecmp_P(type, PSTR(D_CMND_BUTTONRETAIN))) { if ((payload >= 0) && (payload <= 1)) { @@ -808,7 +805,7 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, } sysCfg.flag.mqtt_button_retain = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_BUTTONRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_button_retain)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_BUTTONRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_button_retain)); } else if (!strcasecmp_P(type, PSTR(D_CMND_SWITCHRETAIN))) { if ((payload >= 0) && (payload <= 1)) { @@ -820,33 +817,34 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf, } sysCfg.flag.mqtt_switch_retain = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SWITCHRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_switch_retain)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SWITCHRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_switch_retain)); } else if (!strcasecmp_P(type, PSTR(D_CMND_POWERRETAIN))) { if ((payload >= 0) && (payload <= 1)) { if (!payload) { for(i = 1; i <= Maxdevice; i++) { // Clear MQTT retain in broker getTopic_P(stemp1, 1, sysCfg.mqtt_topic, getPowerDevice(scommand, i, sizeof(scommand))); - mqtt_publish(stemp1, "", sysCfg.flag.mqtt_power_retain); + mqtt_data[0] = '\0'; + mqtt_publish(stemp1, sysCfg.flag.mqtt_power_retain); } } sysCfg.flag.mqtt_power_retain = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_POWERRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_power_retain)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_POWERRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_power_retain)); } else if (!strcasecmp_P(type, PSTR(D_CMND_SENSORRETAIN))) { if ((payload >= 0) && (payload <= 1)) { if (!payload) { - svalue[0] = '\0'; - mqtt_publish_topic_P(2, PSTR(D_RSLT_SENSOR), svalue, sysCfg.flag.mqtt_sensor_retain); + mqtt_data[0] = '\0'; + mqtt_publish_topic_P(2, PSTR(D_RSLT_SENSOR), sysCfg.flag.mqtt_sensor_retain); } sysCfg.flag.mqtt_sensor_retain = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SENSORRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_sensor_retain)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SENSORRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_sensor_retain)); } #ifdef USE_DOMOTICZ - else if (domoticz_command(type, index, dataBuf, data_len, payload, svalue, ssvalue)) { + else if (domoticz_command(type, index, dataBuf, data_len, payload)) { // Serviced } #endif // USE_DOMOTICZ @@ -876,14 +874,14 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) char topicBuf[TOPSZ]; char dataBuf[data_len+1]; - char dataBufUc[128]; - char svalue[MESSZ]; char stemp1[TOPSZ]; char *p; char *mtopic = NULL; char *type = NULL; byte otype = 0; byte ptype = 0; + byte jsflg = 0; + byte lines = 1; uint16_t i = 0; uint16_t grpflg = 0; uint16_t index; @@ -899,9 +897,9 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) memcpy(dataBuf, data +i, sizeof(dataBuf)); dataBuf[sizeof(dataBuf)-1] = 0; - snprintf_P(svalue, sizeof(svalue), PSTR(D_LOG_RESULT D_RECEIVED_TOPIC " %s, " D_DATA_SIZE " %d, " D_DATA " %s"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_RESULT D_RECEIVED_TOPIC " %s, " D_DATA_SIZE " %d, " D_DATA " %s"), topicBuf, data_len, dataBuf); - addLog(LOG_LEVEL_DEBUG_MORE, svalue); + addLog(LOG_LEVEL_DEBUG_MORE); // if (LOG_LEVEL_DEBUG_MORE <= seriallog_level) Serial.println(dataBuf); #ifdef USE_DOMOTICZ @@ -930,21 +928,17 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) type[i] = '\0'; } - for (i = 0; i <= sizeof(dataBufUc); i++) { - dataBufUc[i] = toupper(dataBuf[i]); - } - - snprintf_P(svalue, sizeof(svalue), PSTR(D_LOG_RESULT D_GROUP " %d, " D_INDEX " %d, " D_COMMAND " %s, " D_DATA " %s (%s)"), - grpflg, index, type, dataBuf, dataBufUc); - addLog(LOG_LEVEL_DEBUG, svalue); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_RESULT D_GROUP " %d, " D_INDEX " %d, " D_COMMAND " %s, " D_DATA " %s"), + grpflg, index, type, dataBuf); + addLog(LOG_LEVEL_DEBUG); if (type != NULL) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_COMMAND "\":\"" D_ERROR "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_COMMAND "\":\"" D_ERROR "\"}")); if (sysCfg.ledstate &0x02) { blinks++; } - if (!strcmp(dataBufUc,"?")) { + if (!strcmp(dataBuf,"?")) { data_len = 0; } int16_t payload = -99; // No payload @@ -956,24 +950,24 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } blogdelay = MIN_BACKLOG_DELAY; // Reset backlog delay - if (!strcasecmp_P(dataBuf, PSTR(D_OFF)) || !strcasecmp_P(dataBuf, PSTR(D_FALSE)) || !strcasecmp_P(dataBuf, PSTR(D_STOP)) || !strcasecmp_P(dataBuf, PSTR(D_CELSIUS))) { + if (!strcasecmp_P(dataBuf, PSTR("OFF")) || !strcasecmp_P(dataBuf, PSTR(D_OFF)) || !strcasecmp_P(dataBuf, sysCfg.state_text[0]) || !strcasecmp_P(dataBuf, PSTR(D_FALSE)) || !strcasecmp_P(dataBuf, PSTR(D_STOP)) || !strcasecmp_P(dataBuf, PSTR(D_CELSIUS))) { payload = 0; } - if (!strcasecmp_P(dataBuf, PSTR(D_ON)) || !strcasecmp_P(dataBuf, PSTR(D_TRUE)) || !strcasecmp_P(dataBuf, PSTR(D_START)) || !strcasecmp_P(dataBuf, PSTR(D_FAHRENHEIT)) || !strcasecmp_P(dataBuf, PSTR(D_USER))) { + if (!strcasecmp_P(dataBuf, PSTR("ON")) || !strcasecmp_P(dataBuf, PSTR(D_ON)) || !strcasecmp_P(dataBuf, sysCfg.state_text[1]) || !strcasecmp_P(dataBuf, PSTR(D_TRUE)) || !strcasecmp_P(dataBuf, PSTR(D_START)) || !strcasecmp_P(dataBuf, PSTR(D_FAHRENHEIT)) || !strcasecmp_P(dataBuf, PSTR(D_USER))) { payload = 1; } - if (!strcasecmp_P(dataBuf, PSTR(D_TOGGLE)) || !strcasecmp_P(dataBuf, PSTR(D_ADMIN))) { + if (!strcasecmp_P(dataBuf, PSTR("TOGGLE")) || !strcasecmp_P(dataBuf, PSTR(D_TOGGLE)) || !strcasecmp_P(dataBuf, sysCfg.state_text[2]) || !strcasecmp_P(dataBuf, PSTR(D_ADMIN))) { payload = 2; } - if (!strcasecmp_P(dataBuf, PSTR(D_BLINK))) { + if (!strcasecmp_P(dataBuf, PSTR("BLINK")) || !strcasecmp_P(dataBuf, PSTR(D_BLINK))) { payload = 3; } - if (!strcasecmp_P(dataBuf, PSTR(D_BLINKOFF))) { + if (!strcasecmp_P(dataBuf, PSTR("BLINKOFF")) || !strcasecmp_P(dataBuf, PSTR(D_BLINKOFF))) { payload = 4; } -// snprintf_P(svalue, sizeof(svalue), PSTR("RSLT: Payload %d, Payload16 %d"), payload, payload16); -// addLog(LOG_LEVEL_DEBUG, svalue); +// snprintf_P(log_data, sizeof(log_data), PSTR("RSLT: Payload %d, Payload16 %d"), payload, payload16); +// addLog(LOG_LEVEL_DEBUG); if (!strcasecmp_P(type, PSTR(D_CMND_BACKLOG))) { if (data_len) { @@ -989,18 +983,18 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) blogidx &= 0xF; blcommand = strtok(NULL, ";"); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_BACKLOG "\":\"" D_APPENDED "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_BACKLOG "\":\"" D_APPENDED "\"}")); } else { uint8_t blflag = (blogptr == blogidx); blogptr = blogidx; - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_BACKLOG "\":\"%s\"}"), blflag ? D_EMPTY : D_ABORTED); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_BACKLOG "\":\"%s\"}"), blflag ? D_EMPTY : D_ABORTED); } } else if (!strcasecmp_P(type, PSTR(D_CMND_DELAY))) { if ((payload >= MIN_BACKLOG_DELAY) && (payload <= 3600)) { blogdelay = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_DELAY "\":%d}"), blogdelay); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DELAY "\":%d}"), blogdelay); } else if (!strcasecmp_P(type, PSTR(D_CMND_POWER)) && (index > 0) && (index <= Maxdevice)) { if ((payload < 0) || (payload > 4)) { @@ -1033,14 +1027,14 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } } } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_POWERONSTATE "\":%d}"), sysCfg.poweronstate); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_POWERONSTATE "\":%d}"), sysCfg.poweronstate); } else if (!strcasecmp_P(type, PSTR(D_CMND_PULSETIME)) && (index > 0) && (index <= MAX_PULSETIMERS)) { if (data_len > 0) { sysCfg.pulsetime[index -1] = payload16; // 0 - 65535 pulse_timer[index -1] = 0; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_PULSETIME "%d\":%d}"), index, sysCfg.pulsetime[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PULSETIME "%d\":%d}"), index, sysCfg.pulsetime[index -1]); } else if (!strcasecmp_P(type, PSTR(D_CMND_BLINKTIME))) { if ((payload > 2) && (payload <= 3600)) { @@ -1049,7 +1043,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) blink_timer = sysCfg.blinktime; } } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_BLINKTIME "\":%d}"), sysCfg.blinktime); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_BLINKTIME "\":%d}"), sysCfg.blinktime); } else if (!strcasecmp_P(type, PSTR(D_CMND_BLINKCOUNT))) { if (data_len > 0) { @@ -1058,9 +1052,9 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) blink_counter = sysCfg.blinkcount *2; } } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_BLINKCOUNT "\":%d}"), sysCfg.blinkcount); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_BLINKCOUNT "\":%d}"), sysCfg.blinkcount); } - else if (sfl_flg && sl_command(type, index, dataBufUc, data_len, payload, svalue, sizeof(svalue))) { + else if (sfl_flg && sl_command(type, index, dataBuf, data_len, payload)) { // Serviced } else if (!strcasecmp_P(type, PSTR(D_CMND_SAVEDATA))) { @@ -1075,7 +1069,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) if (sysCfg.savedata > 1) { snprintf_P(stemp1, sizeof(stemp1), PSTR(D_EVERY " %d " D_UNIT_SECOND), sysCfg.savedata); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SAVEDATA "\":\"%s\"}"), (sysCfg.savedata > 1) ? stemp1 : getStateText(sysCfg.savedata)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SAVEDATA "\":\"%s\"}"), (sysCfg.savedata > 1) ? stemp1 : getStateText(sysCfg.savedata)); } else if (!strcasecmp_P(type, PSTR(D_CMND_SETOPTION)) && ((index >= 0) && (index <= 14)) || ((index > 31) && (index <= P_MAX_PARAM8 +31))) { if (index <= 31) { @@ -1126,43 +1120,43 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) if (ptype) { snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), sysCfg.param[index]); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SETOPTION "%d\":\"%s\"}"), (ptype) ? index +32 : index, (ptype) ? stemp1 : getStateText(bitRead(sysCfg.flag.data, index))); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SETOPTION "%d\":\"%s\"}"), (ptype) ? index +32 : index, (ptype) ? stemp1 : getStateText(bitRead(sysCfg.flag.data, index))); } else if (!strcasecmp_P(type, PSTR(D_CMND_TEMPERATURE_RESOLUTION))) { if ((payload >= 0) && (payload <= 3)) { sysCfg.flag.temperature_resolution = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_TEMPERATURE_RESOLUTION "\":%d}"), sysCfg.flag.temperature_resolution); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TEMPERATURE_RESOLUTION "\":%d}"), sysCfg.flag.temperature_resolution); } else if (!strcasecmp_P(type, PSTR(D_CMND_HUMIDITY_RESOLUTION))) { if ((payload >= 0) && (payload <= 3)) { sysCfg.flag.humidity_resolution = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_HUMIDITY_RESOLUTION "\":%d}"), sysCfg.flag.humidity_resolution); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_HUMIDITY_RESOLUTION "\":%d}"), sysCfg.flag.humidity_resolution); } else if (!strcasecmp_P(type, PSTR(D_CMND_PRESSURE_RESOLUTION))) { if ((payload >= 0) && (payload <= 3)) { sysCfg.flag.pressure_resolution = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_PRESSURE_RESOLUTION "\":%d}"), sysCfg.flag.pressure_resolution); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PRESSURE_RESOLUTION "\":%d}"), sysCfg.flag.pressure_resolution); } else if (!strcasecmp_P(type, PSTR(D_CMND_POWER_RESOLUTION))) { if ((payload >= 0) && (payload <= 1)) { sysCfg.flag.wattage_resolution = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_POWER_RESOLUTION "\":%d}"), sysCfg.flag.wattage_resolution); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_POWER_RESOLUTION "\":%d}"), sysCfg.flag.wattage_resolution); } else if (!strcasecmp_P(type, PSTR(D_CMND_VOLTAGE_RESOLUTION))) { if ((payload >= 0) && (payload <= 1)) { sysCfg.flag.voltage_resolution = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_VOLTAGE_RESOLUTION "\":%d}"), sysCfg.flag.voltage_resolution); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_VOLTAGE_RESOLUTION "\":%d}"), sysCfg.flag.voltage_resolution); } else if (!strcasecmp_P(type, PSTR(D_CMND_ENERGY_RESOLUTION))) { if ((payload >= 0) && (payload <= 5)) { sysCfg.flag.energy_resolution = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_ENERGY_RESOLUTION "\":%d}"), sysCfg.flag.energy_resolution); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_ENERGY_RESOLUTION "\":%d}"), sysCfg.flag.energy_resolution); } else if (!strcasecmp_P(type, PSTR(D_CMND_MODULE))) { if ((payload > 0) && (payload <= MAXMODULE)) { @@ -1177,32 +1171,26 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) restartflag = 2; } snprintf_P(stemp1, sizeof(stemp1), modules[sysCfg.module].name); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_MODULE "\":\"%d (%s)\"}"), sysCfg.module +1, stemp1); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULE "\":\"%d (%s)\"}"), sysCfg.module +1, stemp1); } else if (!strcasecmp_P(type, PSTR(D_CMND_MODULES))) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_MODULES "1\":\""), svalue); - byte jsflg = 0; - for (byte i = 0; i < MAXMODULE /2; i++) { - if (jsflg) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s, "), svalue); + for (byte i = 0; i < MAXMODULE; i++) { + if (!jsflg) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MODULES "%d\":\""), lines); + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, "), mqtt_data); } jsflg = 1; snprintf_P(stemp1, sizeof(stemp1), modules[i].name); - snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i +1, stemp1); - } - snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue); - mqtt_publish_topic_P(5, type, svalue); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_MODULES "2\":\""), svalue); - jsflg = 0; - for (byte i = MAXMODULE /2; i < MAXMODULE; i++) { - if (jsflg) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s, "), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%d (%s)"), mqtt_data, i +1, stemp1); + if ((strlen(mqtt_data) > 200) || (i == MAXMODULE -1)) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"}"), mqtt_data); + mqtt_publish_topic_P(5, type); + jsflg = 0; + lines++; } - jsflg = 1; - snprintf_P(stemp1, sizeof(stemp1), modules[i].name); - snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i +1, stemp1); } - snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue); + mqtt_data[0] = '\0'; } else if (!strcasecmp_P(type, PSTR(D_CMND_GPIO)) && (index < MAX_GPIO_PIN)) { mytmplt cmodule; @@ -1216,70 +1204,64 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) sysCfg.my_module.gp.io[index] = payload; restartflag = 2; } - snprintf_P(svalue, sizeof(svalue), PSTR("{"), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{")); byte jsflg = 0; for (byte i = 0; i < MAX_GPIO_PIN; i++) { if (GPIO_USER == cmodule.gp.io[i]) { if (jsflg) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s, "), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, "), mqtt_data); } jsflg = 1; snprintf_P(stemp1, sizeof(stemp1), sensors[sysCfg.my_module.gp.io[i]]); - snprintf_P(svalue, sizeof(svalue), PSTR("%s\"" D_CMND_GPIO "%d\":%d (%s)"), svalue, i, sysCfg.my_module.gp.io[i], stemp1); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_GPIO "%d\":%d (%s)"), mqtt_data, i, sysCfg.my_module.gp.io[i], stemp1); } } if (jsflg) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } else { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_GPIO "\":\"" D_NOT_SUPPORTED "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_GPIO "\":\"" D_NOT_SUPPORTED "\"}")); } } else if (!strcasecmp_P(type, PSTR(D_CMND_GPIOS))) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_GPIOS "1\":\""), svalue); - byte jsflg = 0; - for (byte i = 0; i < GPIO_SENSOR_END /2; i++) { - if (jsflg) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s, "), svalue); + for (byte i = 0; i < GPIO_SENSOR_END; i++) { + if (!jsflg) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_GPIOS "%d\":\""), lines); + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, "), mqtt_data); } jsflg = 1; snprintf_P(stemp1, sizeof(stemp1), sensors[i]); - snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i, stemp1); - } - snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue); - mqtt_publish_topic_P(5, type, svalue); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_GPIOS "2\":\""), svalue); - jsflg = 0; - for (byte i = GPIO_SENSOR_END /2; i < GPIO_SENSOR_END; i++) { - if (jsflg) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s, "), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%d (%s)"), mqtt_data, i, stemp1); + if ((strlen(mqtt_data) > 200) || (i == GPIO_SENSOR_END -1)) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"}"), mqtt_data); + mqtt_publish_topic_P(5, type); + jsflg = 0; + lines++; } - jsflg = 1; - snprintf_P(stemp1, sizeof(stemp1), sensors[i]); - snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i, stemp1); } - snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue); + mqtt_data[0] = '\0'; } else if (!strcasecmp_P(type, PSTR(D_CMND_PWM)) && (index > pwm_idxoffset) && (index <= 5)) { if ((payload >= 0) && (payload <= PWM_RANGE) && (pin[GPIO_PWM1 + index -1] < 99)) { sysCfg.pwmvalue[index -1] = payload; analogWrite(pin[GPIO_PWM1 + index -1], payload); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_PWM "\":{")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PWM "\":{")); bool first = true; for (byte i = 0; i < 5; i++) { if(pin[GPIO_PWM1 + i] < 99) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_PWM "%d\":%d"), svalue, first ? "" : ", ", i+1, sysCfg.pwmvalue[i]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_PWM "%d\":%d"), mqtt_data, first ? "" : ", ", i+1, sysCfg.pwmvalue[i]); first = false; } } - snprintf_P(svalue, sizeof(svalue), PSTR("%s}}"),svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}}"),mqtt_data); } else if (!strcasecmp_P(type, PSTR(D_CMND_COUNTER)) && (index > 0) && (index <= MAX_COUNTERS)) { if ((data_len > 0) && (pin[GPIO_CNTR1 + index -1] < 99)) { rtcMem.pCounter[index -1] = payload16; sysCfg.pCounter[index -1] = payload16; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_COUNTER "%d\":%d}"), index, rtcMem.pCounter[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_COUNTER "%d\":%d}"), index, rtcMem.pCounter[index -1]); } else if (!strcasecmp_P(type, PSTR(D_CMND_COUNTERTYPE)) && (index > 0) && (index <= MAX_COUNTERS)) { if ((payload >= 0) && (payload <= 1) && (pin[GPIO_CNTR1 + index -1] < 99)) { @@ -1287,13 +1269,13 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) rtcMem.pCounter[index -1] = 0; sysCfg.pCounter[index -1] = 0; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_COUNTERTYPE "%d\":%d}"), index, bitRead(sysCfg.pCounterType, index -1)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_COUNTERTYPE "%d\":%d}"), index, bitRead(sysCfg.pCounterType, index -1)); } else if (!strcasecmp_P(type, PSTR(D_CMND_COUNTERDEBOUNCE))) { if ((data_len > 0) && (payload16 < 32001)) { sysCfg.pCounterDebounce = payload16; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_COUNTERDEBOUNCE "\":%d}"), sysCfg.pCounterDebounce); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_COUNTERDEBOUNCE "\":%d}"), sysCfg.pCounterDebounce); } else if (!strcasecmp_P(type, PSTR(D_CMND_SLEEP))) { if ((payload >= 0) && (payload < 251)) { @@ -1303,7 +1285,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) sysCfg.sleep = payload; sleep = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SLEEP "\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.flag.value_units) ? " " D_UNIT_MILLISECOND : "", sysCfg.sleep, (sysCfg.flag.value_units) ? " " D_UNIT_MILLISECOND : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SLEEP "\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.flag.value_units) ? " " D_UNIT_MILLISECOND : "", sysCfg.sleep, (sysCfg.flag.value_units) ? " " D_UNIT_MILLISECOND : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_UPGRADE)) || !strcasecmp_P(type, PSTR(D_CMND_UPLOAD))) { // Check if the payload is numerically 1, and had no trailing chars. @@ -1312,15 +1294,15 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) // We also need at least 3 chars to make a valid version number string. if (((1 == data_len) && (1 == payload)) || ((data_len >= 3) && newerVersion(dataBuf))) { otaflag = 3; - snprintf_P(svalue, sizeof(svalue), "{\"" D_CMND_UPGRADE "\":\"" D_VERSION " %s " D_FROM " %s\"}", Version, sysCfg.otaUrl); + snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"" D_CMND_UPGRADE "\":\"" D_VERSION " %s " D_FROM " %s\"}", Version, sysCfg.otaUrl); } else { - snprintf_P(svalue, sizeof(svalue), "{\"" D_CMND_UPGRADE "\":\"" D_ONE_OR_GT "\"}", Version); + snprintf_P(mqtt_data, sizeof(mqtt_data), "{\"" D_CMND_UPGRADE "\":\"" D_ONE_OR_GT "\"}", Version); } } else if (!strcasecmp_P(type, PSTR(D_CMND_OTAURL))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.otaUrl))) strlcpy(sysCfg.otaUrl, (1 == payload) ? OTA_URL : dataBuf, sizeof(sysCfg.otaUrl)); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_OTAURL "\":\"%s\"}"), sysCfg.otaUrl); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_OTAURL "\":\"%s\"}"), sysCfg.otaUrl); } else if (!strcasecmp_P(type, PSTR(D_CMND_SERIALLOG))) { if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { @@ -1328,7 +1310,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) seriallog_level = payload; seriallog_timer = 0; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SERIALLOG "\":\"%d (" D_ACTIVE " %d)\"}"), sysCfg.seriallog_level, seriallog_level); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SERIALLOG "\":\"%d (" D_ACTIVE " %d)\"}"), sysCfg.seriallog_level, seriallog_level); } else if (!strcasecmp_P(type, PSTR(D_CMND_SYSLOG))) { if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { @@ -1336,19 +1318,19 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) syslog_level = (sysCfg.flag.emulation) ? 0 : payload; syslog_timer = 0; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SYSLOG "\":\"%d (" D_ACTIVE " %d)\"}"), sysCfg.syslog_level, syslog_level); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SYSLOG "\":\"%d (" D_ACTIVE " %d)\"}"), sysCfg.syslog_level, syslog_level); } else if (!strcasecmp_P(type, PSTR(D_CMND_LOGHOST))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.syslog_host))) { strlcpy(sysCfg.syslog_host, (1 == payload) ? SYS_LOG_HOST : dataBuf, sizeof(sysCfg.syslog_host)); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_LOGHOST "\":\"%s\"}"), sysCfg.syslog_host); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_LOGHOST "\":\"%s\"}"), sysCfg.syslog_host); } else if (!strcasecmp_P(type, PSTR(D_CMND_LOGPORT))) { - if ((payload > 0) && (payload < 32766)) { - sysCfg.syslog_port = (1 == payload) ? SYS_LOG_PORT : payload; + if (payload16 > 0) { + sysCfg.syslog_port = (1 == payload16) ? SYS_LOG_PORT : payload16; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_LOGPORT "\":%d}"), sysCfg.syslog_port); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_LOGPORT "\":%d}"), sysCfg.syslog_port); } else if (!strcasecmp_P(type, PSTR(D_CMND_IPADDRESS)) && (index > 0) && (index <= 4)) { if (parseIP(&address, dataBuf)) { @@ -1356,7 +1338,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) // restartflag = 2; } snprintf_P(stemp1, sizeof(stemp1), PSTR(" (%s)"), WiFi.localIP().toString().c_str()); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_IPADDRESS "%d\":\"%s%s\"}"), index, IPAddress(sysCfg.ip_address[index -1]).toString().c_str(), (1 == index) ? stemp1:""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IPADDRESS "%d\":\"%s%s\"}"), index, IPAddress(sysCfg.ip_address[index -1]).toString().c_str(), (1 == index) ? stemp1:""); } else if (!strcasecmp_P(type, PSTR(D_CMND_NTPSERVER)) && (index > 0) && (index <= 3)) { if ((data_len > 0) && (data_len < sizeof(sysCfg.ntp_server[0]))) { @@ -1368,7 +1350,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } restartflag = 2; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_NTPSERVER "%d\":\"%s\"}"), index, sysCfg.ntp_server[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_NTPSERVER "%d\":\"%s\"}"), index, sysCfg.ntp_server[index -1]); } else if (!strcasecmp_P(type, PSTR(D_CMND_AP))) { if ((payload >= 0) && (payload <= 2)) { @@ -1382,23 +1364,23 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } restartflag = 2; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_AP "\":\"%d (%s)\"}"), sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_AP "\":\"%d (%s)\"}"), sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active]); } else if (!strcasecmp_P(type, PSTR(D_CMND_SSID)) && (index > 0) && (index <= 2)) { if ((data_len > 0) && (data_len < sizeof(sysCfg.sta_ssid[0]))) { strlcpy(sysCfg.sta_ssid[index -1], (1 == payload) ? (1 == index) ? STA_SSID1 : STA_SSID2 : dataBuf, sizeof(sysCfg.sta_ssid[0])); - sysCfg.sta_active = 0; + sysCfg.sta_active = index -1; restartflag = 2; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SSID "%d\":\"%s\"}"), index, sysCfg.sta_ssid[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SSID "%d\":\"%s\"}"), index, sysCfg.sta_ssid[index -1]); } else if (!strcasecmp_P(type, PSTR(D_CMND_PASSWORD)) && (index > 0) && (index <= 2)) { if ((data_len > 0) && (data_len < sizeof(sysCfg.sta_pwd[0]))) { strlcpy(sysCfg.sta_pwd[index -1], (1 == payload) ? (1 == index) ? STA_PASS1 : STA_PASS2 : dataBuf, sizeof(sysCfg.sta_pwd[0])); - sysCfg.sta_active = 0; + sysCfg.sta_active = index -1; restartflag = 2; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_PASSWORD "%d\":\"%s\"}"), index, sysCfg.sta_pwd[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PASSWORD "%d\":\"%s\"}"), index, sysCfg.sta_pwd[index -1]); } else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_HOSTNAME))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.hostname))) { @@ -1408,21 +1390,21 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } restartflag = 2; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_HOSTNAME "\":\"%s\"}"), sysCfg.hostname); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_HOSTNAME "\":\"%s\"}"), sysCfg.hostname); } else if (!strcasecmp_P(type, PSTR(D_CMND_WIFICONFIG))) { if ((payload >= WIFI_RESTART) && (payload < MAX_WIFI_OPTION)) { sysCfg.sta_config = payload; wificheckflag = sysCfg.sta_config; snprintf_P(stemp1, sizeof(stemp1), wificfg[sysCfg.sta_config]); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WIFICONFIG "\":\"%s " D_SELECTED "\"}"), stemp1); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WIFICONFIG "\":\"%s " D_SELECTED "\"}"), stemp1); if (WIFI_State() != WIFI_RESTART) { -// snprintf_P(svalue, sizeof(svalue), PSTR("%s after restart"), svalue); +// snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s after restart"), mqtt_data); restartflag = 2; } } else { snprintf_P(stemp1, sizeof(stemp1), wificfg[sysCfg.sta_config]); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WIFICONFIG "\":\"%d (%s)\"}"), sysCfg.sta_config, stemp1); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WIFICONFIG "\":\"%d (%s)\"}"), sysCfg.sta_config, stemp1); } } else if (!strcasecmp_P(type, PSTR(D_CMND_FRIENDLYNAME)) && (index > 0) && (index <= 4)) { @@ -1434,13 +1416,13 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } strlcpy(sysCfg.friendlyname[index -1], (1 == payload) ? stemp1 : dataBuf, sizeof(sysCfg.friendlyname[index -1])); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_FRIENDLYNAME "%d\":\"%s\"}"), index, sysCfg.friendlyname[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_FRIENDLYNAME "%d\":\"%s\"}"), index, sysCfg.friendlyname[index -1]); } - else if (swt_flg && !strcasecmp_P(type, PSTR(D_CMND_SWITCHMODE)) && (index > 0) && (index <= 4)) { + else if (!strcasecmp_P(type, PSTR(D_CMND_SWITCHMODE)) && (index > 0) && (index <= 4)) { if ((payload >= 0) && (payload < MAX_SWITCH_OPTION)) { sysCfg.switchmode[index -1] = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SWITCHMODE "%d\":%d}"), index, sysCfg.switchmode[index-1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SWITCHMODE "%d\":%d}"), index, sysCfg.switchmode[index-1]); } #ifdef USE_WEBSERVER else if (!strcasecmp_P(type, PSTR(D_CMND_WEBSERVER))) { @@ -1448,23 +1430,23 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) sysCfg.webserver = payload; } if (sysCfg.webserver) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_ACTIVE_FOR " %s " D_ON_DEVICE " %s " D_WITH_IP_ADDRESS " %s\"}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_ACTIVE_FOR " %s " D_ON_DEVICE " %s " D_WITH_IP_ADDRESS " %s\"}"), (2 == sysCfg.webserver) ? D_ADMIN : D_USER, Hostname, WiFi.localIP().toString().c_str()); } else { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WEBSERVER "\":\"%s\"}"), getStateText(0)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WEBSERVER "\":\"%s\"}"), getStateText(0)); } } else if (!strcasecmp_P(type, PSTR(D_CMND_WEBPASSWORD))) { if ((data_len > 0) && (data_len < sizeof(sysCfg.web_password))) { strlcpy(sysCfg.web_password, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? WEB_PASSWORD : dataBuf, sizeof(sysCfg.web_password)); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WEBPASSWORD "\":\"%s\"}"), sysCfg.web_password); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WEBPASSWORD "\":\"%s\"}"), sysCfg.web_password); } else if (!strcasecmp_P(type, PSTR(D_CMND_WEBLOG))) { if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { sysCfg.weblog_level = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WEBLOG "\":%d}"), sysCfg.weblog_level); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WEBLOG "\":%d}"), sysCfg.weblog_level); } #ifdef USE_EMULATION else if (!strcasecmp_P(type, PSTR(D_CMND_EMULATION))) { @@ -1472,7 +1454,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) sysCfg.flag.emulation = payload; restartflag = 2; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_EMULATION "\":%d}"), sysCfg.flag.emulation); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_EMULATION "\":%d}"), sysCfg.flag.emulation); } #endif // USE_EMULATION #endif // USE_WEBSERVER @@ -1484,41 +1466,41 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) } tele_period = sysCfg.tele_period; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_TELEPERIOD "\":\"%d%s\"}"), sysCfg.tele_period, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TELEPERIOD "\":\"%d%s\"}"), sysCfg.tele_period, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_RESTART))) { switch (payload) { case 1: restartflag = 2; - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESTART "\":\"" D_RESTARTING "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RESTART "\":\"" D_RESTARTING "\"}")); break; case 99: addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING)); ESP.restart(); break; default: - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESTART "\":\"" D_ONE_TO_RESTART "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RESTART "\":\"" D_ONE_TO_RESTART "\"}")); } } else if (!strcasecmp_P(type, PSTR(D_CMND_RESET))) { switch (payload) { case 1: restartflag = 211; - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESET "\":\"" D_RESET_AND_RESTARTING "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RESET "\":\"" D_RESET_AND_RESTARTING "\"}")); break; case 2: restartflag = 212; - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESET "\":\"" D_ERASE ", " D_RESET_AND_RESTARTING "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RESET "\":\"" D_ERASE ", " D_RESET_AND_RESTARTING "\"}")); break; default: - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESET "\":\"" D_ONE_TO_RESET "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RESET "\":\"" D_ONE_TO_RESET "\"}")); } } else if (!strcasecmp_P(type, PSTR(D_CMND_TIMEZONE))) { if ((data_len > 0) && (((payload >= -12) && (payload <= 12)) || (99 == payload))) { sysCfg.timezone = payload; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_TIMEZONE "\":%d}"), sysCfg.timezone); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_TIMEZONE "\":%d}"), sysCfg.timezone); } else if (!strcasecmp_P(type, PSTR(D_CMND_LEDPOWER))) { if ((payload >= 0) && (payload <= 2)) { @@ -1535,7 +1517,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) blinks = 0; setLed(sysCfg.ledstate &8); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_LEDPOWER "\":\"%s\"}"), getStateText(bitRead(sysCfg.ledstate, 3))); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_LEDPOWER "\":\"%s\"}"), getStateText(bitRead(sysCfg.ledstate, 3))); } else if (!strcasecmp_P(type, PSTR(D_CMND_LEDSTATE))) { if ((payload >= 0) && (payload < MAX_LED_OPTION)) { @@ -1544,33 +1526,28 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) setLed(0); } } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_LEDSTATE "\":%d}"), sysCfg.ledstate); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_LEDSTATE "\":%d}"), sysCfg.ledstate); } else if (!strcasecmp_P(type, PSTR(D_CMND_CFGDUMP))) { CFG_Dump(dataBuf); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_CFGDUMP "\":\"" D_DONE "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_CFGDUMP "\":\"" D_DONE "\"}")); } - else if (sysCfg.flag.mqtt_enabled && mqtt_command(grpflg, type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) { + else if (sysCfg.flag.mqtt_enabled && mqtt_command(grpflg, type, index, dataBuf, data_len, payload, payload16)) { // Serviced } - else if (hlw_flg && hlw_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) { + else if (hlw_flg && hlw_command(type, index, dataBuf, data_len, payload)) { // Serviced } - else if ((SONOFF_BRIDGE == sysCfg.module) && sb_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) { + else if ((SONOFF_BRIDGE == sysCfg.module) && sb_command(type, index, dataBuf, data_len, payload)) { // Serviced } #ifdef USE_I2C else if (i2c_flg && !strcasecmp_P(type, PSTR(D_CMND_I2CSCAN))) { - i2c_scan(svalue, sizeof(svalue)); + i2c_scan(mqtt_data, sizeof(mqtt_data)); } #endif // USE_I2C -#ifdef USE_WS2812 - else if ((pin[GPIO_WS2812] < 99) && ws2812_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) { - // Serviced - } -#endif // USE_WS2812 #ifdef USE_IR_REMOTE - else if ((pin[GPIO_IRSEND] < 99) && ir_send_command(type, index, dataBufUc, data_len, payload, svalue, sizeof(svalue))) { + else if ((pin[GPIO_IRSEND] < 99) && ir_send_command(type, index, dataBuf, data_len, payload)) { // Serviced } #endif // USE_IR_REMOTE @@ -1579,7 +1556,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) if (data_len > 0) { exception_tst(payload); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_EXCEPTION "\":\"" D_DONE "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_EXCEPTION "\":\"" D_DONE "\"}")); } #endif // DEBUG_THEO else { @@ -1589,11 +1566,11 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len) if (type == NULL) { blinks = 201; snprintf_P(topicBuf, sizeof(topicBuf), PSTR(D_COMMAND)); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_COMMAND "\":\"" D_UNKNOWN "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_COMMAND "\":\"" D_UNKNOWN "\"}")); type = (char*)topicBuf; } - if (svalue[0] != '\0') { - mqtt_publish_topic_P(5, type, svalue); + if (mqtt_data[0] != '\0') { + mqtt_publish_topic_P(5, type); } fallbacktopic = 0; } @@ -1612,7 +1589,6 @@ boolean send_button_power(byte key, byte device, byte state) char stopic[TOPSZ]; char scommand[CMDSZ]; - char svalue[TOPSZ]; char stemp1[10]; boolean result = false; @@ -1629,19 +1605,19 @@ boolean send_button_power(byte key, byte device, byte state) getTopic_P(stopic, 0, key_topic, getPowerDevice(scommand, device, sizeof(scommand), key)); if (9 == state) { - svalue[0] = '\0'; + mqtt_data[0] = '\0'; } else { if ((!strcmp(sysCfg.mqtt_topic, key_topic) || !strcmp(sysCfg.mqtt_grptopic, key_topic)) && (2 == state)) { state = ~(power >> (device -1)) & 0x01; } - snprintf_P(svalue, sizeof(svalue), PSTR("%s"), getStateText(state)); + snprintf_P(mqtt_data, sizeof(mqtt_data), getStateText(state)); } #ifdef USE_DOMOTICZ - if (!(domoticz_button(key, device, state, strlen(svalue)))) { - mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); + if (!(domoticz_button(key, device, state, strlen(mqtt_data)))) { + mqtt_publish_sec(stopic, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); } #else - mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); + mqtt_publish_sec(stopic, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain); #endif // USE_DOMOTICZ result = true; } @@ -1756,13 +1732,12 @@ void do_cmnd(char *cmnd) } snprintf_P(stopic, sizeof(stopic), PSTR("/%s"), (token == NULL) ? "" : token); token = strtok(NULL, ""); - snprintf_P(svalue, sizeof(svalue), PSTR("%s"), (token == NULL) ? "" : token); + snprintf_P(svalue, sizeof(svalue), (token == NULL) ? "" : token); mqttDataCb(stopic, (byte*)svalue, strlen(svalue)); } void publish_status(uint8_t payload) { - char svalue[MESSZ]; uint8_t option = 1; // Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX @@ -1778,161 +1753,159 @@ void publish_status(uint8_t payload) } if ((0 == payload) || (99 == payload)) { - snprintf_P(svalue, sizeof(svalue), 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_SAVESTATE "\":%d, \"" D_CMND_BUTTONRETAIN "\":%d, \"" D_CMND_POWERRETAIN "\":%d}}"), + 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_SAVESTATE "\":%d, \"" D_CMND_BUTTONRETAIN "\":%d, \"" D_CMND_POWERRETAIN "\":%d}}"), sysCfg.module +1, sysCfg.friendlyname[0], sysCfg.mqtt_topic, sysCfg.button_topic, power, sysCfg.poweronstate, sysCfg.ledstate, sysCfg.savedata, sysCfg.flag.savestate, sysCfg.flag.mqtt_button_retain, sysCfg.flag.mqtt_power_retain); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS), svalue); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS)); } if ((0 == payload) || (1 == payload)) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_BAUDRATE "\":%d, \"" D_CMND_GROUPTOPIC "\":\"%s\", \"" D_CMND_OTAURL "\":\"%s\", \"" D_UPTIME "\":%d, \"" D_CMND_SLEEP "\":%d, \"" D_BOOTCOUNT "\":%d, \"" D_SAVECOUNT "\":%d, \"" D_SAVEADDRESS "\":\"%X\"}}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_BAUDRATE "\":%d, \"" D_CMND_GROUPTOPIC "\":\"%s\", \"" D_CMND_OTAURL "\":\"%s\", \"" D_UPTIME "\":%d, \"" D_CMND_SLEEP "\":%d, \"" D_BOOTCOUNT "\":%d, \"" D_SAVECOUNT "\":%d, \"" D_SAVEADDRESS "\":\"%X\"}}"), Baudrate, sysCfg.mqtt_grptopic, sysCfg.otaUrl, uptime, sysCfg.sleep, sysCfg.bootcount, sysCfg.saveFlag, CFG_Address()); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "1"), svalue); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "1")); } if ((0 == payload) || (2 == payload)) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_VERSION "\":\"%s\", \"" D_BUILDDATETIME "\":\"%s\", \"" D_BOOTVERSION "\":%d, \"" D_COREVERSION "\":\"%s\", \"" D_SDKVERSION "\":\"%s\"}}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_VERSION "\":\"%s\", \"" D_BUILDDATETIME "\":\"%s\", \"" D_BOOTVERSION "\":%d, \"" D_COREVERSION "\":\"%s\", \"" D_SDKVERSION "\":\"%s\"}}"), Version, getBuildDateTime().c_str(), ESP.getBootVersion(), ESP.getCoreVersion().c_str(), ESP.getSdkVersion()); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "2"), svalue); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "2")); } if ((0 == payload) || (3 == payload)) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d, \"" D_CMND_WEBLOG "\":%d, \"" D_CMND_SYSLOG "\":%d, \"" D_CMND_LOGHOST "\":\"%s\", \"" D_CMND_SSID "1\":\"%s\", \"" D_CMND_SSID "2\":\"%s\", \"" D_CMND_TELEPERIOD "\":%d, \"" D_CMND_SETOPTION "\":\"%08X\"}}"), - sysCfg.seriallog_level, sysCfg.weblog_level, sysCfg.syslog_level, sysCfg.syslog_host, sysCfg.sta_ssid[0], sysCfg.sta_ssid[1], sysCfg.tele_period, sysCfg.flag.data); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "3"), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d, \"" D_CMND_WEBLOG "\":%d, \"" D_CMND_SYSLOG "\":%d, \"" D_CMND_LOGHOST "\":\"%s\", \"" D_CMND_LOGPORT "\":%d, \"" D_CMND_SSID "1\":\"%s\", \"" D_CMND_SSID "2\":\"%s\", \"" D_CMND_TELEPERIOD "\":%d, \"" D_CMND_SETOPTION "\":\"%08X\"}}"), + sysCfg.seriallog_level, sysCfg.weblog_level, sysCfg.syslog_level, sysCfg.syslog_host, sysCfg.syslog_port, sysCfg.sta_ssid[0], sysCfg.sta_ssid[1], sysCfg.tele_period, sysCfg.flag.data); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "3")); } if ((0 == payload) || (4 == payload)) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_PROGRAMSIZE "\":%d, \"" D_FREEMEMORY "\":%d, \"" D_HEAPSIZE "\":%d, \"" D_PROGRAMFLASHSIZE "\":%d, \"" D_FLASHSIZE "\":%d, \"" D_FLASHMODE "\":%d}}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_PROGRAMSIZE "\":%d, \"" D_FREEMEMORY "\":%d, \"" D_HEAPSIZE "\":%d, \"" D_PROGRAMFLASHSIZE "\":%d, \"" D_FLASHSIZE "\":%d, \"" D_FLASHMODE "\":%d}}"), ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipMode()); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "4"), svalue); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "4")); } if ((0 == payload) || (5 == payload)) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\", \"" D_CMND_IPADDRESS "\":\"%s\", \"" D_GATEWAY "\":\"%s\", \"" D_SUBNETMASK "\":\"%s\", \"" D_DNSSERVER "\":\"%s\", \"" D_MAC "\":\"%s\", \"" D_CMND_WEBSERVER "\":%d, \"" D_CMND_WIFICONFIG "\":%d}}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\", \"" D_CMND_IPADDRESS "\":\"%s\", \"" D_GATEWAY "\":\"%s\", \"" D_SUBNETMASK "\":\"%s\", \"" D_DNSSERVER "\":\"%s\", \"" D_MAC "\":\"%s\", \"" D_CMND_WEBSERVER "\":%d, \"" D_CMND_WIFICONFIG "\":%d}}"), Hostname, WiFi.localIP().toString().c_str(), IPAddress(sysCfg.ip_address[1]).toString().c_str(), IPAddress(sysCfg.ip_address[2]).toString().c_str(), IPAddress(sysCfg.ip_address[3]).toString().c_str(), WiFi.macAddress().c_str(), sysCfg.webserver, sysCfg.sta_config); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "5"), svalue); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "5")); } if (((0 == payload) || (6 == payload)) && sysCfg.flag.mqtt_enabled) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\", \"" D_CMND_MQTTPORT "\":%d, \"" D_CMND_MQTTCLIENT D_MASK "\":\"%s\", \"" D_CMND_MQTTCLIENT "\":\"%s\", \"" D_CMND_MQTTUSER "\":\"%s\", \"MAX_PACKET_SIZE\":%d, \"KEEPALIVE\":%d}}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\", \"" D_CMND_MQTTPORT "\":%d, \"" D_CMND_MQTTCLIENT D_MASK "\":\"%s\", \"" D_CMND_MQTTCLIENT "\":\"%s\", \"" D_CMND_MQTTUSER "\":\"%s\", \"MAX_PACKET_SIZE\":%d, \"KEEPALIVE\":%d}}"), sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.mqtt_client, MQTTClient, sysCfg.mqtt_user, MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "6"), svalue); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "6")); } if ((0 == payload) || (7 == payload)) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS7_TIME "\":{\"" D_UTC_TIME "\":\"%s\", \"" D_LOCAL_TIME "\":\"%s\", \"" D_STARTDST "\":\"%s\", \"" D_ENDDST "\":\"%s\", \"" D_CMND_TIMEZONE "\":%d}}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS7_TIME "\":{\"" D_UTC_TIME "\":\"%s\", \"" D_LOCAL_TIME "\":\"%s\", \"" D_STARTDST "\":\"%s\", \"" D_ENDDST "\":\"%s\", \"" D_CMND_TIMEZONE "\":%d}}"), rtc_time(0).c_str(), rtc_time(1).c_str(), rtc_time(2).c_str(), rtc_time(3).c_str(), sysCfg.timezone); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "7"), svalue); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "7")); } if (hlw_flg) { if ((0 == payload) || (8 == payload)) { - hlw_mqttStatus(svalue, sizeof(svalue)); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "8"), svalue); + hlw_mqttStatus(); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "8")); } if ((0 == payload) || (9 == payload)) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS9_MARGIN "\":{\"" D_CMND_POWERLOW "\":%d, \"" D_CMND_POWERHIGH "\":%d, \"" D_CMND_VOLTAGELOW "\":%d, \"" D_CMND_VOLTAGEHIGH "\":%d, \"" D_CMND_CURRENTLOW "\":%d, \"" D_CMND_CURRENTHIGH "\":%d}}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS9_MARGIN "\":{\"" D_CMND_POWERLOW "\":%d, \"" D_CMND_POWERHIGH "\":%d, \"" D_CMND_VOLTAGELOW "\":%d, \"" D_CMND_VOLTAGEHIGH "\":%d, \"" D_CMND_CURRENTLOW "\":%d, \"" D_CMND_CURRENTHIGH "\":%d}}"), sysCfg.hlw_pmin, sysCfg.hlw_pmax, sysCfg.hlw_umin, sysCfg.hlw_umax, sysCfg.hlw_imin, sysCfg.hlw_imax); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "9"), svalue); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "9")); } } if ((0 == payload) || (10 == payload)) { uint8_t djson = 0; - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS10_SENSOR "\":")); - sensors_mqttPresent(svalue, sizeof(svalue), &djson); - snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "10"), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS10_SENSOR "\":")); + sensors_mqttPresent(&djson); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "10")); } if ((0 == payload) || (11 == payload)) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS11_STATUS "\":")); - state_mqttPresent(svalue, sizeof(svalue)); - snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue); - mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "11"), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS11_STATUS "\":")); + state_mqttPresent(); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "11")); } } -void state_mqttPresent(char* svalue, uint16_t ssvalue) +void state_mqttPresent() { char stemp1[16]; - snprintf_P(svalue, ssvalue, PSTR("%s{\"" D_TIME "\":\"%s\", \"" D_UPTIME "\":%d"), svalue, getDateTime().c_str(), uptime); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_TIME "\":\"%s\", \"" D_UPTIME "\":%d"), mqtt_data, getDateTime().c_str(), uptime); #ifdef USE_ADC_VCC dtostrfd((double)ESP.getVcc()/1000, 3, stemp1); - snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_VCC "\":%s"), svalue, stemp1); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_VCC "\":%s"), mqtt_data, stemp1); #endif for (byte i = 0; i < Maxdevice; i++) { - snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":\"%s\""), svalue, getPowerDevice(stemp1, i +1, sizeof(stemp1)), getStateText(bitRead(power, i))); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":\"%s\""), mqtt_data, getPowerDevice(stemp1, i +1, sizeof(stemp1)), getStateText(bitRead(power, i))); } - snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_WIFI "\":{\"" D_AP "\":%d, \"" D_SSID "\":\"%s\", \"" D_RSSI "\":%d, \"" D_APMAC_ADDRESS "\":\"%s\"}}"), - svalue, sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active], WIFI_getRSSIasQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_WIFI "\":{\"" D_AP "\":%d, \"" D_SSID "\":\"%s\", \"" D_RSSI "\":%d, \"" D_APMAC_ADDRESS "\":\"%s\"}}"), + mqtt_data, sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active], WIFI_getRSSIasQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str()); } -void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void sensors_mqttPresent(uint8_t* djson) { - snprintf_P(svalue, ssvalue, PSTR("%s{\"" D_TIME "\":\"%s\""), svalue, getDateTime().c_str()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_TIME "\":\"%s\""), mqtt_data, getDateTime().c_str()); for (byte i = 0; i < 4; i++) { if (pin[GPIO_SWT1 +i] < 99) { boolean swm = ((FOLLOW_INV == sysCfg.switchmode[i]) || (PUSHBUTTON_INV == sysCfg.switchmode[i]) || (PUSHBUTTONHOLD_INV == sysCfg.switchmode[i])); - snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_SWITCH "%d\":\"%s\""), svalue, i +1, getStateText(swm ^ lastwallswitch[i])); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_SWITCH "%d\":\"%s\""), mqtt_data, i +1, getStateText(swm ^ lastwallswitch[i])); *djson = 1; } } - counter_mqttPresent(svalue, ssvalue, djson); + counter_mqttPresent(djson); #ifndef USE_ADC_VCC if (pin[GPIO_ADC0] < 99) { - snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_ANALOG_INPUT0 "\":%d"), svalue, getAdc0()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_ANALOG_INPUT0 "\":%d"), mqtt_data, getAdc0()); *djson = 1; } #endif if (SONOFF_SC == sysCfg.module) { - sc_mqttPresent(svalue, ssvalue, djson); + sc_mqttPresent(djson); } if (pin[GPIO_DSB] < 99) { #ifdef USE_DS18B20 - dsb_mqttPresent(svalue, ssvalue, djson); + dsb_mqttPresent(djson); #endif // USE_DS18B20 #ifdef USE_DS18x20 - ds18x20_mqttPresent(svalue, ssvalue, djson); + ds18x20_mqttPresent(djson); #endif // USE_DS18x20 } #ifdef USE_DHT if (dht_flg) { - dht_mqttPresent(svalue, ssvalue, djson); + dht_mqttPresent(djson); } #endif // USE_DHT #ifdef USE_I2C if (i2c_flg) { #ifdef USE_SHT - sht_mqttPresent(svalue, ssvalue, djson); + sht_mqttPresent(djson); #endif // USE_SHT #ifdef USE_HTU - htu_mqttPresent(svalue, ssvalue, djson); + htu_mqttPresent(djson); #endif // USE_HTU #ifdef USE_BMP - bmp_mqttPresent(svalue, ssvalue, djson); + bmp_mqttPresent(djson); #endif // USE_BMP #ifdef USE_BH1750 - bh1750_mqttPresent(svalue, ssvalue, djson); + bh1750_mqttPresent(djson); #endif // USE_BH1750 } #endif // USE_I2C - if (strstr_P(svalue, PSTR(D_TEMPERATURE))) { - snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_TEMPERATURE_UNIT "\":\"%c\""), svalue, tempUnit()); + if (strstr_P(mqtt_data, PSTR(D_TEMPERATURE))) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_TEMPERATURE_UNIT "\":\"%c\""), mqtt_data, tempUnit()); } - snprintf_P(svalue, ssvalue, PSTR("%s}"), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } /********************************************************************************************/ void every_second() { - char svalue[MESSZ]; - if (blockgpio0) { blockgpio0--; } @@ -2013,15 +1986,15 @@ void every_second() if (tele_period >= sysCfg.tele_period) { tele_period = 0; - svalue[0] = '\0'; - state_mqttPresent(svalue, sizeof(svalue)); - mqtt_publish_topic_P(2, PSTR(D_RSLT_STATE), svalue); + mqtt_data[0] = '\0'; + state_mqttPresent(); + mqtt_publish_topic_P(2, PSTR(D_RSLT_STATE)); uint8_t djson = 0; - svalue[0] = '\0'; - sensors_mqttPresent(svalue, sizeof(svalue), &djson); + mqtt_data[0] = '\0'; + sensors_mqttPresent(&djson); if (djson) { - mqtt_publish_topic_P(2, PSTR(D_RSLT_SENSOR), svalue, sysCfg.flag.mqtt_sensor_retain); + mqtt_publish_topic_P(2, PSTR(D_RSLT_SENSOR), sysCfg.flag.mqtt_sensor_retain); } if (hlw_flg) { @@ -2037,8 +2010,8 @@ void every_second() if ((2 == rtcTime.Minute) && uptime_flg) { uptime_flg = false; uptime++; - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_TIME "\":\"%s\", \"" D_UPTIME "\":%d}"), getDateTime().c_str(), uptime); - mqtt_publish_topic_P(2, PSTR(D_RSLT_UPTIME), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_TIME "\":\"%s\", \"" D_UPTIME "\":%d}"), getDateTime().c_str(), uptime); + mqtt_publish_topic_P(2, PSTR(D_RSLT_UPTIME)); } if ((3 == rtcTime.Minute) && !uptime_flg) { uptime_flg = true; @@ -2055,7 +2028,6 @@ void button_handler() uint8_t butt_present = 0; uint8_t flag = 0; char scmnd[20]; - char log[LOGSZ]; for (byte i = 0; i < Maxdevice; i++) { button = NOT_PRESSED; @@ -2064,8 +2036,8 @@ void button_handler() if (!i && ((SONOFF_DUAL == sysCfg.module) || (CH4 == sysCfg.module))) { butt_present = 1; if (ButtonCode) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " " D_CODE " %04X"), ButtonCode); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " " D_CODE " %04X"), ButtonCode); + addLog(LOG_LEVEL_DEBUG); button = PRESSED; if (0xF500 == ButtonCode) { // Button hold holdbutton[i] = (sysCfg.param[P_HOLD_TIME] * (STATES / 10)) -1; @@ -2086,14 +2058,14 @@ void button_handler() } flag = 0; if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_10), i +1); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_10), i +1); + addLog(LOG_LEVEL_DEBUG); holdbutton[i] = STATES; flag = 1; } if ((NOT_PRESSED == button) && (PRESSED == lastbutton[i])) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_01), i +1); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_01), i +1); + addLog(LOG_LEVEL_DEBUG); if (!holdbutton[i]) { // Do not allow within 1 second flag = 1; } @@ -2106,16 +2078,17 @@ void button_handler() } else { if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) { if (sysCfg.flag.button_single) { // Allow only single button press for immediate action - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_IMMEDIATE), i +1); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_IMMEDIATE), i +1); + addLog(LOG_LEVEL_DEBUG); if (!send_button_power(0, i +1, 2)) { // Execute Toggle command via MQTT if ButtonTopic is set do_cmnd_power(i +1, 2); // Execute Toggle command internally } } else { multipress[i] = (multiwindow[i]) ? multipress[i] +1 : 1; - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_MULTI_PRESS " %d"), i +1, multipress[i]); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_MULTI_PRESS " %d"), i +1, multipress[i]); + addLog(LOG_LEVEL_DEBUG); multiwindow[i] = STATES /2; // 0.5 second multi press window } - addLog(LOG_LEVEL_DEBUG, log); blinks = 201; } @@ -2263,8 +2236,6 @@ void switch_handler() void stateloop() { uint8_t power_now; - char log[LOGSZ]; - char svalue[80]; // was MESSZ timerxs = millis() + (1000 / STATES); state++; @@ -2348,12 +2319,6 @@ void stateloop() sl_animate(); } -#ifdef USE_WS2812 - if (pin[GPIO_WS2812] < 99) { - ws2812_animate(); - } -#endif // USE_WS2812 - /*-------------------------------------------------------------------------------------------*\ * Every 0.2 second \*-------------------------------------------------------------------------------------------*/ @@ -2408,8 +2373,8 @@ void stateloop() otaok = 0; otaretry--; if (otaretry) { -// snprintf_P(log, sizeof(log), PSTR("OTA: Attempt %d"), OTA_ATTEMPTS - otaretry); -// addLog(LOG_LEVEL_INFO, log); +// snprintf_P(log_data, sizeof(log_data), PSTR("OTA: Attempt %d"), OTA_ATTEMPTS - otaretry); +// addLog(LOG_LEVEL_INFO); otaok = (HTTP_UPDATE_FAILED != ESPhttpUpdate.update(sysCfg.otaUrl)); if (!otaok) { otaflag = 2; @@ -2420,12 +2385,12 @@ void stateloop() otaflag = 0; if (otaok) { setFlashModeDout(); // Force DOUT for both ESP8266 and ESP8285 - snprintf_P(svalue, sizeof(svalue), PSTR(D_SUCCESSFUL ". " D_RESTARTING)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_SUCCESSFUL ". " D_RESTARTING)); } else { - snprintf_P(svalue, sizeof(svalue), PSTR(D_FAILED " %s"), ESPhttpUpdate.getLastErrorString().c_str()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR(D_FAILED " %s"), ESPhttpUpdate.getLastErrorString().c_str()); } restartflag = 2; // Restart anyway to keep memory clean webserver - mqtt_publish_topic_P(1, PSTR(D_CMND_UPGRADE), svalue); + mqtt_publish_topic_P(1, PSTR(D_CMND_UPGRADE)); } } break; @@ -2504,8 +2469,6 @@ void stateloop() void serial() { - char log[LOGSZ]; - while (Serial.available()) { yield(); SerialInByte = Serial.read(); @@ -2556,6 +2519,10 @@ void serial() } } +/*-------------------------------------------------------------------------------------------*\ + * Sonoff SC 19200 baud serial interface +\*-------------------------------------------------------------------------------------------*/ + if (SerialInByte == '\x1B') { // Sonoff SC status from ATMEGA328P serialInBuf[SerialInByteCounter] = 0; // serial data completed sc_rcvstat(serialInBuf); @@ -2563,11 +2530,14 @@ void serial() Serial.flush(); return; } + +/*-------------------------------------------------------------------------------------------*/ + else if (SerialInByte == '\n') { serialInBuf[SerialInByteCounter] = 0; // serial data completed seriallog_level = (sysCfg.seriallog_level < LOG_LEVEL_INFO) ? LOG_LEVEL_INFO : sysCfg.seriallog_level; - snprintf_P(log, sizeof(log), PSTR(D_LOG_COMMAND "%s"), serialInBuf); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), serialInBuf); + addLog(LOG_LEVEL_INFO); do_cmnd(serialInBuf); SerialInByteCounter = 0; Serial.flush(); @@ -2580,7 +2550,6 @@ void serial() void GPIO_init() { - char log[LOGSZ]; uint8_t mpin; mytmplt def_module; @@ -2606,8 +2575,8 @@ void GPIO_init() for (byte i = 0; i < MAX_GPIO_PIN; i++) { mpin = my_module.gp.io[i]; -// snprintf_P(log, sizeof(log), PSTR("DBG: gpio pin %d, mpin %d"), i, mpin); -// addLog(LOG_LEVEL_DEBUG, log); +// snprintf_P(log_data, sizeof(log_data), PSTR("DBG: gpio pin %d, mpin %d"), i, mpin); +// addLog(LOG_LEVEL_DEBUG); if (mpin) { if ((mpin >= GPIO_REL1_INV) && (mpin <= GPIO_REL4_INV)) { @@ -2677,27 +2646,32 @@ void GPIO_init() Maxdevice++; } // if (pin[GPIO_KEY1 +i] < 99) { -// pinMode(pin[GPIO_KEY1 +i], INPUT_PULLUP); +// pinMode(pin[GPIO_KEY1 +i], (16 == pin[GPIO_KEY1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP); // } } } for (byte i = 0; i < 4; i++) { if (pin[GPIO_KEY1 +i] < 99) { - pinMode(pin[GPIO_KEY1 +i], INPUT_PULLUP); + pinMode(pin[GPIO_KEY1 +i], (16 == pin[GPIO_KEY1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP); } if (pin[GPIO_LED1 +i] < 99) { pinMode(pin[GPIO_LED1 +i], OUTPUT); digitalWrite(pin[GPIO_LED1 +i], led_inverted[i]); } if (pin[GPIO_SWT1 +i] < 99) { - swt_flg = 1; - pinMode(pin[GPIO_SWT1 +i], INPUT_PULLUP); + pinMode(pin[GPIO_SWT1 +i], (16 == pin[GPIO_SWT1 +i]) ? INPUT_PULLDOWN_16 :INPUT_PULLUP); lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]); // set global now so doesn't change the saved power state on first switch check } } - if (sfl_flg) { // Sonoff B1, AiLight, Sonoff Led or BN-SZ01 - if (sfl_flg < 4) { +#ifdef USE_WS2812 + if (!sfl_flg && (pin[GPIO_WS2812] < 99)) { + Maxdevice++; + sfl_flg = 3; + } +#endif // USE_WS2812 + if (sfl_flg) { // Sonoff B1, AiLight, Sonoff Led or BN-SZ01, WS2812 + if (sfl_flg < 3) { pwm_idxoffset = sfl_flg; // 1 for BN-SZ01, 2 for Sonoff Led } sl_init(); @@ -2716,13 +2690,6 @@ void GPIO_init() } setLed(sysCfg.ledstate &8); -#ifdef USE_WS2812 - if (pin[GPIO_WS2812] < 99) { - Maxdevice++; - ws2812_init(Maxdevice); - } -#endif // USE_WS2812 - #ifdef USE_IR_REMOTE if (pin[GPIO_IRSEND] < 99) { ir_send_init(); @@ -2762,7 +2729,6 @@ extern struct rst_info resetInfo; void setup() { - char log[LOGSZ]; byte idx; Serial.begin(Baudrate); @@ -2792,15 +2758,15 @@ void setup() sleep = sysCfg.sleep; sysCfg.bootcount++; - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BOOT_COUNT " %d"), sysCfg.bootcount); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BOOT_COUNT " %d"), sysCfg.bootcount); + addLog(LOG_LEVEL_DEBUG); GPIO_init(); if (Serial.baudRate() != Baudrate) { if (seriallog_level) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_SET_BAUDRATE_TO " %d"), Baudrate); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_SET_BAUDRATE_TO " %d"), Baudrate); + addLog(LOG_LEVEL_INFO); } delay(100); Serial.flush(); @@ -2872,9 +2838,9 @@ void setup() rtc_init(); - snprintf_P(log, sizeof(log), PSTR(D_PROJECT " %s %s (" D_CMND_TOPIC " %s, " D_FALLBACK " %s, " D_CMND_GROUPTOPIC " %s) " D_VERSION " %s"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_PROJECT " %s %s (" D_CMND_TOPIC " %s, " D_FALLBACK " %s, " D_CMND_GROUPTOPIC " %s) " D_VERSION " %s"), PROJECT, sysCfg.friendlyname[0], sysCfg.mqtt_topic, MQTTClient, sysCfg.mqtt_grptopic, Version); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); } void loop() diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index abb3a33f79ad..8b092b20deeb 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -157,6 +157,8 @@ enum module_t { SONOFF_T12, SONOFF_T13, SUPLA1, + WITTY, + YUNSHAN, MAXMODULE }; /********************************************************************************************/ @@ -199,11 +201,13 @@ const uint8_t nicelist[MAXMODULE] PROGMEM = { ELECTRODRAGON, EXS_RELAY, SUPLA1, + YUNSHAN, WION, H801, HUAFAN_SS, AILIGHT, - WEMOS + WEMOS, + WITTY }; // Default module settings @@ -278,7 +282,8 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, 0, 0, 0, 0, 0, // Flash connection 0, GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - 0, 0, 0, 0 + GPIO_USER, // GPIO14 Optional sensor + 0, 0, 0 }, { "Sonoff Pow", // Sonoff Pow (ESP8266) GPIO_KEY1, // GPIO00 Button @@ -619,6 +624,32 @@ const mytmplt modules[MAXMODULE] PROGMEM = { 0, GPIO_LED1, // GPIO16 Led (1 = On, 0 = Off) GPIO_ADC0 // ADC0 A0 Analog input + }, + { "Witty Cloud", // Witty Cloud Dev Board (ESP8266) - https://www.aliexpress.com/item/ESP8266-serial-WIFI-Witty-cloud-Development-Board-ESP-12F-module-MINI-nodemcu/32643464555.html + GPIO_USER, // GPIO00 D3 flash push button on interface board + GPIO_USER, // GPIO01 Serial RXD and Optional sensor + GPIO_LED1_INV, // GPIO02 D4 Blue Led (0 = On, 1 = Off) on ESP-12F + GPIO_USER, // GPIO03 Serial TXD and Optional sensor + GPIO_KEY1, // GPIO04 D2 push button on ESP-12F board + GPIO_USER, // GPIO05 D1 optional sensor + 0, 0, 0, 0, 0, 0, // Flash connection + GPIO_PWM4, // GPIO12 D6 RGB LED Green + GPIO_PWM5, // GPIO13 D7 RGB LED Blue + GPIO_USER, // GPIO14 D5 optional sensor + GPIO_PWM3, // GPIO15 D8 RGB LED Red + GPIO_USER, // GPIO16 D0 optional sensor + GPIO_ADC0 // ADC0 A0 Light sensor / Requires USE_ADC_VCC in user_config.h to be disabled + }, + { "Yunshan Relay", // Yunshan Wifi Relay (ESP8266) - https://www.ebay.com/p/Esp8266-220v-10a-Network-Relay-WiFi-Module/1369583381 + // Schematics and Info https://ucexperiment.wordpress.com/2016/12/18/yunshan-esp8266-250v-15a-acdc-network-wifi-relay-module/ + 0, // GPIO00 Flash jumper - Module Pin 8 + GPIO_USER, // GPIO01 Serial RXD and Optional sensor - Module Pin 2 + GPIO_LED1_INV, // GPIO02 Blue Led (0 = On, 1 = Off) on ESP-12F - Module Pin 7 + GPIO_USER, // GPIO03 Serial TXD and Optional sensor - Module Pin 3 + GPIO_REL1, // GPIO04 Red Led and Relay (0 = Off, 1 = On) - Module Pin 10 + GPIO_KEY1, // GPIO05 Blue Led and OptoCoupler input - Module Pin 9 + 0, 0, 0, 0, 0, 0, // Flash connection + 0, 0, 0, 0, 0 } }; diff --git a/sonoff/support.ino b/sonoff/support.ino index dd15ccea4523..9c65d35136a3 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -38,9 +38,8 @@ void osw_osWatch() unsigned long last_run = abs(t - osw_last_loop); #ifdef DEBUG_THEO - char log[LOGSZ]; - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_OSWATCH " FreeRam %d, rssi %d, last_run %d"), ESP.getFreeHeap(), WIFI_getRSSIasQuality(WiFi.RSSI()), last_run); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_OSWATCH " FreeRam %d, rssi %d, last_run %d"), ESP.getFreeHeap(), WIFI_getRSSIasQuality(WiFi.RSSI()), last_run); + addLog(LOG_LEVEL_DEBUG); #endif // DEBUG_THEO if (last_run >= (OSWATCH_RESET_TIME * 1000)) { addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_OSWATCH " " D_BLOCKED_LOOP ". " D_RESTARTING)); @@ -372,8 +371,6 @@ void WIFI_wps_status_cb(wps_cb_status status); void WIFI_wps_status_cb(wps_cb_status status) { - char log[LOGSZ]; - /* from user_interface.h: enum wps_cb_status { WPS_CB_ST_SUCCESS = 0, @@ -383,13 +380,12 @@ void WIFI_wps_status_cb(wps_cb_status status) WPS_CB_ST_SCAN_ERR, // can not find the target WPS AP }; */ - _wpsresult = status; if (WPS_CB_ST_SUCCESS == _wpsresult) { wifi_wps_disable(); } else { - snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_WPS_FAILED_WITH_STATUS " %d"), _wpsresult); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_WPS_FAILED_WITH_STATUS " %d"), _wpsresult); + addLog(LOG_LEVEL_DEBUG); _wifiConfigCounter = 2; } } @@ -420,7 +416,7 @@ boolean WIFI_beginWPSConfig(void) void WIFI_config(uint8_t type) { if (!_wificonfigflag) { - if (WIFI_RETRY == type) { + if (type >= WIFI_RETRY) { // WIFI_RETRY and WIFI_WAIT return; } #ifdef USE_EMULATION @@ -458,7 +454,6 @@ void WIFI_config(uint8_t type) void WIFI_begin(uint8_t flag) { const char PhyMode[] = " BGN"; - char log[LOGSZ]; #ifdef USE_EMULATION UDP_Disconnect(); @@ -495,9 +490,9 @@ void WIFI_begin(uint8_t flag) } WiFi.hostname(Hostname); WiFi.begin(sysCfg.sta_ssid[sysCfg.sta_active], sysCfg.sta_pwd[sysCfg.sta_active]); - snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_CONNECTING_TO_AP "%d %s " D_IN_MODE " 11%c " D_AS " %s..."), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_CONNECTING_TO_AP "%d %s " D_IN_MODE " 11%c " D_AS " %s..."), sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active], PhyMode[WiFi.getPhyMode() & 0x3], Hostname); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); } void WIFI_check_ip() @@ -523,11 +518,15 @@ void WIFI_check_ip() break; case WL_NO_SSID_AVAIL: addLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_AP_NOT_REACHED)); - if (_wifiretry > (WIFI_RETRY_SEC / 2)) { - _wifiretry = WIFI_RETRY_SEC / 2; - } - else if (_wifiretry) { - _wifiretry = 0; + if (WIFI_WAIT == sysCfg.sta_config) { + _wifiretry = WIFI_RETRY_SEC; + } else { + if (_wifiretry > (WIFI_RETRY_SEC / 2)) { + _wifiretry = WIFI_RETRY_SEC / 2; + } + else if (_wifiretry) { + _wifiretry = 0; + } } break; case WL_CONNECT_FAILED: @@ -548,9 +547,9 @@ void WIFI_check_ip() } if (_wifiretry) { if (WIFI_RETRY_SEC == _wifiretry) { - WIFI_begin(3); // Select default SSID + WIFI_begin(3); // Select default SSID } - if ((WIFI_RETRY_SEC / 2) == _wifiretry) { + if ((sysCfg.sta_config != WIFI_WAIT) && ((WIFI_RETRY_SEC / 2) == _wifiretry)) { WIFI_begin(2); // Select alternate SSID } _wificounter = 1; @@ -565,8 +564,6 @@ void WIFI_check_ip() void WIFI_Check(uint8_t param) { - char log[LOGSZ]; - _wificounter--; switch (param) { case WIFI_SMARTCONFIG: @@ -593,8 +590,8 @@ void WIFI_Check(uint8_t param) strlcpy(sysCfg.sta_pwd[0], WiFi.psk().c_str(), sizeof(sysCfg.sta_pwd[0])); } sysCfg.sta_active = 0; - snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_WCFG_1_SMARTCONFIG D_CMND_SSID "1 %s, " D_CMND_PASSWORD "1 %s"), sysCfg.sta_ssid[0], sysCfg.sta_pwd[0]); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_WCFG_1_SMARTCONFIG D_CMND_SSID "1 %s, " D_CMND_PASSWORD "1 %s"), sysCfg.sta_ssid[0], sysCfg.sta_pwd[0]); + addLog(LOG_LEVEL_INFO); } } if (!_wifiConfigCounter) { @@ -613,8 +610,8 @@ void WIFI_Check(uint8_t param) #ifdef USE_DISCOVERY if (!mDNSbegun) { mDNSbegun = MDNS.begin(Hostname); - snprintf_P(log, sizeof(log), PSTR(D_LOG_MDNS "%s"), (mDNSbegun) ? D_INITIALIZED : D_FAILED); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS "%s"), (mDNSbegun) ? D_INITIALIZED : D_FAILED); + addLog(LOG_LEVEL_INFO); } #endif // USE_DISCOVERY #ifdef USE_WEBSERVER @@ -673,7 +670,6 @@ void WIFI_Connect() #ifdef MQTT_HOST_DISCOVERY boolean mdns_discoverMQTTServer() { - char log[LOGSZ]; char ip_str[20]; int n; @@ -683,16 +679,16 @@ boolean mdns_discoverMQTTServer() n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service - snprintf_P(log, sizeof(log), PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n); + addLog(LOG_LEVEL_INFO); if (n > 0) { // Note: current strategy is to get the first MQTT service (even when many are found) IPtoCharArray(MDNS.IP(0), ip_str, 20); - snprintf_P(log, sizeof(log), PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(0).c_str(), ip_str, MDNS.port(0)); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); strlcpy(sysCfg.mqtt_host, ip_str, sizeof(sysCfg.mqtt_host)); sysCfg.mqtt_port = MDNS.port(0); @@ -794,7 +790,7 @@ void i2c_scan(char *devs, unsigned int devs_len) byte any = 0; char tstr[10]; - snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_I2CSCAN_DEVICES_FOUND_AT)); + snprintf_P(devs, devs_len, PSTR("{\"I2Cscan\":\"Device(s) found at")); for (address = 1; address <= 127; address++) { Wire.beginTransmission(address); error = Wire.endTransmission(); @@ -804,13 +800,13 @@ void i2c_scan(char *devs, unsigned int devs_len) any = 1; } else if (4 == error) { - snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_I2CSCAN_UNKNOWN_ERROR_AT " 0x%2x\"}"), address); + snprintf_P(devs, devs_len, PSTR("{\"I2Cscan\":\"Unknown error at 0x%2x\"}"), address); } } if (any) { strncat(devs, "\"}", devs_len); } else { - snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_I2CSCAN_NO_DEVICES_FOUND "\"}")); + snprintf_P(devs, devs_len, PSTR("{\"I2Cscan\":\"No devices found\"}")); } } #endif // USE_I2C @@ -1027,7 +1023,7 @@ String rtc_time(int type) if (1 == type) time = loctime; if (2 == type) time = dsttime; if (3 == type) time = stdtime; - snprintf_P(stime, sizeof(stime), PSTR("%s"), sntp_get_real_time(time)); + snprintf_P(stime, sizeof(stime), sntp_get_real_time(time)); return String(stime); } @@ -1052,7 +1048,6 @@ boolean rtc_midnight_now() void rtc_second() { - char log[LOGSZ]; byte ntpsync; uint32_t stdoffset; uint32_t dstoffset; @@ -1076,12 +1071,12 @@ void rtc_second() rtcTime.Year = tmpTime.Year + 1970; dsttime = toTime_t(myDST, rtcTime.Year); stdtime = toTime_t(mySTD, rtcTime.Year); - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION "(" D_UTC_TIME ") %s"), rtc_time(0).c_str()); - addLog(LOG_LEVEL_DEBUG, log); - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION "(" D_DST_TIME ") %s"), rtc_time(2).c_str()); - addLog(LOG_LEVEL_DEBUG, log); - snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION "(" D_STD_TIME ") %s"), rtc_time(3).c_str()); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_UTC_TIME ") %s"), rtc_time(0).c_str()); + addLog(LOG_LEVEL_DEBUG); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_DST_TIME ") %s"), rtc_time(2).c_str()); + addLog(LOG_LEVEL_DEBUG); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_STD_TIME ") %s"), rtc_time(3).c_str()); + addLog(LOG_LEVEL_DEBUG); } } utctime++; @@ -1153,32 +1148,38 @@ uint16_t getAdc0() * Syslog \*********************************************************************************************/ -void syslog(const char *message) +void syslog() { - char str[TOPSZ + MESSZ]; + // Destroys log_data + char syslog_preamble[64]; // Hostname + Id if (portUDP.beginPacket(sysCfg.syslog_host, sysCfg.syslog_port)) { - snprintf_P(str, sizeof(str), PSTR("%s ESP-%s"), Hostname, message); - portUDP.write(str); + snprintf_P(syslog_preamble, sizeof(syslog_preamble), PSTR("%s ESP-"), Hostname); + memmove(log_data + strlen(syslog_preamble), log_data, sizeof(log_data) - strlen(syslog_preamble)); + log_data[sizeof(log_data) -1] = '\0'; + memcpy(log_data, syslog_preamble, strlen(syslog_preamble)); + portUDP.write(log_data); portUDP.endPacket(); } else { syslog_level = 0; syslog_timer = SYSLOG_TIMER; - snprintf_P(str, sizeof(str), PSTR(D_LOG_APPLICATION D_SYSLOG_HOST_NOT_FOUND ". " D_RETRY_IN " %d " D_UNIT_SECOND), SYSLOG_TIMER); - addLog(LOG_LEVEL_INFO, str); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_SYSLOG_HOST_NOT_FOUND ". " D_RETRY_IN " %d " D_UNIT_SECOND), SYSLOG_TIMER); + addLog(LOG_LEVEL_INFO); } } -void addLog(byte loglevel, const char *line) +void addLog(byte loglevel) { - char mxtime[9]; + char mxtime[9]; // 13:45:21 snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), rtcTime.Hour, rtcTime.Minute, rtcTime.Second); - if (loglevel <= seriallog_level) Serial.printf("%s %s\n", mxtime, line); + if (loglevel <= seriallog_level) { + Serial.printf("%s %s\n", mxtime, log_data); + } #ifdef USE_WEBSERVER if (sysCfg.webserver && (loglevel <= sysCfg.weblog_level)) { - Log[logidx] = String(mxtime) + " " + String(line); + Log[logidx] = String(mxtime) + " " + String(log_data); logidx++; if (logidx > MAX_LOG_LINES -1) { logidx = 0; @@ -1186,27 +1187,24 @@ void addLog(byte loglevel, const char *line) } #endif // USE_WEBSERVER if ((WL_CONNECTED == WiFi.status()) && (loglevel <= syslog_level)) { - syslog(line); + syslog(); } } void addLog_P(byte loglevel, const char *formatP) { - char mess[LOGSZ]; // was MESSZ - - snprintf_P(mess, sizeof(mess), formatP); - addLog(loglevel, mess); + snprintf_P(log_data, sizeof(log_data), formatP); + addLog(loglevel); } void addLog_P(byte loglevel, const char *formatP, const char *formatP2) { - char mess[LOGSZ]; // was MESSZ - char mes2[LOGSZ]; + char message[100]; - snprintf_P(mess, sizeof(mess), formatP); - snprintf_P(mes2, sizeof(mes2), formatP2); - strncat(mess, mes2, sizeof(mess)); - addLog(loglevel, mess); + snprintf_P(log_data, sizeof(log_data), formatP); + snprintf_P(message, sizeof(message), formatP2); + strncat(log_data, message, sizeof(log_data)); + addLog(loglevel); } /*********************************************************************************************\ diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 08ab2bac7af8..d614e7593b3e 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -48,7 +48,7 @@ #define STA_SSID2 "indebuurt2" // [Ssid2] Optional alternate AP Wifi SSID #define STA_PASS2 "VnsqrtnrsddbrN" // [Password2] Optional alternate AP Wifi password #define WIFI_CONFIG_TOOL WIFI_WPSCONFIG // [WifiConfig] Default tool if wifi fails to connect - // (WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY) + // (WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT) // -- Syslog -------------------------------------- #define SYS_LOG_HOST "domus1" // [LogHost] (Linux) syslog host @@ -169,7 +169,7 @@ #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+3k code, 0.3k mem) // #define USE_IR_HVAC // Support for HVAC system using IR (+2k code) -#define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+11k code, +1k mem) - Disable by // +#define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+5k code, +1k mem) - Disable by // #define USE_WS2812_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB) // #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem) // When USE_WS2812_DMA is enabled expect Exceptions on Pow diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index c33aea73116d..1873cd6bce1e 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -297,8 +297,6 @@ uint8_t _colcount; void startWebserver(int type, IPAddress ipweb) { - char log[LOGSZ]; - if (!_httpflag) { if (!webServer) { webServer = new ESP8266WebServer((HTTP_MANAGER==type)?80:WEB_PORT); @@ -345,9 +343,9 @@ void startWebserver(int type, IPAddress ipweb) webServer->begin(); // Web server start } if (_httpflag != type) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), Hostname, (mDNSbegun) ? ".local" : "", ipweb.toString().c_str()); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); } if (type) _httpflag = type; } @@ -431,7 +429,8 @@ void handleRoot() if (HTTP_MANAGER == _httpflag) { handleWifi0(); } else { - char stemp[10], line[160]; + char stemp[10]; + char line[160]; String page = FPSTR(HTTP_HEAD); page.replace(F("{v}"), FPSTR(S_MAIN_MENU)); page.replace(F(""), F("")); @@ -715,7 +714,6 @@ void handleWifi(boolean scan) if (httpUser()) { return; } - char log[LOGSZ]; addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_WIFI); @@ -759,8 +757,8 @@ void handleWifi(boolean scan) cssid = WiFi.SSID(indices[i]); for (int j = i + 1; j < n; j++) { if (cssid == WiFi.SSID(indices[j])) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_DUPLICATE_ACCESSPOINT " %s"), WiFi.SSID(indices[j]).c_str()); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_DUPLICATE_ACCESSPOINT " %s"), WiFi.SSID(indices[j]).c_str()); + addLog(LOG_LEVEL_DEBUG); indices[j] = -1; // set dup aps to index -1 } } @@ -772,8 +770,8 @@ void handleWifi(boolean scan) if (-1 == indices[i]) { continue; // skip dups } - snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_SSID " %s, " D_RSSI " %d"), WiFi.SSID(indices[i]).c_str(), WiFi.RSSI(indices[i])); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_SSID " %s, " D_RSSI " %d"), WiFi.SSID(indices[i]).c_str(), WiFi.RSSI(indices[i])); + addLog(LOG_LEVEL_DEBUG); int quality = WIFI_getRSSIasQuality(WiFi.RSSI(indices[i])); if (_minimumQuality == -1 || _minimumQuality < quality) { @@ -960,7 +958,6 @@ void handleSave() return; } - char log[LOGSZ +20]; char stemp[TOPSZ]; char stemp2[TOPSZ]; byte what = 0; @@ -982,9 +979,9 @@ void handleSave() strlcpy(sysCfg.sta_pwd[0], (!strlen(webServer->arg("p1").c_str())) ? STA_PASS1 : webServer->arg("p1").c_str(), sizeof(sysCfg.sta_pwd[0])); strlcpy(sysCfg.sta_ssid[1], (!strlen(webServer->arg("s2").c_str())) ? STA_SSID2 : webServer->arg("s2").c_str(), sizeof(sysCfg.sta_ssid[1])); strlcpy(sysCfg.sta_pwd[1], (!strlen(webServer->arg("p2").c_str())) ? STA_PASS2 : webServer->arg("p2").c_str(), sizeof(sysCfg.sta_pwd[1])); - snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_CMND_HOSTNAME " %s, " D_CMND_SSID "1 %s, " D_CMND_PASSWORD "1 %s, " D_CMND_SSID "2 %s, " D_CMND_PASSWORD "2 %s"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_CMND_HOSTNAME " %s, " D_CMND_SSID "1 %s, " D_CMND_PASSWORD "1 %s, " D_CMND_SSID "2 %s, " D_CMND_PASSWORD "2 %s"), sysCfg.hostname, sysCfg.sta_ssid[0], sysCfg.sta_pwd[0], sysCfg.sta_ssid[1], sysCfg.sta_pwd[1]); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); result += F("
" D_TRYING_TO_CONNECT "
"); break; case 2: @@ -993,7 +990,8 @@ void handleSave() strlcpy(stemp2, (!strlen(webServer->arg("mf").c_str())) ? MQTT_FULLTOPIC : webServer->arg("mf").c_str(), sizeof(stemp2)); mqttfy(1,stemp2); if ((strcmp(stemp, sysCfg.mqtt_topic)) || (strcmp(stemp2, sysCfg.mqtt_fulltopic))) { - mqtt_publish_topic_P(2, S_LWT, (sysCfg.flag.mqtt_offline) ? S_OFFLINE : "", true); // Offline or remove previous retained topic + snprintf_P(mqtt_data, sizeof(mqtt_data), (sysCfg.flag.mqtt_offline) ? S_OFFLINE : ""); + mqtt_publish_topic_P(2, S_LWT, true); // Offline or remove previous retained topic } strlcpy(sysCfg.mqtt_topic, stemp, sizeof(sysCfg.mqtt_topic)); strlcpy(sysCfg.mqtt_fulltopic, stemp2, sizeof(sysCfg.mqtt_fulltopic)); @@ -1002,9 +1000,9 @@ void handleSave() strlcpy(sysCfg.mqtt_client, (!strlen(webServer->arg("mc").c_str())) ? MQTT_CLIENT_ID : webServer->arg("mc").c_str(), sizeof(sysCfg.mqtt_client)); strlcpy(sysCfg.mqtt_user, (!strlen(webServer->arg("mu").c_str())) ? MQTT_USER : (!strcmp(webServer->arg("mu").c_str(),"0")) ? "" : webServer->arg("mu").c_str(), sizeof(sysCfg.mqtt_user)); strlcpy(sysCfg.mqtt_pwd, (!strlen(webServer->arg("mp").c_str())) ? MQTT_PASS : (!strcmp(webServer->arg("mp").c_str(),"0")) ? "" : webServer->arg("mp").c_str(), sizeof(sysCfg.mqtt_pwd)); - snprintf_P(log, sizeof(log), PSTR(D_LOG_MQTT D_CMND_MQTTHOST " %s, " D_CMND_MQTTPORT " %d, " D_CMND_MQTTCLIENT " %s, " D_CMND_MQTTUSER " %s, " D_CMND_MQTTPASSWORD " %s, " D_CMND_TOPIC " %s, " D_CMND_FULLTOPIC " %s"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CMND_MQTTHOST " %s, " D_CMND_MQTTPORT " %d, " D_CMND_MQTTCLIENT " %s, " D_CMND_MQTTUSER " %s, " D_CMND_MQTTPASSWORD " %s, " D_CMND_TOPIC " %s, " D_CMND_FULLTOPIC " %s"), sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.mqtt_client, sysCfg.mqtt_user, sysCfg.mqtt_pwd, sysCfg.mqtt_topic, sysCfg.mqtt_fulltopic); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); break; case 3: sysCfg.seriallog_level = (!strlen(webServer->arg("ls").c_str())) ? SERIAL_LOG_LEVEL : atoi(webServer->arg("ls").c_str()); @@ -1015,9 +1013,9 @@ void handleSave() strlcpy(sysCfg.syslog_host, (!strlen(webServer->arg("lh").c_str())) ? SYS_LOG_HOST : webServer->arg("lh").c_str(), sizeof(sysCfg.syslog_host)); sysCfg.syslog_port = (!strlen(webServer->arg("lp").c_str())) ? SYS_LOG_PORT : atoi(webServer->arg("lp").c_str()); sysCfg.tele_period = (!strlen(webServer->arg("lt").c_str())) ? TELE_PERIOD : atoi(webServer->arg("lt").c_str()); - snprintf_P(log, sizeof(log), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D_CMND_WEBLOG " %d, " D_CMND_SYSLOG " %d, " D_CMND_LOGHOST " %s, " D_CMND_LOGPORT " %d, " D_CMND_TELEPERIOD " %d"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D_CMND_WEBLOG " %d, " D_CMND_SYSLOG " %d, " D_CMND_LOGHOST " %s, " D_CMND_LOGPORT " %d, " D_CMND_TELEPERIOD " %d"), sysCfg.seriallog_level, sysCfg.weblog_level, sysCfg.syslog_level, sysCfg.syslog_host, sysCfg.syslog_port, sysCfg.tele_period); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); break; #ifdef USE_DOMOTICZ case 4: @@ -1034,9 +1032,9 @@ void handleSave() strlcpy(sysCfg.friendlyname[1], (!strlen(webServer->arg("a2").c_str())) ? FRIENDLY_NAME"2" : webServer->arg("a2").c_str(), sizeof(sysCfg.friendlyname[1])); strlcpy(sysCfg.friendlyname[2], (!strlen(webServer->arg("a3").c_str())) ? FRIENDLY_NAME"3" : webServer->arg("a3").c_str(), sizeof(sysCfg.friendlyname[2])); strlcpy(sysCfg.friendlyname[3], (!strlen(webServer->arg("a4").c_str())) ? FRIENDLY_NAME"4" : webServer->arg("a4").c_str(), sizeof(sysCfg.friendlyname[3])); - snprintf_P(log, sizeof(log), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_FRIENDLYNAME " %s, %s, %s, %s"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_FRIENDLYNAME " %s, %s, %s, %s"), getStateText(sysCfg.flag.mqtt_enabled), sysCfg.flag.emulation, sysCfg.friendlyname[0], sysCfg.friendlyname[1], sysCfg.friendlyname[2], sysCfg.friendlyname[3]); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); break; case 6: byte new_module = (!strlen(webServer->arg("g99").c_str())) ? MODULE : atoi(webServer->arg("g99").c_str()); @@ -1056,8 +1054,8 @@ void handleSave() } } snprintf_P(stemp, sizeof(stemp), modules[sysCfg.module].name); - snprintf_P(log, sizeof(log), PSTR(D_LOG_MODULE "%s " D_CMND_MODULE "%s"), stemp, gpios.c_str()); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MODULE "%s " D_CMND_MODULE "%s"), stemp, gpios.c_str()); + addLog(LOG_LEVEL_INFO); break; } @@ -1088,7 +1086,7 @@ void handleReset() return; } - char svalue[16]; // was MESSZ + char svalue[16]; addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_RESET_CONFIGURATION); @@ -1147,7 +1145,7 @@ void handleUpgradeStart() if (httpUser()) { return; } - char svalue[100]; // was MESSZ + char svalue[100]; addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_UPGRADE_STARTED)); WIFI_configCounter(); @@ -1176,7 +1174,6 @@ void handleUploadDone() addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_UPLOAD_DONE)); char error[100]; - char log[LOGSZ]; WIFI_configCounter(); restartflag = 0; @@ -1201,8 +1198,8 @@ void handleUploadDone() snprintf_P(error, sizeof(error), PSTR(D_UPLOAD_ERROR_CODE " %d"), _uploaderror); } page += error; - snprintf_P(log, sizeof(log), PSTR(D_UPLOAD ": %s"), error); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_UPLOAD ": %s"), error); + addLog(LOG_LEVEL_DEBUG); stop_flash_rotate = sysCfg.flag.stop_flash_rotate; } else { page += F("green'>" D_SUCCESSFUL "
"); @@ -1217,7 +1214,6 @@ void handleUploadDone() void handleUploadLoop() { // Based on ESP8266HTTPUpdateServer.cpp uses ESP8266WebServer Parsing.cpp and Cores Updater.cpp (Update) - char log[LOGSZ]; boolean _serialoutput = (LOG_LEVEL_DEBUG <= seriallog_level); if (HTTP_USER == _httpflag) { @@ -1239,8 +1235,8 @@ void handleUploadLoop() return; } CFG_Save(1); // Free flash for upload - snprintf_P(log, sizeof(log), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str()); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str()); + addLog(LOG_LEVEL_INFO); if (!_uploadfiletype) { mqttcounter = 60; #ifdef USE_EMULATION @@ -1319,8 +1315,8 @@ void handleUploadLoop() } } if (!_uploaderror) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_UPLOAD D_SUCCESSFUL " %u bytes. " D_RESTARTING), upload.totalSize); - addLog(LOG_LEVEL_INFO, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_SUCCESSFUL " %u bytes. " D_RESTARTING), upload.totalSize); + addLog(LOG_LEVEL_INFO); } } else if (UPLOAD_FILE_ABORTED == upload.status) { restartflag = 0; @@ -1353,12 +1349,11 @@ void handleCmnd() if (valid) { byte curridx = logidx; if (strlen(webServer->arg("cmnd").c_str())) { -// snprintf_P(svalue, sizeof(svalue), webServer->arg("cmnd").c_str()); - snprintf_P(svalue, sizeof(svalue), PSTR("%s"), webServer->arg("cmnd").c_str()); - byte syslog_now = syslog_level; - syslog_level = 0; // Disable UDP syslog to not trigger hardware WDT + snprintf_P(svalue, sizeof(svalue), webServer->arg("cmnd").c_str()); +// byte syslog_now = syslog_level; +// syslog_level = 0; // Disable UDP syslog to not trigger hardware WDT - Seems to work fine since 5.7.1d (global logging) do_cmnd(svalue); - syslog_level = syslog_now; +// syslog_level = syslog_now; } if (logidx != curridx) { @@ -1413,19 +1408,18 @@ void handleAjax() if (httpUser()) { return; } - char log[LOGSZ]; char svalue[INPUT_BUFFER_SIZE]; // big to serve Backlog byte cflg = 1; byte counter = 99; if (strlen(webServer->arg("c1").c_str())) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s"), webServer->arg("c1").c_str()); - snprintf_P(log, sizeof(log), PSTR(D_LOG_COMMAND "%s"), svalue); - addLog(LOG_LEVEL_INFO, log); - byte syslog_now = syslog_level; - syslog_level = 0; // Disable UDP syslog to not trigger hardware WDT + snprintf_P(svalue, sizeof(svalue), webServer->arg("c1").c_str()); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue); + addLog(LOG_LEVEL_INFO); +// byte syslog_now = syslog_level; +// syslog_level = 0; // Disable UDP syslog to not trigger hardware WDT - Seems to work fine since 5.7.1d (global logging) do_cmnd(svalue); - syslog_level = syslog_now; +// syslog_level = syslog_now; } if (strlen(webServer->arg("c2").c_str())) { diff --git a/sonoff/xdrv_domoticz.ino b/sonoff/xdrv_domoticz.ino index 5c3d18e2b67b..ffc1d5a2e3ca 100644 --- a/sonoff/xdrv_domoticz.ino +++ b/sonoff/xdrv_domoticz.ino @@ -49,25 +49,18 @@ byte domoticz_update_flag = 1; void mqtt_publishDomoticzPowerState(byte device) { - char svalue[64]; // was MESSZ - if (sysCfg.flag.mqtt_enabled && sysCfg.domoticz_relay_idx[device -1]) { if ((device < 1) || (device > Maxdevice)) { device = 1; } if (sfl_flg) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"idx\":%d,\"nvalue\":2,\"svalue\":\"%d\"}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":2,\"svalue\":\"%d\"}"), sysCfg.domoticz_relay_idx[device -1], sysCfg.led_dimmer[device -1]); - mqtt_publish(domoticz_in_topic, svalue); - } - else if ((Maxdevice == device) && (pin[GPIO_WS2812] < 99)) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"idx\":%d,\"nvalue\":2,\"svalue\":\"%d\"}"), - sysCfg.domoticz_relay_idx[device -1], sysCfg.ws_dimmer); - mqtt_publish(domoticz_in_topic, svalue); + mqtt_publish(domoticz_in_topic); } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"\"}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"\"}"), sysCfg.domoticz_relay_idx[device -1], (power & (0x01 << (device -1))) ? 1 : 0); - mqtt_publish(domoticz_in_topic, svalue); + mqtt_publish(domoticz_in_topic); } } @@ -136,7 +129,6 @@ boolean domoticz_update() boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uint16_t sdataBuf) { - char log[LOGSZ]; char stemp1[10]; char scommand[10]; unsigned long idx = 0; @@ -159,8 +151,8 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin idx = domoticz["idx"]; nvalue = domoticz["nvalue"]; - snprintf_P(log, sizeof(log), PSTR(D_LOG_DOMOTICZ "idx %d, nvalue %d"), idx, nvalue); - addLog(LOG_LEVEL_DEBUG_MORE, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DOMOTICZ "idx %d, nvalue %d"), idx, nvalue); + addLog(LOG_LEVEL_DEBUG_MORE); if (nvalue >= 0 && nvalue <= 2) { for (byte i = 0; i < Maxdevice; i++) { @@ -168,9 +160,6 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), i +1); if (2 == nvalue) { nvalue = domoticz["svalue1"]; - if ((pin[GPIO_WS2812] < 99) && (sysCfg.ws_dimmer == nvalue)) { - return 1; - } if (sfl_flg && (sysCfg.led_dimmer[i] == nvalue)) { return 1; } @@ -193,8 +182,8 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin return 1; } - snprintf_P(log, sizeof(log), PSTR(D_LOG_DOMOTICZ D_RECEIVED_TOPIC " %s, " D_DATA " %s"), topicBuf, dataBuf); - addLog(LOG_LEVEL_DEBUG_MORE, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DOMOTICZ D_RECEIVED_TOPIC " %s, " D_DATA " %s"), topicBuf, dataBuf); + addLog(LOG_LEVEL_DEBUG_MORE); domoticz_update_flag = 0; } @@ -205,7 +194,7 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin * Commands \*********************************************************************************************/ -boolean domoticz_command(const char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue) +boolean domoticz_command(const char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload) { boolean serviced = true; uint8_t dmtcz_len = strlen(D_CMND_DOMOTICZ); // Prep for string length change @@ -216,31 +205,31 @@ boolean domoticz_command(const char *type, uint16_t index, char *dataBuf, uint16 sysCfg.domoticz_relay_idx[index -1] = payload; restartflag = 2; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_IDX "%d\":%d}"), index, sysCfg.domoticz_relay_idx[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ D_CMND_IDX "%d\":%d}"), index, sysCfg.domoticz_relay_idx[index -1]); } else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_KEYIDX)) && (index > 0) && (index <= Maxdevice)) { if (payload >= 0) { sysCfg.domoticz_key_idx[index -1] = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_KEYIDX "%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ D_CMND_KEYIDX "%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]); } else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_SWITCHIDX)) && (index > 0) && (index <= Maxdevice)) { if (payload >= 0) { sysCfg.domoticz_switch_idx[index -1] = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_SWITCHIDX "%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ D_CMND_SWITCHIDX "%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]); } else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_SENSORIDX)) && (index > 0) && (index <= DOMOTICZ_MAX_SENSORS)) { if (payload >= 0) { sysCfg.domoticz_sensor_idx[index -1] = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_SENSORIDX "%d\":%d}"), index, sysCfg.domoticz_sensor_idx[index -1]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ D_CMND_SENSORIDX "%d\":%d}"), index, sysCfg.domoticz_sensor_idx[index -1]); } else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_UPDATETIMER))) { if ((payload >= 0) && (payload < 3601)) { sysCfg.domoticz_update_timer = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_UPDATETIMER "\":%d}"), sysCfg.domoticz_update_timer); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ D_CMND_UPDATETIMER "\":%d}"), sysCfg.domoticz_update_timer); } else serviced = false; } @@ -251,11 +240,9 @@ boolean domoticz_command(const char *type, uint16_t index, char *dataBuf, uint16 boolean domoticz_button(byte key, byte device, byte state, byte svalflg) { if ((sysCfg.domoticz_key_idx[device -1] || sysCfg.domoticz_switch_idx[device -1]) && (svalflg)) { - char svalue[80]; // was MESSZ - - snprintf_P(svalue, sizeof(svalue), PSTR("{\"command\":\"switchlight\",\"idx\":%d,\"switchcmd\":\"%s\"}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"command\":\"switchlight\",\"idx\":%d,\"switchcmd\":\"%s\"}"), (key) ? sysCfg.domoticz_switch_idx[device -1] : sysCfg.domoticz_key_idx[device -1], (state) ? (2 == state) ? "Toggle" : "On" : "Off"); - mqtt_publish(domoticz_in_topic, svalue); + mqtt_publish(domoticz_in_topic); return 1; } else { return 0; @@ -274,12 +261,14 @@ uint8_t dom_hum_stat(char *hum) void dom_sensor(byte idx, char *data) { - char dmess[64]; - if (sysCfg.domoticz_sensor_idx[idx]) { - snprintf_P(dmess, sizeof(dmess), PSTR("{\"idx\":%d,\"nvalue\":0,\"svalue\":\"%s\"}"), + char dmess[64]; + + memcpy(dmess, mqtt_data, sizeof(dmess)); + snprintf_P(mqtt_data, sizeof(dmess), PSTR("{\"idx\":%d,\"nvalue\":0,\"svalue\":\"%s\"}"), sysCfg.domoticz_sensor_idx[idx], data); - mqtt_publish(domoticz_in_topic, dmess); + mqtt_publish(domoticz_in_topic); + memcpy(mqtt_data, dmess, sizeof(dmess)); } } @@ -372,7 +361,7 @@ void handleDomoticz() void domoticz_saveSettings() { - char log[LOGSZ], stemp[20]; + char stemp[20]; for (byte i = 0; i < 4; i++) { snprintf_P(stemp, sizeof(stemp), PSTR("r%d"), i +1); @@ -387,16 +376,16 @@ void domoticz_saveSettings() sysCfg.domoticz_sensor_idx[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str()); } sysCfg.domoticz_update_timer = (!strlen(webServer->arg("ut").c_str())) ? DOMOTICZ_UPDATE_TIMER : atoi(webServer->arg("ut").c_str()); - snprintf_P(log, sizeof(log), PSTR(D_LOG_DOMOTICZ D_CMND_IDX " %d, %d, %d, %d, " D_CMND_UPDATETIMER " %d"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DOMOTICZ D_CMND_IDX " %d, %d, %d, %d, " D_CMND_UPDATETIMER " %d"), sysCfg.domoticz_relay_idx[0], sysCfg.domoticz_relay_idx[1], sysCfg.domoticz_relay_idx[2], sysCfg.domoticz_relay_idx[3], sysCfg.domoticz_update_timer); - addLog(LOG_LEVEL_INFO, log); - snprintf_P(log, sizeof(log), PSTR(D_LOG_DOMOTICZ D_CMND_KEYIDX " %d, %d, %d, %d, " D_CMND_SWITCHIDX " %d, %d, %d, %d, " D_CMND_SENSORIDX " %d, %d, %d, %d, %d, %d"), + addLog(LOG_LEVEL_INFO); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DOMOTICZ D_CMND_KEYIDX " %d, %d, %d, %d, " D_CMND_SWITCHIDX " %d, %d, %d, %d, " D_CMND_SENSORIDX " %d, %d, %d, %d, %d, %d"), sysCfg.domoticz_key_idx[0], sysCfg.domoticz_key_idx[1], sysCfg.domoticz_key_idx[2], sysCfg.domoticz_key_idx[3], sysCfg.domoticz_switch_idx[0], sysCfg.domoticz_switch_idx[1], sysCfg.domoticz_switch_idx[2], sysCfg.domoticz_switch_idx[3], sysCfg.domoticz_sensor_idx[0], sysCfg.domoticz_sensor_idx[1], sysCfg.domoticz_sensor_idx[2], sysCfg.domoticz_sensor_idx[3], sysCfg.domoticz_sensor_idx[4], sysCfg.domoticz_sensor_idx[5]); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO); } #endif // USE_WEBSERVER #endif // USE_DOMOTICZ diff --git a/sonoff/xdrv_ir_send.ino b/sonoff/xdrv_ir_send.ino index 0a4abade65cb..ff89de9d9e5d 100644 --- a/sonoff/xdrv_ir_send.ino +++ b/sonoff/xdrv_ir_send.ino @@ -68,7 +68,7 @@ void ir_send_init(void) { "Vendor": "", "Power": <0|1>, "Mode": "", "FanSpeed": "<1|2|3|4|5|Auto|Silence>", "Temp": <17..30> } */ -boolean ir_send_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue) +boolean ir_send_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload) { boolean serviced = true; boolean error = false; @@ -82,67 +82,65 @@ boolean ir_send_command(char *type, uint16_t index, char *dataBufUc, uint16_t da int HVAC_Temp = 21; boolean HVAC_Power = true; -// char log[LOGSZ]; - if (!strcasecmp_P(type, PSTR(D_CMND_IRSEND))) { if (data_len) { StaticJsonBuffer<128> jsonBuf; - JsonObject &ir_json = jsonBuf.parseObject(dataBufUc); + JsonObject &ir_json = jsonBuf.parseObject(dataBuf); if (!ir_json.success()) { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRSEND "\":\"" D_INVALID_JSON "\"}")); // JSON decode failed + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRSEND "\":\"" D_INVALID_JSON "\"}")); // JSON decode failed } else { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRSEND "\":\"" D_DONE "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRSEND "\":\"" D_DONE "\"}")); protocol = ir_json[D_IRSEND_PROTOCOL]; bits = ir_json[D_IRSEND_BITS]; data = ir_json[D_IRSEND_DATA]; if (protocol && bits && data) { - if (!strcmp_P(protocol,PSTR("NEC"))) irsend->sendNEC(data, bits); - else if (!strcmp_P(protocol,PSTR("SONY"))) irsend->sendSony(data, bits); - else if (!strcmp_P(protocol,PSTR("RC5"))) irsend->sendRC5(data, bits); - else if (!strcmp_P(protocol,PSTR("RC6"))) irsend->sendRC6(data, bits); - else if (!strcmp_P(protocol,PSTR("DISH"))) irsend->sendDISH(data, bits); - else if (!strcmp_P(protocol,PSTR("JVC"))) irsend->sendJVC(data, bits, 1); - else if (!strcmp_P(protocol,PSTR("SAMSUNG"))) irsend->sendSAMSUNG(data, bits); + if (!strcasecmp_P(protocol, PSTR("NEC"))) irsend->sendNEC(data, bits); + else if (!strcasecmp_P(protocol, PSTR("SONY"))) irsend->sendSony(data, bits); + else if (!strcasecmp_P(protocol, PSTR("RC5"))) irsend->sendRC5(data, bits); + else if (!strcasecmp_P(protocol, PSTR("RC6"))) irsend->sendRC6(data, bits); + else if (!strcasecmp_P(protocol, PSTR("DISH"))) irsend->sendDISH(data, bits); + else if (!strcasecmp_P(protocol, PSTR("JVC"))) irsend->sendJVC(data, bits, 1); + else if (!strcasecmp_P(protocol, PSTR("SAMSUNG"))) irsend->sendSAMSUNG(data, bits); else { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRSEND "\":\"" D_PROTOCOL_NOT_SUPPORTED "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRSEND "\":\"" D_PROTOCOL_NOT_SUPPORTED "\"}")); } } else error = true; } } else error = true; if (error) { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRSEND "\":\"" D_NO D_IRSEND_PROTOCOL ", " D_IRSEND_BITS " " D_OR " " D_IRSEND_DATA "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRSEND "\":\"" D_NO D_IRSEND_PROTOCOL ", " D_IRSEND_BITS " " D_OR " " D_IRSEND_DATA "\"}")); } } #ifdef USE_IR_HVAC else if (!strcasecmp_P(type, PSTR(D_CMND_IRHVAC))) { if (data_len) { StaticJsonBuffer<164> jsonBufer; - JsonObject &root = jsonBufer.parseObject(dataBufUc); + JsonObject &root = jsonBufer.parseObject(dataBuf); if (!root.success()) { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRHVAC "\":\"" D_INVALID_JSON "\"}")); // JSON decode failed + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRHVAC "\":\"" D_INVALID_JSON "\"}")); // JSON decode failed } else { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRHVAC "\":\"" D_DONE "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRHVAC "\":\"" D_DONE "\"}")); HVAC_Vendor = root[D_IRHVAC_VENDOR]; HVAC_Power = root[D_IRHVAC_POWER]; HVAC_Mode = root[D_IRHVAC_MODE]; HVAC_FanMode = root[D_IRHVAC_FANSPEED]; HVAC_Temp = root[D_IRHVAC_TEMP]; -// snprintf_P(log, sizeof(log), PSTR("IRHVAC: Received Vendor %s, Power %d, Mode %s, FanSpeed %s, Temp %d"), +// snprintf_P(log_data, sizeof(log_data), PSTR("IRHVAC: Received Vendor %s, Power %d, Mode %s, FanSpeed %s, Temp %d"), // HVAC_Vendor, HVAC_Power, HVAC_Mode, HVAC_FanMode, HVAC_Temp); -// addLog(LOG_LEVEL_DEBUG, log); +// addLog(LOG_LEVEL_DEBUG); - if (HVAC_Vendor == NULL || !strcmp_P(HVAC_Vendor,PSTR("TOSHIBA"))) { + if (HVAC_Vendor == NULL || !strcasecmp_P(HVAC_Vendor, PSTR("TOSHIBA"))) { error = ir_hvac_toshiba(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); } - else if (!strcmp_P(HVAC_Vendor,PSTR("MITSUBISHI"))) { + else if (!strcasecmp_P(HVAC_Vendor, PSTR("MITSUBISHI"))) { error = ir_hvac_mitsubishi(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp); } else error = true; } } else error = true; if (error) { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRHVAC "\":\"" D_WRONG D_IRHVAC_VENDOR ", " D_IRHVAC_MODE " " D_OR " " D_IRHVAC_FANSPEED "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_IRHVAC "\":\"" D_WRONG D_IRHVAC_VENDOR ", " D_IRHVAC_MODE " " D_OR " " D_IRHVAC_FANSPEED "\"}")); } } #endif // USE_IR_HVAC @@ -165,7 +163,7 @@ boolean ir_hvac_toshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean if (HVAC_Mode == NULL) { p = (char*)HVACMODE; // default HVAC_HOT } else { - p = strchr(HVACMODE, HVAC_Mode[0]); + p = strchr(HVACMODE, toupper(HVAC_Mode[0])); } if (!p) { return true; @@ -179,7 +177,7 @@ boolean ir_hvac_toshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean if (HVAC_FanMode == NULL) { p = (char*)FANSPEED; // default FAN_SPEED_AUTO } else { - p = strchr(FANSPEED, HVAC_FanMode[0]); + p = strchr(FANSPEED, toupper(HVAC_FanMode[0])); } if (!p) { return true; @@ -246,14 +244,13 @@ boolean ir_hvac_mitsubishi(const char *HVAC_Mode,const char *HVAC_FanMode, boole char *p; char *token; uint8_t mode; - char log[LOGSZ]; mitsubir->stateReset(); if (HVAC_Mode == NULL) { p = (char*)HVACMODE; // default HVAC_HOT } else { - p = strchr(HVACMODE, HVAC_Mode[0]); + p = strchr(HVACMODE, toupper(HVAC_Mode[0])); } if (!p) { return true; @@ -266,7 +263,7 @@ boolean ir_hvac_mitsubishi(const char *HVAC_Mode,const char *HVAC_FanMode, boole if (HVAC_FanMode == NULL) { p = (char*)FANSPEED; // default FAN_SPEED_AUTO } else { - p = strchr(FANSPEED, HVAC_FanMode[0]); + p = strchr(FANSPEED, toupper(HVAC_FanMode[0])); } if (!p) { return true; @@ -278,9 +275,9 @@ boolean ir_hvac_mitsubishi(const char *HVAC_Mode,const char *HVAC_FanMode, boole mitsubir->setVane(MITSUBISHI_AC_VANE_AUTO); mitsubir->send(); -// snprintf_P(log, sizeof(log), PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"), +// snprintf_P(log_data, sizeof(log_data), PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"), // mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane()); -// addLog(LOG_LEVEL_DEBUG, log); +// addLog(LOG_LEVEL_DEBUG); return false; } diff --git a/sonoff/xdrv_snfbridge.ino b/sonoff/xdrv_snfbridge.ino index dc6232d19279..4d366eb76fce 100644 --- a/sonoff/xdrv_snfbridge.ino +++ b/sonoff/xdrv_snfbridge.ino @@ -39,19 +39,18 @@ void sb_received() uint16_t rhi = 0; char svalue[90]; char rfkey[8]; - char log[LOGSZ]; svalue[0] = '\0'; for (i = 0; i < SerialInByteCounter; i++) { snprintf_P(svalue, sizeof(svalue), PSTR("%s%02X "), svalue, serialInBuf[i]); } - snprintf_P(log, sizeof(log), PSTR(D_LOG_BRIDGE D_RECEIVED " %s"), svalue); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_BRIDGE D_RECEIVED " %s"), svalue); + addLog(LOG_LEVEL_DEBUG); if (0xA2 == serialInBuf[0]) { // Learn timeout sfb_learnFlg = 0; - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARN_FAILED "\"}"), sfb_learnKey); - mqtt_publish_topic_P(5, PSTR(D_CMND_RFKEY), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARN_FAILED "\"}"), sfb_learnKey); + mqtt_publish_topic_P(5, PSTR(D_CMND_RFKEY)); } else if (0xA3 == serialInBuf[0]) { // Learned A3 20 F8 01 18 03 3E 2E 1A 22 55 sfb_learnFlg = 0; @@ -61,11 +60,11 @@ void sb_received() for (i = 0; i < 9; i++) { sysCfg.sfb_code[sfb_learnKey][i] = serialInBuf[i +1]; } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARNED "\"}"), sfb_learnKey); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARNED "\"}"), sfb_learnKey); } else { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARN_FAILED "\"}"), sfb_learnKey); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARN_FAILED "\"}"), sfb_learnKey); } - mqtt_publish_topic_P(5, PSTR(D_CMND_RFKEY), svalue); + mqtt_publish_topic_P(5, PSTR(D_CMND_RFKEY)); } else if (0xA4 == serialInBuf[0]) { // Received RF data A4 20 EE 01 18 03 3E 2E 1A 22 55 rsy = serialInBuf[1] << 8 | serialInBuf[2]; // Sync time in uSec @@ -87,9 +86,9 @@ void sb_received() } } } - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_RFRECEIVED "\":{\"" D_SYNC "\":%d, \"" D_LOW "\":%d, \"" D_HIGH "\":%d, \"" D_DATA "\":\"%06X\", \"" D_CMND_RFKEY "\":%s}}"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_RFRECEIVED "\":{\"" D_SYNC "\":%d, \"" D_LOW "\":%d, \"" D_HIGH "\":%d, \"" D_DATA "\":\"%06X\", \"" D_CMND_RFKEY "\":%s}}"), rsy, rlo, rhi, rid, rfkey); - mqtt_publish_topic_P(6, PSTR(D_RFRECEIVED), svalue); + mqtt_publish_topic_P(6, PSTR(D_RFRECEIVED)); } } } @@ -155,7 +154,7 @@ void sb_learn(uint8_t key) * Commands \*********************************************************************************************/ -boolean sb_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue) +boolean sb_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload) { boolean serviced = true; char *p; @@ -170,28 +169,28 @@ boolean sb_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, sysCfg.sfb_code[0][7] = lsb; } } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFDEFAULT "\":\"%0X%0X\"}"), sysCfg.sfb_code[0][6], sysCfg.sfb_code[0][7]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFDEFAULT "\":\"%0X%0X\"}"), sysCfg.sfb_code[0][6], sysCfg.sfb_code[0][7]); } else if (!strcasecmp_P(type, PSTR(D_CMND_RFKEY)) && (index > 0) && (index <= 16)) { if (!sfb_learnFlg) { if (2 == payload) { sb_learn(index); - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_START_LEARNING "\"}"), index); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_START_LEARNING "\"}"), index); } else if (3 == payload) { sysCfg.sfb_code[index][0] = 0; - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_SET_TO_DEFAULT "\"}"), index); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_SET_TO_DEFAULT "\"}"), index); } else { if ((1 == payload) || (0 == sysCfg.sfb_code[index][0])) { sb_send(0, index); - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_DEFAULT_SENT "\"}"), index); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_DEFAULT_SENT "\"}"), index); } else { sb_send(index, 0); - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARNED_SENT "\"}"), index); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARNED_SENT "\"}"), index); } } } else { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARNING_ACTIVE "\"}"), sfb_learnKey); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARNING_ACTIVE "\"}"), sfb_learnKey); } } else { diff --git a/sonoff/xdrv_snfled.ino b/sonoff/xdrv_snfled.ino index 90e5e1a77b76..7424026ce775 100644 --- a/sonoff/xdrv_snfled.ino +++ b/sonoff/xdrv_snfled.ino @@ -1,5 +1,5 @@ /* - xdrv_snfled.ino - sonoff led support for Sonoff-Tasmota + xdrv_snfled.ino - WS2812 and sonoff led support for Sonoff-Tasmota Copyright (C) 2017 Theo Arends @@ -18,44 +18,59 @@ */ /*********************************************************************************************\ - * Sonoff B1, AiLight, Sonoff Led and BN-SZ01 + * WS2812, Sonoff B1, AiLight, Sonoff Led and BN-SZ01 * * sfl_flg Module Color ColorTemp * 1 Sonoff BN-SZ W no * 2 Sonoff Led CW yes - * 3 not used + * 3 +WS2812 RGB no * 4 AiLight RGBW no * 5 Sonoff B1 RGBCW yes + * + * led_scheme WS2812 Others Effect + * 0 yes yes Color On/Off + * 1 yes yes Wakeup light + * 2 yes no Clock + * 3 yes no Incandescent + * 4 yes no RGB + * 5 yes no Christmas + * 6 yes no Hanukkah + * 7 yes no Kwanzaa + * 8 yes no Rainbow + * 9 yes no Fire + * \*********************************************************************************************/ uint8_t ledTable[] = { - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, - 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, - 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, - 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, - 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, - 33, 33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, - 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, - 80, 81, 82, 83, 85, 86, 87, 89, 90, 91, 93, 94, 95, 97, 98, 99, - 101,102,104,105,107,108,110,111,113,114,116,117,119,121,122,124, - 125,127,129,130,132,134,135,137,139,141,142,144,146,148,150,151, - 153,155,157,159,161,163,165,166,168,170,172,174,176,178,180,182, - 184,186,189,191,193,195,197,199,201,204,206,208,210,212,215,217, - 219,221,224,226,228,231,233,235,238,240,243,245,248,250,253,255 }; + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, + 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, + 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, + 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, + 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, + 33, 33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, + 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, + 80, 81, 82, 83, 85, 86, 87, 89, 90, 91, 93, 94, 95, 97, 98, 99, +101,102,104,105,107,108,110,111,113,114,116,117,119,121,122,124, +125,127,129,130,132,134,135,137,139,141,142,144,146,148,150,151, +153,155,157,159,161,163,165,166,168,170,172,174,176,178,180,182, +184,186,189,191,193,195,197,199,201,204,206,208,210,212,215,217, +219,221,224,226,228,231,233,235,238,240,243,245,248,250,253,255 }; uint8_t sl_dcolor[5]; uint8_t sl_tcolor[5]; uint8_t sl_lcolor[5]; -uint8_t sl_power; -uint8_t sl_any; +uint8_t sl_power = 0; +uint8_t sl_any = 0; uint8_t sl_wakeupActive = 0; uint8_t sl_wakeupDimmer = 0; uint16_t sl_wakeupCntr = 0; +unsigned long stripTimerCntr = 0; // Bars and Gradient + /*********************************************************************************************\ * Sonoff B1 and AiLight inspired by OpenLight https://github.com/icamgo/noduino-sdk \*********************************************************************************************/ @@ -139,8 +154,7 @@ void sl_my92x1_duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t duty void sl_init(void) { - pin[GPIO_WS2812] = 99; // I do not allow both Sonoff Led AND WS2812 led - if (sfl_flg < 4) { + if (sfl_flg < 3) { if (!my_module.gp.io[4]) { pinMode(4, OUTPUT); // Stop floating outputs digitalWrite(4, LOW); @@ -157,7 +171,17 @@ void sl_init(void) if (2 == sfl_flg) { sysCfg.pwmvalue[1] = 0; // We use led_color } - } else { + sysCfg.led_scheme = 0; + } +#ifdef USE_WS2812 // ************************************************************************ + else if (3 == sfl_flg) { + ws2812_init(); + if (1 == sysCfg.led_scheme) { + sysCfg.led_scheme = 0; + } + } +#endif // USE_WS2812 ************************************************************************ + else { sl_pdi = pin[GPIO_DI]; sl_pdcki = pin[GPIO_DCKI]; @@ -167,6 +191,7 @@ void sl_init(void) digitalWrite(sl_pdcki, LOW); sl_my92x1_init(); + sysCfg.led_scheme = 0; } sl_power = 0; @@ -257,113 +282,138 @@ char* sl_getColor(char* scolor) return scolor; } -void sl_prepPower(char *svalue, uint16_t ssvalue) +void sl_prepPower() { char scolor[11]; // do_cmnd_power(index, (sysCfg.led_dimmer[0]>0)); - if (sysCfg.led_dimmer[0] && !(power&1)) { - do_cmnd_power(1, 7); // No publishPowerState + if (sysCfg.led_dimmer[0] && !(sl_power)) { + do_cmnd_power(Maxdevice, 7); // No publishPowerState } - else if (!sysCfg.led_dimmer[0] && (power&1)) { - do_cmnd_power(1, 6); // No publishPowerState + else if (!sysCfg.led_dimmer[0] && sl_power) { + do_cmnd_power(Maxdevice, 6); // No publishPowerState } #ifdef USE_DOMOTICZ - mqtt_publishDomoticzPowerState(1); +// mqtt_publishDomoticzPowerState(1); + domoticz_updatePowerState(Maxdevice); #endif // USE_DOMOTICZ if (sfl_flg > 1) { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_RSLT_POWER "\":\"%s\", \"" D_CMND_DIMMER "\":%d, \"" D_CMND_COLOR "\":\"%s\"}"), - getStateText(power &1), sysCfg.led_dimmer[0], sl_getColor(scolor)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_RSLT_POWER "\":\"%s\", \"" D_CMND_DIMMER "\":%d, \"" D_CMND_COLOR "\":\"%s\"}"), + getStateText(sl_power), sysCfg.led_dimmer[0], sl_getColor(scolor)); } else { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_RSLT_POWER "\":\"%s\", \"" D_CMND_DIMMER "\":%d}"), - getStateText(power &1), sysCfg.led_dimmer[0]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_RSLT_POWER "\":\"%s\", \"" D_CMND_DIMMER "\":%d}"), + getStateText(sl_power), sysCfg.led_dimmer[0]); } } -void sl_setPower(uint8_t power) +void sl_setPower(uint8_t mpower) { - sl_power = power &1; + sl_power = ((mpower & (0x01 << (Maxdevice -1))) != 0); if (sl_wakeupActive) { sl_wakeupActive--; } + if (sl_power) { + sl_any = 1; + } sl_animate(); } void sl_animate() { // {"Wakeup":"Done"} - char svalue[32]; // was MESSZ uint8_t fadeValue; uint8_t cur_col[5]; - if (0 == sl_power) { // Power Off + stripTimerCntr++; + if (!sl_power) { // Power Off + sleep = sysCfg.sleep; + stripTimerCntr = 0; for (byte i = 0; i < sfl_flg; i++) { sl_tcolor[i] = 0; } } else { - if (!sl_wakeupActive) { // Power On - sl_setDim(sysCfg.led_dimmer[0]); - if (0 == sysCfg.led_fade) { - for (byte i = 0; i < sfl_flg; i++) { - sl_tcolor[i] = sl_dcolor[i]; - } - } else { - for (byte i = 0; i < sfl_flg; i++) { - if (sl_tcolor[i] != sl_dcolor[i]) { - if (sl_tcolor[i] < sl_dcolor[i]) { - sl_tcolor[i] += ((sl_dcolor[i] - sl_tcolor[i]) >> sysCfg.led_speed) +1; - } - if (sl_tcolor[i] > sl_dcolor[i]) { - sl_tcolor[i] -= ((sl_tcolor[i] - sl_dcolor[i]) >> sysCfg.led_speed) +1; + sleep = 0; + switch (sysCfg.led_scheme) { + case 0: // Power On + sl_setDim(sysCfg.led_dimmer[0]); // Power On + if (0 == sysCfg.led_fade) { + for (byte i = 0; i < sfl_flg; i++) { + sl_tcolor[i] = sl_dcolor[i]; + } + } else { + for (byte i = 0; i < sfl_flg; i++) { + if (sl_tcolor[i] != sl_dcolor[i]) { + if (sl_tcolor[i] < sl_dcolor[i]) { + sl_tcolor[i] += ((sl_dcolor[i] - sl_tcolor[i]) >> sysCfg.led_speed) +1; + } + if (sl_tcolor[i] > sl_dcolor[i]) { + sl_tcolor[i] -= ((sl_tcolor[i] - sl_dcolor[i]) >> sysCfg.led_speed) +1; + } } } } - } - } else { // Power On using wake up duration - if (2 == sl_wakeupActive) { - sl_wakeupActive = 1; - for (byte i = 0; i < sfl_flg; i++) { - sl_tcolor[i] = 0; - } - sl_wakeupCntr = 0; - sl_wakeupDimmer = 0; - } - sl_wakeupCntr++; - if (sl_wakeupCntr > ((sysCfg.led_wakeup * STATES) / sysCfg.led_dimmer[0])) { - sl_wakeupCntr = 0; - sl_wakeupDimmer++; - if (sl_wakeupDimmer <= sysCfg.led_dimmer[0]) { - sl_setDim(sl_wakeupDimmer); + break; + case 1: // Power On using wake up duration + if (2 == sl_wakeupActive) { + sl_wakeupActive = 1; for (byte i = 0; i < sfl_flg; i++) { - sl_tcolor[i] = sl_dcolor[i]; + sl_tcolor[i] = 0; } - } else { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WAKEUP "\":\"" D_DONE "\"}")); - mqtt_publish_topic_P(2, PSTR(D_CMND_WAKEUP), svalue); - sl_wakeupActive = 0; + sl_wakeupCntr = 0; + sl_wakeupDimmer = 0; } - } - } - } - for (byte i = 0; i < sfl_flg; i++) { - if (sl_lcolor[i] != sl_tcolor[i]) { - sl_any = 1; + sl_wakeupCntr++; + if (sl_wakeupCntr > ((sysCfg.led_wakeup * STATES) / sysCfg.led_dimmer[0])) { + sl_wakeupCntr = 0; + sl_wakeupDimmer++; + if (sl_wakeupDimmer <= sysCfg.led_dimmer[0]) { + sl_setDim(sl_wakeupDimmer); + for (byte i = 0; i < sfl_flg; i++) { + sl_tcolor[i] = sl_dcolor[i]; + } + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WAKEUP "\":\"" D_DONE "\"}")); + mqtt_publish_topic_P(2, PSTR(D_CMND_WAKEUP)); + sl_wakeupActive = 0; + sysCfg.led_scheme = 0; + } + } + break; +#ifdef USE_WS2812 // ************************************************************************ + default: + if (3 == sfl_flg) { + ws2812_showScheme(sysCfg.led_scheme -2); + } +#endif // USE_WS2812 ************************************************************************ } } - if (sl_any) { - sl_any = 0; + + if ((sysCfg.led_scheme < 2) || !sl_power) { for (byte i = 0; i < sfl_flg; i++) { - sl_lcolor[i] = sl_tcolor[i]; - cur_col[i] = (sysCfg.led_table) ? ledTable[sl_lcolor[i]] : sl_lcolor[i]; - if (sfl_flg < 4) { - if (pin[GPIO_PWM1 +i] < 99) { - analogWrite(pin[GPIO_PWM1 +i], cur_col[i] * (PWM_RANGE / 255)); - } + if (sl_lcolor[i] != sl_tcolor[i]) { + sl_any = 1; } } - if (sfl_flg > 3) { - sl_my92x1_duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]); + if (sl_any) { + sl_any = 0; + for (byte i = 0; i < sfl_flg; i++) { + sl_lcolor[i] = sl_tcolor[i]; + cur_col[i] = (sysCfg.led_table) ? ledTable[sl_lcolor[i]] : sl_lcolor[i]; + if (sfl_flg < 3) { + if (pin[GPIO_PWM1 +i] < 99) { + analogWrite(pin[GPIO_PWM1 +i], cur_col[i] * (PWM_RANGE / 255)); + } + } + } +#ifdef USE_WS2812 // ************************************************************************ + if (3 == sfl_flg) { + ws2812_setColor(0, cur_col[0], cur_col[1], cur_col[2]); + } +#endif // USE_ES2812 ************************************************************************ + if (sfl_flg > 3) { + sl_my92x1_duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]); + } } } } @@ -372,33 +422,114 @@ void sl_animate() * Hue support \*********************************************************************************************/ -void sl_rgb2hsb(float *hue, float *sat, float *bri) -{ - RgbColor dcolor; +float sl_Hue = 0.0; +float sl_Sat = 0.0; +float sl_Bri = 0.0; +void sl_rgb2hsb() +{ sl_setDim(sysCfg.led_dimmer[0]); - dcolor.R = sl_dcolor[0]; - dcolor.G = sl_dcolor[1]; - dcolor.B = sl_dcolor[2]; - HsbColor hsb = HsbColor(dcolor); - *hue = hsb.H; - *sat = hsb.S; - *bri = hsb.B; + + // convert colors to float between (0.0 - 1.0) + float r = sl_dcolor[0] / 255.0f; + float g = sl_dcolor[1] / 255.0f; + float b = sl_dcolor[2] / 255.0f; + + float max = (r > g && r > b) ? r : (g > b) ? g : b; + float min = (r < g && r < b) ? r : (g < b) ? g : b; + + float d = max - min; + + sl_Hue = 0.0; + sl_Bri = max; + sl_Sat = (0.0f == sl_Bri) ? 0 : (d / sl_Bri); + + if (d != 0.0f) + { + if (r == max) { + sl_Hue = (g - b) / d + (g < b ? 6.0f : 0.0f); + } else if (g == max) { + sl_Hue = (b - r) / d + 2.0f; + } else { + sl_Hue = (r - g) / d + 4.0f; + } + sl_Hue /= 6.0f; + } +} + +void sl_hsb2rgb() +{ + float r; + float g; + float b; + + float h = sl_Hue; + float s = sl_Sat; + float v = sl_Bri; + + if (0.0f == sl_Sat) { + r = g = b = v; // achromatic or black + } else { + if (h < 0.0f) { + h += 1.0f; + } + else if (h >= 1.0f) { + h -= 1.0f; + } + h *= 6.0f; + int i = (int)h; + float f = h - i; + float q = v * (1.0f - s * f); + float p = v * (1.0f - s); + float t = v * (1.0f - s * (1.0f - f)); + switch (i) { + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + default: + r = v; + g = p; + b = q; + break; + } + } + + sl_dcolor[0] = (uint8_t)(r * 255.0f); + sl_dcolor[1] = (uint8_t)(g * 255.0f); + sl_dcolor[2] = (uint8_t)(b * 255.0f); } /********************************************************************************************/ void sl_replaceHSB(String *response) { - float hue; - float sat; - float bri; - if (sfl_flg > 2) { - sl_rgb2hsb(&hue, &sat, &bri); - response->replace("{h}", String((uint16_t)(65535.0f * hue))); - response->replace("{s}", String((uint8_t)(254.0f * sat))); - response->replace("{b}", String((uint8_t)(254.0f * bri))); + sl_rgb2hsb(); + response->replace("{h}", String((uint16_t)(65535.0f * sl_Hue))); + response->replace("{s}", String((uint8_t)(254.0f * sl_Sat))); + response->replace("{b}", String((uint8_t)(254.0f * sl_Bri))); } else { response->replace("{h}", "0"); response->replace("{s}", "0"); @@ -410,7 +541,10 @@ void sl_replaceHSB(String *response) void sl_getHSB(float *hue, float *sat, float *bri) { if (sfl_flg > 2) { - sl_rgb2hsb(hue, sat, bri); + sl_rgb2hsb(); + *hue = sl_Hue; + *sat = sl_Sat; + *bri = sl_Bri; } else { *hue = 0; *sat = 0; @@ -421,36 +555,29 @@ void sl_getHSB(float *hue, float *sat, float *bri) void sl_setHSB(float hue, float sat, float bri, uint16_t ct) { - char svalue[MESSZ]; - HsbColor hsb; - /* - char log[LOGSZ]; char stemp1[10]; char stemp2[10]; char stemp3[10]; dtostrfi(hue, 3, stemp1); dtostrfi(sat, 3, stemp2); dtostrfi(bri, 3, stemp3); - snprintf_P(log, sizeof(log), PSTR("HUE: Set Hue %s, Sat %s, Bri %s, Ct %d"), stemp1, stemp2, stemp3, ct); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR("HUE: Set Hue %s, Sat %s, Bri %s, Ct %d"), stemp1, stemp2, stemp3, ct); + addLog(LOG_LEVEL_DEBUG); */ if (sfl_flg > 2) { if ((5 == sfl_flg) && (ct > 0)) { sl_setColorTemp(ct); } else { - hsb.H = hue; - hsb.S = sat; - hsb.B = bri; - RgbColor tmp = RgbColor(hsb); - sl_dcolor[0] = tmp.R; - sl_dcolor[1] = tmp.G; - sl_dcolor[2] = tmp.B; + sl_Hue = hue; + sl_Sat = sat; + sl_Bri = bri; + sl_hsb2rgb(); sl_setColor(); } - sl_prepPower(svalue, sizeof(svalue)); - mqtt_publish_topic_P(5, PSTR(D_CMND_COLOR), svalue); + sl_prepPower(); + mqtt_publish_topic_P(5, PSTR(D_CMND_COLOR)); } else { uint8_t tmp = (uint8_t)(bri * 100); sysCfg.led_dimmer[0] = tmp; @@ -458,11 +585,11 @@ void sl_setHSB(float hue, float sat, float bri, uint16_t ct) if (ct > 0) { sl_setColorTemp(ct); } - sl_prepPower(svalue, sizeof(svalue)); - mqtt_publish_topic_P(5, PSTR(D_CMND_COLOR), svalue); + sl_prepPower(); + mqtt_publish_topic_P(5, PSTR(D_CMND_COLOR)); } else { - sl_prepPower(svalue, sizeof(svalue)); - mqtt_publish_topic_P(5, PSTR(D_CMND_DIMMER), svalue); + sl_prepPower(); + mqtt_publish_topic_P(5, PSTR(D_CMND_DIMMER)); } } } @@ -471,7 +598,7 @@ void sl_setHSB(float hue, float sat, float bri, uint16_t ct) * Commands \*********************************************************************************************/ -boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue) +boolean sl_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload) { boolean serviced = true; boolean coldim = false; @@ -479,27 +606,78 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le char *p; if ((sfl_flg > 1) && !strcasecmp_P(type, PSTR(D_CMND_COLOR))) { - if (dataBufUc[0] == '#') { - dataBufUc++; + if (dataBuf[0] == '#') { + dataBuf++; data_len--; } if ((2 * sfl_flg) == data_len) { for (byte i = 0; i < sfl_flg; i++) { - strlcpy(scolor, dataBufUc + (i *2), 3); + strlcpy(scolor, dataBuf + (i *2), 3); sl_dcolor[i] = (uint8_t)strtol(scolor, &p, 16); } sl_setColor(); coldim = true; } else { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_COLOR "\":\"%s\"}"), sl_getColor(scolor)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_COLOR "\":\"%s\"}"), sl_getColor(scolor)); + } + } +#ifdef USE_WS2812 // *********************************************************************** + else if ((3 == sfl_flg) && !strcasecmp_P(type, PSTR(D_CMND_LED)) && (index > 0) && (index <= sysCfg.led_pixels)) { + if (dataBuf[0] == '#') { + dataBuf++; + data_len--; + } + uint8_t sl_ledcolor[3]; + if ((2 * sfl_flg) == data_len) { + for (byte i = 0; i < sfl_flg; i++) { + strlcpy(scolor, dataBuf + (i *2), 3); + sl_ledcolor[i] = (uint8_t)strtol(scolor, &p, 16); + } + ws2812_setColor(index, sl_ledcolor[0], sl_ledcolor[1], sl_ledcolor[2]); } + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_LED "%d\":\"%s\"}"), index, ws2812_getColor(index, scolor)); + } + else if ((3 == sfl_flg) && !strcasecmp_P(type, PSTR(D_CMND_PIXELS))) { + if ((payload > 0) && (payload <= WS2812_MAX_LEDS)) { + sysCfg.led_pixels = payload; + ws2812_clear(); + sl_any = 1; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PIXELS "\":%d}"), sysCfg.led_pixels); + } + else if ((3 == sfl_flg) && !strcasecmp_P(type, PSTR(D_CMND_WIDTH))) { + if ((payload >= 0) && (payload <= 4)) { + sysCfg.led_width = payload; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WIDTH "\":%d}"), sysCfg.led_width); + } + else if ((3 == sfl_flg) && !strcasecmp_P(type, PSTR(D_CMND_SCHEME))) { + if ((payload >= 0) && (payload <= 9)) { + sysCfg.led_scheme = payload; + if (1 == sysCfg.led_scheme) { + sl_wakeupActive = 3; + } + do_cmnd_power(Maxdevice, 1); + stripTimerCntr = 0; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SCHEME "\":%d}"), sysCfg.led_scheme); + } +#endif // USE_WS2812 ************************************************************************ + else if (!strcasecmp_P(type, PSTR(D_CMND_WAKEUP))) { + if ((payload >= 0) && (payload <= 100)) { + sysCfg.led_dimmer[0] = payload; + } + sl_wakeupActive = 3; + sysCfg.led_scheme = 1; + do_cmnd_power(Maxdevice, 1); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WAKEUP "\":\"" D_STARTED "\"}")); } else if (!strcasecmp_P(type, PSTR(D_CMND_COLORTEMPERATURE)) && ((2 == sfl_flg) || (5 == sfl_flg))) { // ColorTemp if ((payload >= 153) && (payload <= 500)) { // https://developers.meethue.com/documentation/core-concepts sl_setColorTemp(payload); coldim = true; } else { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_COLORTEMPERATURE "\":%d}"), sl_getColorTemp()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_COLORTEMPERATURE "\":%d}"), sl_getColorTemp()); } } else if (!strcasecmp_P(type, PSTR(D_CMND_DIMMER))) { @@ -507,7 +685,7 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le sysCfg.led_dimmer[0] = payload; coldim = true; } else { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DIMMER "\":%d}"), sysCfg.led_dimmer[0]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DIMMER "\":%d}"), sysCfg.led_dimmer[0]); } } else if (!strcasecmp_P(type, PSTR(D_CMND_LEDTABLE))) { @@ -523,7 +701,7 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le } sl_any = 1; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_LEDTABLE "\":\"%s\"}"), getStateText(sysCfg.led_table)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_LEDTABLE "\":\"%s\"}"), getStateText(sysCfg.led_table)); } else if (!strcasecmp_P(type, PSTR(D_CMND_FADE))) { switch (payload) { @@ -535,39 +713,34 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le sysCfg.led_fade ^= 1; break; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_FADE "\":\"%s\"}"), getStateText(sysCfg.led_fade)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_FADE "\":\"%s\"}"), getStateText(sysCfg.led_fade)); } else if (!strcasecmp_P(type, PSTR(D_CMND_SPEED))) { // 1 - fast, 8 - slow if ((payload > 0) && (payload <= 8)) { sysCfg.led_speed = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SPEED "\":%d}"), sysCfg.led_speed); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SPEED "\":%d}"), sysCfg.led_speed); } else if (!strcasecmp_P(type, PSTR(D_CMND_WAKEUPDURATION))) { if ((payload > 0) && (payload < 3001)) { sysCfg.led_wakeup = payload; sl_wakeupActive = 0; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_WAKEUPDURATION "\":%d}"), sysCfg.led_wakeup); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_WAKEUP))) { - sl_wakeupActive = 3; - do_cmnd_power(1, 1); - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_WAKEUP "\":\"" D_STARTED "\"}")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WAKEUPDURATION "\":%d}"), sysCfg.led_wakeup); } else if (!strcasecmp_P(type, PSTR("UNDOCA"))) { // Theos legacy status sl_getColor(scolor); scolor[6] = '\0'; // RGB only - snprintf_P(svalue, ssvalue, PSTR("%s, %d, %d, 1, %d, 1"), - scolor, sysCfg.led_fade, sysCfg.led_table, sysCfg.led_speed); - mqtt_publish_topic_P(1, type, svalue); - svalue[0] = '\0'; + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, %d, %d, %d, %d, %d"), + scolor, sysCfg.led_fade, sysCfg.led_table, sysCfg.led_scheme, sysCfg.led_speed, sysCfg.led_width); + mqtt_publish_topic_P(1, type); + mqtt_data[0] = '\0'; } else { serviced = false; // Unknown command } if (coldim) { - sl_prepPower(svalue, ssvalue); + sl_prepPower(); } return serviced; } diff --git a/sonoff/xdrv_snfsc.ino b/sonoff/xdrv_snfsc.ino index 37d8fa9f58e4..c6ed4c76750e 100644 --- a/sonoff/xdrv_snfsc.ino +++ b/sonoff/xdrv_snfsc.ino @@ -55,11 +55,19 @@ uint16_t sc_value[5] = { 0 }; +void sc_send(const char *data) +{ + Serial.write(data); + Serial.write('\x1B'); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SERIAL D_TRANSMIT " %s"), data); + addLog(LOG_LEVEL_DEBUG); +} + void sc_init() { -// Serial.write("AT+DEVCONFIG=\"uploadFreq\":1800\e"); - Serial.write("AT+START\e"); -// Serial.write("AT+STATUS\e"); +// sc_send("AT+DEVCONFIG=\"uploadFreq\":1800"); + sc_send("AT+START"); +// sc_send("AT+STATUS"); } void sc_rcvstat(char *rcvstat) @@ -68,7 +76,10 @@ void sc_rcvstat(char *rcvstat) char *str; uint16_t value[5] = { 0 }; - if (!strncmp(rcvstat, "AT+UPDATE=", 10)) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SERIAL D_RECEIVED " %s"), rcvstat); + addLog(LOG_LEVEL_DEBUG); + + if (!strncasecmp_P(rcvstat, PSTR("AT+UPDATE="), 10)) { int8_t i = -1; for (str = strtok_r(rcvstat, ":", &p); str && i < 5; str = strtok_r(NULL, ":", &p)) { value[i++] = atoi(str); @@ -80,13 +91,13 @@ void sc_rcvstat(char *rcvstat) sc_value[2] = (11 - sc_value[2]) * 10; // Invert light level sc_value[3] *= 10; sc_value[4] = (11 - sc_value[4]) * 10; // Invert dust level - Serial.write("AT+SEND=ok\e"); + sc_send("AT+SEND=ok"); } else { - Serial.write("AT+SEND=fail\e"); + sc_send("AT+SEND=fail"); } } - else if (!strcmp_P(rcvstat,PSTR("AT+STATUS?"))) { - Serial.write("AT+STATUS=4\e"); + else if (!strcasecmp_P(rcvstat, PSTR("AT+STATUS?"))) { + sc_send("AT+STATUS=4"); } } @@ -94,12 +105,7 @@ void sc_rcvstat(char *rcvstat) * Presentation \*********************************************************************************************/ -float sc_convertCtoF(float c) -{ - return c * 1.8 + 32; -} - -void sc_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void sc_mqttPresent(uint8_t* djson) { if (sc_value[0] > 0) { char stemp1[10]; @@ -109,8 +115,8 @@ void sc_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) dtostrfd(t, sysCfg.flag.temperature_resolution, stemp1); float h = sc_value[0]; dtostrfd(h, sysCfg.flag.humidity_resolution, stemp2); - snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_LIGHT "\":%d, \"" D_NOISE "\":%d, \"" D_AIRQUALITY "\":%d"), - svalue, stemp1, stemp2, sc_value[2], sc_value[3], sc_value[4]); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_LIGHT "\":%d, \"" D_NOISE "\":%d, \"" D_AIRQUALITY "\":%d"), + mqtt_data, stemp1, stemp2, sc_value[2], sc_value[3], sc_value[4]); *djson = 1; #ifdef USE_DOMOTICZ domoticz_sensor2(stemp1, stemp2); diff --git a/sonoff/xdrv_wemohue.ino b/sonoff/xdrv_wemohue.ino index 10fc809a16b5..8500f28dc977 100644 --- a/sonoff/xdrv_wemohue.ino +++ b/sonoff/xdrv_wemohue.ino @@ -68,7 +68,6 @@ String wemo_UUID() void wemo_respondToMSearch() { char message[TOPSZ]; - char log[LOGSZ]; if (portUDP.beginPacket(portUDP.remoteIP(), portUDP.remotePort())) { String response = FPSTR(WEMO_MSEARCH); @@ -80,9 +79,9 @@ void wemo_respondToMSearch() } else { snprintf_P(message, sizeof(message), PSTR(D_FAILED_TO_SEND_RESPONSE)); } - snprintf_P(log, sizeof(log), PSTR(D_LOG_UPNP D_WEMO " %s " D_TO " %s:%d"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPNP D_WEMO " %s " D_TO " %s:%d"), message, portUDP.remoteIP().toString().c_str(), portUDP.remotePort()); - addLog(LOG_LEVEL_DEBUG, log); + addLog(LOG_LEVEL_DEBUG); } /*********************************************************************************************\ @@ -140,7 +139,6 @@ String hue_UUID() void hue_respondToMSearch() { char message[TOPSZ]; - char log[LOGSZ]; if (portUDP.beginPacket(portUDP.remoteIP(), portUDP.remotePort())) { String response1 = FPSTR(HUE_RESPONSE); @@ -153,31 +151,25 @@ void hue_respondToMSearch() portUDP.write(response.c_str()); portUDP.endPacket(); -//addLog(LOG_LEVEL_DEBUG_MORE, response.c_str()); - response = response1; response += FPSTR(HUE_ST2); response.replace("{r3}", hue_UUID()); portUDP.write(response.c_str()); portUDP.endPacket(); -//addLog(LOG_LEVEL_DEBUG_MORE, response.c_str()); - response = response1; response += FPSTR(HUE_ST3); response.replace("{r3}", hue_UUID()); portUDP.write(response.c_str()); portUDP.endPacket(); -//addLog(LOG_LEVEL_DEBUG_MORE, response.c_str()); - snprintf_P(message, sizeof(message), PSTR(D_3_RESPONSE_PACKETS_SENT)); } else { snprintf_P(message, sizeof(message), PSTR(D_FAILED_TO_SEND_RESPONSE)); } - snprintf_P(log, sizeof(log), PSTR(D_LOG_UPNP D_HUE " %s " D_TO " %s:%d"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPNP D_HUE " %s " D_TO " %s:%d"), message, portUDP.remoteIP().toString().c_str(), portUDP.remotePort()); - addLog(LOG_LEVEL_DEBUG, log); + addLog(LOG_LEVEL_DEBUG); } /*********************************************************************************************\ @@ -440,10 +432,8 @@ void handleUPnPsetupHue() void hue_todo(String *path) { - char log[LOGSZ]; - - snprintf_P(log, sizeof(log), PSTR(D_LOG_HTTP D_HUE_API_NOT_IMPLEMENTED " (%s)"), path->c_str()); - addLog(LOG_LEVEL_DEBUG_MORE, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_HTTP D_HUE_API_NOT_IMPLEMENTED " (%s)"), path->c_str()); + addLog(LOG_LEVEL_DEBUG_MORE); webServer->send(200, FPSTR(HDR_CTYPE_JSON), "{}"); } @@ -474,11 +464,6 @@ void hue_light_status(byte device, String *response) if (sfl_flg) { sl_replaceHSB(response); -#ifdef USE_WS2812 - } - else if (pin[GPIO_WS2812] < 99) { - ws2812_replaceHSB(response); -#endif // USE_WS2812 } else { response->replace("{h}", "0"); response->replace("{s}", "0"); @@ -589,11 +574,6 @@ void hue_lights(String *path) if (sfl_flg) { sl_getHSB(&hue,&sat,&bri); -#ifdef USE_WS2812 - } - else if (pin[GPIO_WS2812] < 99) { - ws2812_getHSB(&hue,&sat,&bri); -#endif // USE_WS2812 } if (hue_json.containsKey("bri")) { @@ -648,11 +628,6 @@ void hue_lights(String *path) if (change) { if (sfl_flg) { sl_setHSB(hue, sat, bri, ct); -#ifdef USE_WS2812 - } - else if (pin[GPIO_WS2812] < 99) { - ws2812_setHSB(hue, sat, bri); -#endif // USE_WS2812 } change = false; } @@ -665,8 +640,6 @@ void hue_lights(String *path) response = FPSTR(HUE_ERROR_JSON); } -//addLog(LOG_LEVEL_DEBUG_MORE, response.c_str()); - webServer->send(200, FPSTR(HDR_CTYPE_JSON), response); } else if(path->indexOf("/lights/") >= 0) { // Got /lights/ID @@ -718,17 +691,16 @@ void handle_hue_api(String *path) * (c) Heiko Krupp, 2017 */ - char log[LOGSZ]; uint8_t args = 0; path->remove(0, 4); // remove /api uint16_t apilen = path->length(); - snprintf_P(log, sizeof(log), PSTR(D_LOG_HTTP D_HUE_API " (%s)"), path->c_str()); - addLog(LOG_LEVEL_DEBUG_MORE, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_HTTP D_HUE_API " (%s)"), path->c_str()); + addLog(LOG_LEVEL_DEBUG_MORE); for (args = 0; args < webServer->args(); args++) { String json = webServer->arg(args); - snprintf_P(log, sizeof(log), PSTR(D_LOG_HTTP D_HUE_POST_ARGS " (%s)"), json.c_str()); - addLog(LOG_LEVEL_DEBUG_MORE, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_HTTP D_HUE_POST_ARGS " (%s)"), json.c_str()); + addLog(LOG_LEVEL_DEBUG_MORE); } if (path->endsWith("/invalid/")) {} // Just ignore diff --git a/sonoff/xdrv_ws2812.ino b/sonoff/xdrv_ws2812.ino index 39d181186e51..ea2d1bba8ce4 100644 --- a/sonoff/xdrv_ws2812.ino +++ b/sonoff/xdrv_ws2812.ino @@ -22,7 +22,7 @@ * WS2812 Leds using NeopixelBus library \*********************************************************************************************/ -//#include // Global defined as also used by Sonoff Led +#include #ifdef USE_WS2812_DMA #if (USE_WS2812_CTYPE == 1) @@ -75,101 +75,28 @@ uint8_t repeatValues[5] = { 4, // Large 2, // Largest 1 }; // All -uint8_t speedValues[6] = { - 0, // None - 9 * (STATES / 10), // Slowest - 7 * (STATES / 10), // Slower - 5 * (STATES / 10), // Slow - 3 * (STATES / 10), // Fast - 1 * (STATES / 10) }; // Fastest - -uint8_t lany = 0; -RgbColor dcolor; -RgbColor tcolor; -RgbColor lcolor; - -uint8_t wakeupDimmer = 0; -uint8_t ws_bit = 0; -uint16_t wakeupCntr = 0; -unsigned long stripTimerCntr = 0; // Bars and Gradient - -void ws2812_setDim(uint8_t myDimmer) -{ - float newDim = 100 / (float)myDimmer; - float fmyRed = (float)sysCfg.ws_red / newDim; - float fmyGrn = (float)sysCfg.ws_green / newDim; - float fmyBlu = (float)sysCfg.ws_blue / newDim; - dcolor.R = (uint8_t)fmyRed; - dcolor.G = (uint8_t)fmyGrn; - dcolor.B = (uint8_t)fmyBlu; -} -void ws2812_setColor(uint16_t led, char* colstr) -{ - HtmlColor hcolor; - char log[LOGSZ]; - char lcolstr[8]; - - snprintf_P(lcolstr, sizeof(lcolstr), PSTR("#%s"), colstr); - uint8_t result = hcolor.Parse((char *)lcolstr, 7); - if (result) { - if (led) { - strip->SetPixelColor(led -1, RgbColor(hcolor)); // Led 1 is strip Led 0 -> substract offset 1 - strip->Show(); - } else { - dcolor = RgbColor(hcolor); - -// snprintf_P(log, sizeof(log), PSTR("DBG: Red %02X, Green %02X, Blue %02X"), dcolor.R, dcolor.G, dcolor.B); -// addLog(LOG_LEVEL_DEBUG, log); - - uint16_t temp = dcolor.R; - if (temp < dcolor.G) { - temp = dcolor.G; - } - if (temp < dcolor.B) { - temp = dcolor.B; - } - float mDim = (float)temp / 2.55; - sysCfg.ws_dimmer = (uint8_t)mDim; - - float newDim = 100 / mDim; - float fmyRed = (float)dcolor.R * newDim; - float fmyGrn = (float)dcolor.G * newDim; - float fmyBlu = (float)dcolor.B * newDim; - sysCfg.ws_red = (uint8_t)fmyRed; - sysCfg.ws_green = (uint8_t)fmyGrn; - sysCfg.ws_blue = (uint8_t)fmyBlu; - - lany = 1; - } - } -} +uint8_t speedValues[9] = { + 0, // None + 1 * (STATES / 10), // Fastest + 3 * (STATES / 10), + 5 * (STATES / 10), // Fast + 7 * (STATES / 10), + 9 * (STATES / 10), + 11 * (STATES / 10), // Slow + 13 * (STATES / 10), + 15 * (STATES / 10) }; // Slowest -void ws2812_getColor(uint16_t led, char* svalue, uint16_t ssvalue) -{ - RgbColor mcolor; - char stemp[20]; +uint8_t ws2812_showNext = 1; - if (led) { - mcolor = strip->GetPixelColor(led -1); - snprintf_P(stemp, sizeof(stemp), PSTR(D_CMND_LED "%d"), led); - } else { - ws2812_setDim(sysCfg.ws_dimmer); - mcolor = dcolor; - snprintf_P(stemp, sizeof(stemp), PSTR(D_CMND_COLOR)); - } - uint32_t color = (uint32_t)mcolor.R << 16; - color += (uint32_t)mcolor.G << 8; - color += (uint32_t)mcolor.B; - snprintf_P(svalue, ssvalue, PSTR("{\"%s\":\"%06X\"}"), stemp, color); -} +/********************************************************************************************/ void ws2812_stripShow() { RgbColor c; - if (sysCfg.ws_ledtable) { - for (uint16_t i = 0; i < sysCfg.ws_pixels; i++) { + if (sysCfg.led_table) { + for (uint16_t i = 0; i < sysCfg.led_pixels; i++) { c = strip->GetPixelColor(i); strip->SetPixelColor(i, RgbColor(ledTable[c.R], ledTable[c.G], ledTable[c.B])); } @@ -177,17 +104,6 @@ void ws2812_stripShow() strip->Show(); } -void ws2812_resetWakupState() -{ - wakeupDimmer = 0; - wakeupCntr = 0; -} - -void ws2812_resetStripTimer() -{ - stripTimerCntr = 0; -} - int mod(int a, int b) { int ret = a % b; @@ -202,7 +118,7 @@ void ws2812_clock() RgbColor c; strip->ClearTo(0); // Reset strip - float newDim = 100 / (float)sysCfg.ws_dimmer; + float newDim = 100 / (float)sysCfg.led_dimmer[0]; float f1 = 255 / newDim; uint8_t i1 = (uint8_t)f1; float f2 = 127 / newDim; @@ -210,7 +126,7 @@ void ws2812_clock() float f3 = 63 / newDim; uint8_t i3 = (uint8_t)f3; - int j = sysCfg.ws_pixels; + int j = sysCfg.led_pixels; int clksize = 600 / j; int i = (rtcTime.Second * 10) / clksize; @@ -228,13 +144,13 @@ void ws2812_clock() ws2812_stripShow(); } -void ws2812_gradientColor(struct wsColor* mColor, uint16_t range, uint16_t gradRange, uint16_t i) +void ws2812_gradientColor(uint8_t schemenr, struct wsColor* mColor, uint16_t range, uint16_t gradRange, uint16_t i) { /* * Compute the color of a pixel at position i using a gradient of the color scheme. * This function is used internally by the gradient function. */ - ColorScheme scheme = schemes[sysCfg.ws_scheme -3]; + ColorScheme scheme = schemes[schemenr]; uint16_t curRange = i / range; uint16_t rangeIndex = i % range; uint16_t colorIndex = rangeIndex / gradRange; @@ -244,7 +160,7 @@ void ws2812_gradientColor(struct wsColor* mColor, uint16_t range, uint16_t gradR start = (scheme.count -1) - start; end = (scheme.count -1) - end; } - float newDim = 100 / (float)sysCfg.ws_dimmer; + float newDim = 100 / (float)sysCfg.led_dimmer[0]; float fmyRed = (float)map(rangeIndex % gradRange, 0, gradRange, scheme.colors[start].red, scheme.colors[end].red) / newDim; float fmyGrn = (float)map(rangeIndex % gradRange, 0, gradRange, scheme.colors[start].green, scheme.colors[end].green) / newDim; float fmyBlu = (float)map(rangeIndex % gradRange, 0, gradRange, scheme.colors[start].blue, scheme.colors[end].blue) / newDim; @@ -253,7 +169,7 @@ void ws2812_gradientColor(struct wsColor* mColor, uint16_t range, uint16_t gradR mColor->blue = (uint8_t)fmyBlu; } -void ws2812_gradient() +void ws2812_gradient(uint8_t schemenr) { /* * This routine courtesy Tony DiCola (Adafruit) @@ -262,28 +178,28 @@ void ws2812_gradient() */ RgbColor c; - ColorScheme scheme = schemes[sysCfg.ws_scheme -3]; + ColorScheme scheme = schemes[schemenr]; if (scheme.count < 2) { return; } - uint8_t repeat = repeatValues[sysCfg.ws_width]; // number of scheme.count per ledcount - uint16_t range = (uint16_t)ceil((float)sysCfg.ws_pixels / (float)repeat); + uint8_t repeat = repeatValues[sysCfg.led_width]; // number of scheme.count per ledcount + uint16_t range = (uint16_t)ceil((float)sysCfg.led_pixels / (float)repeat); uint16_t gradRange = (uint16_t)ceil((float)range / (float)(scheme.count - 1)); - uint16_t offset = speedValues[sysCfg.ws_speed] > 0 ? stripTimerCntr / speedValues[sysCfg.ws_speed] : 0; + uint16_t offset = speedValues[sysCfg.led_speed] > 0 ? stripTimerCntr / speedValues[sysCfg.led_speed] : 0; wsColor oldColor, currentColor; - ws2812_gradientColor(&oldColor, range, gradRange, offset); + ws2812_gradientColor(schemenr, &oldColor, range, gradRange, offset); currentColor = oldColor; - for (uint16_t i = 0; i < sysCfg.ws_pixels; i++) { - if (repeatValues[sysCfg.ws_width] > 1) { - ws2812_gradientColor(¤tColor, range, gradRange, i +offset); + for (uint16_t i = 0; i < sysCfg.led_pixels; i++) { + if (repeatValues[sysCfg.led_width] > 1) { + ws2812_gradientColor(schemenr, ¤tColor, range, gradRange, i +offset); } - if (sysCfg.ws_speed > 0) { + if (sysCfg.led_speed > 0) { // Blend old and current color based on time for smooth movement. - c.R = map(stripTimerCntr % speedValues[sysCfg.ws_speed], 0, speedValues[sysCfg.ws_speed], oldColor.red, currentColor.red); - c.G = map(stripTimerCntr % speedValues[sysCfg.ws_speed], 0, speedValues[sysCfg.ws_speed], oldColor.green, currentColor.green); - c.B = map(stripTimerCntr % speedValues[sysCfg.ws_speed], 0, speedValues[sysCfg.ws_speed], oldColor.blue, currentColor.blue); + c.R = map(stripTimerCntr % speedValues[sysCfg.led_speed], 0, speedValues[sysCfg.led_speed], oldColor.red, currentColor.red); + c.G = map(stripTimerCntr % speedValues[sysCfg.led_speed], 0, speedValues[sysCfg.led_speed], oldColor.green, currentColor.green); + c.B = map(stripTimerCntr % speedValues[sysCfg.led_speed], 0, speedValues[sysCfg.led_speed], oldColor.blue, currentColor.blue); } else { // No animation, just use the current color. @@ -297,7 +213,7 @@ void ws2812_gradient() ws2812_stripShow(); } -void ws2812_bars() +void ws2812_bars(uint8_t schemenr) { /* * This routine courtesy Tony DiCola (Adafruit) @@ -307,18 +223,18 @@ void ws2812_bars() RgbColor c; uint16_t i; - ColorScheme scheme = schemes[sysCfg.ws_scheme -3]; + ColorScheme scheme = schemes[schemenr]; - uint16_t maxSize = sysCfg.ws_pixels / scheme.count; - if (widthValues[sysCfg.ws_width] > maxSize) { + uint16_t maxSize = sysCfg.led_pixels / scheme.count; + if (widthValues[sysCfg.led_width] > maxSize) { maxSize = 0; } - uint8_t offset = speedValues[sysCfg.ws_speed] > 0 ? stripTimerCntr / speedValues[sysCfg.ws_speed] : 0; + uint8_t offset = speedValues[sysCfg.led_speed] > 0 ? stripTimerCntr / speedValues[sysCfg.led_speed] : 0; wsColor mcolor[scheme.count]; memcpy(mcolor, scheme.colors, sizeof(mcolor)); - float newDim = 100 / (float)sysCfg.ws_dimmer; + float newDim = 100 / (float)sysCfg.led_dimmer[0]; for (i = 0; i < scheme.count; i++) { float fmyRed = (float)mcolor[i].red / newDim; float fmyGrn = (float)mcolor[i].green / newDim; @@ -328,9 +244,9 @@ void ws2812_bars() mcolor[i].blue = (uint8_t)fmyBlu; } uint8_t colorIndex = offset % scheme.count; - for (i = 0; i < sysCfg.ws_pixels; i++) { + for (i = 0; i < sysCfg.led_pixels; i++) { if (maxSize) { - colorIndex = ((i + offset) % (scheme.count * widthValues[sysCfg.ws_width])) / widthValues[sysCfg.ws_width]; + colorIndex = ((i + offset) % (scheme.count * widthValues[sysCfg.led_width])) / widthValues[sysCfg.led_width]; } c.R = mcolor[colorIndex].red; c.G = mcolor[colorIndex].green; @@ -340,122 +256,12 @@ void ws2812_bars() ws2812_stripShow(); } -void ws2812_animate() -{ - char log[LOGSZ]; - uint8_t fadeValue; - - stripTimerCntr++; - if (0 == bitRead(power, ws_bit)) { // Power Off - sleep = sysCfg.sleep; - stripTimerCntr = 0; - tcolor = 0; - } - else { - sleep = 0; - switch (sysCfg.ws_scheme) { - case 0: // Power On - ws2812_setDim(sysCfg.ws_dimmer); - if (0 == sysCfg.ws_fade) { - tcolor = dcolor; - } else { - if (tcolor != dcolor) { - uint8_t ws_speed = speedValues[sysCfg.ws_speed]; - if (tcolor.R < dcolor.R) { - tcolor.R += ((dcolor.R - tcolor.R) / ws_speed) +1; - } - if (tcolor.G < dcolor.G) { - tcolor.G += ((dcolor.G - tcolor.G) / ws_speed) +1; - } - if (tcolor.B < dcolor.B) { - tcolor.B += ((dcolor.B - tcolor.B) / ws_speed) +1; - } - if (tcolor.R > dcolor.R) { - tcolor.R -= ((tcolor.R - dcolor.R) / ws_speed) +1; - } - if (tcolor.G > dcolor.G) { - tcolor.G -= ((tcolor.G - dcolor.G) / ws_speed) +1; - } - if (tcolor.B > dcolor.B) { - tcolor.B -= ((tcolor.B - dcolor.B) / ws_speed) +1; - } - } - } - break; - case 1: // Wake up light - wakeupCntr++; - if (0 == wakeupDimmer) { - tcolor = 0; - wakeupDimmer++; - } - else { - if (wakeupCntr > ((sysCfg.ws_wakeup * STATES) / sysCfg.ws_dimmer)) { - wakeupCntr = 0; - wakeupDimmer++; - if (wakeupDimmer <= sysCfg.ws_dimmer) { - ws2812_setDim(wakeupDimmer); - tcolor = dcolor; - } else { - sysCfg.ws_scheme = 0; - } - } - } - break; - case 2: // Clock - if (((STATES/10)*2 == state) || (lany != 2)) { - ws2812_clock(); - } - lany = 2; - break; - default: - if (1 == sysCfg.ws_fade) { - ws2812_gradient(); - } else { - ws2812_bars(); - } - lany = 1; - break; - } - } - - if ((sysCfg.ws_scheme <= 1) || (0 == bitRead(power, ws_bit))) { - if ((lcolor != tcolor) || lany) { - lany = 0; - lcolor = tcolor; - -// snprintf_P(log, sizeof(log), PSTR("DBG: StripPixels %d, CfgPixels %d, Red %02X, Green %02X, Blue %02X"), strip->PixelCount(), sysCfg.ws_pixels, lcolor.R, lcolor.G, lcolor.B); -// addLog(LOG_LEVEL_DEBUG, log); - - if (sysCfg.ws_ledtable) { - for (uint16_t i = 0; i < sysCfg.ws_pixels; i++) { - strip->SetPixelColor(i, RgbColor(ledTable[lcolor.R],ledTable[lcolor.G],ledTable[lcolor.B])); - } - } else { - for (uint16_t i = 0; i < sysCfg.ws_pixels; i++) { - strip->SetPixelColor(i, lcolor); - } - } - strip->Show(); - } - } -} - -void ws2812_update() -{ - lany = 1; -} - -void ws2812_pixels() -{ - strip->ClearTo(0); - strip->Show(); - tcolor = 0; - lany = 1; -} +/*********************************************************************************************\ + * Public +\*********************************************************************************************/ -void ws2812_init(uint8_t powerbit) +void ws2812_init() { - ws_bit = powerbit -1; #ifdef USE_WS2812_DMA #if (USE_WS2812_CTYPE == 1) strip = new NeoPixelBus(WS2812_MAX_LEDS); // For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use. @@ -470,161 +276,67 @@ void ws2812_init(uint8_t powerbit) #endif // USE_WS2812_CTYPE #endif // USE_WS2812_DMA strip->Begin(); - ws2812_pixels(); + ws2812_clear(); } -/*********************************************************************************************\ - * Hue support -\*********************************************************************************************/ - -void ws2812_replaceHSB(String *response) +void ws2812_clear() { - ws2812_setDim(sysCfg.ws_dimmer); - HsbColor hsb = HsbColor(dcolor); - response->replace("{h}", String((uint16_t)(65535.0f * hsb.H))); - response->replace("{s}", String((uint8_t)(254.0f * hsb.S))); - response->replace("{b}", String((uint8_t)(254.0f * hsb.B))); + strip->ClearTo(0); + strip->Show(); + ws2812_showNext = 1; } -void ws2812_getHSB(float *hue, float *sat, float *bri) +void ws2812_setColor(uint16_t led, uint8_t red, uint8_t green, uint8_t blue) { - ws2812_setDim(sysCfg.ws_dimmer); - HsbColor hsb = HsbColor(dcolor); - *hue = hsb.H; - *sat = hsb.S; - *bri = hsb.B; + RgbColor lcolor; + lcolor.R = red; + lcolor.G = green; + lcolor.B = blue; + if (led) { + strip->SetPixelColor(led -1, lcolor); // Led 1 is strip Led 0 -> substract offset 1 + } else { +// strip->ClearTo(lcolor); // Set WS2812_MAX_LEDS pixels + for (uint16_t i = 0; i < sysCfg.led_pixels; i++) { + strip->SetPixelColor(i, lcolor); + } + } + strip->Show(); + ws2812_showNext = 1; } -void ws2812_setHSB(float hue, float sat, float bri) +char* ws2812_getColor(uint16_t led, char* scolor) { - char rgb[7]; - - HsbColor hsb; - hsb.H = hue; - hsb.S = sat; - hsb.B = bri; - RgbColor tmp = RgbColor(hsb); - sprintf(rgb,"%02X%02X%02X", tmp.R, tmp.G, tmp.B); - ws2812_setColor(0,rgb); + uint8_t sl_ledcolor[3]; + + RgbColor lcolor = strip->GetPixelColor(led -1); + sl_ledcolor[0] = lcolor.R; + sl_ledcolor[1] = lcolor.G; + sl_ledcolor[2] = lcolor.B; + scolor[0] = '\0'; + for (byte i = 0; i < 3; i++) { + snprintf_P(scolor, 11, PSTR("%s%02X"), scolor, sl_ledcolor[i]); + } + return scolor; } -/*********************************************************************************************\ - * Commands -\*********************************************************************************************/ - -boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue) +void ws2812_showScheme(uint8_t scheme) { - boolean serviced = true; - - if (!strcasecmp_P(type, PSTR(D_CMND_PIXELS))) { - if ((payload > 0) && (payload <= WS2812_MAX_LEDS)) { - sysCfg.ws_pixels = payload; - ws2812_pixels(); - } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_PIXELS "\":%d}"), sysCfg.ws_pixels); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_LED)) && (index > 0) && (index <= sysCfg.ws_pixels)) { - if (6 == data_len) { - ws2812_setColor(index, dataBuf); - } - ws2812_getColor(index, svalue, ssvalue); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_COLOR))) { - if (dataBuf[0] == '#') { - dataBuf++; - data_len--; - } - if (6 == data_len) { - ws2812_setColor(0, dataBuf); - bitSet(power, ws_bit); - } - ws2812_getColor(0, svalue, ssvalue); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_DIMMER))) { - if ((payload >= 0) && (payload <= 100)) { - sysCfg.ws_dimmer = payload; - bitSet(power, ws_bit); -#ifdef USE_DOMOTICZ -// mqtt_publishDomoticzPowerState(index); - mqtt_publishDomoticzPowerState(ws_bit +1); -#endif // USE_DOMOTICZ - } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DIMMER "\":%d}"), sysCfg.ws_dimmer); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_LEDTABLE))) { - if ((payload >= 0) && (payload <= 2)) { - switch (payload) { - case 0: // Off - case 1: // On - sysCfg.ws_ledtable = payload; - break; - case 2: // Toggle - sysCfg.ws_ledtable ^= 1; - break; + switch (scheme) { + case 0: // Clock + if (((STATES/10)*2 == state) || (ws2812_showNext)) { + ws2812_clock(); + ws2812_showNext = 0; } - ws2812_update(); - } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_LEDTABLE "\":\"%s\"}"), getStateText(sysCfg.ws_ledtable)); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_FADE))) { - switch (payload) { - case 0: // Off - case 1: // On - sysCfg.ws_fade = payload; - break; - case 2: // Toggle - sysCfg.ws_fade ^= 1; break; - } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_FADE "\":\"%s\"}"), getStateText(sysCfg.ws_fade)); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_SPEED))) { // 1 - fast, 5 - slow - if ((payload > 0) && (payload <= 5)) { - sysCfg.ws_speed = payload; - } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SPEED "\":%d}"), sysCfg.ws_speed); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_WIDTH))) { - if ((payload >= 0) && (payload <= 4)) { - sysCfg.ws_width = payload; - } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_WIDTH "\":%d}"), sysCfg.ws_width); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_WAKEUP))) { - if ((payload > 0) && (payload < 3001)) { - sysCfg.ws_wakeup = payload; - if (1 == sysCfg.ws_scheme) { - sysCfg.ws_scheme = 0; - } - } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_WAKEUP "\":%d}"), sysCfg.ws_wakeup); - } - else if (!strcasecmp_P(type, PSTR(D_CMND_SCHEME))) { - if ((payload >= 0) && (payload <= 9)) { - sysCfg.ws_scheme = payload; - if (1 == sysCfg.ws_scheme) { - ws2812_resetWakupState(); + default: + if (1 == sysCfg.led_fade) { + ws2812_gradient(scheme -1); + } else { + ws2812_bars(scheme -1); } - bitSet(power, ws_bit); - ws2812_resetStripTimer(); - } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SCHEME "\":%d}"), sysCfg.ws_scheme); - } - else if (!strcasecmp_P(type, PSTR("UNDOCA"))) { // Theos legacy status - RgbColor mcolor; - ws2812_setDim(sysCfg.ws_dimmer); - mcolor = dcolor; - uint32_t color = (uint32_t)mcolor.R << 16; - color += (uint32_t)mcolor.G << 8; - color += (uint32_t)mcolor.B; - snprintf_P(svalue, ssvalue, PSTR("%06X, %d, %d, %d, %d, %d"), - color, sysCfg.ws_fade, sysCfg.ws_ledtable, sysCfg.ws_scheme, sysCfg.ws_speed, sysCfg.ws_width); - mqtt_publish_topic_P(1, type, svalue); - svalue[0] = '\0'; - } - else { - serviced = false; // Unknown command + ws2812_showNext = 1; + break; } - return serviced; } + #endif // USE_WS2812 diff --git a/sonoff/xsns_bh1750.ino b/sonoff/xsns_bh1750.ino index ded769ef4241..e0a96ca61204 100644 --- a/sonoff/xsns_bh1750.ino +++ b/sonoff/xsns_bh1750.ino @@ -47,7 +47,6 @@ boolean bh1750_detect() return true; } - char log[LOGSZ]; uint8_t status; boolean success = false; @@ -67,8 +66,8 @@ boolean bh1750_detect() strcpy_P(bh1750stype, PSTR("BH1750")); } if (success) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), bh1750stype, bh1750addr); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), bh1750stype, bh1750addr); + addLog(LOG_LEVEL_DEBUG); } else { bh1750type = 0; } @@ -79,14 +78,14 @@ boolean bh1750_detect() * Presentation \*********************************************************************************************/ -void bh1750_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void bh1750_mqttPresent(uint8_t* djson) { if (!bh1750type) { return; } uint16_t l = bh1750_readLux(); - snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"" D_ILLUMINANCE "\":%d}"), svalue, bh1750stype, l); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_ILLUMINANCE "\":%d}"), mqtt_data, bh1750stype, l); *djson = 1; #ifdef USE_DOMOTICZ domoticz_sensor5(l); diff --git a/sonoff/xsns_bmp.ino b/sonoff/xsns_bmp.ino index 34ebd6e71f3d..0d5f2830d471 100644 --- a/sonoff/xsns_bmp.ino +++ b/sonoff/xsns_bmp.ino @@ -394,7 +394,6 @@ boolean bmp_detect() return true; } - char log[LOGSZ]; boolean success = false; bmpaddr = BMP_ADDR; @@ -418,8 +417,8 @@ boolean bmp_detect() strcpy_P(bmpstype, PSTR("BME280")); } if (success) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), bmpstype, bmpaddr); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), bmpstype, bmpaddr); + addLog(LOG_LEVEL_DEBUG); } else { bmptype = 0; } @@ -430,7 +429,7 @@ boolean bmp_detect() * Presentation \*********************************************************************************************/ -void bmp_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void bmp_mqttPresent(uint8_t* djson) { if (!bmptype) { return; @@ -447,11 +446,11 @@ void bmp_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) dtostrfd(p, sysCfg.flag.pressure_resolution, stemp2); dtostrfd(h, sysCfg.flag.humidity_resolution, stemp3); if (!strcmp(bmpstype,"BME280")) { - snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_PRESSURE "\":%s}"), - svalue, bmpstype, stemp1, stemp3, stemp2); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_PRESSURE "\":%s}"), + mqtt_data, bmpstype, stemp1, stemp3, stemp2); } else { - snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_PRESSURE "\":%s}"), - svalue, bmpstype, stemp1, stemp2); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_PRESSURE "\":%s}"), + mqtt_data, bmpstype, stemp1, stemp2); } *djson = 1; #ifdef USE_DOMOTICZ diff --git a/sonoff/xsns_counter.ino b/sonoff/xsns_counter.ino index b9377a31a4f5..54e51c9179cd 100644 --- a/sonoff/xsns_counter.ino +++ b/sonoff/xsns_counter.ino @@ -25,8 +25,6 @@ unsigned long pTimeLast[MAX_COUNTERS]; // Last counter time in milli seconds void counter_update(byte index) { -// char log[LOGSZ]; - unsigned long pTime = millis() - pTimeLast[index -1]; if (pTime > sysCfg.pCounterDebounce) { pTimeLast[index -1] = millis(); @@ -36,8 +34,8 @@ void counter_update(byte index) rtcMem.pCounter[index -1]++; } -// snprintf_P(log, sizeof(log), PSTR("CNTR: Interrupt %d"), index); -// addLog(LOG_LEVEL_DEBUG, log); +// snprintf_P(log_data, sizeof(log_data), PSTR("CNTR: Interrupt %d"), index); +// addLog(LOG_LEVEL_DEBUG); } } @@ -87,7 +85,7 @@ void counter_init() * Presentation \*********************************************************************************************/ -void counter_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void counter_mqttPresent(uint8_t* djson) { char stemp[16]; @@ -100,7 +98,7 @@ void counter_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) dsxflg++; dtostrfd(rtcMem.pCounter[i], 0, stemp); } - snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_COUNTER "%d\":%s"), svalue, i +1, stemp); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_COUNTER "%d\":%s"), mqtt_data, i +1, stemp); *djson = 1; #ifdef USE_DOMOTICZ if (1 == dsxflg) { diff --git a/sonoff/xsns_dht.ino b/sonoff/xsns_dht.ino index 85d5a19ca7ed..e051a54252e0 100644 --- a/sonoff/xsns_dht.ino +++ b/sonoff/xsns_dht.ino @@ -38,7 +38,7 @@ struct DHTSTRUCT { byte type; char stype[10]; uint32_t lastreadtime; - bool lastresult; + uint16_t lastresult; float t; float h = 0; } dht[DHT_MAX_SENSORS]; @@ -62,14 +62,13 @@ uint32_t dht_expectPulse(byte sensor, bool level) return count; } -boolean dht_read(byte sensor) +void dht_read(byte sensor) { - char log[LOGSZ]; uint32_t cycles[80]; uint32_t currenttime = millis(); if ((currenttime - dht[sensor].lastreadtime) < 2000) { - return dht[sensor].lastresult; + return; } dht[sensor].lastreadtime = currenttime; @@ -89,13 +88,13 @@ boolean dht_read(byte sensor) delayMicroseconds(10); if (0 == dht_expectPulse(sensor, LOW)) { addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_LOW " " D_PULSE)); - dht[sensor].lastresult = false; - return dht[sensor].lastresult; + dht[sensor].lastresult++; + return; } if (0 == dht_expectPulse(sensor, HIGH)) { addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_HIGH " " D_PULSE)); - dht[sensor].lastresult = false; - return dht[sensor].lastresult; + dht[sensor].lastresult++; + return; } for (int i = 0; i < 80; i += 2) { cycles[i] = dht_expectPulse(sensor, LOW); @@ -108,8 +107,8 @@ boolean dht_read(byte sensor) uint32_t highCycles = cycles[2*i+1]; if ((0 == lowCycles) || (0 == highCycles)) { addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_PULSE)); - dht[sensor].lastresult = false; - return dht[sensor].lastresult; + dht[sensor].lastresult++; + return; } dht_data[i/8] <<= 1; if (highCycles > lowCycles) { @@ -117,17 +116,16 @@ boolean dht_read(byte sensor) } } - snprintf_P(log, sizeof(log), PSTR(D_LOG_DHT D_RECEIVED " %02X, %02X, %02X, %02X, %02X =? %02X"), + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DHT D_RECEIVED " %02X, %02X, %02X, %02X, %02X =? %02X"), dht_data[0], dht_data[1], dht_data[2], dht_data[3], dht_data[4], (dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF); - addLog(LOG_LEVEL_DEBUG, log); + addLog(LOG_LEVEL_DEBUG); if (dht_data[4] == ((dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF)) { - dht[sensor].lastresult = true; + dht[sensor].lastresult = 0; } else { addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_CHECKSUM_FAILURE)); - dht[sensor].lastresult = false; + dht[sensor].lastresult++; } - return dht[sensor].lastresult; } boolean dht_readTempHum(byte sensor, float &t, float &h) @@ -136,11 +134,16 @@ boolean dht_readTempHum(byte sensor, float &t, float &h) t = NAN; h = NAN; } else { + if (dht[sensor].lastresult > 8) { // Reset after 8 misses + dht[sensor].t = NAN; + dht[sensor].h = NAN; + } t = dht[sensor].t; h = dht[sensor].h; } - if (dht_read(sensor)) { + dht_read(sensor); + if (!dht[sensor].lastresult) { switch (dht[sensor].type) { case GPIO_DHT11: h = dht_data[0]; @@ -187,13 +190,12 @@ boolean dht_setup(byte pin, byte type) void dht_init() { - char log[LOGSZ]; - dht_maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for reading pulses from DHT sensor. for (byte i = 0; i < dht_sensors; i++) { pinMode(dht[i].pin, INPUT_PULLUP); - dht[i].lastreadtime = -MIN_INTERVAL; + dht[i].lastreadtime = 0; + dht[i].lastresult = 0; switch (dht[i].type) { case GPIO_DHT11: strcpy_P(dht[i].stype, PSTR("DHT11")); @@ -214,7 +216,7 @@ void dht_init() * Presentation \*********************************************************************************************/ -void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void dht_mqttPresent(uint8_t* djson) { char stemp1[10]; char stemp2[10]; @@ -226,7 +228,7 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) if (dht_readTempHum(i, t, h)) { // Read temperature dtostrfd(t, sysCfg.flag.temperature_resolution, stemp1); dtostrfd(h, sysCfg.flag.humidity_resolution, stemp2); - snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, dht[i].stype, stemp1, stemp2); + snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, dht[i].stype, stemp1, stemp2); *djson = 1; #ifdef USE_DOMOTICZ if (!dsxflg) { diff --git a/sonoff/xsns_ds18b20.ino b/sonoff/xsns_ds18b20.ino index a27860eb1c9a..5940dfdbd147 100644 --- a/sonoff/xsns_ds18b20.ino +++ b/sonoff/xsns_ds18b20.ino @@ -25,6 +25,7 @@ \*********************************************************************************************/ float dsb_mt = 0; +uint16_t dsb_lastresult = 0; uint8_t dsb_reset() { @@ -131,6 +132,10 @@ boolean dsb_readTemp(float &t) if (!dsb_mt) { t = NAN; } else { + dsb_lastresult++; + if (dsb_lastresult > 8) { // Reset after 8 misses + dsb_mt = NAN; + } t = dsb_mt; } @@ -168,8 +173,11 @@ boolean dsb_readTemp(float &t) sign = -1; } t = convertTemp((float)sign * DSTemp * 0.0625); + dsb_lastresult = 0; + } + if (!isnan(t)) { + dsb_mt = t; } - if (!isnan(t)) dsb_mt = t; return !isnan(t); } @@ -177,14 +185,14 @@ boolean dsb_readTemp(float &t) * Presentation \*********************************************************************************************/ -void dsb_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void dsb_mqttPresent(uint8_t* djson) { char stemp1[10]; float t; if (dsb_readTemp(t)) { // Check if read failed dtostrfd(t, sysCfg.flag.temperature_resolution, stemp1); - snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18B20\":{\"" D_TEMPERATURE "\":%s}"), svalue, stemp1); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18B20\":{\"" D_TEMPERATURE "\":%s}"), mqtt_data, stemp1); *djson = 1; #ifdef USE_DOMOTICZ domoticz_sensor1(stemp1); diff --git a/sonoff/xsns_ds18x20.ino b/sonoff/xsns_ds18x20.ino index e30c2d4d86f7..3e20ecef34cb 100644 --- a/sonoff/xsns_ds18x20.ino +++ b/sonoff/xsns_ds18x20.ino @@ -180,7 +180,7 @@ void ds18x20_type(uint8_t sensor) } } -void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void ds18x20_mqttPresent(uint8_t* djson) { char stemp1[10]; char stemp2[10]; @@ -192,13 +192,13 @@ void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) ds18x20_type(i); dtostrfd(t, sysCfg.flag.temperature_resolution, stemp2); if (!dsxflg) { - snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18x20\":{"), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18x20\":{"), mqtt_data); *djson = 1; stemp1[0] = '\0'; } dsxflg++; - snprintf_P(svalue, ssvalue, PSTR("%s%s\"DS%d\":{\"" D_TYPE "\":\"%s\", \"" D_ADDRESS "\":\"%s\", \"" D_TEMPERATURE "\":%s}"), - svalue, stemp1, i +1, dsbstype, ds18x20_address(i).c_str(), stemp2); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"DS%d\":{\"" D_TYPE "\":\"%s\", \"" D_ADDRESS "\":\"%s\", \"" D_TEMPERATURE "\":%s}"), + mqtt_data, stemp1, i +1, dsbstype, ds18x20_address(i).c_str(), stemp2); strcpy(stemp1, ", "); #ifdef USE_DOMOTICZ if (1 == dsxflg) domoticz_sensor1(stemp2); @@ -206,7 +206,7 @@ void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) } } if (dsxflg) { - snprintf_P(svalue, ssvalue, PSTR("%s}"), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } } diff --git a/sonoff/xsns_hlw8012.ino b/sonoff/xsns_hlw8012.ino index 9e25c8a5a2fc..cf3f494e604a 100644 --- a/sonoff/xsns_hlw8012.ino +++ b/sonoff/xsns_hlw8012.ino @@ -194,9 +194,8 @@ void hlw_readEnergy(byte option, float &et, float &ed, float &e, float &w, float uint16_t hlw_period; uint16_t hlw_interval; -//char log[LOGSZ]; -//snprintf_P(log, sizeof(log), PSTR("HLW: CF %d, CF1U %d (%d), CF1I %d (%d)"), hlw_cf_plen, hlw_cf1u_plen, hlw_cf1u_pcntmax, hlw_cf1i_plen, hlw_cf1i_pcntmax); -//addLog(LOG_LEVEL_DEBUG, log); +//snprintf_P(log_data, sizeof(log_data), PSTR("HLW: CF %d, CF1U %d (%d), CF1I %d (%d)"), hlw_cf_plen, hlw_cf1u_plen, hlw_cf1u_pcntmax, hlw_cf1i_plen, hlw_cf1i_pcntmax); +//addLog(LOG_LEVEL_DEBUG); et = (float)(rtcMem.hlw_kWhtotal + (cur_kWhtoday / 1000)) / 100000; ed = 0; @@ -312,8 +311,6 @@ void hlw_setPowerSteadyCounter(byte value) void hlw_margin_chk() { - char log[LOGSZ]; - char svalue[200]; // was MESSZ float pet; float ped; float pe; @@ -339,38 +336,38 @@ void hlw_margin_chk() puv = (uint16_t)(pu); piv = (uint16_t)(pi * 1000); -// snprintf_P(log, sizeof(log), PSTR("HLW: W %d, U %d, I %d"), pw, pu, piv); -// addLog(LOG_LEVEL_DEBUG, log); +// snprintf_P(log_data, sizeof(log_data), PSTR("HLW: W %d, U %d, I %d"), pw, pu, piv); +// addLog(LOG_LEVEL_DEBUG); - snprintf_P(svalue, sizeof(svalue), PSTR("{")); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{")); jsonflg = 0; if (hlw_margin(0, sysCfg.hlw_pmin, pwv, flag, hlw_pminflg)) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_POWERLOW "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_POWERLOW "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", getStateText(flag)); jsonflg = 1; } if (hlw_margin(1, sysCfg.hlw_pmax, pwv, flag, hlw_pmaxflg)) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_POWERHIGH "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_POWERHIGH "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", getStateText(flag)); jsonflg = 1; } if (hlw_margin(0, sysCfg.hlw_umin, puv, flag, hlw_uminflg)) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_VOLTAGELOW "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_VOLTAGELOW "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", getStateText(flag)); jsonflg = 1; } if (hlw_margin(1, sysCfg.hlw_umax, puv, flag, hlw_umaxflg)) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_VOLTAGEHIGH "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_VOLTAGEHIGH "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", getStateText(flag)); jsonflg = 1; } if (hlw_margin(0, sysCfg.hlw_imin, piv, flag, hlw_iminflg)) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_CURRENTLOW "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_CURRENTLOW "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", getStateText(flag)); jsonflg = 1; } if (hlw_margin(1, sysCfg.hlw_imax, piv, flag, hlw_imaxflg)) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_CURRENTHIGH "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_CURRENTHIGH "\":\"%s\""), mqtt_data, (jsonflg)?", ":"", getStateText(flag)); jsonflg = 1; } if (jsonflg) { - snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue); - mqtt_publish_topic_P(2, PSTR(D_RSLT_MARGINS), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + mqtt_publish_topic_P(2, PSTR(D_RSLT_MARGINS)); hlw_mqttPresent(0); } } @@ -384,8 +381,8 @@ void hlw_margin_chk() } else { hlw_mplh_counter--; if (!hlw_mplh_counter) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_MAXPOWERREACHED "\":\"%d%s\"}"), pwv, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); - mqtt_publish_topic_P(1, S_RSLT_WARNING, svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_MAXPOWERREACHED "\":\"%d%s\"}"), pwv, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); + mqtt_publish_topic_P(1, S_RSLT_WARNING); hlw_mqttPresent(0); do_cmnd_power(1, 0); if (!hlw_mplr_counter) { @@ -407,12 +404,12 @@ void hlw_margin_chk() if (hlw_mplr_counter) { hlw_mplr_counter--; if (hlw_mplr_counter) { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_POWERMONITOR "\":\"%s\"}"), getStateText(1)); - mqtt_publish_topic_P(5, PSTR(D_POWERMONITOR), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_POWERMONITOR "\":\"%s\"}"), getStateText(1)); + mqtt_publish_topic_P(5, PSTR(D_POWERMONITOR)); do_cmnd_power(1, 1); } else { - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_MAXPOWERREACHEDRETRY "\":\"%s\"}"), getStateText(0)); - mqtt_publish_topic_P(1, S_RSLT_WARNING, svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_MAXPOWERREACHEDRETRY "\":\"%s\"}"), getStateText(0)); + mqtt_publish_topic_P(1, S_RSLT_WARNING); hlw_mqttPresent(0); } } @@ -425,15 +422,15 @@ void hlw_margin_chk() uped = (uint16_t)(ped * 1000); if (!hlw_mkwh_state && (rtcTime.Hour == sysCfg.hlw_mkwhs)) { hlw_mkwh_state = 1; - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_ENERGYMONITOR "\":\"%s\"}"), getStateText(1)); - mqtt_publish_topic_P(5, PSTR(D_ENERGYMONITOR), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_ENERGYMONITOR "\":\"%s\"}"), getStateText(1)); + mqtt_publish_topic_P(5, PSTR(D_ENERGYMONITOR)); do_cmnd_power(1, 1); } else if ((1 == hlw_mkwh_state) && (uped >= sysCfg.hlw_mkwh)) { hlw_mkwh_state = 2; - dtostrfd(ped, 3, svalue); - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_MAXENERGYREACHED "\":\"%s%s\"}"), svalue, (sysCfg.flag.value_units) ? " " D_UNIT_KILOWATTHOUR : ""); - mqtt_publish_topic_P(1, S_RSLT_WARNING, svalue); + dtostrfd(ped, 3, mqtt_data); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_MAXENERGYREACHED "\":\"%s%s\"}"), mqtt_data, (sysCfg.flag.value_units) ? " " D_UNIT_KILOWATTHOUR : ""); + mqtt_publish_topic_P(1, S_RSLT_WARNING); hlw_mqttPresent(0); do_cmnd_power(1, 0); } @@ -445,7 +442,7 @@ void hlw_margin_chk() * Commands \*********************************************************************************************/ -boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue) +boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload) { boolean serviced = true; uint8_t caltext = 0; @@ -454,37 +451,37 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_pmin = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_POWERLOW "\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_POWERLOW "\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_POWERHIGH))) { if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_pmax = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_POWERHIGH "\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_POWERHIGH "\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_VOLTAGELOW))) { if ((payload >= 0) && (payload < 501)) { sysCfg.hlw_umin = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_VOLTAGELOW "\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.flag.value_units) ? " " D_UNIT_VOLT : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_VOLTAGELOW "\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.flag.value_units) ? " " D_UNIT_VOLT : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_VOLTAGEHIGH))) { if ((payload >= 0) && (payload < 501)) { sysCfg.hlw_umax = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_VOLTAGEHIGH "\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.flag.value_units) ? " " D_UNIT_VOLT : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_VOLTAGEHIGH "\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.flag.value_units) ? " " D_UNIT_VOLT : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_CURRENTLOW))) { if ((payload >= 0) && (payload < 16001)) { sysCfg.hlw_imin = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_CURRENTLOW "\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.flag.value_units) ? " " D_UNIT_MILLIAMPERE : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_CURRENTLOW "\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.flag.value_units) ? " " D_UNIT_MILLIAMPERE : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_CURRENTHIGH))) { if ((payload >= 0) && (payload < 16001)) { sysCfg.hlw_imax = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_CURRENTHIGH "\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.flag.value_units) ? " " D_UNIT_MILLIAMPERE : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_CURRENTHIGH "\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.flag.value_units) ? " " D_UNIT_MILLIAMPERE : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_ENERGYRESET))) { if ((payload >= 1) && (payload <= 3)) { @@ -509,7 +506,7 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len dtostrfd((float)sysCfg.hlw_kWhyesterday / 100000000, sysCfg.flag.energy_resolution, sey); dtostrfd((float)rtcMem.hlw_kWhtoday / 100000000, sysCfg.flag.energy_resolution, sen); dtostrfd((float)(rtcMem.hlw_kWhtotal + (hlw_kWhtoday / 1000)) / 100000, sysCfg.flag.energy_resolution, set); - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_ENERGYRESET "\":{\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s}}"), set, sey, sen); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_ENERGYRESET "\":{\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s}}"), set, sey, sen); } else if (!strcasecmp_P(type, PSTR(D_CMND_HLWPCAL))) { if ((payload > 0) && (payload < 32001)) { @@ -552,50 +549,50 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mpl = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXPOWER "\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MAXPOWER "\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_MAXPOWERHOLD))) { if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mplh = (1 == payload) ? MAX_POWER_HOLD : payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXPOWERHOLD "\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MAXPOWERHOLD "\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_MAXPOWERWINDOW))) { if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mplw = (1 == payload) ? MAX_POWER_WINDOW : payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXPOWERWINDOW "\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MAXPOWERWINDOW "\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_SAFEPOWER))) { if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mspl = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SAFEPOWER "\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SAFEPOWER "\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_SAFEPOWERHOLD))) { if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_msplh = (1 == payload) ? SAFE_POWER_HOLD : payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SAFEPOWERHOLD "\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SAFEPOWERHOLD "\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_SAFEPOWERWINDOW))) { if ((payload >= 0) && (payload < 1440)) { sysCfg.hlw_msplw = (1 == payload) ? SAFE_POWER_WINDOW : payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SAFEPOWERWINDOW "\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.flag.value_units) ? " " D_UNIT_MINUTE : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SAFEPOWERWINDOW "\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.flag.value_units) ? " " D_UNIT_MINUTE : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_MAXENERGY))) { if ((payload >= 0) && (payload < 3601)) { sysCfg.hlw_mkwh = payload; hlw_mkwh_state = 3; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXENERGY "\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.flag.value_units) ? " " D_UNIT_WATTHOUR : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MAXENERGY "\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.flag.value_units) ? " " D_UNIT_WATTHOUR : ""); } else if (!strcasecmp_P(type, PSTR(D_CMND_MAXENERGYSTART))) { if ((payload >= 0) && (payload < 24)) { sysCfg.hlw_mkwhs = payload; } - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXENERGYSTART "\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.flag.value_units) ? " " D_UNIT_HOUR : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_MAXENERGYSTART "\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.flag.value_units) ? " " D_UNIT_HOUR : ""); } #endif // FEATURE_POWER_LIMIT else { @@ -603,13 +600,13 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len } switch (caltext) { case 1: - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_HLWPCAL "\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.flag.value_units) ? " " D_UNIT_MICROSECOND : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_HLWPCAL "\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.flag.value_units) ? " " D_UNIT_MICROSECOND : ""); break; case 2: - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_HLWUCAL "\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.flag.value_units) ? " " D_UNIT_MICROSECOND : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_HLWUCAL "\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.flag.value_units) ? " " D_UNIT_MICROSECOND : ""); break; case 3: - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_HLWICAL "\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.flag.value_units) ? " " D_UNIT_MICROSECOND : ""); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_HLWICAL "\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.flag.value_units) ? " " D_UNIT_MICROSECOND : ""); break; } return serviced; @@ -619,7 +616,7 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len * Presentation \*********************************************************************************************/ -void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue) +void hlw_mqttStat(byte option) { /* option 0 = do not show period energy usage * option 1 = show period energy usage @@ -651,8 +648,8 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue) dtostrfd(pc, 2, spc); dtostrfd((float)sysCfg.hlw_kWhyesterday / 100000000, sysCfg.flag.energy_resolution, sey); snprintf_P(speriod, sizeof(speriod), PSTR(", \"" D_PERIOD "\":%s"), spe); - snprintf_P(svalue, ssvalue, PSTR("%s\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s%s, \"" D_POWERUSAGE "\":%s, \"" D_POWERFACTOR "\":%s, \"" D_VOLTAGE "\":%s, \"" D_CURRENT "\":%s}"), - svalue, spet, sey, sped, (option) ? speriod : "", spw, spc, spu, spi); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s%s, \"" D_POWERUSAGE "\":%s, \"" D_POWERFACTOR "\":%s, \"" D_VOLTAGE "\":%s, \"" D_CURRENT "\":%s}"), + mqtt_data, spet, sey, sped, (option) ? speriod : "", spw, spc, spu, spi); #ifdef USE_DOMOTICZ if (option) { // Only send if telemetry dtostrfd(pet * 1000, 1, spet); @@ -667,18 +664,16 @@ void hlw_mqttPresent(byte option) * option 1 = show period energy usage */ // {"Time":"2017-03-04T13:37:24", "Total":0.013, "Yesterday":0.013, "Today":0.000, "Period":0, "Power":0, "Factor":0.00, "Voltage":0, "Current":0.000} - char svalue[200]; // was MESSZ - - snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_TIME "\":\"%s\", "), getDateTime().c_str()); - hlw_mqttStat(option, svalue, sizeof(svalue)); - mqtt_publish_topic_P(2, PSTR(D_RSLT_ENERGY), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_TIME "\":\"%s\", "), getDateTime().c_str()); + hlw_mqttStat(option); + mqtt_publish_topic_P(2, PSTR(D_RSLT_ENERGY)); } -void hlw_mqttStatus(char* svalue, uint16_t ssvalue) +void hlw_mqttStatus() { - snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_STATUS D_STATUS8_POWER "\":{")); - hlw_mqttStat(0, svalue, ssvalue); - snprintf_P(svalue, ssvalue, PSTR("%s}"), svalue); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS8_POWER "\":{")); + hlw_mqttStat(0); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } #ifdef USE_WEBSERVER diff --git a/sonoff/xsns_htu21.ino b/sonoff/xsns_htu21.ino index f0b25c82209e..658e03458fce 100644 --- a/sonoff/xsns_htu21.ino +++ b/sonoff/xsns_htu21.ino @@ -211,7 +211,6 @@ uint8_t htu_detect() return true; } - char log[LOGSZ]; boolean success = false; htuaddr = HTU21_ADDR; @@ -244,8 +243,8 @@ uint8_t htu_detect() delayH=23; } if (success) { - snprintf_P(log, sizeof(log), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), htustype, htuaddr); - addLog(LOG_LEVEL_DEBUG, log); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), htustype, htuaddr); + addLog(LOG_LEVEL_DEBUG); } else { htutype = 0; } @@ -256,7 +255,7 @@ uint8_t htu_detect() * Presentation \*********************************************************************************************/ -void htu_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void htu_mqttPresent(uint8_t* djson) { if (!htutype) { return; @@ -270,7 +269,7 @@ void htu_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) h = htu21_compensatedHumidity(h, t); dtostrfd(t, sysCfg.flag.temperature_resolution, stemp1); dtostrfd(h, sysCfg.flag.humidity_resolution, stemp2); - snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, htustype, stemp1, stemp2); + snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, htustype, stemp1, stemp2); *djson = 1; #ifdef USE_DOMOTICZ domoticz_sensor2(stemp1, stemp2); diff --git a/sonoff/xsns_sht1x.ino b/sonoff/xsns_sht1x.ino index 899c1fbdd823..c4e191791d1e 100644 --- a/sonoff/xsns_sht1x.ino +++ b/sonoff/xsns_sht1x.ino @@ -184,7 +184,7 @@ boolean sht_detect() * Presentation \*********************************************************************************************/ -void sht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) +void sht_mqttPresent(uint8_t* djson) { if (!shttype) { return; @@ -199,7 +199,7 @@ void sht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson) dtostrfd(t, sysCfg.flag.temperature_resolution, stemp); dtostrfd(h, sysCfg.flag.humidity_resolution, shum); - snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, "SHT1X", stemp, shum); + snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, "SHT1X", stemp, shum); *djson = 1; #ifdef USE_DOMOTICZ domoticz_sensor2(stemp, shum);