From 9c04666a17e11dd4bf8c80f289163e97d785e913 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Sun, 27 May 2018 14:16:51 +0200 Subject: [PATCH 01/82] Add SDS0X1 RX and TX gpio pins to sonoff_template.h --- sonoff/sonoff_template.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index f97c32203..315ce4316 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -88,7 +88,8 @@ enum UserSelectablePins { GPIO_SPI_DC, // SPI Data Direction GPIO_BACKLIGHT, // Display backlight control GPIO_PMS5003, // Plantower PMS5003 Serial interface - GPIO_SDS0X1, // Nova Fitness SDS011 Serial interface + GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface + GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface GPIO_SBR_TX, // Serial Bridge Serial interface GPIO_SBR_RX, // Serial Bridge Serial interface GPIO_SR04_TRIG, // SR04 Trigger pin @@ -138,7 +139,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|" D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|" - D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1 "|" + D_SENSOR_PMS5003 "|" + D_SENSOR_SDS0X1_TX "|" D_SENSOR_SDS0X1_RX "|" D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|" D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|" D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|" @@ -912,4 +914,4 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { */ -#endif // _SONOFF_TEMPLATE_H_ \ No newline at end of file +#endif // _SONOFF_TEMPLATE_H_ From 91b07f2943c46b1cfee5d3003418d4c74a984053 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Sun, 27 May 2018 14:19:53 +0200 Subject: [PATCH 02/82] Add SDS0X1 gpio pins to support.ino --- sonoff/support.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sonoff/support.ino b/sonoff/support.ino index 2bc80c5eb..6449912e8 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -527,7 +527,8 @@ boolean GetUsedInModule(byte val, uint8_t *arr) if (GPIO_PMS5003 == val) { return true; } #endif #ifndef USE_NOVA_SDS - if (GPIO_SDS0X1 == val) { return true; } + if (GPIO_SDS0X1_TX == val) { return true; } + if (GPIO_SDS0X1_RX == val) { return true; } #endif #ifndef USE_SERIAL_BRIDGE if (GPIO_SBR_TX == val) { return true; } From c41a092c7d45b0be5514e577a111a1a332b1a75a Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Sun, 27 May 2018 14:23:25 +0200 Subject: [PATCH 03/82] SDS0X1 RX TX pin handling in NovaSdsInit --- sonoff/xsns_20_novasds.ino | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index dc5f0ab66..610e07427 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -83,12 +83,14 @@ void NovaSdsSecond() // Every second void NovaSdsInit() { novasds_type = 0; - if (pin[GPIO_SDS0X1] < 99) { - NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1], -1, 1); + if (pin[GPIO_SDS0X1_RX] < 99 && pin[GPIO_SDS0X1_TX] < 99) { + NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1_RX], pin[GPIO_SDS0X1_TX], 1); + if (NovaSdsSerial->begin(9600)) { - if (NovaSdsSerial->hardwareSerial()) { ClaimSerial(); } + if (NovaSdsSerial->hardwareSerial()) ClaimSerial(); novasds_type = 1; } + } } @@ -154,4 +156,4 @@ boolean Xsns20(byte function) return result; } -#endif // USE_NOVA_SDS \ No newline at end of file +#endif // USE_NOVA_SDS From 7cefc9b76efa762772fbac412df992174cb42b07 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Sun, 27 May 2018 14:24:53 +0200 Subject: [PATCH 04/82] SDS0X1 add start and stop functions to idle the sensor --- sonoff/xsns_20_novasds.ino | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index 610e07427..c54297911 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -94,6 +94,26 @@ void NovaSdsInit() } } +void NovaSdsStart() +{ + AddLog_P(LOG_LEVEL_DEBUG, "SDS: start"); + const uint8_t novasds_start_cmd[] = {0xAA, 0xB4, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x06, 0xAB}; + NovaSdsSerial->write(novasds_start_cmd, sizeof(novasds_start_cmd)); + NovaSdsSerial->flush(); +} + +void NovaSdsStop() +{ + AddLog_P(LOG_LEVEL_DEBUG, "SDS: stop"); + const uint8_t novasds_stop_cmd[] = {0xAA, 0xB4, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x05, 0xAB}; + NovaSdsSerial->write(novasds_stop_cmd, sizeof(novasds_stop_cmd)); + NovaSdsSerial->flush(); + // drain any old data + while (NovaSdsSerial->available()) { + NovaSdsSerial->read(); + } +} + #ifdef USE_WEBSERVER const char HTTP_SDS0X1_SNS[] PROGMEM = "%s" "{s}SDS0X1 " D_ENVIRONMENTAL_CONCENTRATION " 2.5 " D_UNIT_MICROMETER "{m}%s " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}" From 4a588581d145837dfd006e06ca932ca3dadd0e23 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Sun, 27 May 2018 14:28:31 +0200 Subject: [PATCH 05/82] Allow NovaSdsReadData to read without publishing data --- sonoff/xsns_20_novasds.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index c54297911..03b4965f8 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -37,7 +37,8 @@ struct sds011data { uint16_t pm25; } novasds_data; -bool NovaSdsReadData() + +bool NovaSdsReadData(bool publish) { if (! NovaSdsSerial->available()) return false; @@ -51,7 +52,9 @@ bool NovaSdsReadData() NovaSdsSerial->flush(); AddLogSerial(LOG_LEVEL_DEBUG_MORE, d, 8); - + if (!publish){ + return false; + } if (d[7] == ((d[1] + d[2] + d[3] + d[4] + d[5] + d[6]) & 0xFF)) { novasds_data.pm25 = (d[1] + 256 * d[2]); novasds_data.pm100 = (d[3] + 256 * d[4]); @@ -59,9 +62,6 @@ bool NovaSdsReadData() AddLog_P(LOG_LEVEL_DEBUG, PSTR("SDS: " D_CHECKSUM_FAILURE)); return false; } - - novasds_valid = 10; - return true; } From 87e3dcddb9fde27ed5f057dbe8308a77829c0cd8 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Sun, 27 May 2018 14:29:53 +0200 Subject: [PATCH 06/82] SDS0X1 take one stable reading every 3 minutes --- sonoff/xsns_20_novasds.ino | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index 03b4965f8..a9dd180b6 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -31,6 +31,10 @@ TasmotaSerial *NovaSdsSerial; uint8_t novasds_type = 1; uint8_t novasds_valid = 0; +uint8_t novasds_running = 1; +uint8_t novasds_read_tick = 30; +uint8_t novasds_wakup_tick = 179; +uint8_t novasds_ticker = 0; struct sds011data { uint16_t pm100; @@ -69,12 +73,35 @@ bool NovaSdsReadData(bool publish) void NovaSdsSecond() // Every second { - if (NovaSdsReadData()) { - novasds_valid = 10; - } else { - if (novasds_valid) { - novasds_valid--; + if (novasds_ticker < novasds_read_tick) { + // wake up the sensor and wait read ticks to stabalize the sensor + if (!novasds_running) { + NovaSdsStart(); + novasds_running = 1; } + + // drain the serial without publishing data + NovaSdsReadData(false); + novasds_ticker++; + + } else if (novasds_ticker == novasds_read_tick) { + + // try to take a single stable reading and sleep the sensor + if (NovaSdsReadData(true)) { + novasds_valid = 1; + NovaSdsStop(); + novasds_running = 0; + novasds_ticker++; + } else { + novasds_valid = 0; + } + + } else if (novasds_ticker >= novasds_wakup_tick) { + // reset the counter + novasds_ticker = 0; + } else { + // sensor is sleeping keep waiting + novasds_ticker++; } } From f11386cfe7da93bedac801747fb093d8498177a8 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Sun, 27 May 2018 14:30:40 +0200 Subject: [PATCH 07/82] Update language files for SDS0X1 RX and TX --- sonoff/language/bg-BG.h | 3 ++- sonoff/language/cs-CZ.h | 3 ++- sonoff/language/de-DE.h | 3 ++- sonoff/language/el-GR.h | 3 ++- sonoff/language/en-GB.h | 3 ++- sonoff/language/es-AR.h | 3 ++- sonoff/language/fr-FR.h | 3 ++- sonoff/language/hu-HU.h | 3 ++- sonoff/language/it-IT.h | 3 ++- sonoff/language/nl-NL.h | 3 ++- sonoff/language/pl-PL.h | 3 ++- sonoff/language/pt-BR.h | 3 ++- sonoff/language/pt-PT.h | 3 ++- sonoff/language/ru-RU.h | 3 ++- sonoff/language/zh-CN.h | 3 ++- sonoff/language/zh-TW.h | 3 ++- 16 files changed, 32 insertions(+), 16 deletions(-) diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index 55482d55c..9981f1902 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "Подсветка" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 9f939534a..6ee0bea8d 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 7d2e7285d..c2fdd0640 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 97eefcd7b..5db01909b 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 9eb8c9d4a..4af5f998e 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index aff7b2665..69737de8c 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index f37d3cfae..a862c54a0 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "RétroÉcl" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 4ebeffbf6..879204ace 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "Háttérvil" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 16c11645b..54868fd2d 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 262daee7b..f9a16a720 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 683d43cb3..d3e753946 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index 02bdec2e4..6db472624 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "Luz de fundo" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index 4cf9e0da3..398e32a58 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "Luz negra" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index 3336484e9..5ea49a669 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index 1c3ee0bb7..c97929c32 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index e8505010f..9f79ddb89 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -456,7 +456,8 @@ #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" -#define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" From ff132238077ffd04ac432dcfb0f65c6c49b32eb6 Mon Sep 17 00:00:00 2001 From: Johann Weging Date: Sun, 27 May 2018 14:34:47 +0200 Subject: [PATCH 08/82] SDS0X1 minor code cleanup --- sonoff/xsns_20_novasds.ino | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index a9dd180b6..851326f3f 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -114,7 +114,9 @@ void NovaSdsInit() NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1_RX], pin[GPIO_SDS0X1_TX], 1); if (NovaSdsSerial->begin(9600)) { - if (NovaSdsSerial->hardwareSerial()) ClaimSerial(); + if (NovaSdsSerial->hardwareSerial()) { + ClaimSerial(); + } novasds_type = 1; } @@ -137,8 +139,8 @@ void NovaSdsStop() NovaSdsSerial->flush(); // drain any old data while (NovaSdsSerial->available()) { - NovaSdsSerial->read(); - } + NovaSdsSerial->read(); + } } #ifdef USE_WEBSERVER From ababc351d74b485fa733fdb6b17a7172ab012220 Mon Sep 17 00:00:00 2001 From: MadDoct <32080323+MadDoct@users.noreply.github.com> Date: Tue, 4 Sep 2018 09:45:26 +0100 Subject: [PATCH 09/82] prepare to allow h801 tx and rx pins to be gpio_user --- sonoff/sonoff.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 8d82efc18..12aea14e9 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2362,7 +2362,7 @@ void GpioInit() if (mpin) pin[mpin] = i; } - if (2 == pin[GPIO_TXD]) Serial.set_tx(2); + if ((2 == pin[GPIO_TXD]) || (Settings.module == 20)) Serial.set_tx(2); analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h) analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c) From a8b673487b631a8b2f3ffdd4962dcffe93b9db93 Mon Sep 17 00:00:00 2001 From: MadDoct <32080323+MadDoct@users.noreply.github.com> Date: Tue, 4 Sep 2018 09:56:43 +0100 Subject: [PATCH 10/82] h801 tx and rx user selectable --- sonoff/sonoff_template.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 8d3fac176..f2fe93003 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -550,8 +550,8 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { { "H801", // Lixada H801 Wifi (ESP8266) GPIO_USER, // GPIO00 E-FW Button GPIO_LED1, // GPIO01 Green LED - GPIO_TXD, // GPIO02 RX - Pin next to TX on the PCB - GPIO_RXD, // GPIO03 TX - Pin next to GND on the PCB + GPIO_USER, // GPIO02 RX and Optional sensor - Pin next to TX on the PCB + GPIO_USER, // GPIO03 TX and Optional sensor - Pin next to GND on the PCB GPIO_PWM5, // GPIO04 W2 - PWM5 GPIO_LED2_INV, // GPIO05 Red LED 0, 0, 0, 0, 0, 0, // Flash connection @@ -1019,4 +1019,4 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { } */ -#endif // _SONOFF_TEMPLATE_H_ \ No newline at end of file +#endif // _SONOFF_TEMPLATE_H_ From e7ae727c659b5471fbc2713d20e9341dba36560f Mon Sep 17 00:00:00 2001 From: MadDoct <32080323+MadDoct@users.noreply.github.com> Date: Tue, 4 Sep 2018 18:53:44 +0100 Subject: [PATCH 11/82] Update sonoff.ino --- sonoff/sonoff.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 12aea14e9..9ada9f656 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2362,7 +2362,7 @@ void GpioInit() if (mpin) pin[mpin] = i; } - if ((2 == pin[GPIO_TXD]) || (Settings.module == 20)) Serial.set_tx(2); + if ((2 == pin[GPIO_TXD]) || (H801 == Settings.module)) Serial.set_tx(2); analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h) analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c) From bd0323f6f28df037aed04a476798291acaf31cb5 Mon Sep 17 00:00:00 2001 From: gitolicious Date: Tue, 4 Sep 2018 22:43:27 +0200 Subject: [PATCH 12/82] Added toggle function for RGBW lights #3695 Proposed fix for #3695 --- sonoff/xdrv_04_light.ino | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 22fce0c33..f8dde0ce6 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -69,6 +69,12 @@ struct LRgbColor { const LRgbColor kFixedColor[MAX_FIXED_COLOR] PROGMEM = { 255,0,0, 0,255,0, 0,0,255, 228,32,0, 0,228,32, 0,32,228, 188,64,0, 0,160,96, 160,32,240, 255,255,0, 255,0,170, 255,255,255 }; +struct LWColor { + uint8_t W; +}; +#define MAX_FIXED_WHITE 3 +const LWColor kFixedWhite[MAX_FIXED_WHITE] PROGMEM = { 0, 255, 128 }; + struct LCwColor { uint8_t C, W; }; @@ -1006,7 +1012,11 @@ boolean LightColorEntry(char *buffer, uint8_t buffer_length) entry_type = 1; // Hexadecimal } else if ((value > 199) && (value <= 199 + MAX_FIXED_COLD_WARM)) { - if (LST_COLDWARM == light_subtype) { + if (LST_RGBW == light_subtype) { + memcpy_P(&light_entry_color[3], &kFixedWhite[value -200], 1); + entry_type = 1; // Hexadecimal + } + else if (LST_COLDWARM == light_subtype) { memcpy_P(&light_entry_color, &kFixedColdWarm[value -200], 2); entry_type = 1; // Hexadecimal } From 170013c1e13860c33da91014ee73beec3cbe5d50 Mon Sep 17 00:00:00 2001 From: gitolicious Date: Tue, 4 Sep 2018 23:03:19 +0200 Subject: [PATCH 13/82] Added 4th dimming step It wasn't a good idea to cycle through three dimming steps only, as the 4th would be triggered by the toggle, but nothing happened (`Color 203` got ignored). --- sonoff/xdrv_04_light.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index f8dde0ce6..209fe467a 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -72,8 +72,8 @@ const LRgbColor kFixedColor[MAX_FIXED_COLOR] PROGMEM = struct LWColor { uint8_t W; }; -#define MAX_FIXED_WHITE 3 -const LWColor kFixedWhite[MAX_FIXED_WHITE] PROGMEM = { 0, 255, 128 }; +#define MAX_FIXED_WHITE 4 +const LWColor kFixedWhite[MAX_FIXED_WHITE] PROGMEM = { 0, 255, 128, 32 }; struct LCwColor { uint8_t C, W; From eaff2962624a24d44fd03e9a24d0e9bf9ab7a509 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 5 Sep 2018 11:22:58 +0200 Subject: [PATCH 14/82] v6.2.1.1 - Released v6.2.1 Released v6.2.1 to solve important issues --- RELEASENOTES.md | 6 ++++++ sonoff/_changelog.ino | 14 +++++++------- sonoff/sonoff_version.h | 2 +- sonoff/xplg_wemohue.ino | 1 - 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7cacefa47..8cf1a0022 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -104,6 +104,12 @@ See [Tasmota ESP/Arduino library version related issues](https://github.com/aren | USE_RF_FLASH | - | - | x | x | x | ## Changelog +Version 6.2.1 20180905 + * Fix possible ambiguity on command parameters if StateText contains numbers only (#3656) + * Fix Wemo emulation to select the first relay when more than one relay is present (#3657) + * Fix possible exception due to buffer overflow (#3659) + * Fix lost energy today and total energy value after power cycle (#3689) + Version 6.2.0 20180901 * Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561) * Disable wifi sleep for both Esp8266/Arduino core 2.4.1 and 2.4.2 to solve device freeze caused by Espressif SDK bug (#3554) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 0b3c115cd..145e435e3 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,14 +1,14 @@ -/* 6.2.0.2 20180904 +/* 6.2.1.1 20180905 * Rewrite energy monitoring using energy sensor driver modules - * Fix lost today and total energy value after power cycle (#3689) - * - * 6.2.0.1 20180902 - * Fix possible ambiguity on command parameters if StateText contains numbers only (#3656) - * Fix possible exception due to buffer overflow (#3659) * Add Wifi channel number to state message (#3664) - * Fix Wemo emulation to select the first relay when more than one relay is present (#3657) * Add support for Shelly 1 and basic support for Shelly 2 - No energy monitoring yet (#2789) * + * 6.2.1 20180905 + * Fix possible ambiguity on command parameters if StateText contains numbers only (#3656) + * Fix Wemo emulation to select the first relay when more than one relay is present (#3657) + * Fix possible exception due to buffer overflow (#3659) + * Fix lost energy today and total energy value after power cycle (#3689) + * * 6.2.0 20180901 * Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561) * Disable wifi sleep for both Esp8266/Arduino core 2.4.1 and 2.4.2 to solve device freeze caused by Espressif SDK bug (#3554) diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index e9e92cc9d..f4df759c8 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06020002 +#define VERSION 0x06020101 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/xplg_wemohue.ino b/sonoff/xplg_wemohue.ino index bc579782a..93912bc76 100644 --- a/sonoff/xplg_wemohue.ino +++ b/sonoff/xplg_wemohue.ino @@ -397,7 +397,6 @@ void HandleUpnpEvent() uint8_t device = (light_type) ? devices_present : 1; // Select either a configured light or relay1 ExecuteCommandPower(device, power, SRC_WEMO); } - } else if(request.indexOf(F("GetBinaryState")) > 0){ state_xml.replace(F("Set"), F("Get")); From 36242e0e02102e7f6534f53ec519ac304515cac3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 5 Sep 2018 15:38:48 +0200 Subject: [PATCH 15/82] Add network information Add network information to display start screen (#3704) --- sonoff/_changelog.ino | 1 + sonoff/sonoff.h | 2 +- sonoff/sonoff.ino | 10 +++++----- sonoff/xdrv_13_display.ino | 22 +++++++++++++++++++--- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 145e435e3..77020540e 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -2,6 +2,7 @@ * Rewrite energy monitoring using energy sensor driver modules * Add Wifi channel number to state message (#3664) * Add support for Shelly 1 and basic support for Shelly 2 - No energy monitoring yet (#2789) + * Add network information to display start screen (#3704) * * 6.2.1 20180905 * Fix possible ambiguity on command parameters if StateText contains numbers only (#3656) diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 2c5d5cce9..a0b65b348 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -204,7 +204,7 @@ enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MA enum XsnsFunctions {FUNC_PRE_INIT, FUNC_INIT, FUNC_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_100_MSECOND, FUNC_EVERY_200_MSECOND, FUNC_EVERY_250_MSECOND, FUNC_EVERY_SECOND, FUNC_PREP_BEFORE_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_APPEND, FUNC_SAVE_BEFORE_RESTART, FUNC_COMMAND, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SHOW_SENSOR, - FUNC_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM}; + FUNC_RULES_PROCESS, FUNC_SERIAL, FUNC_DISPLAY, FUNC_FREE_MEM}; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index c92a8db76..8afae580e 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2540,19 +2540,19 @@ void setup() snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BOOT_COUNT " %d"), Settings.bootcount); AddLog(LOG_LEVEL_DEBUG); - GpioInit(); - - SetSerialBaudrate(baudrate); - Format(mqtt_client, Settings.mqtt_client, sizeof(mqtt_client)); Format(mqtt_topic, Settings.mqtt_topic, sizeof(mqtt_topic)); - if (strstr(Settings.hostname, "%")) { strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname)); snprintf_P(my_hostname, sizeof(my_hostname)-1, Settings.hostname, mqtt_topic, ESP.getChipId() & 0x1FFF); } else { snprintf_P(my_hostname, sizeof(my_hostname)-1, Settings.hostname); } + + GpioInit(); + + SetSerialBaudrate(baudrate); + WifiConnect(); if (MOTOR == Settings.module) Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo! diff --git a/sonoff/xdrv_13_display.ino b/sonoff/xdrv_13_display.ino index 74b4069e1..c8972536a 100644 --- a/sonoff/xdrv_13_display.ino +++ b/sonoff/xdrv_13_display.ino @@ -626,11 +626,24 @@ void DisplayLogBufferInit() DisplayReAllocLogBuffer(); - char buffer[20]; + char buffer[40]; snprintf_P(buffer, sizeof(buffer), PSTR(D_VERSION " %s"), my_version); DisplayLogBufferAdd(buffer); snprintf_P(buffer, sizeof(buffer), PSTR("Display mode %d"), Settings.display_mode); DisplayLogBufferAdd(buffer); + + snprintf_P(buffer, sizeof(buffer), PSTR(D_CMND_HOSTNAME " %s"), my_hostname); + DisplayLogBufferAdd(buffer); + snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), Settings.sta_ssid[Settings.sta_active]); + DisplayLogBufferAdd(buffer); + snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), WiFi.macAddress().c_str()); + DisplayLogBufferAdd(buffer); + if (!global_state.wifi_down && (static_cast(WiFi.localIP()) != 0)) { + snprintf_P(buffer, sizeof(buffer), PSTR("IP %s"), WiFi.localIP().toString().c_str()); + DisplayLogBufferAdd(buffer); + snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_RSSI " %d%%"), WifiGetRssiAsQuality(WiFi.RSSI())); + DisplayLogBufferAdd(buffer); + } } } @@ -915,8 +928,8 @@ boolean DisplayCommand() if (last_display_mode && !Settings.display_mode) { // Switch to mode 0 DisplayInit(DISPLAY_INIT_MODE); DisplayClear(); - } - if (!last_display_mode && Settings.display_mode) { // Switch to non mode 0 + } else { +// if (!last_display_mode && Settings.display_mode) { // Switch to non mode 0 DisplayLogBufferInit(); DisplayInit(DISPLAY_INIT_MODE); } @@ -1047,6 +1060,9 @@ boolean Xdrv13(byte function) case FUNC_PRE_INIT: DisplayInitDriver(); break; + case FUNC_DISPLAY: + DisplayLogBufferAdd(log_data); + break; case FUNC_EVERY_50_MSECOND: if (Settings.display_model) { XdspCall(FUNC_DISPLAY_EVERY_50_MSECOND); } break; From 35d0e502c46b99d18b5389c9162d399be9e38f04 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 5 Sep 2018 18:01:15 +0200 Subject: [PATCH 16/82] Some additions * Add command Display to show all settings at once * Add toggle function RGBW lights (#3695, #3697) * Add user configurable GPIO02 and GPIO03 on H801 devices (#3692) --- sonoff/_changelog.ino | 3 +++ sonoff/sonoff.ino | 2 +- sonoff/sonoff_template.h | 17 +++++++---------- sonoff/xdrv_13_display.ino | 10 ++++++++-- sonoff/xdsp_03_matrix.ino | 4 +++- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 77020540e..910f70bbc 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -3,6 +3,9 @@ * Add Wifi channel number to state message (#3664) * Add support for Shelly 1 and basic support for Shelly 2 - No energy monitoring yet (#2789) * Add network information to display start screen (#3704) + * Add command Display to show all settings at once + * Add toggle function RGBW lights (#3695, #3697) + * Add user configurable GPIO02 and GPIO03 on H801 devices (#3692) * * 6.2.1 20180905 * Fix possible ambiguity on command parameters if StateText contains numbers only (#3656) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index fa59bb06d..a7315623d 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2347,7 +2347,7 @@ void GpioInit() if (mpin) pin[mpin] = i; } - if ((2 == pin[GPIO_TXD]) || (H801 == Settings.module)) Serial.set_tx(2); + if ((2 == pin[GPIO_TXD]) || (H801 == Settings.module)) { Serial.set_tx(2); } analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h) analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index f2fe93003..b1087da97 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -136,9 +136,6 @@ enum ProgramSelectablePins { GPIO_DI, // my92x1 PWM input GPIO_DCKI, // my92x1 CLK input GPIO_ARIRFRCV, // AliLux RF Receive input - GPIO_MCP39_TX, // MCP39F501 Serial output - GPIO_MCP39_RX, // MCP39F501 Serial input - GPIO_MCP39_RST, // MCP39F501 Serial reset GPIO_USER, // User configurable GPIO_MAX }; @@ -550,8 +547,8 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { { "H801", // Lixada H801 Wifi (ESP8266) GPIO_USER, // GPIO00 E-FW Button GPIO_LED1, // GPIO01 Green LED - GPIO_USER, // GPIO02 RX and Optional sensor - Pin next to TX on the PCB - GPIO_USER, // GPIO03 TX and Optional sensor - Pin next to GND on the PCB + GPIO_USER, // GPIO02 TX and Optional sensor - Pin next to TX on the PCB + GPIO_USER, // GPIO03 RX and Optional sensor - Pin next to GND on the PCB GPIO_PWM5, // GPIO04 W2 - PWM5 GPIO_LED2_INV, // GPIO05 Red LED 0, 0, 0, 0, 0, 0, // Flash connection @@ -923,16 +920,16 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { }, { "Shelly 2", // Shelly2 (ESP8266 - 2MB) - https://shelly.cloud/shelly2/ 0, - GPIO_MCP39_RX, // GPIO01 MCP39F501 Serial input + GPIO_TXD, // GPIO01 MCP39F501 Serial input 0, - GPIO_MCP39_TX, // GPIO03 MCP39F501 Serial output + GPIO_RXD, // GPIO03 MCP39F501 Serial output GPIO_REL1, // GPIO04 GPIO_REL2, // GPIO05 0, 0, 0, 0, 0, 0, // Flash connection GPIO_SWT1_NP, // GPIO12 0, GPIO_SWT2_NP, // GPIO14 - GPIO_MCP39_RST, // GPIO15 MCP39F501 Reset + 0, // GPIO15 MCP39F501 Reset 0, 0 } }; @@ -1002,7 +999,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, 0 } - { "Ledunia", // Ledunia (ESP8266) - http://ledunia.de/ + { "Ledunia", // Ledunia (ESP8266 - 32MB) - http://ledunia.de/ GPIO_USER, // GPIO00 (D0) GPIO_USER, // GPIO01 (D7) Serial RXD GPIO_USER, // GPIO02 (D2) @@ -1019,4 +1016,4 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { } */ -#endif // _SONOFF_TEMPLATE_H_ +#endif // _SONOFF_TEMPLATE_H_ \ No newline at end of file diff --git a/sonoff/xdrv_13_display.ino b/sonoff/xdrv_13_display.ino index c8972536a..083aae74a 100644 --- a/sonoff/xdrv_13_display.ino +++ b/sonoff/xdrv_13_display.ino @@ -49,10 +49,10 @@ enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_E enum DisplayInitModes { DISPLAY_INIT_MODE, DISPLAY_INIT_PARTIAL, DISPLAY_INIT_FULL }; -enum DisplayCommands { CMND_DISP_MODEL, CMND_DISP_MODE, CMND_DISP_REFRESH, CMND_DISP_DIMMER, CMND_DISP_COLS, CMND_DISP_ROWS, +enum DisplayCommands { CMND_DISPLAY, CMND_DISP_MODEL, CMND_DISP_MODE, CMND_DISP_REFRESH, CMND_DISP_DIMMER, CMND_DISP_COLS, CMND_DISP_ROWS, CMND_DISP_SIZE, CMND_DISP_FONT, CMND_DISP_ROTATE, CMND_DISP_TEXT, CMND_DISP_ADDRESS }; const char kDisplayCommands[] PROGMEM = - D_CMND_DISP_MODEL "|" D_CMND_DISP_MODE "|" D_CMND_DISP_REFRESH "|" D_CMND_DISP_DIMMER "|" D_CMND_DISP_COLS "|" D_CMND_DISP_ROWS "|" + "|" D_CMND_DISP_MODEL "|" D_CMND_DISP_MODE "|" D_CMND_DISP_REFRESH "|" D_CMND_DISP_DIMMER "|" D_CMND_DISP_COLS "|" D_CMND_DISP_ROWS "|" D_CMND_DISP_SIZE "|" D_CMND_DISP_FONT "|" D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS ; const char S_JSON_DISPLAY_COMMAND_VALUE[] PROGMEM = "{\"" D_CMND_DISPLAY "%s\":\"%s\"}"; @@ -898,6 +898,12 @@ boolean DisplayCommand() if (-1 == command_code) { serviced = false; // Unknown command } + else if (CMND_DISPLAY == command_code) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DISPLAY "\":{\"" D_CMND_DISP_MODEL "\":%d,\"" D_CMND_DISP_MODE "\":%d,\"" D_CMND_DISP_DIMMER "\":%d,\"" + D_CMND_DISP_SIZE "\":%d,\"" D_CMND_DISP_FONT "\":%d,\"" D_CMND_DISP_ROTATE "\":%d,\"" D_CMND_DISP_REFRESH "\":%d,\"" D_CMND_DISP_COLS "\":[%d,%d],\"" D_CMND_DISP_ROWS "\":%d}}"), + Settings.display_model, Settings.display_mode, Settings.display_dimmer, Settings.display_size, Settings.display_font, Settings.display_rotate, Settings.display_refresh, + Settings.display_cols[0], Settings.display_cols[1], Settings.display_rows); + } else if (CMND_DISP_MODEL == command_code) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < DISPLAY_MAX_DRIVERS)) { uint8_t last_display_model = Settings.display_model; diff --git a/sonoff/xdsp_03_matrix.ino b/sonoff/xdsp_03_matrix.ino index 4989ad24b..36c5955d6 100644 --- a/sonoff/xdsp_03_matrix.ino +++ b/sonoff/xdsp_03_matrix.ino @@ -243,7 +243,8 @@ void MatrixPrintLog(uint8_t direction) uint8_t space = 0; uint8_t max_cols = (disp_log_buffer_cols < MTX_MAX_SCREEN_BUFFER) ? disp_log_buffer_cols : MTX_MAX_SCREEN_BUFFER; mtx_buffer[0] = '\0'; - for (byte i = 0; i < max_cols; i++) { + uint8_t i = 0; + while ((txt[i] != '\0') && (i < max_cols)) { if (txt[i] == ' ') { space++; } else { @@ -252,6 +253,7 @@ void MatrixPrintLog(uint8_t direction) if (space < 2) { strncat(mtx_buffer, (const char*)txt +i, 1); } + i++; } snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "[%s]"), mtx_buffer); From 00814c7fc64cb37e8db373e8565fb13e83fffea3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 5 Sep 2018 20:51:17 +0200 Subject: [PATCH 17/82] Fix compile error Fix compile error --- sonoff/sonoff.h | 2 +- sonoff/xdrv_13_display.ino | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index a0b65b348..2c5d5cce9 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -204,7 +204,7 @@ enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MA enum XsnsFunctions {FUNC_PRE_INIT, FUNC_INIT, FUNC_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_100_MSECOND, FUNC_EVERY_200_MSECOND, FUNC_EVERY_250_MSECOND, FUNC_EVERY_SECOND, FUNC_PREP_BEFORE_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_APPEND, FUNC_SAVE_BEFORE_RESTART, FUNC_COMMAND, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SHOW_SENSOR, - FUNC_RULES_PROCESS, FUNC_SERIAL, FUNC_DISPLAY, FUNC_FREE_MEM}; + FUNC_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM}; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; diff --git a/sonoff/xdrv_13_display.ino b/sonoff/xdrv_13_display.ino index 083aae74a..4d6ce2e89 100644 --- a/sonoff/xdrv_13_display.ino +++ b/sonoff/xdrv_13_display.ino @@ -1066,9 +1066,6 @@ boolean Xdrv13(byte function) case FUNC_PRE_INIT: DisplayInitDriver(); break; - case FUNC_DISPLAY: - DisplayLogBufferAdd(log_data); - break; case FUNC_EVERY_50_MSECOND: if (Settings.display_model) { XdspCall(FUNC_DISPLAY_EVERY_50_MSECOND); } break; From c6507482c4969d452a764c209ebe603265ff7394 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 5 Sep 2018 20:56:43 +0200 Subject: [PATCH 18/82] Bump README.md version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ab25ac17..581b38e83 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute! [![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/tasmota) ### Development -[![Dev Version](https://img.shields.io/badge/development%20version-6.2.0.x-blue.svg)](https://github.com/arendst/Sonoff-Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-6.2.1.x-blue.svg)](https://github.com/arendst/Sonoff-Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) [![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota) From b8e7ee865085370ba53fd1db589420cf5529eb02 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Wed, 5 Sep 2018 18:35:02 -0300 Subject: [PATCH 19/82] Fixed Exception Issue Solves Bug #3700 --- sonoff/support.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/support.ino b/sonoff/support.ino index 8aaeabf88..a48156444 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -143,7 +143,7 @@ char* subStr(char* dest, char* str, const char *delim, int index) int i; // Since strtok consumes the first arg, make a copy - strlcpy(dest, str, strlen(str)); + strncpy(dest, str, strlen(str)); for (i = 1, act = dest; i <= index; i++, act = NULL) { sub = strtok_r(act, delim, &ptr); if (sub == NULL) break; From 9413ba9f47386fbd4ade98d8046e10382160382c Mon Sep 17 00:00:00 2001 From: Rodney Gitzel Date: Sun, 2 Sep 2018 01:42:52 -0700 Subject: [PATCH 20/82] optionally append timezone to timestamp in JSON messages --- .gitignore | 3 ++ sonoff/sonoff.h | 2 +- sonoff/sonoff.ino | 6 ++-- sonoff/support.ino | 68 +++++++++++++++++++----------------- sonoff/user_config.h | 3 ++ sonoff/xdrv_02_webserver.ino | 2 +- 6 files changed, 46 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index b6460347b..028a76667 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ build ## Visual Studio Code specific ###### .vscode +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 3a1dc14c6..b7df1408a 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -170,7 +170,7 @@ enum WeekInMonthOptions {Last, First, Second, Third, Fourth}; enum DayOfTheWeekOptions {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat}; enum MonthNamesOptions {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; enum HemisphereOptions {North, South}; -enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART, DT_UPTIME }; +enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART }; enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 254f88184..bf12d97eb 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1418,7 +1418,7 @@ void PublishStatus(uint8_t payload) if ((0 == payload) || (1 == payload)) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_JSON_BAUDRATE "\":%d,\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"), - baudrate, Settings.mqtt_grptopic, Settings.ota_url, GetResetReason().c_str(), GetDateAndTime(DT_UPTIME).c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress()); + baudrate, Settings.mqtt_grptopic, Settings.ota_url, GetResetReason().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress()); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1")); } @@ -1509,7 +1509,7 @@ void MqttShowState() { char stemp1[33]; - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\""), mqtt_data, GetDateAndTime(DT_LOCAL).c_str(), GetDateAndTime(DT_UPTIME).c_str()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\""), mqtt_data, GetDateAndTime(DT_LOCAL).c_str(), GetUptime().c_str()); #ifdef USE_ADC_VCC dtostrfd((double)ESP.getVcc()/1000, 3, stemp1); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1); @@ -1626,7 +1626,7 @@ void PerformEverySecond() if ((2 == RtcTime.minute) && latest_uptime_flag) { latest_uptime_flag = false; - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\"}"), GetDateAndTime(DT_LOCAL).c_str(), GetDateAndTime(DT_UPTIME).c_str()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\"}"), GetDateAndTime(DT_LOCAL).c_str(), GetUptime().c_str()); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_UPTIME)); } if ((3 == RtcTime.minute) && !latest_uptime_flag) latest_uptime_flag = true; diff --git a/sonoff/support.ino b/sonoff/support.ino index 8cc064fe5..290acf231 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -1802,44 +1802,46 @@ String GetBuildDateAndTime() return String(bdt); } +/* + * timestamps in https://en.wikipedia.org/wiki/ISO_8601 format + * + * DT_UTC - current data and time in Greenwich, England (aka GMT) + * DT_LOCAL - current date and time taking timezone into account + * DT_RESTART - the date and time this device last started, in local timezone + * + * Format: + * "2017-03-07T11:08:02-07:00" - if DT_LOCAL and TIME_APPEND_TIMEZONE=1 + * "2017-03-07T11:08:02" - otherwise + */ String GetDateAndTime(byte time_type) { - // enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART, DT_UPTIME }; - // "2017-03-07T11:08:02" - ISO8601:2004 - char dt[21]; + // "2017-03-07T11:08:02-07:00" - ISO8601:2004 + char dt[27]; TIME_T tmpTime; - if (DT_UPTIME == time_type) { - if (restart_time) { - BreakTime(utc_time - restart_time, tmpTime); - } else { - BreakTime(uptime, tmpTime); - } - // "P128DT14H35M44S" - ISO8601:2004 - https://en.wikipedia.org/wiki/ISO_8601 Durations - // snprintf_P(dt, sizeof(dt), PSTR("P%dDT%02dH%02dM%02dS"), ut.days, ut.hour, ut.minute, ut.second); - // "128 14:35:44" - OpenVMS - // "128T14:35:44" - Tasmota - snprintf_P(dt, sizeof(dt), PSTR("%dT%02d:%02d:%02d"), - tmpTime.days, tmpTime.hour, tmpTime.minute, tmpTime.second); - } else { - switch (time_type) { - case DT_UTC: - BreakTime(utc_time, tmpTime); - tmpTime.year += 1970; - break; - case DT_RESTART: - if (restart_time == 0) { - return ""; - } - BreakTime(restart_time, tmpTime); - tmpTime.year += 1970; - break; - default: - tmpTime = RtcTime; - } - snprintf_P(dt, sizeof(dt), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"), - tmpTime.year, tmpTime.month, tmpTime.day_of_month, tmpTime.hour, tmpTime.minute, tmpTime.second); + switch (time_type) { + case DT_UTC: + BreakTime(utc_time, tmpTime); + tmpTime.year += 1970; + break; + case DT_RESTART: + if (restart_time == 0) { + return ""; + } + BreakTime(restart_time, tmpTime); + tmpTime.year += 1970; + break; + default: + tmpTime = RtcTime; } + + snprintf_P(dt, sizeof(dt), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"), + tmpTime.year, tmpTime.month, tmpTime.day_of_month, tmpTime.hour, tmpTime.minute, tmpTime.second); + + if (TIME_APPEND_TIMEZONE && (time_type == DT_LOCAL)) { + snprintf_P(dt, sizeof(dt), PSTR("%s%+03d:00"), dt, Settings.timezone); + } + return String(dt); } diff --git a/sonoff/user_config.h b/sonoff/user_config.h index a8457ff97..3dbf9c5b2 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -152,6 +152,9 @@ #define TIME_STD_HOUR 3 // Hour (0 to 23) #define TIME_STD_OFFSET +60 // Offset from UTC in minutes (-780 to +780) +// -- Time - formatting options +#define TIME_APPEND_TIMEZONE 0 // for local timestamps: 0 = no timezone in string, 1 = append numeric timezone (e.g. "+1:00" or "-7:00") + // -- Location ------------------------------------ #define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset #define LONGITUDE 2.294442 // [Longitude] Your location to be used with sunrise and sunset diff --git a/sonoff/xdrv_02_webserver.ino b/sonoff/xdrv_02_webserver.ino index c919c8f43..8725bd6f5 100644 --- a/sonoff/xdrv_02_webserver.ino +++ b/sonoff/xdrv_02_webserver.ino @@ -1291,7 +1291,7 @@ void HandleInformation() func += F(D_PROGRAM_VERSION "}2"); func += my_version; func += F("}1" D_BUILD_DATE_AND_TIME "}2"); func += GetBuildDateAndTime(); func += F("}1" D_CORE_AND_SDK_VERSION "}2" ARDUINO_ESP8266_RELEASE "/"); func += String(ESP.getSdkVersion()); - func += F("}1" D_UPTIME "}2"); func += GetDateAndTime(DT_UPTIME); + func += F("}1" D_UPTIME "}2"); func += GetUptime(); snprintf_P(stopic, sizeof(stopic), PSTR(" at %X"), GetSettingsAddress()); func += F("}1" D_FLASH_WRITE_COUNT "}2"); func += String(Settings.save_flag); func += stopic; func += F("}1" D_BOOT_COUNT "}2"); func += String(Settings.bootcount); From 359877489d7acba5f19c221a35921bdc83c97017 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 6 Sep 2018 10:42:22 +0200 Subject: [PATCH 21/82] 6.2.1.2 - Fix KNX PA exception 6.2.1.2 20180906 * Fix KNX PA exception. Regression from 6.2.1 buffer overflow (#3700, #3710) --- sonoff/_changelog.ino | 5 ++++- sonoff/settings.h | 4 ++-- sonoff/sonoff.ino | 9 ++++++--- sonoff/sonoff_version.h | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 910f70bbc..c34a70697 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,7 @@ -/* 6.2.1.1 20180905 +/* 6.2.1.2 20180906 + * Fix KNX PA exception. Regression from 6.2.1 buffer overflow (#3700, #3710) + * + * 6.2.1.1 20180905 * Rewrite energy monitoring using energy sensor driver modules * Add Wifi channel number to state message (#3664) * Add support for Shelly 1 and basic support for Shelly 2 - No energy monitoring yet (#2789) diff --git a/sonoff/settings.h b/sonoff/settings.h index 3876baf60..7a44ef9cc 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -64,7 +64,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t data; // Allow bit manipulation using SetOption struct { // SetOption50 .. SetOption81 uint32_t timers_enable : 1; // bit 0 (v6.1.1b) - uint32_t spare01 : 1; + uint32_t user_esp8285_enable : 1; // bit 1 (v6.1.1.14) uint32_t spare02 : 1; uint32_t spare03 : 1; uint32_t spare04 : 1; @@ -94,7 +94,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t spare28 : 1; uint32_t spare29 : 1; uint32_t spare30 : 1; - uint32_t user_esp8285_enable : 1; // bit 31 (v6.1.1.14) + uint32_t spare31 : 1; }; } SysBitfield3; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index a7315623d..b3760faa2 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -843,9 +843,11 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) else if ((CMND_GPIO == command_code) && (index < MAX_GPIO_PIN)) { mytmplt cmodule; memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule)); - if ((GPIO_USER == cmodule.gp.io[index]) && (payload >= 0) && (payload < GPIO_SENSOR_END)) { +// if ((GPIO_USER == cmodule.gp.io[index]) && (payload >= 0) && (payload < GPIO_SENSOR_END)) { + if ((GPIO_USER == ValidGPIO(index, cmodule.gp.io[index])) && (payload >= 0) && (payload < GPIO_SENSOR_END)) { for (byte i = 0; i < MAX_GPIO_PIN; i++) { - if ((GPIO_USER == cmodule.gp.io[i]) && (Settings.my_gp.io[i] == payload)) { +// if ((GPIO_USER == cmodule.gp.io[i]) && (Settings.my_gp.io[i] == payload)) { + if ((GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) && (Settings.my_gp.io[i] == payload)) { Settings.my_gp.io[i] = 0; } } @@ -854,7 +856,8 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) } snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{")); for (byte i = 0; i < MAX_GPIO_PIN; i++) { - if (GPIO_USER == cmodule.gp.io[i]) { +// if (GPIO_USER == cmodule.gp.io[i]) { + if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) { if (jsflg) snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data); jsflg = 1; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_GPIO "%d\":\"%d (%s)\""), diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index f4df759c8..178e0af68 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06020101 +#define VERSION 0x06020102 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" From dd95bb393e807eb9fa30670df68d9c7c8be722d7 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 6 Sep 2018 12:37:50 +0200 Subject: [PATCH 22/82] Add command SetOption52 Add command SetOption52 to control display of optional time offset from UTC in JSON messages (#3629, #3711) --- sonoff/_changelog.ino | 1 + sonoff/settings.h | 2 +- sonoff/support.ino | 10 +++++----- sonoff/user_config.h | 27 ++++++++++++--------------- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index c34a70697..7e7bdc520 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,5 +1,6 @@ /* 6.2.1.2 20180906 * Fix KNX PA exception. Regression from 6.2.1 buffer overflow (#3700, #3710) + * Add command SetOption52 to control display of optional time offset from UTC in JSON messages (#3629, #3711) * * 6.2.1.1 20180905 * Rewrite energy monitoring using energy sensor driver modules diff --git a/sonoff/settings.h b/sonoff/settings.h index 7a44ef9cc..32bc80ad0 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -65,7 +65,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu struct { // SetOption50 .. SetOption81 uint32_t timers_enable : 1; // bit 0 (v6.1.1b) uint32_t user_esp8285_enable : 1; // bit 1 (v6.1.1.14) - uint32_t spare02 : 1; + uint32_t time_append_timezone : 1; // bit 2 (v6.2.1.2) uint32_t spare03 : 1; uint32_t spare04 : 1; uint32_t spare05 : 1; diff --git a/sonoff/support.ino b/sonoff/support.ino index ca361d3b3..51b59c554 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -1804,13 +1804,13 @@ String GetBuildDateAndTime() /* * timestamps in https://en.wikipedia.org/wiki/ISO_8601 format - * + * * DT_UTC - current data and time in Greenwich, England (aka GMT) * DT_LOCAL - current date and time taking timezone into account * DT_RESTART - the date and time this device last started, in local timezone - * + * * Format: - * "2017-03-07T11:08:02-07:00" - if DT_LOCAL and TIME_APPEND_TIMEZONE=1 + * "2017-03-07T11:08:02-07:00" - if DT_LOCAL and SetOption52 = 1 * "2017-03-07T11:08:02" - otherwise */ String GetDateAndTime(byte time_type) @@ -1838,8 +1838,8 @@ String GetDateAndTime(byte time_type) snprintf_P(dt, sizeof(dt), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"), tmpTime.year, tmpTime.month, tmpTime.day_of_month, tmpTime.hour, tmpTime.minute, tmpTime.second); - if (TIME_APPEND_TIMEZONE && (time_type == DT_LOCAL)) { - snprintf_P(dt, sizeof(dt), PSTR("%s%+03d:00"), dt, Settings.timezone); + if (Settings.flag3.time_append_timezone && (time_type == DT_LOCAL)) { + snprintf_P(dt, sizeof(dt), PSTR("%s%+03d:%02d"), dt, time_timezone / 10, abs((time_timezone % 10) * 6)); // if timezone = +2:30 then time_timezone = 25 } return String(dt); diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 3dbf9c5b2..ece854530 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -137,23 +137,20 @@ #define NTP_SERVER3 "0.nl.pool.ntp.org" // [NtpServer3] Select third NTP server by name or IP address (93.94.224.67) // -- Time - Start Daylight Saving Time and timezone offset from UTC in minutes -#define TIME_DST_HEMISPHERE North // [TimeDst] Hemisphere (0 or North, 1 or South) -#define TIME_DST_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth) -#define TIME_DST_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat) -#define TIME_DST_MONTH Mar // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec) -#define TIME_DST_HOUR 2 // Hour (0 to 23) -#define TIME_DST_OFFSET +120 // Offset from UTC in minutes (-780 to +780) +#define TIME_DST_HEMISPHERE North // [TimeDst] Hemisphere (0 or North, 1 or South) +#define TIME_DST_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth) +#define TIME_DST_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat) +#define TIME_DST_MONTH Mar // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec) +#define TIME_DST_HOUR 2 // Hour (0 to 23) +#define TIME_DST_OFFSET +120 // Offset from UTC in minutes (-780 to +780) // -- Time - Start Standard Time and timezone offset from UTC in minutes -#define TIME_STD_HEMISPHERE North // [TimeStd] Hemisphere (0 or North, 1 or South) -#define TIME_STD_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth) -#define TIME_STD_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat) -#define TIME_STD_MONTH Oct // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec) -#define TIME_STD_HOUR 3 // Hour (0 to 23) -#define TIME_STD_OFFSET +60 // Offset from UTC in minutes (-780 to +780) - -// -- Time - formatting options -#define TIME_APPEND_TIMEZONE 0 // for local timestamps: 0 = no timezone in string, 1 = append numeric timezone (e.g. "+1:00" or "-7:00") +#define TIME_STD_HEMISPHERE North // [TimeStd] Hemisphere (0 or North, 1 or South) +#define TIME_STD_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth) +#define TIME_STD_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat) +#define TIME_STD_MONTH Oct // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec) +#define TIME_STD_HOUR 3 // Hour (0 to 23) +#define TIME_STD_OFFSET +60 // Offset from UTC in minutes (-780 to +780) // -- Location ------------------------------------ #define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset From b441c8577655629e532f299ff69e4a1c3fc5bb34 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 6 Sep 2018 17:35:57 +0200 Subject: [PATCH 23/82] Experimental PZEM-003,014,016,017 Add experimental support for PZEM-003,014,016,017 Energy monitoring (#3694) --- sonoff/_changelog.ino | 1 + sonoff/sonoff_template.h | 5 +- sonoff/user_config.h | 5 +- sonoff/xdrv_03_energy.ino | 1 + sonoff/xnrg_05_pzem2.ino | 215 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 sonoff/xnrg_05_pzem2.ino diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 7e7bdc520..49193dfbd 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,6 +1,7 @@ /* 6.2.1.2 20180906 * Fix KNX PA exception. Regression from 6.2.1 buffer overflow (#3700, #3710) * Add command SetOption52 to control display of optional time offset from UTC in JSON messages (#3629, #3711) + * Add experimental support for PZEM-003,014,016,017 Energy monitoring (#3694) * * 6.2.1.1 20180905 * Rewrite energy monitoring using energy sensor driver modules diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index b1087da97..3881f8c3e 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -120,6 +120,8 @@ enum UserSelectablePins { GPIO_CNTR2_NP, GPIO_CNTR3_NP, GPIO_CNTR4_NP, + GPIO_PZEM2_TX, // PZEM-003,014,016,017 Serial interface + GPIO_PZEM2_RX, // PZEM-003,014,016,017 Serial interface GPIO_SENSOR_END }; // Programmer selectable GPIO functionality offset by user selectable GPIOs @@ -169,7 +171,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_TM1638_CLK "|" D_SENSOR_TM1638_DIO "|" D_SENSOR_TM1638_STB "|" D_SENSOR_SWITCH "1n|" D_SENSOR_SWITCH "2n|" D_SENSOR_SWITCH "3n|" D_SENSOR_SWITCH "4n|" D_SENSOR_SWITCH "5n|" D_SENSOR_SWITCH "6n|" D_SENSOR_SWITCH "7n|" D_SENSOR_SWITCH "8n|" D_SENSOR_BUTTON "1n|" D_SENSOR_BUTTON "2n|" D_SENSOR_BUTTON "3n|" D_SENSOR_BUTTON "4n|" - D_SENSOR_COUNTER "1n|" D_SENSOR_COUNTER "2n|" D_SENSOR_COUNTER "3n|" D_SENSOR_COUNTER "4n|"; + D_SENSOR_COUNTER "1n|" D_SENSOR_COUNTER "2n|" D_SENSOR_COUNTER "3n|" D_SENSOR_COUNTER "4n|" + D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|"; /********************************************************************************************/ diff --git a/sonoff/user_config.h b/sonoff/user_config.h index ece854530..b742196a8 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -335,13 +335,16 @@ #define CO2_HIGH 1200 // Above this CO2 value show red light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1) #define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code) #define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code) -#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code) //#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code) #define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud) //#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code) #define SDM630_SPEED 9600 // SDM630-Modbus RS485 serial speed (default: 9600 baud) +// Power monitoring sensors ----------------------- +#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) +#define USE_PZEM2 // Add support for PZEM003,014,016,017 Energy monitor (+2k code) + // -- Low level interface devices ----------------- #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram) // #define USE_IR_HVAC // Support for HVAC system using IR (+2k code) diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino index 5c122c314..d9cfee8cb 100644 --- a/sonoff/xdrv_03_energy.ino +++ b/sonoff/xdrv_03_energy.ino @@ -44,6 +44,7 @@ const char kEnergyCommands[] PROGMEM = float energy_voltage = 0; // 123.1 V float energy_current = 0; // 123.123 A float energy_power = 0; // 123.1 W +float energy_frequency = 0; // 123.1 Hz float energy_power_factor = 0; // 0.12 float energy_daily = 0; // 123.123 kWh float energy_total = 0; // 12345.12345 kWh diff --git a/sonoff/xnrg_05_pzem2.ino b/sonoff/xnrg_05_pzem2.ino new file mode 100644 index 000000000..2b326f216 --- /dev/null +++ b/sonoff/xnrg_05_pzem2.ino @@ -0,0 +1,215 @@ +/* + xnrg_06_pzem2.ino - PZEM-003,017 and PZEM-014,016 Modbus energy sensor support for Sonoff-Tasmota + + Copyright (C) 2018 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_ENERGY_SENSOR +#ifdef USE_PZEM2 +/*********************************************************************************************\ + * PZEM-003 - DC 300V 10A Energy + * PZEM-014 - AC 220V 10A Energy + * PZEM-016 - AC 220V 100A Energy + * PZEM-017 - DC 300V 50A - 300A Energy + * + * Based on: + * PZEM-003,017 docs Https://pan.baidu.com/s/1V9bDWj3RK2u6_fbBJ3GtqQ password rq37 + * PZEM-014,016 docs https://pan.baidu.com/s/1B0MdMgURyjtO1oQa2lavKw password ytkv + * + * Hardware Serial will be selected if GPIO1 = [99 PZEM Rx] and GPIO3 = [98 PZEM Tx] +\*********************************************************************************************/ + +#define XNRG_05 5 + +#define PZEM2_TYPES_003_017 8 // Result 16 bit register count +#define PZEM2_TYPES_014_016 10 // Result 16 bit register count + +#define PZEM2_READ_RESULT 0x04 + +#include + +TasmotaSerial *Pzem2Serial; + +uint8_t pzem2_type = PZEM2_TYPES_014_016; + +/*********************************************************************************************/ + +uint16_t Pzem2ModbusCalculateCRC(uint8_t *frame, uint8_t num) +{ + uint16_t crc = 0xFFFF; + uint16_t flag; + + for (uint8_t i = 0; i < num; i++) { + crc ^= frame[i]; + for (uint8_t j = 8; j; j--) { + if ((crc & 0x0001) != 0) { // If the LSB is set + crc >>= 1; // Shift right and XOR 0xA001 + crc ^= 0xA001; + } else { // Else LSB is not set + crc >>= 1; // Just shift right + } + } + } + return crc; +} + +void Pzem2ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t register_count) +{ + uint8_t frame[8]; + + frame[0] = 0xFE; // Any Address + frame[1] = function_code; + frame[2] = (uint8_t)(start_address >> 8); + frame[3] = (uint8_t)(start_address); + frame[4] = (uint8_t)(register_count >> 8); + frame[5] = (uint8_t)(register_count); + uint16_t crc = Pzem2ModbusCalculateCRC(frame, 6); + frame[6] = (uint8_t)((crc >> 8) & 0xFF); + frame[7] = (uint8_t)(crc & 0xFF); + + Pzem2Serial->flush(); + Pzem2Serial->write(frame, sizeof(frame)); +} + +bool Pzem2ModbusReceiveReady() +{ + return (Pzem2Serial->available() >= 5); // 5 - Error frame, 21 or 25 - Ok frame +} + +uint8_t Pzem2ModbusReceive() +{ + uint8_t buffer[26]; + +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 +// FE 04 14 08 98 03 E8 00 00 08 98 00 00 00 00 00 00 01 F4 00 64 00 00 HH LL = PZEM-014 +// Id Cc Sz Volt- Current---- Power------ Energy----- Frequ PFact Alarm Crc-- +// FE 04 10 27 10 00 64 03 E8 00 00 00 00 00 00 00 00 00 00 HH LL = PZEM-017 +// Id Cc Sz Volt- Curre Power------ Energy----- HiAlm LoAlm Crc-- + + uint8_t len = 0; + while (Pzem2Serial->available() > 0) { + buffer[len++] = (uint8_t)Pzem2Serial->read(); + if (3 == len) { + if (buffer[1] & 0x80) { // fe 84 02 f2 f1 + return buffer[2]; // 1 = Illegal Function, 2 = Illegal Address, 3 = Illegal Data, 4 = Slave Error + } + } + if (sizeof(buffer) == len) { break; } + } + + AddLogSerial(LOG_LEVEL_DEBUG_MORE, buffer, len); + + if (len < 5) { return 8; } // 8 = Not enough data + if (len != buffer[2] + 5) { return 9; } // 9 = Unexpected result + + uint16_t crc = (buffer[len -2] << 8) | buffer[len -1]; + if (Pzem2ModbusCalculateCRC(buffer, len -3) == crc) { + float energy = 0; + if (0x10 == buffer[2]) { // PZEM-003,017 + pzem2_type = PZEM2_TYPES_003_017; + energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 10.0; // 65535.x V + energy_current = (float)((buffer[5] << 8) + buffer[6]); // 65535.xx A + energy_power = (float)((uint32_t)buffer[9] << 24 + (uint32_t)buffer[10] << 16 + (uint32_t)buffer[7] << 8 + buffer[8]); // 65535 W + energy = (float)((uint32_t)buffer[13] << 24 + (uint32_t)buffer[14] << 16 + (uint32_t)buffer[11] << 8 + buffer[12]); // 65535 Wh + if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any + energy_kWhtoday += (energy - energy_start) * 100; + energy_start = energy; + EnergyUpdateToday(); + } + else if (0x14 == buffer[2]) { // PZEM-014,016 + pzem2_type = PZEM2_TYPES_014_016; + energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 10.0; // 65535.x V + energy_current = (float)((uint32_t)buffer[7] << 24 + (uint32_t)buffer[8] << 16 + (uint32_t)buffer[5] << 8 + buffer[6]); // 65535.xx A + energy_power = (float)((uint32_t)buffer[11] << 24 + (uint32_t)buffer[12] << 16 + (uint32_t)buffer[9] << 8 + buffer[10]); // 65535 W + energy_frequency = (float)((buffer[13] << 8) + buffer[14]) / 10.0; // 50.0 Hz + energy = (float)((uint32_t)buffer[15] << 24 + (uint32_t)buffer[16] << 16 + (uint32_t)buffer[13] << 8 + buffer[14]); // 65535 Wh + if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any + energy_kWhtoday += (energy - energy_start) * 100; + energy_start = energy; + EnergyUpdateToday(); + } + } else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Pzem2 crc error")); + } + + return 0; // 0 = No error +} + +/*********************************************************************************************/ + +uint8_t pzem2_sendRetry = 0; + +void Pzem2EverySecond() +{ + bool data_ready = Pzem2ModbusReceiveReady(); + + if (data_ready) { Pzem2ModbusReceive(); } + + if (0 == pzem2_sendRetry || data_ready) { + pzem2_sendRetry = 5; + Pzem2ModbusSend(PZEM2_READ_RESULT, 0, pzem2_type); + } + else { + pzem2_sendRetry--; + } +} + +void Pzem2SnsInit() +{ + // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions + Pzem2Serial = new TasmotaSerial(pin[GPIO_PZEM2_RX], pin[GPIO_PZEM2_TX], 1); + if (Pzem2Serial->begin(9600)) { + if (Pzem2Serial->hardwareSerial()) { ClaimSerial(); } + } else { + energy_flg = ENERGY_NONE; + } +} + +void Pzem2DrvInit() +{ + if (!energy_flg) { + if ((pin[GPIO_PZEM2_RX] < 99) && (pin[GPIO_PZEM2_TX] < 99)) { // Any device with a Pzem-003,014,016,017 + energy_flg = XNRG_05; + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +int Xnrg05(byte function) +{ + int result = 0; + + if (FUNC_PRE_INIT == function) { + Pzem2DrvInit(); + } + else if (XNRG_03 == energy_flg) { + switch (function) { + case FUNC_INIT: + Pzem2SnsInit(); + break; + case FUNC_EVERY_SECOND: + Pzem2EverySecond(); + break; + } + } + return result; +} + +#endif // USE_PZEM2 +#endif // USE_ENERGY_SENSOR From 2fdc91f1b4b671b8d1af45354073e3fed1b66a02 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 6 Sep 2018 18:08:10 +0200 Subject: [PATCH 24/82] Housekeeping --- sonoff/support.ino | 19 ++++++++++++++++++- sonoff/user_config.h | 2 +- tools/decode-status.py | 8 +++++--- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/sonoff/support.ino b/sonoff/support.ino index 51b59c554..57cb6d9f4 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -609,6 +609,10 @@ boolean GetUsedInModule(byte val, uint8_t *arr) if (GPIO_PZEM_TX == val) { return true; } if (GPIO_PZEM_RX == val) { return true; } #endif +#ifndef USE_PZEM2 + if (GPIO_PZEM2_TX == val) { return true; } + if (GPIO_PZEM2_RX == val) { return true; } +#endif #ifndef USE_SENSEAIR if (GPIO_SAIR_TX == val) { return true; } if (GPIO_SAIR_RX == val) { return true; } @@ -965,7 +969,7 @@ void GetFeatures() feature_sns1 |= 0x00000004; // xdrv_03_energy.ino #endif #ifdef USE_PZEM004T - feature_sns1 |= 0x00000008; // xdrv_03_energy.ino + feature_sns1 |= 0x00000008; // xnrg_03_pzem004t.ino #endif #ifdef USE_DS18B20 feature_sns1 |= 0x00000010; // xsns_05_ds18b20.ino @@ -1074,6 +1078,19 @@ void GetFeatures() #ifdef USE_MCP230xx_DISPLAYOUTPUT feature_sns2 |= 0x00000020; // xsns_29_mcp230xx.ino #endif +#ifdef USE_HLW8012 + feature_sns2 |= 0x00000040; // xnrg_01_hlw8012.ino +#endif +#ifdef USE_CSE7766 + feature_sns2 |= 0x00000080; // xnrg_02_cse7766.ino +#endif +#ifdef USE_MCP39F501 + feature_sns2 |= 0x00000100; // xnrg_04_mcp39f501.ino +#endif +#ifdef USE_PZEM2 + feature_sns2 |= 0x00000200; // xnrg_05_pzem2.ino +#endif + } /*********************************************************************************************\ diff --git a/sonoff/user_config.h b/sonoff/user_config.h index b742196a8..81928f1e7 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -343,7 +343,7 @@ // Power monitoring sensors ----------------------- #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) -#define USE_PZEM2 // Add support for PZEM003,014,016,017 Energy monitor (+2k code) +#define USE_PZEM2 // Add support for PZEM003,014,016,017 Energy monitor (+1k1 code) // -- Low level interface devices ----------------- #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram) diff --git a/tools/decode-status.py b/tools/decode-status.py index 7f06b674b..b26be9df0 100644 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -83,7 +83,9 @@ a_setoption = [[ "Do not show Wifi and Mqtt state using Led" ],[ "Timers enabled", - "","","", + "Generic ESP8285 GPIO enabled", + "Add UTC time offset to JSON message", + "", "","","","", "","","","", "","","","", @@ -122,8 +124,8 @@ a_features = [[ "USE_SDM630","USE_LM75AD","USE_APDS9960","USE_TM1638" ],[ "USE_MCP230xx","USE_MPR121","USE_CCS811","USE_MPU6050", - "USE_MCP230xx_OUTPUT","USE_MCP230xx_DISPLAYOUTPUT","","", - "","","","", + "USE_MCP230xx_OUTPUT","USE_MCP230xx_DISPLAYOUTPUT","USE_HLW8012","USE_CSE7766", + "USE_MCP39F501","USE_PZEM2","","", "","","","", "","","","", "","","","", From 420be8f4990ec838d51b0f58dad8c814db058461 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Thu, 6 Sep 2018 14:21:52 -0300 Subject: [PATCH 25/82] Simplified Function Substr --- sonoff/support.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/support.ino b/sonoff/support.ino index 57cb6d9f4..d00ee009b 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -143,7 +143,7 @@ char* subStr(char* dest, char* str, const char *delim, int index) int i; // Since strtok consumes the first arg, make a copy - strncpy(dest, str, strlen(str)); + strncpy(dest, str, strlen(str)+1); for (i = 1, act = dest; i <= index; i++, act = NULL) { sub = strtok_r(act, delim, &ptr); if (sub == NULL) break; From 96aff63c712f2ec81ae28e1cf207d8fb4ccbe278 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Thu, 6 Sep 2018 14:26:26 -0300 Subject: [PATCH 26/82] Code Simplification for Substr --- sonoff/xdrv_11_knx.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sonoff/xdrv_11_knx.ino b/sonoff/xdrv_11_knx.ino index ca5e22090..3897caac7 100644 --- a/sonoff/xdrv_11_knx.ino +++ b/sonoff/xdrv_11_knx.ino @@ -1156,7 +1156,7 @@ boolean KnxCommand() else if (CMND_KNX_PA == command_code) { if (XdrvMailbox.data_len) { if (strstr(XdrvMailbox.data, ".")) { // Process parameter entry - char sub_string[XdrvMailbox.data_len +1]; + char sub_string[XdrvMailbox.data_len]; int pa_area = atoi(subStr(sub_string, XdrvMailbox.data, ".", 1)); int pa_line = atoi(subStr(sub_string, XdrvMailbox.data, ".", 2)); @@ -1183,7 +1183,7 @@ boolean KnxCommand() else if ((CMND_KNX_GA == command_code) && (index > 0) && (index <= MAX_KNX_GA)) { if (XdrvMailbox.data_len) { if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry - char sub_string[XdrvMailbox.data_len +1]; + char sub_string[XdrvMailbox.data_len]; int ga_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1)); int ga_area = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); @@ -1232,7 +1232,7 @@ boolean KnxCommand() else if ((CMND_KNX_CB == command_code) && (index > 0) && (index <= MAX_KNX_CB)) { if (XdrvMailbox.data_len) { if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry - char sub_string[XdrvMailbox.data_len +1]; + char sub_string[XdrvMailbox.data_len]; int cb_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1)); int cb_area = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); From c827270cc2c3e1f3bc315cf5a420c7ba8b65fec2 Mon Sep 17 00:00:00 2001 From: andrethomas Date: Thu, 6 Sep 2018 19:26:52 +0200 Subject: [PATCH 27/82] Update MCP230xx to conform to new usage of subStr() --- sonoff/support.ino | 2 +- sonoff/xsns_29_mcp230xx.ino | 27 ++++++++++++++------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/sonoff/support.ino b/sonoff/support.ino index 57cb6d9f4..d00ee009b 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -143,7 +143,7 @@ char* subStr(char* dest, char* str, const char *delim, int index) int i; // Since strtok consumes the first arg, make a copy - strncpy(dest, str, strlen(str)); + strncpy(dest, str, strlen(str)+1); for (i = 1, act = dest; i <= index; i++, act = NULL) { sub = strtok_r(act, delim, &ptr); if (sub == NULL) break; diff --git a/sonoff/xsns_29_mcp230xx.ino b/sonoff/xsns_29_mcp230xx.ino index f27d68990..d6683da44 100644 --- a/sonoff/xsns_29_mcp230xx.ino +++ b/sonoff/xsns_29_mcp230xx.ino @@ -421,10 +421,11 @@ bool MCP230xx_Command(void) { uint8_t paramcount = 0; if (XdrvMailbox.data_len > 0) { paramcount=1; - sprintf(XdrvMailbox.data,"%s,",XdrvMailbox.data); // need a trailing comma to make substr work properly with last variable - bug? dunno? - XdrvMailbox.data_len++; + } else { + serviced = false; + return serviced; } - char sub_string[XdrvMailbox.data_len +1]; + char sub_string[XdrvMailbox.data_len]; for (uint8_t ca=0;ca 2) { + if (paramcount > 1) { uint8_t intpri = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); if ((intpri >= 0) && (intpri <= 20)) { Settings.mcp230xx_int_prio = intpri; @@ -455,7 +456,7 @@ bool MCP230xx_Command(void) { } if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTTIMER")) { - if (paramcount > 2) { + if (paramcount > 1) { uint8_t inttim = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); if ((inttim >= 0) && (inttim <= 3600)) { Settings.mcp230xx_int_timer = inttim; @@ -470,7 +471,7 @@ bool MCP230xx_Command(void) { } if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTDEF")) { - if (paramcount > 2) { + if (paramcount > 1) { uint8_t pin = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); if (pin < mcp230xx_pincount) { if (pin == 0) { @@ -480,7 +481,7 @@ bool MCP230xx_Command(void) { } } if (validpin) { - if (paramcount > 3) { + if (paramcount > 2) { uint8_t intdef = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3)); if ((intdef >= 0) && (intdef <= 15)) { Settings.mcp230xx_config[pin].int_report_defer=intdef; @@ -510,7 +511,7 @@ bool MCP230xx_Command(void) { } if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTCNT")) { - if (paramcount > 2) { + if (paramcount > 1) { uint8_t pin = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); if (pin < mcp230xx_pincount) { if (pin == 0) { @@ -520,7 +521,7 @@ bool MCP230xx_Command(void) { } } if (validpin) { - if (paramcount > 3) { + if (paramcount > 2) { uint8_t intcnt = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3)); if ((intcnt >= 0) && (intcnt <= 1)) { Settings.mcp230xx_config[pin].int_count_en=intcnt; @@ -567,7 +568,7 @@ bool MCP230xx_Command(void) { validpin=true; } } - if (validpin && (paramcount > 2)) { + if (validpin && (paramcount > 1)) { if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 2), "?")) { uint8_t port = 0; if (pin > 7) { port = 1; } @@ -606,13 +607,13 @@ bool MCP230xx_Command(void) { uint8_t pinmode = 0; uint8_t pullup = 0; uint8_t intmode = 0; - if (paramcount > 2) { + if (paramcount > 1) { pinmode = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); } - if (paramcount > 3) { + if (paramcount > 2) { pullup = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3)); } - if (paramcount > 4) { + if (paramcount > 3) { intmode = atoi(subStr(sub_string, XdrvMailbox.data, ",", 4)); } #ifdef USE_MCP230xx_OUTPUT From 10bb6b856f8588f43943015124161675c343cae5 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Thu, 6 Sep 2018 15:38:10 -0300 Subject: [PATCH 28/82] Fix Compilation of Sonoff Classic Version --- sonoff/sonoff_post.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index dc49211d1..7504af3b4 100755 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -137,6 +137,7 @@ void KNX_CB_Action(message_t const &msg, void *arg); #undef USE_PMS5003 // Disable support for PMS5003 and PMS7003 particle concentration sensor #undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor #undef USE_PZEM004T // Disable PZEM004T energy sensor +#undef USE_PZEM2 // Disable PZEM003,014,016,017 Energy monitor #undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge #undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter #undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy meter From 7722f5232a4d484b5c2ca862f55a6e727119a26c Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 07:54:29 +0200 Subject: [PATCH 29/82] Added DFPlayer Mini MP3 Player (RB-DFR-562) --- sonoff/sonoff_template.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 3881f8c3e..c6e70b98c 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -122,6 +122,7 @@ enum UserSelectablePins { GPIO_CNTR4_NP, GPIO_PZEM2_TX, // PZEM-003,014,016,017 Serial interface GPIO_PZEM2_RX, // PZEM-003,014,016,017 Serial interface + GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player GPIO_SENSOR_END }; // Programmer selectable GPIO functionality offset by user selectable GPIOs @@ -172,7 +173,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_SWITCH "1n|" D_SENSOR_SWITCH "2n|" D_SENSOR_SWITCH "3n|" D_SENSOR_SWITCH "4n|" D_SENSOR_SWITCH "5n|" D_SENSOR_SWITCH "6n|" D_SENSOR_SWITCH "7n|" D_SENSOR_SWITCH "8n|" D_SENSOR_BUTTON "1n|" D_SENSOR_BUTTON "2n|" D_SENSOR_BUTTON "3n|" D_SENSOR_BUTTON "4n|" D_SENSOR_COUNTER "1n|" D_SENSOR_COUNTER "2n|" D_SENSOR_COUNTER "3n|" D_SENSOR_COUNTER "4n|" - D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|"; + D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|" + D_SENSOR_MP3_DFR562; /********************************************************************************************/ @@ -1019,4 +1021,4 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { } */ -#endif // _SONOFF_TEMPLATE_H_ \ No newline at end of file +#endif // _SONOFF_TEMPLATE_H_ From a416f0b33487bd5dc37ab2dd1cec6c8e2d55839c Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 07:59:08 +0200 Subject: [PATCH 30/82] Add files via upload --- sonoff/xdrv_91_mp3.ino | 117 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 sonoff/xdrv_91_mp3.ino diff --git a/sonoff/xdrv_91_mp3.ino b/sonoff/xdrv_91_mp3.ino new file mode 100644 index 000000000..82c778127 --- /dev/null +++ b/sonoff/xdrv_91_mp3.ino @@ -0,0 +1,117 @@ +/* + xdrv_91_mp3.ino - MP3 Player support for Sonoff-Tasmota + Player type: RB-DFR-562, DFPlayer Mini MP3 Player + Copyright (C) 2018 Theo Arends + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#ifdef USE_MP3_PLAYER + +#include + +TasmotaSerial *MP3Player; + +#define D_CMND_MP3 "MP3" +const char S_JSON_MP3_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MP3 "%s\":%d}"; +const char S_JSON_MP3_COMMAND[] PROGMEM = "{\"" D_CMND_MP3 "%s\"}"; + +enum MP3_Commands { CMND_MP3_PLAY, CMND_MP3_STOP, CMND_MP3_VOLUME}; +const char kMP3_Commands[] PROGMEM = "Play" "|" "Stop" "|" "Volume"; + +#define MP3_CMD_PLAY 3 +#define MP3_CMD_VOLUME 6 +#define MP3_CMD_STOP 0x0e + +uint16_t MP3_Checksum(uint8_t *array) +{ + uint16_t checksum = 0; + for (uint8_t i = 0; i < 6; i++) { + checksum += array[i]; + } + checksum = checksum^0xffff; + return checksum+1; +} + +// init player define serial tx port +void InitMP3Player() { + MP3Player = new TasmotaSerial(-1, pin[GPIO_MP3PLAYER]); + + if (MP3Player->begin(9600)) { + //serial_bridge_active = 1; + MP3Player->flush(); + } +} + +void MP3_CMD(uint8_t mp3cmd,uint16_t val) { + uint8_t cmd[10] = {0x7e,0xff,6,0,0,0,0,0,0,0xef}; + cmd[3] = mp3cmd; + cmd[5] = val>>8; + cmd[6] = val; + uint16_t chks = MP3_Checksum(&cmd[1]); // calculate out + cmd[7] = chks>>8; + cmd[8] = chks; + MP3Player->write(cmd, sizeof(cmd)); +} + +boolean MP3PlayerCmd() { + char command[CMDSZ]; + boolean serviced = true; + uint8_t disp_len = strlen(D_CMND_MP3); + + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_MP3), disp_len)) { // Prefix + int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + disp_len, kMP3_Commands); + + if (CMND_MP3_PLAY == command_code) { + if (XdrvMailbox.data_len > 0) { // play + MP3_CMD(MP3_CMD_PLAY, XdrvMailbox.payload); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND_NVALUE, command, XdrvMailbox.payload); + } + else if (CMND_MP3_VOLUME == command_code) { + if (XdrvMailbox.data_len > 0) { // set volume + MP3_CMD(MP3_CMD_VOLUME, XdrvMailbox.payload * 30 / 100); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND_NVALUE, command, XdrvMailbox.payload); + } + else if (CMND_MP3_STOP == command_code) { // stop + MP3_CMD(MP3_CMD_STOP, 0); + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND, command, XdrvMailbox.payload); + } else { + serviced = false; // Unknown command + } + } + return serviced; +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +#define XDRV_91 + +boolean Xdrv91(byte function) +{ + boolean result = false; + + switch (function) { + case FUNC_PRE_INIT: + InitMP3Player(); + break; + case FUNC_COMMAND: + result = MP3PlayerCmd(); + break; + } + return result; +} + +#endif // USE_MP3_PLAYER From 5582c85b3b36bad9d37bc0d4af9f8c118c0f5573 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:05:58 +0200 Subject: [PATCH 31/82] define MP3 Player added //#define USE_MP3_PLAYER --- sonoff/user_config.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 81928f1e7..b7a54408d 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -268,6 +268,9 @@ // -- Internal Analog input ----------------------- #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices +// -- MP3 player ---------------------------------- +//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop + // -- One wire sensors ---------------------------- // WARNING: Select none for default one DS18B20 sensor or enable one of the following two options for multiple sensors #define USE_DS18x20 // Optional for more than one DS18x20 sensors with id sort, single scan and read retry (+1k3 code) From b13c5452a510774019a172a10b031b13639af5fb Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:10:32 +0200 Subject: [PATCH 32/82] Added #define D_SENSOR_MP3_DFR562 "MP3 Player" --- sonoff/language/en-GB.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 558877db2..e6ce2eca4 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_MP3_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1" From 7fd8dcd68dfe77624e7b227208e56e4b4fe78233 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:11:53 +0200 Subject: [PATCH 33/82] Update en-GB.h --- sonoff/language/en-GB.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index e6ce2eca4..a622419fa 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -456,7 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" -#define D_SENSOR_MP3_DFR562 "MP3 Player" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1" From 96682723d32e400bb37ba00e95c92f5b04c5db2b Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:14:07 +0200 Subject: [PATCH 34/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/sonoff_template.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index c6e70b98c..2ab43286d 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -174,7 +174,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BUTTON "1n|" D_SENSOR_BUTTON "2n|" D_SENSOR_BUTTON "3n|" D_SENSOR_BUTTON "4n|" D_SENSOR_COUNTER "1n|" D_SENSOR_COUNTER "2n|" D_SENSOR_COUNTER "3n|" D_SENSOR_COUNTER "4n|" D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|" - D_SENSOR_MP3_DFR562; + D_SENSOR_DFR562; /********************************************************************************************/ From 14ab4b718d2257e2acc350692e0376d0eaaaae67 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:16:03 +0200 Subject: [PATCH 35/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/bg-BG.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index b1ecd6fa6..bd76cf0be 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Ключ" // Suffix "1" #define D_SENSOR_BUTTON "Бутон" // Suffix "1" From 7722c663a033b1fad68ca9e78aa441ffb8f1c8ff Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:17:26 +0200 Subject: [PATCH 36/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/cs-CZ.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 2f51ccc93..0a3430e01 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Spínač" // Suffix "1" #define D_SENSOR_BUTTON "Tlačítko" // Suffix "1" From a5c85a6882a4648b1e5e8258be5d07968ef6eac2 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:18:06 +0200 Subject: [PATCH 37/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/de-DE.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 888345d8a..32d6a8f2b 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRSend" #define D_SENSOR_SWITCH "Switch " // Suffix "1" #define D_SENSOR_BUTTON "Button " // Suffix "1" From 9ce856bb6ee7b7a146354a1fb226b4887c687e48 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:19:41 +0200 Subject: [PATCH 38/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/el-GR.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 3187eadf9..b2fa8feb6 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Διακόπτης" // Suffix "1" #define D_SENSOR_BUTTON "Κουμπί" // Suffix "1" From f891a8a2e73d172e7368ac5d089ba4a9c017ed2e Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:22:02 +0200 Subject: [PATCH 39/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/es-AR.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 986b9507f..398d0442f 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IR TX" #define D_SENSOR_SWITCH "Llave" // Suffix "1" #define D_SENSOR_BUTTON "Botón" // Suffix "1" From 1791f8e034ffb1f0fab077592eb4b913e75ef2b8 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:23:00 +0200 Subject: [PATCH 40/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/fr-FR.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index 2a46f7b53..a4b7d2011 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "ÉmetIR" #define D_SENSOR_SWITCH "Inter." // Suffix "1" #define D_SENSOR_BUTTON "Bouton" // Suffix "1" From f3ebfe7c5f3e10f19ed406720b8136070eeba2b7 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:24:03 +0200 Subject: [PATCH 41/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/it-IT.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index d07a33021..509105eb5 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1" From efd1b8a1a3643af57ffda75a049288ab83f3ce72 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:24:12 +0200 Subject: [PATCH 42/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/hu-HU.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index c57278176..79fd88d8e 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRadó" #define D_SENSOR_SWITCH "Kapcsoló" // Suffix "1" #define D_SENSOR_BUTTON "Gomb" // Suffix "1" From 3b22dc7d52b1f7b7761a746389928b1a8a9120c3 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:26:33 +0200 Subject: [PATCH 43/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/nl-NL.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 05ec4666b..2761e45d3 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Speler" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1" From d6324a9f44edf58e4fe9d29b66832ba5aa8c3732 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:27:28 +0200 Subject: [PATCH 44/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/pl-PL.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index faaf8df6d..9fa16ac9f 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Przela" // Suffix "1" #define D_SENSOR_BUTTON "Przyci" // Suffix "1" From 1cf7bc747df792834a412914c5fe7f69ed54e384 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:28:50 +0200 Subject: [PATCH 45/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/pt-PT.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index d39ec6e50..d4cea0a48 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Interruptor" // Suffix "1" #define D_SENSOR_BUTTON "Botão" // Suffix "1" From f6f69e3b4df2245e739c969e62cd7c1e181c127b Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:29:00 +0200 Subject: [PATCH 46/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/pt-BR.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index 318f69e45..46a21b998 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Interruptor" // Suffix "1" #define D_SENSOR_BUTTON "Botão" // Suffix "1" From 764af507b9df4fa057cc8202f3455404c1d0d1ee Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:30:24 +0200 Subject: [PATCH 47/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/tr-TR.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index b133d2c80..1f11d4a01 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1" From 8dfbaf656651cbdc164c2177ae9fd9eef6cdb004 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:30:31 +0200 Subject: [PATCH 48/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/ru-RU.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index 5fea0468e..e782e9409 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Свич" // Suffix "1" #define D_SENSOR_BUTTON "Кнопка" // Suffix "1" From a33566f93e547a6014119b4aa1c41cee2a102a78 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:34:15 +0200 Subject: [PATCH 49/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/zh-TW.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index abb92d359..c07023268 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1" From a37f0b397335ff79a558852d4e38d29c322fc845 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:34:22 +0200 Subject: [PATCH 50/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/zh-CN.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index 88f680f8e..24eb38f6f 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1" From 9bb6c201dfe882a157077d53ac8b21e4f391e8b3 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 7 Sep 2018 08:34:31 +0200 Subject: [PATCH 51/82] Added DFPlayer Mini MP3 Player, D_SENSOR_DFR562 --- sonoff/language/uk-UK.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index 9cf66773b..90cfb9f4a 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -456,6 +456,7 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" #define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_SWITCH "Перемикач" // Suffix "1" #define D_SENSOR_BUTTON "Кнопка" // Suffix "1" From b659444c3abb8fd641ed1eb7eeeaa08034297f4f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 7 Sep 2018 10:54:24 +0200 Subject: [PATCH 52/82] Add basic MP3 player * Fix KNX PA exception. Regression from 6.2.1 buffer overflow caused by subStr() (#3700, #3710) * Add basic support for MP3 player using DFRobot RB-DFR-562 (#3723) --- sonoff/_changelog.ino | 3 +- sonoff/user_config.h | 4 +-- sonoff/{xdrv_91_mp3.ino => xdrv_14_mp3.ino} | 36 ++++++++++++--------- 3 files changed, 24 insertions(+), 19 deletions(-) rename sonoff/{xdrv_91_mp3.ino => xdrv_14_mp3.ino} (83%) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 49193dfbd..82d12f28e 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,7 +1,8 @@ /* 6.2.1.2 20180906 - * Fix KNX PA exception. Regression from 6.2.1 buffer overflow (#3700, #3710) + * Fix KNX PA exception. Regression from 6.2.1 buffer overflow caused by subStr() (#3700, #3710) * Add command SetOption52 to control display of optional time offset from UTC in JSON messages (#3629, #3711) * Add experimental support for PZEM-003,014,016,017 Energy monitoring (#3694) + * Add basic support for MP3 player using DFRobot RB-DFR-562 (#3723) * * 6.2.1.1 20180905 * Rewrite energy monitoring using energy sensor driver modules diff --git a/sonoff/user_config.h b/sonoff/user_config.h index b7a54408d..d46a295d7 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -268,9 +268,6 @@ // -- Internal Analog input ----------------------- #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices -// -- MP3 player ---------------------------------- -//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop - // -- One wire sensors ---------------------------- // WARNING: Select none for default one DS18B20 sensor or enable one of the following two options for multiple sensors #define USE_DS18x20 // Optional for more than one DS18x20 sensors with id sort, single scan and read retry (+1k3 code) @@ -343,6 +340,7 @@ #define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud) //#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code) #define SDM630_SPEED 9600 // SDM630-Modbus RS485 serial speed (default: 9600 baud) +//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop // Power monitoring sensors ----------------------- #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) diff --git a/sonoff/xdrv_91_mp3.ino b/sonoff/xdrv_14_mp3.ino similarity index 83% rename from sonoff/xdrv_91_mp3.ino rename to sonoff/xdrv_14_mp3.ino index 82c778127..e4c72cb16 100644 --- a/sonoff/xdrv_91_mp3.ino +++ b/sonoff/xdrv_14_mp3.ino @@ -1,32 +1,39 @@ /* - xdrv_91_mp3.ino - MP3 Player support for Sonoff-Tasmota - Player type: RB-DFR-562, DFPlayer Mini MP3 Player - Copyright (C) 2018 Theo Arends + xdrv_14_mp3.ino - MP3 support for Sonoff-Tasmota + + Copyright (C) 2018 gemu2015, mike2nl and Theo Arends + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with this program. If not, see . - */ #ifdef USE_MP3_PLAYER +/*********************************************************************************************\ + * MP3 control for RB-DFR-562 DFRobot mini MP3 player + * https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299 +\*********************************************************************************************/ #include TasmotaSerial *MP3Player; #define D_CMND_MP3 "MP3" + const char S_JSON_MP3_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MP3 "%s\":%d}"; const char S_JSON_MP3_COMMAND[] PROGMEM = "{\"" D_CMND_MP3 "%s\"}"; enum MP3_Commands { CMND_MP3_PLAY, CMND_MP3_STOP, CMND_MP3_VOLUME}; -const char kMP3_Commands[] PROGMEM = "Play" "|" "Stop" "|" "Volume"; +const char kMP3_Commands[] PROGMEM = "Play|Stop|Volume"; #define MP3_CMD_PLAY 3 #define MP3_CMD_VOLUME 6 @@ -43,11 +50,10 @@ uint16_t MP3_Checksum(uint8_t *array) } // init player define serial tx port -void InitMP3Player() { - MP3Player = new TasmotaSerial(-1, pin[GPIO_MP3PLAYER]); - +void MP3PlayerInit() { + MP3Player = new TasmotaSerial(-1, pin[GPIO_MP3_DFR562]); + if (MP3Player->begin(9600)) { - //serial_bridge_active = 1; MP3Player->flush(); } } @@ -67,7 +73,7 @@ boolean MP3PlayerCmd() { char command[CMDSZ]; boolean serviced = true; uint8_t disp_len = strlen(D_CMND_MP3); - + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_MP3), disp_len)) { // Prefix int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + disp_len, kMP3_Commands); @@ -82,7 +88,7 @@ boolean MP3PlayerCmd() { MP3_CMD(MP3_CMD_VOLUME, XdrvMailbox.payload * 30 / 100); } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND_NVALUE, command, XdrvMailbox.payload); - } + } else if (CMND_MP3_STOP == command_code) { // stop MP3_CMD(MP3_CMD_STOP, 0); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND, command, XdrvMailbox.payload); @@ -97,15 +103,15 @@ boolean MP3PlayerCmd() { * Interface \*********************************************************************************************/ -#define XDRV_91 +#define XDRV_14 -boolean Xdrv91(byte function) +boolean Xdrv14(byte function) { boolean result = false; switch (function) { case FUNC_PRE_INIT: - InitMP3Player(); + MP3PlayerInit(); break; case FUNC_COMMAND: result = MP3PlayerCmd(); @@ -114,4 +120,4 @@ boolean Xdrv91(byte function) return result; } -#endif // USE_MP3_PLAYER +#endif // USE_MP3_PLAYER From f517755303587f5d5a6b60fb9c75d3dda2dabcde Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 7 Sep 2018 18:15:47 +0200 Subject: [PATCH 53/82] Prep for frequency display Prep for energy frequency display and update xnrg_05_pzem2.ino with correct register values --- sonoff/i18n.h | 1 + sonoff/settings.h | 3 +- sonoff/sonoff.ino | 14 +++-- sonoff/xdrv_03_energy.ino | 76 ++++++++++++++++++--------- sonoff/xnrg_01_hlw8012.ino | 37 ++++++------- sonoff/xnrg_02_cse7766.ino | 1 + sonoff/xnrg_03_pzem004t.ino | 1 + sonoff/xnrg_05_pzem2.ino | 101 ++++++++++++++++++++---------------- sonoff/xsns_23_sdm120.ino | 2 +- 9 files changed, 142 insertions(+), 94 deletions(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 5559ac6d1..da47371d8 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -181,6 +181,7 @@ #define D_CMND_PRESSURE_RESOLUTION "PressRes" #define D_CMND_POWER_RESOLUTION "WattRes" #define D_CMND_VOLTAGE_RESOLUTION "VoltRes" +#define D_CMND_FREQUENCY_RESOLUTION "FreqRes" #define D_CMND_CURRENT_RESOLUTION "AmpRes" #define D_CMND_ENERGY_RESOLUTION "EnergyRes" #define D_CMND_MODULE "Module" diff --git a/sonoff/settings.h b/sonoff/settings.h index 32bc80ad0..a1fd218ac 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -112,8 +112,7 @@ typedef union { uint32_t spare08 : 1; uint32_t spare09 : 1; uint32_t spare10 : 1; - uint32_t spare11 : 1; - uint32_t spare12 : 1; + uint32_t frequency_resolution : 2; uint32_t axis_resolution : 2; uint32_t current_resolution : 2; uint32_t voltage_resolution : 2; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 6163acfa4..6b2e8422b 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -77,8 +77,8 @@ enum TasmotaCommands { CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_FANSPEED, CMND_STATUS, CMND_STATE, CMND_POWERONSTATE, CMND_PULSETIME, CMND_BLINKTIME, CMND_BLINKCOUNT, CMND_SENSOR, CMND_SAVEDATA, CMND_SETOPTION, CMND_TEMPERATURE_RESOLUTION, CMND_HUMIDITY_RESOLUTION, - CMND_PRESSURE_RESOLUTION, CMND_POWER_RESOLUTION, CMND_VOLTAGE_RESOLUTION, CMND_CURRENT_RESOLUTION, CMND_ENERGY_RESOLUTION, CMND_MODULE, CMND_MODULES, - CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE, + CMND_PRESSURE_RESOLUTION, CMND_POWER_RESOLUTION, CMND_VOLTAGE_RESOLUTION, CMND_FREQUENCY_RESOLUTION, CMND_CURRENT_RESOLUTION, CMND_ENERGY_RESOLUTION, + CMND_MODULE, CMND_MODULES, CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE, CMND_COUNTERDEBOUNCE, CMND_BUTTONDEBOUNCE, CMND_SWITCHDEBOUNCE, CMND_SLEEP, CMND_UPGRADE, CMND_UPLOAD, CMND_OTAURL, CMND_SERIALLOG, CMND_SYSLOG, CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME, CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, @@ -87,8 +87,8 @@ enum TasmotaCommands { const char kTasmotaCommands[] PROGMEM = D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_FANSPEED "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|" D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SENSOR "|" D_CMND_SAVEDATA "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|" - D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|" D_CMND_MODULE "|" D_CMND_MODULES "|" - D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|" + D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_FREQUENCY_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|" + D_CMND_MODULE "|" D_CMND_MODULES "|" D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|" D_CMND_COUNTERDEBOUNCE "|" D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" @@ -794,6 +794,12 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.voltage_resolution); } + else if (CMND_FREQUENCY_RESOLUTION == command_code) { + if ((payload >= 0) && (payload <= 3)) { + Settings.flag2.frequency_resolution = payload; + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.frequency_resolution); + } else if (CMND_CURRENT_RESOLUTION == command_code) { if ((payload >= 0) && (payload <= 3)) { Settings.flag2.current_resolution = payload; diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino index d9cfee8cb..081b52d83 100644 --- a/sonoff/xdrv_03_energy.ino +++ b/sonoff/xdrv_03_energy.ino @@ -44,11 +44,13 @@ const char kEnergyCommands[] PROGMEM = float energy_voltage = 0; // 123.1 V float energy_current = 0; // 123.123 A float energy_power = 0; // 123.1 W -float energy_frequency = 0; // 123.1 Hz -float energy_power_factor = 0; // 0.12 +float energy_power_factor = NAN; // 0.12 +int energy_calc_power_factor = 0; // Do not calculate power factor from data +float energy_frequency = NAN; // 123.1 Hz +float energy_start = 0; // 12345.12345 kWh total previous + float energy_daily = 0; // 123.123 kWh float energy_total = 0; // 12345.12345 kWh -float energy_start = 0; // 12345.12345 kWh total previous unsigned long energy_kWhtoday_delta = 0; // 1212312345 Wh 10^-5 (deca micro Watt hours) - Overflows to energy_kWhtoday (HLW and CSE only) unsigned long energy_kWhtoday; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = energy_daily unsigned long energy_period = 0; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = energy_daily @@ -123,12 +125,14 @@ void Energy200ms() XnrgCall(FUNC_EVERY_200_MSECOND); - float power_factor = 0; - if (energy_voltage && energy_current && energy_power) { - power_factor = energy_power / (energy_voltage * energy_current); - if (power_factor > 1) power_factor = 1; + if (energy_calc_power_factor) { + float power_factor = 0; + if (energy_voltage && energy_current && energy_power) { + power_factor = energy_power / (energy_voltage * energy_current); + if (power_factor > 1) power_factor = 1; + } + energy_power_factor = power_factor; } - energy_power_factor = power_factor; } void EnergySaveState() @@ -537,11 +541,18 @@ void EnergySnsInit() } #ifdef USE_WEBSERVER -const char HTTP_ENERGY_SNS[] PROGMEM = "%s" +const char HTTP_ENERGY_SNS1[] PROGMEM = "%s" "{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}" "{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}" - "{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}" - "{s}" D_POWER_FACTOR "{m}%s{e}" + "{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}"; + +const char HTTP_ENERGY_SNS2[] PROGMEM = "%s" + "{s}" D_POWER_FACTOR "{m}%s{e}"; + +const char HTTP_ENERGY_SNS3[] PROGMEM = "%s" + "{s}" D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"; + +const char HTTP_ENERGY_SNS4[] PROGMEM = "%s" "{s}" D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}" "{s}" D_ENERGY_YESTERDAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}" "{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; // {s} = , {m} = , {e} = @@ -555,31 +566,43 @@ void EnergyShow(boolean json) char energy_power_chr[10]; char energy_voltage_chr[10]; char energy_current_chr[10]; + char energy_frequency_chr[10]; char energy_power_factor_chr[10]; char energy_yesterday_chr[10]; char speriod[20]; + char spfactor[20]; + char sfrequency[20]; bool show_energy_period = (0 == tele_period); + dtostrfd(energy_power, Settings.flag2.wattage_resolution, energy_power_chr); + dtostrfd(energy_voltage, Settings.flag2.voltage_resolution, energy_voltage_chr); + dtostrfd(energy_current, Settings.flag2.current_resolution, energy_current_chr); + dtostrfd(energy_total, Settings.flag2.energy_resolution, energy_total_chr); + dtostrfd(energy_daily, Settings.flag2.energy_resolution, energy_daily_chr); + dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr); + float energy = 0; if (show_energy_period) { if (energy_period) energy = (float)(energy_kWhtoday - energy_period) / 100; energy_period = energy_kWhtoday; + dtostrfd(energy, Settings.flag2.wattage_resolution, energy_period_chr); + snprintf_P(speriod, sizeof(speriod), PSTR(",\"" D_JSON_PERIOD "\":%s"), energy_period_chr); + } + if (!isnan(energy_frequency)) { + dtostrfd(energy_frequency, Settings.flag2.frequency_resolution, energy_frequency_chr); + snprintf_P(sfrequency, sizeof(sfrequency), PSTR(",\"" D_JSON_FREQUENCY "\":%s"), energy_frequency_chr); + } + if (!isnan(energy_power_factor)) { + dtostrfd(energy_power_factor, 2, energy_power_factor_chr); + snprintf_P(spfactor, sizeof(spfactor), PSTR(",\"" D_JSON_POWERFACTOR "\":%s"), energy_power_factor_chr); } - dtostrfd(energy_total, Settings.flag2.energy_resolution, energy_total_chr); - dtostrfd(energy_daily, Settings.flag2.energy_resolution, energy_daily_chr); - dtostrfd(energy, Settings.flag2.wattage_resolution, energy_period_chr); - dtostrfd(energy_power, Settings.flag2.wattage_resolution, energy_power_chr); - dtostrfd(energy_voltage, Settings.flag2.voltage_resolution, energy_voltage_chr); - dtostrfd(energy_current, Settings.flag2.current_resolution, energy_current_chr); - dtostrfd(energy_power_factor, 2, energy_power_factor_chr); - dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr); - if (json) { - snprintf_P(speriod, sizeof(speriod), PSTR(",\"" D_JSON_PERIOD "\":%s"), energy_period_chr); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s%s,\"" D_JSON_POWERUSAGE "\":%s,\"" D_JSON_POWERFACTOR "\":%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s}"), - mqtt_data, energy_total_chr, energy_yesterday_chr, energy_daily_chr, (show_energy_period) ? speriod : "", energy_power_chr, energy_power_factor_chr, energy_voltage_chr, energy_current_chr); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s%s,\"" + D_JSON_POWERUSAGE "\":%s%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s%s}"), + mqtt_data, energy_total_chr, energy_yesterday_chr, energy_daily_chr, (show_energy_period) ? speriod : "", + energy_power_chr, (!isnan(energy_power_factor)) ? spfactor : "", energy_voltage_chr, energy_current_chr, (!isnan(energy_frequency)) ? sfrequency : ""); #ifdef USE_DOMOTICZ if (show_energy_period) { // Only send if telemetry dtostrfd(energy_total * 1000, 1, energy_total_chr); @@ -593,7 +616,7 @@ void EnergyShow(boolean json) KnxSensor(KNX_ENERGY_VOLTAGE, energy_voltage); KnxSensor(KNX_ENERGY_CURRENT, energy_current); KnxSensor(KNX_ENERGY_POWER, energy_power); - KnxSensor(KNX_ENERGY_POWERFACTOR, energy_power_factor); + if (!isnan(energy_power_factor)) { KnxSensor(KNX_ENERGY_POWERFACTOR, energy_power_factor); } KnxSensor(KNX_ENERGY_DAILY, energy_daily); KnxSensor(KNX_ENERGY_TOTAL, energy_total); KnxSensor(KNX_ENERGY_START, energy_start); @@ -601,7 +624,10 @@ void EnergyShow(boolean json) #endif // USE_KNX #ifdef USE_WEBSERVER } else { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS, mqtt_data, energy_voltage_chr, energy_current_chr, energy_power_chr, energy_power_factor_chr, energy_daily_chr, energy_yesterday_chr, energy_total_chr); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS1, mqtt_data, energy_voltage_chr, energy_current_chr, energy_power_chr); + if (!isnan(energy_power_factor)) { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS2, mqtt_data, energy_power_factor_chr); } + if (!isnan(energy_frequency)) { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS3, mqtt_data, energy_frequency_chr); } + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS4, mqtt_data, energy_daily_chr, energy_yesterday_chr, energy_total_chr); #endif // USE_WEBSERVER } } diff --git a/sonoff/xnrg_01_hlw8012.ino b/sonoff/xnrg_01_hlw8012.ino index 440112c15..6ef196fb1 100644 --- a/sonoff/xnrg_01_hlw8012.ino +++ b/sonoff/xnrg_01_hlw8012.ino @@ -41,26 +41,26 @@ #define HLW_POWER_PROBE_TIME 10 // Number of seconds to probe for power before deciding none used -static byte hlw_select_ui_flag; -static byte hlw_ui_flag = 1; -static byte hlw_load_off; -static byte hlw_cf1_timer; -static unsigned long hlw_cf_pulse_length; -static unsigned long hlw_cf_pulse_last_time; -static unsigned long hlw_cf1_pulse_length; -static unsigned long hlw_cf1_pulse_last_time; -static unsigned long hlw_cf1_summed_pulse_length; -static unsigned long hlw_cf1_pulse_counter; -static unsigned long hlw_cf1_voltage_pulse_length; -static unsigned long hlw_cf1_current_pulse_length; -static unsigned long hlw_energy_period_counter; +byte hlw_select_ui_flag; +byte hlw_ui_flag = 1; +byte hlw_load_off; +byte hlw_cf1_timer; +unsigned long hlw_cf_pulse_length; +unsigned long hlw_cf_pulse_last_time; +unsigned long hlw_cf1_pulse_length; +unsigned long hlw_cf1_pulse_last_time; +unsigned long hlw_cf1_summed_pulse_length; +unsigned long hlw_cf1_pulse_counter; +unsigned long hlw_cf1_voltage_pulse_length; +unsigned long hlw_cf1_current_pulse_length; +unsigned long hlw_energy_period_counter; -static unsigned long hlw_power_ratio = 0; -static unsigned long hlw_voltage_ratio = 0; -static unsigned long hlw_current_ratio = 0; +unsigned long hlw_power_ratio = 0; +unsigned long hlw_voltage_ratio = 0; +unsigned long hlw_current_ratio = 0; -static unsigned long hlw_cf1_voltage_max_pulse_counter; -static unsigned long hlw_cf1_current_max_pulse_counter; +unsigned long hlw_cf1_voltage_max_pulse_counter; +unsigned long hlw_cf1_current_max_pulse_counter; #ifndef USE_WS2812_DMA // Collides with Neopixelbus but solves exception void HlwCfInterrupt() ICACHE_RAM_ATTR; @@ -217,6 +217,7 @@ void HlwDrvInit() { if (!energy_flg) { if ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99)) { // Sonoff Pow or any HLW8012 based device + energy_calc_power_factor = 1; // Calculate power factor from data energy_flg = XNRG_01; } } diff --git a/sonoff/xnrg_02_cse7766.ino b/sonoff/xnrg_02_cse7766.ino index 640da704e..84535cf96 100644 --- a/sonoff/xnrg_02_cse7766.ino +++ b/sonoff/xnrg_02_cse7766.ino @@ -185,6 +185,7 @@ void CseDrvInit() if ((SONOFF_S31 == Settings.module) || (SONOFF_POW_R2 == Settings.module)) { // Sonoff S31 or Sonoff Pow R2 baudrate = 4800; serial_config = SERIAL_8E1; + energy_calc_power_factor = 1; // Calculate power factor from data energy_flg = XNRG_02; } } diff --git a/sonoff/xnrg_03_pzem004t.ino b/sonoff/xnrg_03_pzem004t.ino index d009feea4..03581862c 100644 --- a/sonoff/xnrg_03_pzem004t.ino +++ b/sonoff/xnrg_03_pzem004t.ino @@ -215,6 +215,7 @@ void PzemDrvInit() { if (!energy_flg) { if ((pin[GPIO_PZEM_RX] < 99) && (pin[GPIO_PZEM_TX] < 99)) { // Any device with a Pzem004T + energy_calc_power_factor = 1; // Calculate power factor from data energy_flg = XNRG_03; } } diff --git a/sonoff/xnrg_05_pzem2.ino b/sonoff/xnrg_05_pzem2.ino index 2b326f216..7f9a4f8ba 100644 --- a/sonoff/xnrg_05_pzem2.ino +++ b/sonoff/xnrg_05_pzem2.ino @@ -89,61 +89,29 @@ bool Pzem2ModbusReceiveReady() return (Pzem2Serial->available() >= 5); // 5 - Error frame, 21 or 25 - Ok frame } -uint8_t Pzem2ModbusReceive() +uint8_t Pzem2ModbusReceive(uint8_t *buffer, uint8_t register_count) { - uint8_t buffer[26]; - -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 -// FE 04 14 08 98 03 E8 00 00 08 98 00 00 00 00 00 00 01 F4 00 64 00 00 HH LL = PZEM-014 -// Id Cc Sz Volt- Current---- Power------ Energy----- Frequ PFact Alarm Crc-- -// FE 04 10 27 10 00 64 03 E8 00 00 00 00 00 00 00 00 00 00 HH LL = PZEM-017 -// Id Cc Sz Volt- Curre Power------ Energy----- HiAlm LoAlm Crc-- + // 0 1 2 3 4 5 6 + // FE 04 02 08 98 HH LL + // Id Cc Sz Regis Crc-- uint8_t len = 0; - while (Pzem2Serial->available() > 0) { + while ((Pzem2Serial->available() > 0) && (len < (register_count *2) + 5)) { buffer[len++] = (uint8_t)Pzem2Serial->read(); if (3 == len) { if (buffer[1] & 0x80) { // fe 84 02 f2 f1 return buffer[2]; // 1 = Illegal Function, 2 = Illegal Address, 3 = Illegal Data, 4 = Slave Error } } - if (sizeof(buffer) == len) { break; } } AddLogSerial(LOG_LEVEL_DEBUG_MORE, buffer, len); - if (len < 5) { return 8; } // 8 = Not enough data - if (len != buffer[2] + 5) { return 9; } // 9 = Unexpected result + if (len < 7) { return 7; } // 7 = Not enough data + if (len != buffer[2] + 5) { return 8; } // 8 = Unexpected result uint16_t crc = (buffer[len -2] << 8) | buffer[len -1]; - if (Pzem2ModbusCalculateCRC(buffer, len -3) == crc) { - float energy = 0; - if (0x10 == buffer[2]) { // PZEM-003,017 - pzem2_type = PZEM2_TYPES_003_017; - energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 10.0; // 65535.x V - energy_current = (float)((buffer[5] << 8) + buffer[6]); // 65535.xx A - energy_power = (float)((uint32_t)buffer[9] << 24 + (uint32_t)buffer[10] << 16 + (uint32_t)buffer[7] << 8 + buffer[8]); // 65535 W - energy = (float)((uint32_t)buffer[13] << 24 + (uint32_t)buffer[14] << 16 + (uint32_t)buffer[11] << 8 + buffer[12]); // 65535 Wh - if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any - energy_kWhtoday += (energy - energy_start) * 100; - energy_start = energy; - EnergyUpdateToday(); - } - else if (0x14 == buffer[2]) { // PZEM-014,016 - pzem2_type = PZEM2_TYPES_014_016; - energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 10.0; // 65535.x V - energy_current = (float)((uint32_t)buffer[7] << 24 + (uint32_t)buffer[8] << 16 + (uint32_t)buffer[5] << 8 + buffer[6]); // 65535.xx A - energy_power = (float)((uint32_t)buffer[11] << 24 + (uint32_t)buffer[12] << 16 + (uint32_t)buffer[9] << 8 + buffer[10]); // 65535 W - energy_frequency = (float)((buffer[13] << 8) + buffer[14]) / 10.0; // 50.0 Hz - energy = (float)((uint32_t)buffer[15] << 24 + (uint32_t)buffer[16] << 16 + (uint32_t)buffer[13] << 8 + buffer[14]); // 65535 Wh - if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any - energy_kWhtoday += (energy - energy_start) * 100; - energy_start = energy; - EnergyUpdateToday(); - } - } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Pzem2 crc error")); - } + if (Pzem2ModbusCalculateCRC(buffer, len -3) != crc) { return 9; } // 9 = crc error return 0; // 0 = No error } @@ -152,11 +120,56 @@ uint8_t Pzem2ModbusReceive() uint8_t pzem2_sendRetry = 0; -void Pzem2EverySecond() +void Pzem2Every200ms() { bool data_ready = Pzem2ModbusReceiveReady(); - if (data_ready) { Pzem2ModbusReceive(); } + if (data_ready) { + uint8_t buffer[26]; + uint8_t error = Pzem2ModbusReceive(buffer, pzem2_type); + if (error) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "PZEM2 response error %d"), error); + AddLog(LOG_LEVEL_DEBUG); +// if (9 == error) { + if (PZEM2_TYPES_014_016 == pzem2_type) { + pzem2_type = PZEM2_TYPES_003_017; + } else { + pzem2_type = PZEM2_TYPES_014_016; + } +// } + } else { + float energy = 0; + + if (PZEM2_TYPES_003_017 == pzem2_type) { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 + // FE 04 10 27 10 00 64 03 E8 00 00 00 00 00 00 00 00 00 00 HH LL = PZEM-017 + // Id Cc Sz Volt- Curre Power------ Energy----- HiAlm LoAlm Crc-- + energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 100.0; // 655.00 V + energy_current = (float)((buffer[5] << 8) + buffer[6]) / 100.0; // 655.00 A + energy_power = (float)((uint32_t)buffer[9] << 24 + (uint32_t)buffer[10] << 16 + (uint32_t)buffer[7] << 8 + buffer[8]) / 10.0; // 429496729.0 W + energy = (float)((uint32_t)buffer[13] << 24 + (uint32_t)buffer[14] << 16 + (uint32_t)buffer[11] << 8 + buffer[12]); // 4294967295 Wh + if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any + energy_kWhtoday += (energy - energy_start) * 100; + energy_start = energy; + EnergyUpdateToday(); + } + else if (PZEM2_TYPES_014_016 == pzem2_type) { // PZEM-014,016 + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 + // FE 04 14 08 98 03 E8 00 00 08 98 00 00 00 00 00 00 01 F4 00 64 00 00 HH LL = PZEM-014 + // Id Cc Sz Volt- Current---- Power------ Energy----- Frequ PFact Alarm Crc-- + energy_voltage = (float)((buffer[3] << 8) + buffer[4]) / 10.0; // 6553.0 V + energy_current = (float)((uint32_t)buffer[7] << 24 + (uint32_t)buffer[8] << 16 + (uint32_t)buffer[5] << 8 + buffer[6]) / 1000.0; // 4294967.000 A + energy_power = (float)((uint32_t)buffer[11] << 24 + (uint32_t)buffer[12] << 16 + (uint32_t)buffer[9] << 8 + buffer[10]) / 10.0; // 429496729.0 W + energy_frequency = (float)((buffer[17] << 8) + buffer[18]) / 10.0; // 50.0 Hz + energy_power_factor = (float)((buffer[19] << 8) + buffer[20]) / 100.0; // 1.00 + energy = (float)((uint32_t)buffer[15] << 24 + (uint32_t)buffer[16] << 16 + (uint32_t)buffer[13] << 8 + buffer[14]); // 4294967295 Wh + if (!energy_start || (energy < energy_start)) { energy_start = energy; } // Init after restart and hanlde roll-over if any + energy_kWhtoday += (energy - energy_start) * 100; + energy_start = energy; + EnergyUpdateToday(); + } + } + } if (0 == pzem2_sendRetry || data_ready) { pzem2_sendRetry = 5; @@ -203,8 +216,8 @@ int Xnrg05(byte function) case FUNC_INIT: Pzem2SnsInit(); break; - case FUNC_EVERY_SECOND: - Pzem2EverySecond(); + case FUNC_EVERY_200_MSECOND: + Pzem2Every200ms(); break; } } diff --git a/sonoff/xsns_23_sdm120.ino b/sonoff/xsns_23_sdm120.ino index c22bc28cb..e5cc64418 100644 --- a/sonoff/xsns_23_sdm120.ino +++ b/sonoff/xsns_23_sdm120.ino @@ -246,7 +246,7 @@ void SDM120Show(boolean json) dtostrfd(sdm120_apparent_power, Settings.flag2.wattage_resolution, apparent_power); dtostrfd(sdm120_reactive_power, Settings.flag2.wattage_resolution, reactive_power); dtostrfd(sdm120_power_factor, 2, power_factor); - dtostrfd(sdm120_frequency, 2, frequency); + dtostrfd(sdm120_frequency, Settings.flag2.frequency_resolution, frequency); dtostrfd(sdm120_energy_total, Settings.flag2.energy_resolution, energy_total); if (json) { From b5d7f75647ab656bca132ae8986ad520c30eaf8e Mon Sep 17 00:00:00 2001 From: Erik Date: Sat, 8 Sep 2018 08:49:08 +0200 Subject: [PATCH 54/82] Fix setting and getting color temperature for Philips Hue emulation - Improve setting and getting color temperature for Philips Hue emulation - Clamp Philips Hue API values - Turn off white LEDs when setting hue+saturation --- sonoff/xdrv_04_light.ino | 26 ++++++++++++++++---------- sonoff/xplg_wemohue.ino | 33 +++++++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 209fe467a..93c2c522c 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -557,8 +557,8 @@ void LightState(uint8_t append) if (light_subtype > LST_SINGLE) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor)); // Add status for HSB - LightGetHsb(&hsb[0],&hsb[1],&hsb[2]); - // Scale these percentages up to the numbers expected byt he client + LightGetHsb(&hsb[0],&hsb[1],&hsb[2], false); + // Scale these percentages up to the numbers expected by the client h = round(hsb[0] * 360); s = round(hsb[1] * 100); b = round(hsb[2] * 100); @@ -911,13 +911,15 @@ void LightHsbToRgb() light_current_color[0] = (uint8_t)(r * 255.0f); light_current_color[1] = (uint8_t)(g * 255.0f); light_current_color[2] = (uint8_t)(b * 255.0f); + light_current_color[3] = 0; + light_current_color[4] = 0; } /********************************************************************************************/ -void LightGetHsb(float *hue, float *sat, float *bri) +void LightGetHsb(float *hue, float *sat, float *bri, bool gotct) { - if (light_subtype > LST_COLDWARM) { + if (light_subtype > LST_COLDWARM && !gotct) { LightRgbToHsb(); *hue = light_hue; *sat = light_saturation; @@ -925,16 +927,19 @@ void LightGetHsb(float *hue, float *sat, float *bri) } else { *hue = 0; *sat = 0; -// *bri = (2.54f * (float)Settings.light_dimmer); *bri = (0.01f * (float)Settings.light_dimmer); } } -void LightSetHsb(float hue, float sat, float bri, uint16_t ct) +void LightSetHsb(float hue, float sat, float bri, uint16_t ct, bool gotct) { if (light_subtype > LST_COLDWARM) { - if ((LST_RGBWC == light_subtype) && (ct > 0)) { - LightSetColorTemp(ct); + if ((LST_RGBWC == light_subtype) && (gotct)) { + uint8_t tmp = (uint8_t)(bri * 100); + Settings.light_dimmer = tmp; + if (ct > 0) { + LightSetColorTemp(ct); + } } else { light_hue = hue; light_saturation = sat; @@ -1114,7 +1119,7 @@ boolean LightCommand() } else { // Command with only 1 parameter, Hue (0360) ? (HSB[0] % 360) : HSB[0] ) /360.0, ( (HSB[1]>100) ? (HSB[1] % 100) : HSB[1] ) /100.0, ( (HSB[2]>100) ? (HSB[2] % 100) : HSB[2] ) /100.0, - 0); + 0, + false); } } else { LightState(0); diff --git a/sonoff/xplg_wemohue.ino b/sonoff/xplg_wemohue.ino index 93912bc76..f0b20ef59 100644 --- a/sonoff/xplg_wemohue.ino +++ b/sonoff/xplg_wemohue.ino @@ -17,6 +17,9 @@ along with this program. If not, see . */ +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) + #if defined(USE_WEBSERVER) && defined(USE_EMULATION) /*********************************************************************************************\ * Belkin WeMo and Philips Hue bridge emulation @@ -462,10 +465,10 @@ const char HUE_LIGHTS_STATUS_JSON[] PROGMEM = "\"hue\":{h}," "\"sat\":{s}," "\"xy\":[0.5, 0.5]," - "\"ct\":500," + "\"ct\":{t}," "\"alert\":\"none\"," "\"effect\":\"none\"," - "\"colormode\":\"hs\"," + "\"colormode\":\"{m}\"," "\"reachable\":true}"; const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM = ",\"type\":\"Extended color light\"," @@ -559,20 +562,26 @@ void HueConfig(String *path) WebServer->send(200, FPSTR(HDR_CTYPE_JSON), response); } +bool g_gotct = false; + void HueLightStatus1(byte device, String *response) { float hue = 0; float sat = 0; float bri = 0; + uint16_t ct = 500; if (light_type) { - LightGetHsb(&hue, &sat, &bri); + LightGetHsb(&hue, &sat, &bri, g_gotct); + ct = LightGetColorTemp(); } *response += FPSTR(HUE_LIGHTS_STATUS_JSON); response->replace("{state}", (power & (1 << (device-1))) ? "true" : "false"); 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))); + response->replace("{t}", String(ct)); + response->replace("{m}", g_gotct?"ct":"hs"); } void HueLightStatus2(byte device, String *response) @@ -678,11 +687,13 @@ void HueLights(String *path) } if (light_type) { - LightGetHsb(&hue, &sat, &bri); + LightGetHsb(&hue, &sat, &bri, g_gotct); } - if (hue_json.containsKey("bri")) { + if (hue_json.containsKey("bri")) { // Brightness is a scale from 1 (the minimum the light is capable of) to 254 (the maximum). Note: a brightness of 1 is not off. tmp = hue_json["bri"]; + tmp = max(tmp, 1); + tmp = min(tmp, 254); bri = (float)tmp / 254.0f; if (resp) { response += ","; @@ -694,7 +705,7 @@ void HueLights(String *path) resp = true; change = true; } - if (hue_json.containsKey("hue")) { + if (hue_json.containsKey("hue")) { // The hue value is a wrapping value between 0 and 65535. Both 0 and 65535 are red, 25500 is green and 46920 is blue. tmp = hue_json["hue"]; hue = (float)tmp / 65535.0f; if (resp) { @@ -704,11 +715,14 @@ void HueLights(String *path) response.replace("{id", String(device)); response.replace("{cm", "hue"); response.replace("{re", String(tmp)); + g_gotct = false; resp = true; change = true; } - if (hue_json.containsKey("sat")) { + if (hue_json.containsKey("sat")) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white). tmp = hue_json["sat"]; + tmp = max(tmp, 0); + tmp = min(tmp, 254); sat = (float)tmp / 254.0f; if (resp) { response += ","; @@ -717,6 +731,8 @@ void HueLights(String *path) response.replace("{id", String(device)); response.replace("{cm", "sat"); response.replace("{re", String(tmp)); + g_gotct = false; + resp = true; change = true; } if (hue_json.containsKey("ct")) { // Color temperature 153 (Cold) to 500 (Warm) @@ -728,11 +744,12 @@ void HueLights(String *path) response.replace("{id", String(device)); response.replace("{cm", "ct"); response.replace("{re", String(ct)); + g_gotct = true; change = true; } if (change) { if (light_type) { - LightSetHsb(hue, sat, bri, ct); + LightSetHsb(hue, sat, bri, ct, g_gotct); } change = false; } From 7cd92248196550964de87ada6bf86a2b742b5b3d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 8 Sep 2018 17:18:31 +0200 Subject: [PATCH 55/82] 6.2.1.3 - Change drop down list 6.2.1.3 20180907 * Change web Configure Module GPIO drop down list order for better readability * Fix showing Period Power in energy threshold messages * Fix ButtonRetain to not use default topic for clearing retain messages (#3737) --- sonoff/_changelog.ino | 8 ++- sonoff/sonoff.ino | 2 +- sonoff/sonoff_template.h | 108 ++++++++++++++++++++++++++++++++++- sonoff/sonoff_version.h | 2 +- sonoff/xdrv_01_mqtt.ino | 6 +- sonoff/xdrv_02_webserver.ino | 8 +-- sonoff/xdrv_03_energy.ino | 3 + sonoff/xdrv_10_rules.ino | 2 +- 8 files changed, 125 insertions(+), 14 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 82d12f28e..c62144f8d 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,8 +1,14 @@ -/* 6.2.1.2 20180906 +/* 6.2.1.3 20180907 + * Change web Configure Module GPIO drop down list order for better readability + * Fix showing Period Power in energy threshold messages + * Fix ButtonRetain to not use default topic for clearing retain messages (#3737) + * + * 6.2.1.2 20180906 * Fix KNX PA exception. Regression from 6.2.1 buffer overflow caused by subStr() (#3700, #3710) * Add command SetOption52 to control display of optional time offset from UTC in JSON messages (#3629, #3711) * Add experimental support for PZEM-003,014,016,017 Energy monitoring (#3694) * Add basic support for MP3 player using DFRobot RB-DFR-562 (#3723) + * Fix setting and getting color temperature for Philips Hue emulation (#3733) * * 6.2.1.1 20180905 * Rewrite energy monitoring using energy sensor driver modules diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 6b2e8422b..a1ab907ab 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -134,7 +134,7 @@ int ota_state_flag = 0; // OTA state flag int ota_result = 0; // OTA result int restart_flag = 0; // Sonoff restart flag int wifi_state_flag = WIFI_RESTART; // Wifi state flag -int tele_period = 0; // Tele period timer +int tele_period = 1; // Tele period timer int blinks = 201; // Number of LED blinks uint32_t uptime = 0; // Counting every second until 4294967295 = 130 year uint32_t global_update = 0; // Timestamp of last global temperature and humidity update diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 2ab43286d..23019ff10 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -21,6 +21,8 @@ #define _SONOFF_TEMPLATE_H_ // User selectable GPIO functionality +// ATTENTION: Only add at the end of this list just before GPIO_SENSOR_END +// Then add the same name(s) in a nice location in array kGpioNiceList enum UserSelectablePins { GPIO_NONE, // Not used GPIO_DHT11, // DHT11 @@ -244,7 +246,111 @@ typedef struct MYTMPLT { myio gp; } mytmplt; -const uint8_t kNiceList[MAXMODULE] PROGMEM = { +const uint8_t kGpioNiceList[GPIO_SENSOR_END] PROGMEM = { + GPIO_NONE, // Not used + GPIO_KEY1, // Buttons + GPIO_KEY1_NP, + GPIO_KEY2, + GPIO_KEY2_NP, + GPIO_KEY3, + GPIO_KEY3_NP, + GPIO_KEY4, + GPIO_KEY4_NP, + GPIO_SWT1, // User connected external switches + GPIO_SWT1_NP, + GPIO_SWT2, + GPIO_SWT2_NP, + GPIO_SWT3, + GPIO_SWT3_NP, + GPIO_SWT4, + GPIO_SWT4_NP, + GPIO_SWT5, + GPIO_SWT5_NP, + GPIO_SWT6, + GPIO_SWT6_NP, + GPIO_SWT7, + GPIO_SWT7_NP, + GPIO_SWT8, + GPIO_SWT8_NP, + GPIO_REL1, // Relays + GPIO_REL1_INV, + GPIO_REL2, + GPIO_REL2_INV, + GPIO_REL3, + GPIO_REL3_INV, + GPIO_REL4, + GPIO_REL4_INV, + GPIO_REL5, + GPIO_REL5_INV, + GPIO_REL6, + GPIO_REL6_INV, + GPIO_REL7, + GPIO_REL7_INV, + GPIO_REL8, + GPIO_REL8_INV, + GPIO_LED1, // Leds + GPIO_LED1_INV, + GPIO_LED2, + GPIO_LED2_INV, + GPIO_LED3, + GPIO_LED3_INV, + GPIO_LED4, + GPIO_LED4_INV, + GPIO_PWM1, // RGB Red or C Cold White + GPIO_PWM1_INV, + GPIO_PWM2, // RGB Green or CW Warm White + GPIO_PWM2_INV, + GPIO_PWM3, // RGB Blue + GPIO_PWM3_INV, + GPIO_PWM4, // RGBW (Cold) White + GPIO_PWM4_INV, + GPIO_PWM5, // RGBCW Warm White + GPIO_PWM5_INV, + GPIO_CNTR1, // Counters + GPIO_CNTR1_NP, + GPIO_CNTR2, + GPIO_CNTR2_NP, + GPIO_CNTR3, + GPIO_CNTR3_NP, + GPIO_CNTR4, + GPIO_CNTR4_NP, + GPIO_I2C_SCL, // I2C SCL + GPIO_I2C_SDA, // I2C SDA + GPIO_SPI_CS, // SPI Chip Select + GPIO_SPI_DC, // SPI Data Direction + GPIO_BACKLIGHT, // Display backlight control + GPIO_DHT11, // DHT11 + GPIO_DHT22, // DHT21, DHT22, AM2301, AM2302, AM2321 + GPIO_SI7021, // iTead SI7021 + GPIO_DSB, // Single wire DS18B20 or DS18S20 + GPIO_WS2812, // WS2812 Led string + GPIO_IRSEND, // IR remote + GPIO_IRRECV, // IR receiver + GPIO_SR04_TRIG, // SR04 Trigger pin + GPIO_SR04_ECHO, // SR04 Echo pin + GPIO_TM16CLK, // TM1638 Clock + GPIO_TM16DIO, // TM1638 Data I/O + GPIO_TM16STB, // TM1638 Strobe + GPIO_SBR_TX, // Serial Bridge Serial interface + GPIO_SBR_RX, // Serial Bridge Serial interface + GPIO_MHZ_TXD, // MH-Z19 Serial interface + GPIO_MHZ_RXD, // MH-Z19 Serial interface + GPIO_SAIR_TX, // SenseAir Serial interface + GPIO_SAIR_RX, // SenseAir Serial interface + GPIO_SDS0X1, // Nova Fitness SDS011 Serial interface + GPIO_PZEM_TX, // PZEM004T Serial interface + GPIO_PZEM_RX, // PZEM004T Serial interface + GPIO_PZEM2_TX, // PZEM-003,014,016,017 Serial interface + GPIO_PZEM2_RX, // PZEM-003,014,016,017 Serial interface + GPIO_SDM120_TX, // SDM120 Serial interface + GPIO_SDM120_RX, // SDM120 Serial interface + GPIO_SDM630_TX, // SDM630 Serial interface + GPIO_SDM630_RX, // SDM630 Serial interface + GPIO_PMS5003, // Plantower PMS5003 Serial interface + GPIO_MP3_DFR562 // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface +}; + +const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { SONOFF_BASIC, SONOFF_RF, SONOFF_TH, diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 178e0af68..f068473ab 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06020102 +#define VERSION 0x06020103 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/xdrv_01_mqtt.ino b/sonoff/xdrv_01_mqtt.ino index c47728df0..f3f33d693 100644 --- a/sonoff/xdrv_01_mqtt.ino +++ b/sonoff/xdrv_01_mqtt.ino @@ -380,9 +380,7 @@ void MqttConnected() MqttPublishPowerState(i); if (SONOFF_IFAN02 == Settings.module) { break; } // Only report status of light relay } - if (Settings.tele_period) { - tele_period = Settings.tele_period -9; - } + if (Settings.tele_period) { tele_period = Settings.tele_period -9; } // Enable TelePeriod in 9 seconds rules_flag.system_boot = 1; XdrvCall(FUNC_MQTT_INIT); } @@ -718,7 +716,6 @@ bool MqttCommand() } else if (CMND_BUTTONRETAIN == command_code) { if ((payload >= 0) && (payload <= 1)) { - strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic)); if (!payload) { for(i = 1; i <= MAX_KEYS; i++) { SendKey(0, i, 9); // Clear MQTT retain in broker @@ -730,7 +727,6 @@ bool MqttCommand() } else if (CMND_SWITCHRETAIN == command_code) { if ((payload >= 0) && (payload <= 1)) { - strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic)); if (!payload) { for(i = 1; i <= MAX_SWITCHES; i++) { SendKey(1, i, 9); // Clear MQTT retain in broker diff --git a/sonoff/xdrv_02_webserver.ino b/sonoff/xdrv_02_webserver.ino index 4059459c5..4398a9eb0 100644 --- a/sonoff/xdrv_02_webserver.ino +++ b/sonoff/xdrv_02_webserver.ino @@ -768,7 +768,7 @@ void HandleModuleConfiguration() page.replace(F("{v}"), FPSTR(S_CONFIGURE_MODULE)); page += FPSTR(HTTP_SCRIPT_MODULE1); for (byte i = 0; i < MAXMODULE; i++) { - midx = pgm_read_byte(kNiceList + i); + midx = pgm_read_byte(kModuleNiceList + i); snprintf_P(stemp, sizeof(stemp), kModules[midx].name); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, midx, midx +1, stemp); page += mqtt_data; @@ -779,10 +779,10 @@ void HandleModuleConfiguration() mytmplt cmodule; memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule)); - for (byte j = 0; j < GPIO_SENSOR_END; j++) { - if (!GetUsedInModule(j, cmodule.gp.io)) { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, j, j, GetTextIndexed(stemp, sizeof(stemp), j, kSensorNames)); + midx = pgm_read_byte(kGpioNiceList + j); + if (!GetUsedInModule(midx, cmodule.gp.io)) { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, midx, midx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames)); page += mqtt_data; } } diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino index 081b52d83..ac26a18da 100644 --- a/sonoff/xdrv_03_energy.ino +++ b/sonoff/xdrv_03_energy.ino @@ -304,7 +304,10 @@ void EnergyMqttShow() { // {"Time":"2017-12-16T11:48:55","ENERGY":{"Total":0.212,"Yesterday":0.000,"Today":0.014,"Period":2.0,"Power":22.0,"Factor":1.00,"Voltage":213.6,"Current":0.100}} snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); + int tele_period_save = tele_period; + tele_period = 2; EnergyShow(1); + tele_period = tele_period_save; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); energy_power_delta = 0; diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino index df27cb4cd..930bde7d5 100644 --- a/sonoff/xdrv_10_rules.ino +++ b/sonoff/xdrv_10_rules.ino @@ -426,7 +426,7 @@ void RulesEvery100ms() { if (Settings.rule_enabled) { // Any rule enabled mqtt_data[0] = '\0'; - uint16_t tele_period_save = tele_period; + int tele_period_save = tele_period; tele_period = 2; // Do not allow HA updates during next function call XsnsNextCall(FUNC_JSON_APPEND); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089} tele_period = tele_period_save; From b96c0d7773477b758ec2ce0818f3b8901b7312d6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 8 Sep 2018 18:17:36 +0200 Subject: [PATCH 56/82] Fix Novafitnes GPIO selection Fix Novafitnes GPIO selection --- sonoff/sonoff_template.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index fd2806fa9..1ab62ae63 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -94,8 +94,7 @@ enum UserSelectablePins { GPIO_SPI_DC, // SPI Data Direction GPIO_BACKLIGHT, // Display backlight control GPIO_PMS5003, // Plantower PMS5003 Serial interface - GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface - GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface + GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface GPIO_SBR_TX, // Serial Bridge Serial interface GPIO_SBR_RX, // Serial Bridge Serial interface GPIO_SR04_TRIG, // SR04 Trigger pin @@ -126,6 +125,7 @@ enum UserSelectablePins { GPIO_PZEM2_TX, // PZEM-003,014,016,017 Serial interface GPIO_PZEM2_RX, // PZEM-003,014,016,017 Serial interface GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player + GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface GPIO_SENSOR_END }; // Programmer selectable GPIO functionality offset by user selectable GPIOs @@ -167,8 +167,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|" D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|" - D_SENSOR_PMS5003 "|" - D_SENSOR_SDS0X1_TX "|" D_SENSOR_SDS0X1_RX "|" + D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1_RX "|" D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|" D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|" D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|" @@ -178,7 +177,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BUTTON "1n|" D_SENSOR_BUTTON "2n|" D_SENSOR_BUTTON "3n|" D_SENSOR_BUTTON "4n|" D_SENSOR_COUNTER "1n|" D_SENSOR_COUNTER "2n|" D_SENSOR_COUNTER "3n|" D_SENSOR_COUNTER "4n|" D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|" - D_SENSOR_DFR562; + D_SENSOR_DFR562 "|" D_SENSOR_SDS0X1_TX; /********************************************************************************************/ @@ -339,7 +338,8 @@ const uint8_t kGpioNiceList[GPIO_SENSOR_END] PROGMEM = { GPIO_MHZ_RXD, // MH-Z19 Serial interface GPIO_SAIR_TX, // SenseAir Serial interface GPIO_SAIR_RX, // SenseAir Serial interface - GPIO_SDS0X1, // Nova Fitness SDS011 Serial interface + GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface + GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface GPIO_PZEM_TX, // PZEM004T Serial interface GPIO_PZEM_RX, // PZEM004T Serial interface GPIO_PZEM2_TX, // PZEM-003,014,016,017 Serial interface From 3b029797b6534bdcd8c78be42b9e0b99cf7eed53 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 8 Sep 2018 18:25:06 +0200 Subject: [PATCH 57/82] Add sleep to Nova Fitness SDS01X Add sleep to Nova Fitness SDS01X sensor (#2841, #3724) --- sonoff/_changelog.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index c62144f8d..230a541b7 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -2,6 +2,7 @@ * Change web Configure Module GPIO drop down list order for better readability * Fix showing Period Power in energy threshold messages * Fix ButtonRetain to not use default topic for clearing retain messages (#3737) + * Add sleep to Nova Fitness SDS01X sensor (#2841, #3724) * * 6.2.1.2 20180906 * Fix KNX PA exception. Regression from 6.2.1 buffer overflow caused by subStr() (#3700, #3710) From 56920ad8263c7b50f5811a29b057807af483417a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 8 Sep 2018 18:33:56 +0200 Subject: [PATCH 58/82] Adjust list box width Adjust GPIO drop down list box width --- sonoff/xdrv_02_webserver.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xdrv_02_webserver.ino b/sonoff/xdrv_02_webserver.ino index 4398a9eb0..55eb0f41b 100644 --- a/sonoff/xdrv_02_webserver.ino +++ b/sonoff/xdrv_02_webserver.ino @@ -805,7 +805,7 @@ void HandleModuleConfiguration() for (byte i = 0; i < MAX_GPIO_PIN; i++) { if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) { snprintf_P(stemp, 3, PINS_WEMOS +i*2); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s " D_GPIO "%d %s"), + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s " D_GPIO "%d %s"), (WEMOS==Settings.module)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(9==i)? "ESP8285" :(10==i)? "ESP8285" :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i); page += mqtt_data; } From 4c41ea446154e780610bc1b96ec0f08803893a6b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 9 Sep 2018 14:31:40 +0200 Subject: [PATCH 59/82] Houskeeping --- sonoff/sonoff.ino | 3 --- sonoff/support.ino | 12 ++++++++++++ sonoff/xdrv_02_webserver.ino | 2 +- tools/decode-status.py | 6 +++--- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index a1ab907ab..52cdb68ba 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -849,10 +849,8 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) else if ((CMND_GPIO == command_code) && (index < MAX_GPIO_PIN)) { mytmplt cmodule; memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule)); -// if ((GPIO_USER == cmodule.gp.io[index]) && (payload >= 0) && (payload < GPIO_SENSOR_END)) { if ((GPIO_USER == ValidGPIO(index, cmodule.gp.io[index])) && (payload >= 0) && (payload < GPIO_SENSOR_END)) { for (byte i = 0; i < MAX_GPIO_PIN; i++) { -// if ((GPIO_USER == cmodule.gp.io[i]) && (Settings.my_gp.io[i] == payload)) { if ((GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) && (Settings.my_gp.io[i] == payload)) { Settings.my_gp.io[i] = 0; } @@ -862,7 +860,6 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) } snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{")); for (byte i = 0; i < MAX_GPIO_PIN; i++) { -// if (GPIO_USER == cmodule.gp.io[i]) { if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) { if (jsflg) snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data); jsflg = 1; diff --git a/sonoff/support.ino b/sonoff/support.ino index 291f2069d..af93fa148 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -936,8 +936,20 @@ void GetFeatures() #ifdef USE_DISPLAY_SH1106 feature_drv2 |= 0x00001000; // xdsp_06_sh1106.ino #endif +#ifdef USE_MP3_PLAYER + feature_drv2 |= 0x00002000; // xdrv_14_mp3.ino +#endif +#ifdef NO_EXTRA_4K_HEAP + feature_drv2 |= 0x00800000; // sonoff_post.h +#endif +#ifdef VTABLES_IN_IRAM + feature_drv2 |= 0x01000000; // platformio.ini +#endif +#ifdef VTABLES_IN_DRAM + feature_drv2 |= 0x02000000; // platformio.ini +#endif #ifdef VTABLES_IN_FLASH feature_drv2 |= 0x04000000; // platformio.ini #endif diff --git a/sonoff/xdrv_02_webserver.ino b/sonoff/xdrv_02_webserver.ino index 55eb0f41b..6cadb952f 100644 --- a/sonoff/xdrv_02_webserver.ino +++ b/sonoff/xdrv_02_webserver.ino @@ -1193,7 +1193,7 @@ void HandleSaveSettings() if (Settings.last_module != new_module) { Settings.my_gp.io[i] = 0; } else { - if (GPIO_USER == cmodule.gp.io[i]) { + if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) { snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), i); WebGetArg(stemp, tmp, sizeof(tmp)); Settings.my_gp.io[i] = (!strlen(tmp)) ? 0 : atoi(tmp); diff --git a/tools/decode-status.py b/tools/decode-status.py index b26be9df0..154b6e719 100644 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -108,10 +108,10 @@ a_features = [[ "USE_CONFIG_OVERRIDE","BE_MINIMAL","USE_SENSORS","USE_CLASSIC", "USE_KNX_NO_EMULATION","USE_DISPLAY_MODES1TO5","USE_DISPLAY_GRAPH","USE_DISPLAY_LCD", "USE_DISPLAY_SSD1306","USE_DISPLAY_MATRIX","USE_DISPLAY_ILI9341","USE_DISPLAY_EPAPER", - "USE_DISPLAY_SH1106","","","", + "USE_DISPLAY_SH1106","USE_MP3_PLAYER","","", "","","","", - "","","","", - "","","VTABLES_IN_FLASH","PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH", + "","","","NO_EXTRA_4K_HEAP", + "VTABLES_IN_IRAM","VTABLES_IN_DRAM","VTABLES_IN_FLASH","PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH", "PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY","PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH","DEBUG_THEO","USE_DEBUG_DRIVER" ],[ "","USE_ADC_VCC","USE_ENERGY_SENSOR","USE_PZEM004T", From 550c7d256f3d63f24f9b6613bc0e2f5d311fbf89 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 9 Sep 2018 14:58:50 +0200 Subject: [PATCH 60/82] Add option -mtarget-align Add option -mtarget-align to solve linux compiled un-aligned binaries (#3678) --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index 4cda52b6f..d333fd187 100644 --- a/platformio.ini +++ b/platformio.ini @@ -61,6 +61,7 @@ build_unflags = -Wall build_flags = -Wl,-Tesp8266.flash.1m0.ld + -mtarget-align ; -DUSE_CONFIG_OVERRIDE ; lwIP 1.4 (Default) ; -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH From cc23deac00908118000a7851df88c3edc695bf06 Mon Sep 17 00:00:00 2001 From: Nico Date: Mon, 10 Sep 2018 11:37:16 +0200 Subject: [PATCH 61/82] use SDS0X1 working period command --- sonoff/xsns_20_novasds.ino | 119 ++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 62 deletions(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index 851326f3f..607bcc545 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -27,26 +27,65 @@ #include +#ifndef WORKING_PERIOD + #define WORKING_PERIOD 5 +#endif + TasmotaSerial *NovaSdsSerial; uint8_t novasds_type = 1; uint8_t novasds_valid = 0; -uint8_t novasds_running = 1; -uint8_t novasds_read_tick = 30; -uint8_t novasds_wakup_tick = 179; -uint8_t novasds_ticker = 0; + +uint8_t novasds_workperiod[19] = {0xAA, 0xB4, 0x08, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x0C, 0xAB}; //5 minutes +uint8_t novasds_setquerymode[19] = {0xAA, 0xB4, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0xAB}; //query mode +uint8_t novasds_querydata[19] = {0xAA, 0xB4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0xAB}; //query DATA + struct sds011data { uint16_t pm100; uint16_t pm25; } novasds_data; +//Put sensor to sleep +void NovaSdsSetWorkPeriod() +{ -bool NovaSdsReadData(bool publish) + while (NovaSdsSerial->available() > 0) { + NovaSdsSerial->read(); + } + + novasds_workperiod[4] = WORKING_PERIOD; + novasds_workperiod[17] = ((novasds_workperiod[2] + novasds_workperiod[3] + novasds_workperiod[4] + novasds_workperiod[15] + novasds_workperiod[16]) & 0xFF); //checksum + + + NovaSdsSerial->write(novasds_workperiod, sizeof(novasds_workperiod)); + + NovaSdsSerial->flush(); + + while (NovaSdsSerial->available() > 0) { + NovaSdsSerial->read(); + } + + NovaSdsSerial->write(novasds_setquerymode, sizeof(novasds_setquerymode)); + + NovaSdsSerial->flush(); + + while (NovaSdsSerial->available() > 0) { + NovaSdsSerial->read(); + } +} + + + +bool NovaSdsReadData() { if (! NovaSdsSerial->available()) return false; - while ((NovaSdsSerial->peek() != 0xAA) && NovaSdsSerial->available()) { + NovaSdsSerial->write(novasds_querydata, sizeof(novasds_querydata)); + + NovaSdsSerial->flush(); + + while ((NovaSdsSerial->peek() != 0xAA) && NovaSdsSerial->available()) { NovaSdsSerial->read(); } @@ -56,9 +95,7 @@ bool NovaSdsReadData(bool publish) NovaSdsSerial->flush(); AddLogSerial(LOG_LEVEL_DEBUG_MORE, d, 8); - if (!publish){ - return false; - } + if (d[7] == ((d[1] + d[2] + d[3] + d[4] + d[5] + d[6]) & 0xFF)) { novasds_data.pm25 = (d[1] + 256 * d[2]); novasds_data.pm100 = (d[3] + 256 * d[4]); @@ -66,6 +103,9 @@ bool NovaSdsReadData(bool publish) AddLog_P(LOG_LEVEL_DEBUG, PSTR("SDS: " D_CHECKSUM_FAILURE)); return false; } + + novasds_valid = 10; + return true; } @@ -73,35 +113,12 @@ bool NovaSdsReadData(bool publish) void NovaSdsSecond() // Every second { - if (novasds_ticker < novasds_read_tick) { - // wake up the sensor and wait read ticks to stabalize the sensor - if (!novasds_running) { - NovaSdsStart(); - novasds_running = 1; - } - - // drain the serial without publishing data - NovaSdsReadData(false); - novasds_ticker++; - - } else if (novasds_ticker == novasds_read_tick) { - - // try to take a single stable reading and sleep the sensor - if (NovaSdsReadData(true)) { - novasds_valid = 1; - NovaSdsStop(); - novasds_running = 0; - novasds_ticker++; - } else { - novasds_valid = 0; - } - - } else if (novasds_ticker >= novasds_wakup_tick) { - // reset the counter - novasds_ticker = 0; + if (NovaSdsReadData()) { + novasds_valid = 10; } else { - // sensor is sleeping keep waiting - novasds_ticker++; + if (novasds_valid) { + novasds_valid--; + } } } @@ -110,37 +127,15 @@ void NovaSdsSecond() // Every second void NovaSdsInit() { novasds_type = 0; - if (pin[GPIO_SDS0X1_RX] < 99 && pin[GPIO_SDS0X1_TX] < 99) { + if ((pin[GPIO_SDS0X1_RX] < 99) && (pin[GPIO_SDS0X1_TX] < 99)) { NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1_RX], pin[GPIO_SDS0X1_TX], 1); - if (NovaSdsSerial->begin(9600)) { - if (NovaSdsSerial->hardwareSerial()) { - ClaimSerial(); - } + if (NovaSdsSerial->hardwareSerial()) { ClaimSerial(); } novasds_type = 1; } - } -} -void NovaSdsStart() -{ - AddLog_P(LOG_LEVEL_DEBUG, "SDS: start"); - const uint8_t novasds_start_cmd[] = {0xAA, 0xB4, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x06, 0xAB}; - NovaSdsSerial->write(novasds_start_cmd, sizeof(novasds_start_cmd)); - NovaSdsSerial->flush(); -} - -void NovaSdsStop() -{ - AddLog_P(LOG_LEVEL_DEBUG, "SDS: stop"); - const uint8_t novasds_stop_cmd[] = {0xAA, 0xB4, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x05, 0xAB}; - NovaSdsSerial->write(novasds_stop_cmd, sizeof(novasds_stop_cmd)); - NovaSdsSerial->flush(); - // drain any old data - while (NovaSdsSerial->available()) { - NovaSdsSerial->read(); - } + NovaSdsSetWorkPeriod(); } #ifdef USE_WEBSERVER From 0f25925357554efa51fe40346196fe8e46c2b2e8 Mon Sep 17 00:00:00 2001 From: edelstahlratte <17500289+edelstahlratte@users.noreply.github.com> Date: Mon, 10 Sep 2018 11:50:54 +0200 Subject: [PATCH 62/82] Add SDS0X1 working period --- sonoff/user_config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/user_config.h b/sonoff/user_config.h index d46a295d7..357fe5fab 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -335,6 +335,7 @@ #define CO2_HIGH 1200 // Above this CO2 value show red light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1) #define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code) #define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code) + #define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code) //#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code) #define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud) From ef6d5bb340c6d26509414c450d4afce71b4a45b3 Mon Sep 17 00:00:00 2001 From: Nico Date: Mon, 10 Sep 2018 12:11:28 +0200 Subject: [PATCH 63/82] cosmetics --- sonoff/xsns_20_novasds.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index 607bcc545..02614c912 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -46,7 +46,6 @@ struct sds011data { uint16_t pm25; } novasds_data; -//Put sensor to sleep void NovaSdsSetWorkPeriod() { @@ -57,7 +56,6 @@ void NovaSdsSetWorkPeriod() novasds_workperiod[4] = WORKING_PERIOD; novasds_workperiod[17] = ((novasds_workperiod[2] + novasds_workperiod[3] + novasds_workperiod[4] + novasds_workperiod[15] + novasds_workperiod[16]) & 0xFF); //checksum - NovaSdsSerial->write(novasds_workperiod, sizeof(novasds_workperiod)); NovaSdsSerial->flush(); @@ -127,10 +125,12 @@ void NovaSdsSecond() // Every second void NovaSdsInit() { novasds_type = 0; - if ((pin[GPIO_SDS0X1_RX] < 99) && (pin[GPIO_SDS0X1_TX] < 99)) { + if (pin[GPIO_SDS0X1_RX] < 99 && pin[GPIO_SDS0X1_TX] < 99) { NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1_RX], pin[GPIO_SDS0X1_TX], 1); if (NovaSdsSerial->begin(9600)) { - if (NovaSdsSerial->hardwareSerial()) { ClaimSerial(); } + if (NovaSdsSerial->hardwareSerial()) { + ClaimSerial(); + } novasds_type = 1; } } From 804e74d0de0322eac9a466db6a57f3578c99b351 Mon Sep 17 00:00:00 2001 From: Nico Date: Mon, 10 Sep 2018 12:22:00 +0200 Subject: [PATCH 64/82] cosmetics --- sonoff/xsns_20_novasds.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index 02614c912..2bce13e2a 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -53,7 +53,7 @@ void NovaSdsSetWorkPeriod() NovaSdsSerial->read(); } - novasds_workperiod[4] = WORKING_PERIOD; + novasds_workperiod[4] = WORKING_PERIOD; novasds_workperiod[17] = ((novasds_workperiod[2] + novasds_workperiod[3] + novasds_workperiod[4] + novasds_workperiod[15] + novasds_workperiod[16]) & 0xFF); //checksum NovaSdsSerial->write(novasds_workperiod, sizeof(novasds_workperiod)); From dc3d699fd1436c245806bbe804e117a9c2ad7dba Mon Sep 17 00:00:00 2001 From: Nico Date: Mon, 10 Sep 2018 12:23:51 +0200 Subject: [PATCH 65/82] cosmetics --- sonoff/xsns_20_novasds.ino | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index 2bce13e2a..b6bd4a2c0 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -60,17 +60,17 @@ void NovaSdsSetWorkPeriod() NovaSdsSerial->flush(); - while (NovaSdsSerial->available() > 0) { - NovaSdsSerial->read(); - } + while (NovaSdsSerial->available() > 0) { + NovaSdsSerial->read(); + } NovaSdsSerial->write(novasds_setquerymode, sizeof(novasds_setquerymode)); NovaSdsSerial->flush(); - while (NovaSdsSerial->available() > 0) { - NovaSdsSerial->read(); - } + while (NovaSdsSerial->available() > 0) { + NovaSdsSerial->read(); + } } From 047932a191ccc38c43d4ffb262b5695aaae903ee Mon Sep 17 00:00:00 2001 From: Nico Date: Mon, 10 Sep 2018 12:25:57 +0200 Subject: [PATCH 66/82] cosmetics --- sonoff/xsns_20_novasds.ino | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index b6bd4a2c0..46db2fb6a 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -57,15 +57,13 @@ void NovaSdsSetWorkPeriod() novasds_workperiod[17] = ((novasds_workperiod[2] + novasds_workperiod[3] + novasds_workperiod[4] + novasds_workperiod[15] + novasds_workperiod[16]) & 0xFF); //checksum NovaSdsSerial->write(novasds_workperiod, sizeof(novasds_workperiod)); - NovaSdsSerial->flush(); while (NovaSdsSerial->available() > 0) { NovaSdsSerial->read(); } - NovaSdsSerial->write(novasds_setquerymode, sizeof(novasds_setquerymode)); - + NovaSdsSerial->write(novasds_setquerymode, sizeof(novasds_setquerymode)); NovaSdsSerial->flush(); while (NovaSdsSerial->available() > 0) { @@ -80,10 +78,9 @@ bool NovaSdsReadData() if (! NovaSdsSerial->available()) return false; NovaSdsSerial->write(novasds_querydata, sizeof(novasds_querydata)); - NovaSdsSerial->flush(); - while ((NovaSdsSerial->peek() != 0xAA) && NovaSdsSerial->available()) { + while ((NovaSdsSerial->peek() != 0xAA) && NovaSdsSerial->available()) { NovaSdsSerial->read(); } From b9d1bb965ced0887af43467f747cef38da692209 Mon Sep 17 00:00:00 2001 From: Nico Date: Mon, 10 Sep 2018 14:06:31 +0200 Subject: [PATCH 67/82] correct error --- sonoff/xsns_20_novasds.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sonoff/xsns_20_novasds.ino b/sonoff/xsns_20_novasds.ino index 46db2fb6a..815041cab 100644 --- a/sonoff/xsns_20_novasds.ino +++ b/sonoff/xsns_20_novasds.ino @@ -129,10 +129,9 @@ void NovaSdsInit() ClaimSerial(); } novasds_type = 1; + NovaSdsSetWorkPeriod(); } } - - NovaSdsSetWorkPeriod(); } #ifdef USE_WEBSERVER From 6f4fefbd771008fe2ea9ce5adb2a1a34a744451e Mon Sep 17 00:00:00 2001 From: andrethomas Date: Mon, 10 Sep 2018 18:32:41 +0200 Subject: [PATCH 68/82] Fix potential buffer overun for EVENT --- sonoff/xsns_29_mcp230xx.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xsns_29_mcp230xx.ino b/sonoff/xsns_29_mcp230xx.ino index d6683da44..058d6c25c 100644 --- a/sonoff/xsns_29_mcp230xx.ino +++ b/sonoff/xsns_29_mcp230xx.ino @@ -300,7 +300,7 @@ void MCP230xx_CheckForInterrupt(void) { MqttPublishPrefixTopic_P(RESULT_OR_STAT, mqtt_data); } if (int_event) { - char command[18]; + char command[19]; // Theoretical max = 'event MCPINT_D16=1' so 18 + 1 (for the \n) sprintf(command,"event MCPINT_D%i=%i",intp+(mcp230xx_port*8),((mcp230xx_intcap >> intp) & 0x01)); ExecuteCommand(command, SRC_RULE); } From 786fd792b715607fc0752c1c2ffb6ce7f9492c27 Mon Sep 17 00:00:00 2001 From: andrethomas Date: Mon, 10 Sep 2018 19:44:23 +0200 Subject: [PATCH 69/82] Fix tr-TR.h and uk-UK.h compiler errors --- sonoff/language/tr-TR.h | 2 ++ sonoff/language/uk-UK.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index 1f11d4a01..086c236aa 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -476,6 +476,8 @@ #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" #define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index 90cfb9f4a..19094d574 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -476,6 +476,8 @@ #define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_PMS5003 "PMS5003" #define D_SENSOR_SDS0X1 "SDS0X1" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_SBR_RX "SerBr Rx" #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" From 40b9e06b1e678497018d305910aa19150009d4c3 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Mon, 10 Sep 2018 18:04:21 -0300 Subject: [PATCH 70/82] Enable AD0 in sonoff-sensors.bin #3756 --- sonoff/sonoff_post.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h index 7504af3b4..8622d0818 100755 --- a/sonoff/sonoff_post.h +++ b/sonoff/sonoff_post.h @@ -62,7 +62,10 @@ void KNX_CB_Action(message_t const &msg, void *arg); #ifdef USE_SENSORS -#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices +#ifdef USE_ADC_VCC +#undef USE_ADC_VCC +#endif +//#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices #define USE_DS18x20 // For more than one DS18x20 sensors with id sort, single scan and read retry (+1k3 code) //#define USE_DS18x20_LEGACY // For more than one DS18x20 sensors with dynamic scan using library OneWire (+1k5 code) #define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram) From e4ebee738b437fcc101f80e2f8d7df119aea9f02 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 11 Sep 2018 10:49:13 +0200 Subject: [PATCH 71/82] Minor fixes Minor fixes --- sonoff/_changelog.ino | 3 ++- sonoff/xdrv_99_debug.ino | 3 +-- sonoff/xdsp_05_epaper.ino | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 230a541b7..d9044fcae 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -2,7 +2,8 @@ * Change web Configure Module GPIO drop down list order for better readability * Fix showing Period Power in energy threshold messages * Fix ButtonRetain to not use default topic for clearing retain messages (#3737) - * Add sleep to Nova Fitness SDS01X sensor (#2841, #3724) + * Add sleep to Nova Fitness SDS01X sensor (#2841, #3724, #3749) + * Add Analog input AD0 enabled to sonoff-sensors.bin (#3756, #3757) * * 6.2.1.2 20180906 * Fix KNX PA exception. Regression from 6.2.1 buffer overflow caused by subStr() (#3700, #3710) diff --git a/sonoff/xdrv_99_debug.ino b/sonoff/xdrv_99_debug.ino index 8a167511c..3cd2e69c5 100644 --- a/sonoff/xdrv_99_debug.ino +++ b/sonoff/xdrv_99_debug.ino @@ -182,6 +182,7 @@ void CpuLoadLoop() #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) // All version before core 2.4.2 +// https://github.com/esp8266/Arduino/issues/2557 extern "C" { #include @@ -190,7 +191,6 @@ extern "C" { void DebugFreeMem() { -// https://github.com/esp8266/Arduino/issues/2557 register uint32_t *sp asm("a1"); // snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d, UnmodifiedStack %d (%s)"), @@ -213,7 +213,6 @@ extern "C" { void DebugFreeMem() { -// https://github.com/esp8266/Arduino/issues/2557 register uint32_t *sp asm("a1"); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"), diff --git a/sonoff/xdsp_05_epaper.ino b/sonoff/xdsp_05_epaper.ino index 59a08584b..91eb747f2 100644 --- a/sonoff/xdsp_05_epaper.ino +++ b/sonoff/xdsp_05_epaper.ino @@ -188,7 +188,7 @@ boolean Xdsp05(byte function) if (FUNC_DISPLAY_INIT_DRIVER == function) { EpdInitDriver(); } - else if (XDSP_04 == Settings.display_model) { + else if (XDSP_05 == Settings.display_model) { if (!dsp_color) { dsp_color = COLORED; } From 702f44cf04467a389260b4189b8170fe64f91953 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Tue, 11 Sep 2018 14:10:51 -0300 Subject: [PATCH 72/82] Fixed Compilation Bug #3766 --- sonoff/xnrg_05_pzem2.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xnrg_05_pzem2.ino b/sonoff/xnrg_05_pzem2.ino index 7f9a4f8ba..b7e1eab42 100644 --- a/sonoff/xnrg_05_pzem2.ino +++ b/sonoff/xnrg_05_pzem2.ino @@ -211,7 +211,7 @@ int Xnrg05(byte function) if (FUNC_PRE_INIT == function) { Pzem2DrvInit(); } - else if (XNRG_03 == energy_flg) { + else if (XNRG_05 == energy_flg) { switch (function) { case FUNC_INIT: Pzem2SnsInit(); From e60f7e4e9edf3fed6188c6a46fce30d1cb4ac1d3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 11 Sep 2018 19:14:15 +0200 Subject: [PATCH 73/82] Update xnrg_05_pzem2.ino --- sonoff/xnrg_05_pzem2.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xnrg_05_pzem2.ino b/sonoff/xnrg_05_pzem2.ino index 7f9a4f8ba..b7e1eab42 100644 --- a/sonoff/xnrg_05_pzem2.ino +++ b/sonoff/xnrg_05_pzem2.ino @@ -211,7 +211,7 @@ int Xnrg05(byte function) if (FUNC_PRE_INIT == function) { Pzem2DrvInit(); } - else if (XNRG_03 == energy_flg) { + else if (XNRG_05 == energy_flg) { switch (function) { case FUNC_INIT: Pzem2SnsInit(); From 8025f28409f210760a86f603df4e7b547d3a4cec Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Wed, 12 Sep 2018 19:00:35 -0300 Subject: [PATCH 74/82] Let syslog to be active when emulation is active too solves issue https://github.com/arendst/Sonoff-Tasmota/issues/2109 --- sonoff/sonoff.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 52cdb68ba..a55e896c4 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1004,7 +1004,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) else if (CMND_SYSLOG == command_code) { if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { Settings.syslog_level = payload; - syslog_level = (Settings.flag2.emulation) ? 0 : payload; + syslog_level = payload; syslog_timer = 0; } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, command, Settings.syslog_level, syslog_level); @@ -1596,7 +1596,7 @@ void PerformEverySecond() if (syslog_timer) { // Restore syslog level syslog_timer--; if (!syslog_timer) { - syslog_level = (Settings.flag2.emulation) ? 0 : Settings.syslog_level; + syslog_level = Settings.syslog_level; if (Settings.syslog_level) { AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SYSLOG_LOGGING_REENABLED)); // Might trigger disable again (on purpose) } @@ -2513,7 +2513,7 @@ void setup() #ifndef USE_EMULATION Settings.flag2.emulation = 0; #endif // USE_EMULATION - syslog_level = (Settings.flag2.emulation) ? 0 : Settings.syslog_level; + syslog_level = Settings.syslog_level; stop_flash_rotate = Settings.flag.stop_flash_rotate; save_data_counter = Settings.save_data; sleep = Settings.sleep; From f8115a5abde45eac2748ccfb28fa5aba5e6cb9cc Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Thu, 13 Sep 2018 11:43:23 -0300 Subject: [PATCH 75/82] Added support for Xiaomi-Phillips bulb https://github.com/arendst/Sonoff-Tasmota/issues/3055 --- sonoff/sonoff_template.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 1ab62ae63..781b1004d 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -230,6 +230,7 @@ enum SupportedModules { BLITZWOLF_BWSHP2, SHELLY1, SHELLY2, + PHILIPS, MAXMODULE }; /********************************************************************************************/ @@ -399,7 +400,8 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { KMC_70011, AILIGHT, WEMOS, - WITTY + WITTY, + PHILIPS }; // Default module settings @@ -1044,6 +1046,14 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_SWT2_NP, // GPIO14 0, // GPIO15 MCP39F501 Reset 0, 0 + }, + { "Xiaomi Philips", // Xiaomi Philips bulb (ESP8266) + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + GPIO_PWM2, // GPIO12 cold/warm light + 0, 0, + GPIO_PWM1, // GPIO15 light intensity + 0, 0 } }; From 6f724e705b63b93d38a24ea66109ff0ac04deca6 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Thu, 13 Sep 2018 11:45:01 -0300 Subject: [PATCH 76/82] Added support for Xiaomi-Phillips bulb --- sonoff/xdrv_04_light.ino | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 93c2c522c..2a5a15b0c 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -427,6 +427,11 @@ void LightSetColorTemp(uint16_t ct) } uint16_t icold = (100 * (347 - my_ct)) / 136; uint16_t iwarm = (100 * my_ct) / 136; + if (PHILIPS == Settings.module) { + // Xiaomi Philips bulbs follow a different scheme: + // channel 0=intensity, channel2=temperature + Settings.light_color[1] = (uint8_t)icold; + } else if (LST_RGBWC == light_subtype) { Settings.light_color[0] = 0; Settings.light_color[1] = 0; @@ -458,6 +463,15 @@ void LightSetDimmer(uint8_t myDimmer) { float temp; + if (PHILIPS == Settings.module) { + // Xiaomi Philips bulbs use two PWM channels with a different scheme: + float dimmer = 100 / (float)myDimmer; + temp = (float)Settings.light_color[0] / dimmer; // channel 1 is intensity + light_current_color[0] = (uint8_t)temp; + temp = (float)Settings.light_color[1]; // channel 2 is temperature + light_current_color[1] = (uint8_t)temp; + return; + } if (LT_PWM1 == light_type) { Settings.light_color[0] = 255; // One PWM channel only supports Dimmer but needs max color } From 2b6e97146edc91af0d9c6b6dad6d8cbca87d5b59 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Thu, 13 Sep 2018 11:53:27 -0300 Subject: [PATCH 77/82] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 581b38e83..3f695f666 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ The following devices are supported: - [Supla device - Espablo-inCan mod. for electrical Installation box](https://forum.supla.org/viewtopic.php?f=33&t=2188) - [BlitzWolf BW-SHP2 Smart Socket with Energy Monitoring](https://www.banggood.com/BlitzWolf-BW-SHP2-Smart-WIFI-Socket-EU-Plug-220V-16A-Work-with-Amazon-Alexa-Google-Assistant-p-1292899.html) - [Luani HVIO board](https://luani.de/projekte/esp8266-hvio/) +- Xiaomi-Phillips Bulbs - Wemos D1 mini, NodeMcu and Ledunia ### Contribute From b3d2447fc708f470c21341283f63652a2c083ba4 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Thu, 13 Sep 2018 11:54:24 -0300 Subject: [PATCH 78/82] Update _changelog.ino --- sonoff/_changelog.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index d9044fcae..eed6ffcc7 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -4,6 +4,7 @@ * Fix ButtonRetain to not use default topic for clearing retain messages (#3737) * Add sleep to Nova Fitness SDS01X sensor (#2841, #3724, #3749) * Add Analog input AD0 enabled to sonoff-sensors.bin (#3756, #3757) + * Add Support to Xiaomi-Phillips Bulbs * * 6.2.1.2 20180906 * Fix KNX PA exception. Regression from 6.2.1 buffer overflow caused by subStr() (#3700, #3710) From 15fb7307fc363c2e7d8f478183dc3c0af63ad58f Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Fri, 14 Sep 2018 16:39:06 +0200 Subject: [PATCH 79/82] Add login parms for tools/decode-status.py --- tools/decode-status.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/decode-status.py b/tools/decode-status.py index 154b6e719..74b10a57c 100644 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -28,12 +28,13 @@ Instructions: and store it in file status.json Usage: - ./decode-status.py -d + ./decode-status.py -d [-u username] [-p password] or ./decode-status.py -f Example: ./decode-status.py -d sonoff1 + ./decode-status.py -d sonoff1 -p 12345678 or ./decode-status.py -f status.json """ @@ -42,6 +43,7 @@ import io import os.path import json import pycurl +import urllib2 from sys import exit from optparse import OptionParser from StringIO import StringIO @@ -136,13 +138,20 @@ usage = "usage: decode-status {-d | -f} arg" parser = OptionParser(usage) parser.add_option("-d", "--dev", action="store", type="string", dest="device", help="device to retrieve status from") +parser.add_option("-u", "--username", action="store", type="string", + dest="username", help="username for login", default="admin") +parser.add_option("-p", "--password", action="store", type="string", + dest="password", help="password for login", default=None) parser.add_option("-f", "--file", metavar="FILE", dest="jsonfile", default="status.json", help="status json file (default: status.json)") (options, args) = parser.parse_args() if (options.device): buffer = StringIO() - url = str("http://{}/cm?cmnd=status%200".format(options.device)) + loginstr = "" + if options.password is not None: + loginstr = "user={}&password={}&".format(urllib2.quote(options.username), urllib2.quote(options.password)) + url = str("http://{}/cm?{}cmnd=status%200".format(options.device, loginstr)) c = pycurl.Curl() c.setopt(c.URL, url) c.setopt(c.WRITEDATA, buffer) @@ -217,4 +226,4 @@ if __name__ == "__main__": try: StartDecode() except Exception as e: - print("E: {}".format(e)) \ No newline at end of file + print("E: {}".format(e)) From 63a1763a3f50a87fd2221f26cdb07f05e5974203 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 15 Sep 2018 09:13:39 +0200 Subject: [PATCH 80/82] added MP3_VOLUME to init the MP3 Player --- sonoff/user_config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 357fe5fab..a07c87ec3 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -342,6 +342,7 @@ //#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code) #define SDM630_SPEED 9600 // SDM630-Modbus RS485 serial speed (default: 9600 baud) //#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop +// #define MP3_VOLUME 10 // Set the startup volume on init, the range can be 0..30(max) // Power monitoring sensors ----------------------- #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) From 3c947e4c81fa71c95bfa4964a55b098affa8d427 Mon Sep 17 00:00:00 2001 From: Mike Date: Sat, 15 Sep 2018 09:33:53 +0200 Subject: [PATCH 81/82] Added version info and new MP3 Player commands - Added the version information to have some little hints what is done. - Added new commands and changed two commands from the first version. -- Intention was to get as less of commands as needed. -- There will be possible a version with much more function and serial->read. Command list: - MP3TRACK -- specify playback of a track, e.g. MP3Track 003. - MP3PLAY -- Play, works as a normal play on a real MP3 Player, starts at 001.mp3 file on the selected device. - MP3PAUSE -- Pause, was original designed as stop, see data sheet. - MP3STOP -- Stop, it's a real stop now, in the original version it was a pause command. - MP3VOLUME -- specifies the volume and means a console input as 0..100. - MP3EQ -- specify the EQ(0/1/2/3/4/5), 0:Normal, 1:Pop, 2:Rock, 3:Jazz, 4:Classic, 5:Bass. - MP3DEVICE -- specify playback device, USB=1, SD-Card=2, default is 2 also after reset or power down/up. --- sonoff/xdrv_14_mp3.ino | 147 ++++++++++++++++++++++++++++++----------- 1 file changed, 110 insertions(+), 37 deletions(-) diff --git a/sonoff/xdrv_14_mp3.ino b/sonoff/xdrv_14_mp3.ino index e4c72cb16..d799aa1f0 100644 --- a/sonoff/xdrv_14_mp3.ino +++ b/sonoff/xdrv_14_mp3.ino @@ -15,6 +15,40 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . + + -------------------------------------------------------------------------------------------- + Version yyyymmdd Action Description + -------------------------------------------------------------------------------------------- + 1.0.0.3 20180915 added - select device for SD-Card or USB Stick, default will be SD-Card + tested - works by MP3Device 1 = USB STick, or MP3Device 2 = SD-Card + - after power and/or reset the SD-Card(2) is the default device + --- + 1.0.0.2 20180912 added - again some if-commands to switch() because of new commands + --- + 1.0.0.1 20180911 added - command eq (equalizer 0..5) + tested - works in console with MP3EQ 1, the value can be 0..5 + added - USB device selection via command in console + tested - looks like it is working + erased - code for USB device about some errors, will be added in a next release + --- + 1.0.0.1 20180910 changed - command real MP3Stop in place of pause/stop used in the original version + changed - the command MP3Play e.g. 001 to MP3Track e.g. 001, + added - new normal command MP3Play and MP3Pause + --- + 1.0.0.0 20180907 merged - by arendst + changed - the driver name from xdrv_91_mp3.ino to xdrv_14_mp3.ino + --- + 0.9.0.3 20180906 request - Pull Request + changed - if-commands to switch() for faster response + --- + 0.9.0.2 20180906 cleaned - source code for faster reading + --- + 0.9.0.1 20180905 added - #include because compiler error (Arduino IDE v1.8.5) + --- + 0.9.0.0 20180901 started - further development by mike2nl - https://github.com/mike2nl/Sonoff-Tasmota + base - code base from gemu2015 ;-) - https://github.com/gemu2015/Sonoff-Tasmota + forked - from arendst/tasmota - https://github.com/arendst/Sonoff-Tasmota + */ #ifdef USE_MP3_PLAYER @@ -31,14 +65,30 @@ TasmotaSerial *MP3Player; const char S_JSON_MP3_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MP3 "%s\":%d}"; const char S_JSON_MP3_COMMAND[] PROGMEM = "{\"" D_CMND_MP3 "%s\"}"; +const char kMP3_Commands[] PROGMEM = "Track|Play|Pause|Stop|Volume|EQ|Device"; -enum MP3_Commands { CMND_MP3_PLAY, CMND_MP3_STOP, CMND_MP3_VOLUME}; -const char kMP3_Commands[] PROGMEM = "Play|Stop|Volume"; +// enumerations +enum MP3_Commands { // commands useable in console or rules + CMND_MP3_TRACK, // MP3Track 001...255 + CMND_MP3_PLAY, // MP3Play, after pause or normal start to play + CMND_MP3_PAUSE, // MP3Pause + CMND_MP3_STOP, // MP3Stop, real stop, original version was pause function + CMND_MP3_VOLUME, // MP3Volume 0..100 + CMND_MP3_EQ, // MP3EQ 0..5 + CMND_MP3_DEVICE }; // sd-card: 02, usb-stick: 01 -#define MP3_CMD_PLAY 3 -#define MP3_CMD_VOLUME 6 -#define MP3_CMD_STOP 0x0e +// defines +#define MP3_CMD_TRACK 0x03 // specify playback of a track, e.g. MP3Track 003 +#define MP3_CMD_PLAY 0x0d // Play, works as a normal play on a real MP3 Player, starts at 001.mp3 file on the selected device +#define MP3_CMD_PAUSE 0x0e // Pause, was original designed as stop, see data sheet +#define MP3_CMD_STOP 0x16 // Stop, it's a real stop now, in the original version it was a pause command +#define MP3_CMD_VOLUME 0x06 // specifies the volume and means a console input as 0..100 +#define MP3_CMD_EQ 0x07 // specify EQ(0/1/2/3/4/5), 0:Normal, 1:Pop, 2:Rock, 3:Jazz, 4:Classic, 5:Bass +#define MP3_CMD_DEVICE 0x09 // specify playback device, USB=1, SD-Card=2, default is 2 also after reset or power down/up +// calculate the checksum +// starts with cmd[1] with a length of 6 bytes +// uint16_t MP3_Checksum(uint8_t *array) { uint16_t checksum = 0; @@ -49,51 +99,74 @@ uint16_t MP3_Checksum(uint8_t *array) return checksum+1; } -// init player define serial tx port +// init player, define serial tx port +// fixed with 9600 baud +// void MP3PlayerInit() { MP3Player = new TasmotaSerial(-1, pin[GPIO_MP3_DFR562]); - - if (MP3Player->begin(9600)) { + // start serial communication fixed to 9600 baud + if (MP3Player->begin(9600)) { MP3Player->flush(); + delay(1000); // set delay + // volume setting + MP3_CMD(MP3_CMD_VOLUME, MP3_VOLUME); // set volume depending on the entry in the user_config.h } } +// create mp3 command payload and send it via serail interface to the MP3 player +// {start byte, version, length, command, feedback, para MSB, para LSB, chks MSB, chks LSB, end byte}; +// {cmd[0] , cmd[1] , cmd[2], cmd[3] , cmd[4] , cmd[5] , cmd[6] , cmd[7] , cmd[8] , cmd[9] }; +// {0x7e , 0xff , 6 , 0 , 0/1 , 0 , 0 , 0 , 0 , 0xef }; +// void MP3_CMD(uint8_t mp3cmd,uint16_t val) { - uint8_t cmd[10] = {0x7e,0xff,6,0,0,0,0,0,0,0xef}; - cmd[3] = mp3cmd; - cmd[5] = val>>8; - cmd[6] = val; - uint16_t chks = MP3_Checksum(&cmd[1]); // calculate out - cmd[7] = chks>>8; - cmd[8] = chks; - MP3Player->write(cmd, sizeof(cmd)); + uint8_t cmd[10] = {0x7e,0xff,6,0,0,0,0,0,0,0xef}; // fill array + cmd[3] = mp3cmd; // mp3 command value + //cmd[4] = ; // feedback, yet not use + cmd[5] = val>>8; // data value, shift 8 byte right + cmd[6] = val; // data value low byte + uint16_t chks = MP3_Checksum(&cmd[1]); // see calculate the checksum, line 62..72 + cmd[7] = chks>>8; // checksum. shift 8 byte right + cmd[8] = chks; // checksum low byte + MP3Player->write(cmd, sizeof(cmd)); // write mp3 data array to player } +// check the MP3 commands +// boolean MP3PlayerCmd() { char command[CMDSZ]; boolean serviced = true; uint8_t disp_len = strlen(D_CMND_MP3); - if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_MP3), disp_len)) { // Prefix + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_MP3), disp_len)) { // prefix int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + disp_len, kMP3_Commands); - - if (CMND_MP3_PLAY == command_code) { - if (XdrvMailbox.data_len > 0) { // play - MP3_CMD(MP3_CMD_PLAY, XdrvMailbox.payload); - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND_NVALUE, command, XdrvMailbox.payload); - } - else if (CMND_MP3_VOLUME == command_code) { - if (XdrvMailbox.data_len > 0) { // set volume - MP3_CMD(MP3_CMD_VOLUME, XdrvMailbox.payload * 30 / 100); - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND_NVALUE, command, XdrvMailbox.payload); - } - else if (CMND_MP3_STOP == command_code) { // stop - MP3_CMD(MP3_CMD_STOP, 0); - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND, command, XdrvMailbox.payload); - } else { - serviced = false; // Unknown command + + switch (command_code) { + case CMND_MP3_TRACK: + case CMND_MP3_VOLUME: + case CMND_MP3_EQ: + case CMND_MP3_DEVICE: + // play a track, set volume, select EQ, sepcify file device + if (XdrvMailbox.data_len > 0) { + if (command_code == CMND_MP3_TRACK) { MP3_CMD(MP3_CMD_TRACK, XdrvMailbox.payload); } + if (command_code == CMND_MP3_VOLUME) { MP3_CMD(MP3_CMD_VOLUME, XdrvMailbox.payload * 30 / 100); } + if (command_code == CMND_MP3_EQ) { MP3_CMD(MP3_CMD_EQ, XdrvMailbox.payload); } + if (command_code == CMND_MP3_DEVICE) { MP3_CMD(MP3_CMD_DEVICE, XdrvMailbox.payload); } + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND_NVALUE, command, XdrvMailbox.payload); + break; + case CMND_MP3_PLAY: + case CMND_MP3_PAUSE: + case CMND_MP3_STOP: + // play or re-play after pause, pause, stop, + if (command_code == CMND_MP3_PLAY) { MP3_CMD(MP3_CMD_PLAY, 0); } + if (command_code == CMND_MP3_PAUSE) { MP3_CMD(MP3_CMD_PAUSE, 0); } + if (command_code == CMND_MP3_STOP) { MP3_CMD(MP3_CMD_STOP, 0); } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_MP3_COMMAND, command, XdrvMailbox.payload); + break; + default: + // else for Unknown command + serviced = false; + break; } } return serviced; @@ -111,10 +184,10 @@ boolean Xdrv14(byte function) switch (function) { case FUNC_PRE_INIT: - MP3PlayerInit(); + MP3PlayerInit(); // init and start communication break; case FUNC_COMMAND: - result = MP3PlayerCmd(); + result = MP3PlayerCmd(); // return result from mp3 player command break; } return result; From 9fc5d7162965e1d3415cee133404f961e85c9e99 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 15 Sep 2018 12:00:22 +0200 Subject: [PATCH 82/82] Update Czech translation Update Czech translation --- sonoff/language/cs-CZ.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 9a0b11062..e90797725 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -94,7 +94,7 @@ #define D_FALSE "Nepravda" #define D_FILE "Soubor" #define D_FREE_MEMORY "Volná paměť" -#define D_FREQUENCY "Frequency" +#define D_FREQUENCY "Kmitočet" #define D_GAS "Plyn" #define D_GATEWAY "Výchozí brána" #define D_GROUP "Skupina" @@ -128,7 +128,7 @@ #define D_POWERUSAGE_APPARENT "Apparent Power" #define D_POWERUSAGE_REACTIVE "Reactive Power" #define D_PRESSURE "Tlak" -#define D_PRESSUREATSEALEVEL "Tlak na úrovni hladiny moře" +#define D_PRESSUREATSEALEVEL "Tlak na hladině moře" #define D_PROGRAM_FLASH_SIZE "Velikost paměti flash" #define D_PROGRAM_SIZE "Velikost programu" #define D_PROJECT "Projekt"