From 40052a343ffe94ad1ac4f077700acdb42eadb941 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 25 Sep 2018 15:35:49 +0200
Subject: [PATCH 01/18] Add image sonoff-display
Add define USE_DISPLAYS for selecting image sonoff-display
---
platformio.ini | 15 +++++++++++++++
sonoff/_changelog.ino | 1 +
sonoff/sonoff_post.h | 26 +++++++++++++++++++++++++-
sonoff/user_config.h | 3 ++-
4 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/platformio.ini b/platformio.ini
index d333fd187..c01485f5a 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -16,6 +16,7 @@ env_default = sonoff
;env_default = sonoff-classic
;env_default = sonoff-knx
;env_default = sonoff-sensors
+;env_default = sonoff-display
;env_default = sonoff-BG
;env_default = sonoff-BR
;env_default = sonoff-CN
@@ -167,6 +168,20 @@ upload_resetmethod = ${common.upload_resetmethod}
upload_speed = ${common.upload_speed}
extra_scripts = ${common.extra_scripts}
+[env:sonoff-display]
+platform = ${common.platform}
+framework = ${common.framework}
+board = ${common.board}
+board_build.flash_mode = ${common.board_build.flash_mode}
+board_build.f_cpu = ${common.board_build.f_cpu}
+build_unflags = ${common.build_unflags}
+build_flags = ${common.build_flags} -DUSE_DISPLAYS
+monitor_speed = ${common.monitor_speed}
+upload_port = ${common.upload_port}
+upload_resetmethod = ${common.upload_resetmethod}
+upload_speed = ${common.upload_speed}
+extra_scripts = ${common.extra_scripts}
+
[env:sonoff-BG]
platform = ${common.platform}
framework = ${common.framework}
diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino
index 333a524a6..f2525b2a7 100644
--- a/sonoff/_changelog.ino
+++ b/sonoff/_changelog.ino
@@ -2,6 +2,7 @@
* Remove restart after ntpserver change and force NTP re-sync (#3890)
* Release full Shelly2 support
* Released tools/decode-config.py by Norbert Richter to decode configuration data. See file for information
+ * Add define USE_DISPLAYS for selecting image sonoff-display
*
* 6.2.1.6 20180922
* Removed commands PowerCal, VoltageCal and CurrentCal as more functionality is provided by commands PowerSet, VoltageSet and CurrentSet
diff --git a/sonoff/sonoff_post.h b/sonoff/sonoff_post.h
index 8622d0818..423a75f3c 100755
--- a/sonoff/sonoff_post.h
+++ b/sonoff/sonoff_post.h
@@ -51,7 +51,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#endif
#define USE_DHT // Default DHT11 sensor needs no external library
-#define USE_ENERGY_SENSOR // Use energy sensors
+#define USE_ENERGY_SENSOR // Use energy sensors (+14k code)
#define USE_HLW8012 // Use energy sensor for Sonoff Pow and WolfBlitz
#define USE_CSE7766 // Use energy sensor for Sonoff S31 and Pow R2
@@ -167,6 +167,30 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#undef USE_EMULATION // Disable Belkin WeMo and Hue Bridge emulation for Alexa (-16k code, -2k mem)
#endif // USE_KNX_NO_EMULATION
+/*********************************************************************************************\
+ * [sonoff-display.bin]
+ * Provide an image with display drivers enabled
+\*********************************************************************************************/
+
+#ifdef USE_DISPLAYS
+
+#undef USE_ENERGY_SENSOR // Disable energy sensors (-14k code)
+#undef USE_EMULATION // Disable Belkin WeMo and Hue Bridge emulation for Alexa (-16k code, -2k mem)
+
+#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)
+ #define USE_DISPLAY // Add I2C Display Support (+2k code)
+ #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
+ #define USE_DISPLAY_LCD // [DisplayModel 1] Enable Lcd display (I2C addresses 0x27 and 0x3F) (+6k code)
+ #define USE_DISPLAY_SSD1306 // [DisplayModel 2] Enable SSD1306 Oled 128x64 display (I2C addresses 0x3C and 0x3D) (+16k code)
+ #define USE_DISPLAY_MATRIX // [DisplayModel 3] Enable 8x8 Matrix display (I2C adresseses see below) (+11k code)
+
+#define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC)
+ #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code)
+
+#undef USE_ARILUX_RF // Remove support for Arilux RF remote controller (-0k8 code, 252 iram (non 2.3.0))
+#undef USE_RF_FLASH // Remove support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (-3k code)
+#endif // USE_DISPLAYS
+
/*********************************************************************************************\
* Mandatory define for DS18x20 if changed by above image selections
\*********************************************************************************************/
diff --git a/sonoff/user_config.h b/sonoff/user_config.h
index b93e44211..f86350334 100644
--- a/sonoff/user_config.h
+++ b/sonoff/user_config.h
@@ -321,7 +321,7 @@
#endif // USE_I2C
// -- SPI sensors ---------------------------------
-//#define USE_SPI // SPI using library TasmotaTFT
+//#define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC)
#ifdef USE_SPI
#ifndef USE_DISPLAY
@@ -384,6 +384,7 @@
//#define USE_CLASSIC // Create sonoff-classic with initial configuration tools WPS, SmartConfig and WifiManager
//#define USE_SENSORS // Create sonoff-sensors with useful sensors enabled
//#define USE_KNX_NO_EMULATION // Create sonoff-knx with KNX but without Emulation
+//#define USE_DISPLAYS // Create sonoff-display with display drivers enabled
//#define BE_MINIMAL // Create sonoff-minimal as intermediate firmware for OTA-MAGIC
/*********************************************************************************************\
From eb53605fc1ee76f3fd893b0728ef8b9117183060 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 25 Sep 2018 17:03:22 +0200
Subject: [PATCH 02/18] Fix VEML6070 compile errors
---
sonoff/i18n.h | 2 +-
sonoff/user_config.h | 6 +++---
sonoff/xsns_11_veml6070.ino | 30 +++++++++++++++---------------
3 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/sonoff/i18n.h b/sonoff/i18n.h
index 1c628b7b7..c8d3e219f 100644
--- a/sonoff/i18n.h
+++ b/sonoff/i18n.h
@@ -130,7 +130,7 @@
#define D_JSON_TYPE "Type"
#define D_JSON_UPTIME "Uptime"
#define D_JSON_UTC_TIME "UTC"
-#define D_JSON_UVINDEX "UvIndex"
+#define D_JSON_UV_INDEX "UvIndex"
#define D_JSON_UV_LEVEL "UvLevel"
#define D_JSON_UV_POWER "UvPower"
#define D_JSON_VCC "Vcc"
diff --git a/sonoff/user_config.h b/sonoff/user_config.h
index b864d7aa6..eceadc68d 100644
--- a/sonoff/user_config.h
+++ b/sonoff/user_config.h
@@ -282,9 +282,9 @@
#define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address 0x76 or 0x77) (+4k code)
// #define USE_BME680 // Enable support for BME680 sensor using Bosch BME680 library (+4k code)
#define USE_BH1750 // Enable BH1750 sensor (I2C address 0x23 or 0x5C) (+0k5 code)
-// #define USE_VEML6070 // Enable VEML6070 sensor (I2C addresses 0x38 and 0x39) (+0k5 code)
-// #define USE_VEML6070_RSET 270000 // VEML6070, Rset in Ohm used on PCB board, default 270K = 270000ohm, range for this sensor: 220K ... 1Meg
-// #define USE_VEML6070_SHOW_RAW // VEML6070, shows the raw value of UV-A
+// #define USE_VEML6070 // Enable VEML6070 sensor (I2C addresses 0x38 and 0x39) (+1k5 code)
+ #define USE_VEML6070_RSET 270000 // VEML6070, Rset in Ohm used on PCB board, default 270K = 270000ohm, range for this sensor: 220K ... 1Meg
+ #define USE_VEML6070_SHOW_RAW // VEML6070, shows the raw value of UV-A
// #define USE_ADS1115 // Enable ADS1115 16 bit A/D converter (I2C address 0x48, 0x49, 0x4A or 0x4B) based on Adafruit ADS1x15 library (no library needed) (+0k7 code)
// #define USE_ADS1115_I2CDEV // Enable ADS1115 16 bit A/D converter (I2C address 0x48, 0x49, 0x4A or 0x4B) using library i2cdevlib-Core and i2cdevlib-ADS1115 (+2k code)
// #define USE_INA219 // Enable INA219 (I2C address 0x40, 0x41 0x44 or 0x45) Low voltage and current sensor (+1k code)
diff --git a/sonoff/xsns_11_veml6070.ino b/sonoff/xsns_11_veml6070.ino
index be7d3daa0..f60c0f00f 100644
--- a/sonoff/xsns_11_veml6070.ino
+++ b/sonoff/xsns_11_veml6070.ino
@@ -30,7 +30,7 @@
--------------------------------------------------------------------------------------------
Version Date Action Description
--------------------------------------------------------------------------------------------
-
+
1.0.0.1 20180925 tests - all tests are done with 1x sonoff sv, 2x Wemos D1 (not the mini)
- 3 different VEMl6070 sensors from 3 different online shops
- all the last three test where good and all looks working so far
@@ -43,7 +43,7 @@
cleaned - source code a little bit
added - missing void in function calls: void name(void)
added - UV Risk level now defined as UV Index, 0.00 based on NASA standard with text behind the value
- added - UV Power level now named as UV Power, used W/m2 because official standards
+ added - UV Power level now named as UV Power, used W/m2 because official standards
added - automatic fill of the uv-risk compare table based on the coefficient calculation
added - suspend and wakeup mode for the uv seonsor
- current drain in wake-up-ed mode was around 180uA incl. I2C bus
@@ -51,7 +51,7 @@
changed - 2x the power calculation about some incorrent data sheet values
changed - float to double calculation because a rare effect on uv compare map filling
- in that case @andrethomas was a big help too (while(work){output=lot_of_fun};)
- added - USE_VEML6070_RSET
+ added - USE_VEML6070_RSET
- in user_config as possible input, different resistor values depending on PCB types
added - USE_VEML6070_SHOW_RAW
- in user_config, show or show-NOT the uv raw value
@@ -62,12 +62,12 @@
safety - personal, please read this: http://www.segurancaetrabalho.com.br/download/uv_index_karel_vanicek.pdf
next - possible i will add the calculation for LAT and LONG coordinates for much more precission
- show not only the UV Power value in W/m2, possible a @define value to show it as joule value
- - add a #define to select how many characters are shown benhind the decimal point for the UV Index
+ - add a #define to select how many characters are shown benhind the decimal point for the UV Index
---
1.0.0.0 20180912 started - further development by mike2nl - https://github.com/mike2nl/Sonoff-Tasmota
forked - from arendst/tasmota - https://github.com/arendst/Sonoff-Tasmota
base - code base from arendst too
-
+
*/
#ifdef USE_I2C
@@ -87,8 +87,8 @@
#define VEML6070_RSET_DEFAULT 270000 // 270K default resistor value 270000 ohm, range from 220K..1Meg
#define VEML6070_UV_MAX_INDEX 15 // normal 11, internal on weather laboratories and NASA it's 15 so far the sensor is linear
#define VEML6070_UV_MAX_DEFAULT 11 // 11 = public default table values
-#define VEML6070_POWER_COEFFCIENT 0.025 // based on calculations from Karel Vanicek and reorder by hand
-#define VEML6070_TABLE_COEFFCIENT 32.86270591 // calculated by hand with help from a friend of mine, a professor which works in aero space things
+#define VEML6070_POWER_COEFFCIENT 0.025 // based on calculations from Karel Vanicek and reorder by hand
+#define VEML6070_TABLE_COEFFCIENT 32.86270591 // calculated by hand with help from a friend of mine, a professor which works in aero space things
// (resistor, differences, power coefficients and official UV index calculations (LAT & LONG will be added later)
/********************************************************************************************/
@@ -110,7 +110,7 @@ void Veml6070Detect(void)
Wire.beginTransmission(veml6070_address);
Wire.write((itime << 2) | 0x02);
uint8_t status = Wire.endTransmission();
-
+
if (!status) {
veml6070_type = 1;
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "VEML6070", veml6070_address);
@@ -130,7 +130,7 @@ void Veml6070ModeCmd(boolean mode_cmd)
} else {
opmode = VEML6070_DISABLE;
}
-
+
veml6070_address = VEML6070_ADDR_L;
Wire.beginTransmission(veml6070_address);
Wire.write((opmode << 0) | 0x02 | (itime << 2));
@@ -165,7 +165,7 @@ double Veml6070UvRiskLevel(uint16_t uv_level)
{
double risk = 0;
double uv_risk_map[VEML6070_UV_MAX_INDEX] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
+
// fill the uv-risk compare table based on the coefficient calculation
for (uint8_t i = 0; i < VEML6070_UV_MAX_INDEX; i++) {
#ifdef USE_VEML6070_RSET
@@ -179,7 +179,7 @@ double Veml6070UvRiskLevel(uint16_t uv_level)
#else
uv_risk_map[i] = ( (VEML6070_RSET_DEFAULT / VEML6070_TABLE_COEFFCIENT) / VEML6070_UV_MAX_DEFAULT) * (i+1);
#endif
- }
+ }
// get the uv-risk level
if (uv_level < uv_risk_map[VEML6070_UV_MAX_INDEX-1]) {
@@ -223,8 +223,8 @@ void Veml6070Show(boolean json)
{
if (veml6070_type) {
// wakeup the sensor
- Veml6070ModeCmd(1);
-
+ Veml6070ModeCmd(1);
+
// get values from functions
uint16_t uvlevel = Veml6070ReadUv();
double uvrisk = Veml6070UvRiskLevel(uvlevel);
@@ -243,7 +243,7 @@ void Veml6070Show(boolean json)
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"VEML6070\":{\"" D_JSON_UV_INDEX "\":%s}"), mqtt_data, str_uvrisk);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"VEML6070\":{\"" D_JSON_UV_POWER "\":%s}"), mqtt_data, str_uvpower);
#ifdef USE_DOMOTICZ
- if (0 == tele_period) { DomoticzSensor(DZ_ILLUMINANCE, uvlevel) };
+ if (0 == tele_period) { DomoticzSensor(DZ_ILLUMINANCE, uvlevel); };
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
@@ -270,7 +270,7 @@ void Veml6070Show(boolean json)
} else {
// else for Unknown or Out Of Range error = 99
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_UV_INDEX7, mqtt_data, str_uvrisk);
- }
+ }
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_UV_POWER, mqtt_data, str_uvpower);
#endif // USE_WEBSERVER
}
From b78626fd480e2b8254e39afd0ca7832e8087623e Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 25 Sep 2018 17:08:16 +0200
Subject: [PATCH 03/18] Updated with Shelly
---
README.md | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 3f695f666..498cd2f80 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,7 @@ See [Community](https://groups.google.com/d/forum/sonoffusers) for forum.
See [Chat](https://discord.gg/Ks2Kzd4) for more user experience.
The following devices are supported:
-- [iTead Sonoff Basic](https://www.itead.cc/smart-home/sonoff-wifi-wireless-switch-1.html)
+- [iTead Sonoff Basic (R2)](https://www.itead.cc/smart-home/sonoff-wifi-wireless-switch-1.html)
- [iTead Sonoff RF](https://www.itead.cc/smart-home/sonoff-rf.html)
- [iTead Sonoff SV](https://www.itead.cc/smart-home/sonoff-sv.html)
- [iTead Sonoff TH10/TH16 with temperature sensor](https://www.itead.cc/smart-home/sonoff-th.html)
@@ -90,10 +90,15 @@ The following devices are supported:
- [MagicHome PWM LED controller](https://github.com/arendst/Sonoff-Tasmota/wiki/MagicHome-LED-strip-controller)
- AriLux AL-LC01, AL-LC06 and AL-LC11 PWM LED controller
- [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)
+- [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
+- [Wemos D1 mini](https://wiki.wemos.cc/products:d1:d1_mini)
+- [HuaFan Smart Socket](HuaFan-Smart-Socket)
+- [Hyleton-313 Smart Plug](Hyleton-313-Smart-Plug)
+- [Allterco Shelly 1](https://shelly.cloud/shelly1-open-source/)
+- [Allterco Shelly 2 with Energy Monitoring](https://shelly.cloud/shelly2/)
+- NodeMcu and Ledunia
+- [KS-602 based switches like GresaTek, Jesiya, NewRice, Lyasi etc](https://ucexperiment.wordpress.com/2017/11/14/reprogramming-a-lyasi-wifi-wall-switch-with-esp8285/)
### Contribute
You can contribute to Sonoff-Tasmota by
From 71964e0aa46e945b7fa7d958cf926fa276d69339 Mon Sep 17 00:00:00 2001
From: localhost61
Date: Wed, 26 Sep 2018 00:59:00 +0200
Subject: [PATCH 04/18] Update French localization
---
sonoff/language/fr-FR.h | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h
index c4c913fec..9a479177a 100644
--- a/sonoff/language/fr-FR.h
+++ b/sonoff/language/fr-FR.h
@@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele.
*
- * Updated until v6.1.1.7
+ * Updated until v6.2.1.7
\*********************************************************************/
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@@ -65,7 +65,7 @@
#define D_BY "par" // Written by me
#define D_BYTES "Bytes"
#define D_CELSIUS "Celsius"
-#define D_CHANNEL "Channel"
+#define D_CHANNEL "Canal"
#define D_CO2 "Dioxyde de carbone"
#define D_CODE "code" // Button code
#define D_COLDLIGHT "Froid"
@@ -163,15 +163,15 @@
#define D_USER "Utilisateur"
#define D_UTC_TIME "UTC"
#define D_UV_INDEX "Indice UV"
-#define D_UV_INDEX_1 "Low"
-#define D_UV_INDEX_2 "Mid"
-#define D_UV_INDEX_3 "High"
-#define D_UV_INDEX_4 "Danger"
-#define D_UV_INDEX_5 "BurnL1/2"
-#define D_UV_INDEX_6 "BurnL3"
-#define D_UV_INDEX_7 "OoR"
+#define D_UV_INDEX_1 "Faible"
+#define D_UV_INDEX_2 "Modéré"
+#define D_UV_INDEX_3 "Élevé"
+#define D_UV_INDEX_4 "Très élevé"
+#define D_UV_INDEX_5 "Brûlure niv.1/2"
+#define D_UV_INDEX_6 "Brûlure niv.3"
+#define D_UV_INDEX_7 "Extrême"
#define D_UV_LEVEL "Niveau UV"
-#define D_UV_POWER "UV Power"
+#define D_UV_POWER "Puissance UV"
#define D_VERSION "Version"
#define D_VOLTAGE "Tension"
#define D_WARMLIGHT "Chaud"
From 6798eb585441e6cbceb241878dfc65a2f0dee59d Mon Sep 17 00:00:00 2001
From: Adrian Scillato <35405447+ascillato@users.noreply.github.com>
Date: Tue, 25 Sep 2018 21:00:56 -0300
Subject: [PATCH 05/18] Updated Spanish Translation
---
sonoff/language/es-AR.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h
index b67e6e79f..713e166ab 100644
--- a/sonoff/language/es-AR.h
+++ b/sonoff/language/es-AR.h
@@ -163,13 +163,13 @@
#define D_USER "Usuario"
#define D_UTC_TIME "UTC"
#define D_UV_INDEX "Índice UV"
-#define D_UV_INDEX_1 "Low"
-#define D_UV_INDEX_2 "Mid"
-#define D_UV_INDEX_3 "High"
-#define D_UV_INDEX_4 "Danger"
-#define D_UV_INDEX_5 "BurnL1/2"
-#define D_UV_INDEX_6 "BurnL3"
-#define D_UV_INDEX_7 "OoR"
+#define D_UV_INDEX_1 "Bajo"
+#define D_UV_INDEX_2 "Medio"
+#define D_UV_INDEX_3 "Alto"
+#define D_UV_INDEX_4 "Peligroso"
+#define D_UV_INDEX_5 "Quemaduras 1 a 2 grad"
+#define D_UV_INDEX_6 "Quemaduras 3 grad"
+#define D_UV_INDEX_7 "Fuera de Rango"
#define D_UV_LEVEL "Nivel UV"
#define D_UV_POWER "UV Power"
#define D_VERSION "Versión"
From 8ff696b34b19cc2fcefcf2bce64ab6cb701a90b8 Mon Sep 17 00:00:00 2001
From: localhost61
Date: Wed, 26 Sep 2018 02:37:27 +0200
Subject: [PATCH 06/18] Correct the OoR translation (thanks Adrian ;-) )
---
sonoff/language/fr-FR.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h
index 9a479177a..a7adaea39 100644
--- a/sonoff/language/fr-FR.h
+++ b/sonoff/language/fr-FR.h
@@ -169,7 +169,7 @@
#define D_UV_INDEX_4 "Très élevé"
#define D_UV_INDEX_5 "Brûlure niv.1/2"
#define D_UV_INDEX_6 "Brûlure niv.3"
-#define D_UV_INDEX_7 "Extrême"
+#define D_UV_INDEX_7 "Hors échelle"
#define D_UV_LEVEL "Niveau UV"
#define D_UV_POWER "Puissance UV"
#define D_VERSION "Version"
@@ -184,7 +184,7 @@
#define D_SERIAL_LOGGING_DISABLED "Journalisation série désactivée"
#define D_SYSLOG_LOGGING_REENABLED "Jounalisation syslog réactivée"
-#define D_SET_BAUDRATE_TO "Définir baudrate à"
+#define D_SET_BAUDRATE_TO "Définir le débit à"
#define D_RECEIVED_TOPIC "Topic reçu" // Terme MQTT
#define D_DATA_SIZE "Taille données"
#define D_ANALOG_INPUT "Analogique"
From bac33345a05e57fc3fb17f8c0f82ac2f406151a8 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 26 Sep 2018 10:13:44 +0200
Subject: [PATCH 07/18] 6.2.1.8 Extent status JSON
6.2.1.8 20180926
* Change status JSON message providing more switch and retain information
---
sonoff/_changelog.ino | 5 ++++-
sonoff/sonoff.ino | 9 +++++++--
sonoff/sonoff_version.h | 2 +-
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino
index f2525b2a7..a442bf59e 100644
--- a/sonoff/_changelog.ino
+++ b/sonoff/_changelog.ino
@@ -1,4 +1,7 @@
-/* 6.2.1.7 20180925
+/* 6.2.1.8 20180926
+ * Change status JSON message providing more switch and retain information
+ *
+ * 6.2.1.7 20180925
* Remove restart after ntpserver change and force NTP re-sync (#3890)
* Release full Shelly2 support
* Released tools/decode-config.py by Norbert Richter to decode configuration data. See file for information
diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino
index f0619f362..5bcf5fa7c 100755
--- a/sonoff/sonoff.ino
+++ b/sonoff/sonoff.ino
@@ -1412,6 +1412,7 @@ void PublishStatus(uint8_t payload)
{
uint8_t option = STAT;
char stemp[MAX_FRIENDLYNAMES * (sizeof(Settings.friendlyname[0]) +MAX_FRIENDLYNAMES)];
+ char stemp2[MAX_SWITCHES * 3];
// Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX
if (!strcmp(Settings.mqtt_prefix[0],Settings.mqtt_prefix[1]) && (!payload)) option++; // TELE
@@ -1426,8 +1427,12 @@ void PublishStatus(uint8_t payload)
for (byte i = 0; i < maxfn; i++) {
snprintf_P(stemp, sizeof(stemp), PSTR("%s%s\"%s\"" ), stemp, (i > 0 ? "," : ""), Settings.friendlyname[i]);
}
- snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"),
- Settings.module +1, stemp, mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_power_retain);
+ stemp2[0] = '\0';
+ for (byte i = 0; i < MAX_SWITCHES; i++) {
+ snprintf_P(stemp2, sizeof(stemp2), PSTR("%s%s%d" ), stemp2, (i > 0 ? "," : ""), Settings.switchmode[i]);
+ }
+ snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_SWITCHTOPIC "\":\"%s\",\"" D_CMND_SWITCHMODE "\":[%s],\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_SWITCHRETAIN "\":%d,\"" D_CMND_SENSORRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"),
+ Settings.module +1, stemp, mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.switch_topic, stemp2, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_switch_retain, Settings.flag.mqtt_sensor_retain, Settings.flag.mqtt_power_retain);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS));
}
diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h
index 16c554783..915ce52d2 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 0x06020107
+#define VERSION 0x06020108
#define D_PROGRAMNAME "Sonoff-Tasmota"
#define D_AUTHOR "Theo Arends"
From 6939d6eead78d72dc2ffc104f8a6578711c5afe1 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 26 Sep 2018 11:56:58 +0200
Subject: [PATCH 08/18] Fix Shelly Ghost and Rule sensors
* Change pinmode for no-pullup defined switches to pullup when configured as switchmode PUSHBUTTON (=3 and up) (#3896)
* Add delay after restart before processing rule sensor data (#3811)
---
sonoff/_changelog.ino | 2 ++
sonoff/sonoff.ino | 18 ++++++++++++++++--
sonoff/sonoff_template.h | 22 ++++++++++++++++++++--
sonoff/xdrv_10_rules.ino | 2 +-
4 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino
index a442bf59e..06ebd36c1 100644
--- a/sonoff/_changelog.ino
+++ b/sonoff/_changelog.ino
@@ -1,5 +1,7 @@
/* 6.2.1.8 20180926
* Change status JSON message providing more switch and retain information
+ * Change pinmode for no-pullup defined switches to pullup when configured as switchmode PUSHBUTTON (=3 and up) (#3896)
+ * Add delay after restart before processing rule sensor data (#3811)
*
* 6.2.1.7 20180925
* Remove restart after ntpserver change and force NTP re-sync (#3890)
diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino
index 5bcf5fa7c..6b354bb24 100755
--- a/sonoff/sonoff.ino
+++ b/sonoff/sonoff.ino
@@ -147,6 +147,7 @@ uint16_t blink_counter = 0; // Number of blink cycles
uint16_t seriallog_timer = 0; // Timer to disable Seriallog
uint16_t syslog_timer = 0; // Timer to re-enable syslog_level
uint16_t holdbutton[MAX_KEYS] = { 0 }; // Timer for button hold
+uint16_t switch_no_pullup = 0; // Switch pull-up bitmask flags
int16_t save_data_counter; // Counter and flag for config save to Flash
RulesBitfield rules_flag; // Rule state flags (16 bits)
uint8_t serial_local = 0; // Handle serial locally;
@@ -1119,6 +1120,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
else if ((CMND_SWITCHMODE == command_code) && (index > 0) && (index <= MAX_SWITCHES)) {
if ((payload >= 0) && (payload < MAX_SWITCH_OPTION)) {
Settings.switchmode[index -1] = payload;
+ GpioSwitchPinMode(index -1);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_NVALUE, command, index, Settings.switchmode[index-1]);
}
@@ -2296,11 +2298,23 @@ void SerialInput()
/********************************************************************************************/
+void GpioSwitchPinMode(uint8_t index)
+{
+ if (pin[GPIO_SWT1 +index] < 99) {
+// pinMode(pin[GPIO_SWT1 +index], (16 == pin[GPIO_SWT1 +index]) ? INPUT_PULLDOWN_16 : bitRead(switch_no_pullup, index) ? INPUT : INPUT_PULLUP);
+
+ uint8_t no_pullup = 0;
+ if (bitRead(switch_no_pullup, index)) {
+ no_pullup = (Settings.switchmode[index] < PUSHBUTTON);
+ }
+ pinMode(pin[GPIO_SWT1 +index], (16 == pin[GPIO_SWT1 +index]) ? INPUT_PULLDOWN_16 : (no_pullup) ? INPUT : INPUT_PULLUP);
+ }
+}
+
void GpioInit()
{
uint8_t mpin;
uint8_t key_no_pullup = 0;
- uint16_t switch_no_pullup = 0;
mytmplt def_module;
if (!Settings.module || (Settings.module >= MAXMODULE)) {
@@ -2457,7 +2471,7 @@ void GpioInit()
for (byte i = 0; i < MAX_SWITCHES; i++) {
lastwallswitch[i] = 1; // Init global to virtual switch state;
if (pin[GPIO_SWT1 +i] < 99) {
- pinMode(pin[GPIO_SWT1 +i], (16 == pin[GPIO_SWT1 +i]) ? INPUT_PULLDOWN_16 : bitRead(switch_no_pullup, i) ? INPUT : INPUT_PULLUP);
+ GpioSwitchPinMode(i);
lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]); // Set global now so doesn't change the saved power state on first switch check
}
virtualswitch[i] = lastwallswitch[i];
diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h
index 781b1004d..f5e332531 100644
--- a/sonoff/sonoff_template.h
+++ b/sonoff/sonoff_template.h
@@ -399,9 +399,9 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
HUAFAN_SS,
KMC_70011,
AILIGHT,
- WEMOS,
+ PHILIPS,
WITTY,
- PHILIPS
+ WEMOS
};
// Default module settings
@@ -1060,6 +1060,24 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
/*
Optionals
+ { "Arilux LC10", // Arilux LC10 (ESP8285), RGBW + RF
+ // https://github.com/arendst/Sonoff-Tasmota/wiki/MagicHome-with-ESP8285
+ // https://www.aliexpress.com/item/DC5-24V-Wireless-WIFI-LED-RGB-Controller-RGBW-Controller-IR-RF-Remote-Control-IOS-Android-for/32827253255.html
+ // https://www.aliexpress.com/item/Wifi-LED-RGB-Controler-DC12V-MIni-Wifi-RGB-RGBW-LED-Controller-for-RGB-RGBW-LED-Strip/32673444047.html
+ GPIO_USER, // GPIO00 Optional Button
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ 0,
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor0
+ GPIO_ARIRFRCV, // GPIO04 RF receiver input
+ GPIO_PWM2, // GPIO05 RGB LED Green
+ 0, 0, 0, 0, 0, 0, // Flash connection
+ GPIO_PWM3, // GPIO12 RGB LED Blue
+ GPIO_PWM4, // GPIO13 RGBW LED White
+ GPIO_PWM1, // GPIO14 RGB LED Red
+ GPIO_LED2_INV, // GPIO15 RF receiver control
+ 0, 0
+ }
+
{ "Xenon 3CH", // Xenon 3CH (ESP8266) - (#1128)
0, 0, 0,
GPIO_KEY2, // GPIO03 Serial TXD and Optional sensor
diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino
index 303207c10..060bf085f 100644
--- a/sonoff/xdrv_10_rules.ino
+++ b/sonoff/xdrv_10_rules.ino
@@ -425,7 +425,7 @@ void RulesEvery50ms()
void RulesEvery100ms()
{
- if (Settings.rule_enabled) { // Any rule enabled
+ if (Settings.rule_enabled && (uptime > 4)) { // Any rule enabled and allow 4 seconds start-up time for sensors (#3811)
mqtt_data[0] = '\0';
int tele_period_save = tele_period;
tele_period = 2; // Do not allow HA updates during next function call
From 76d203d5aaed61bf4769aaa51bce6f30953b23c0 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Wed, 26 Sep 2018 15:18:01 +0200
Subject: [PATCH 09/18] 'decode-config.py' version bugfixes & json output
enhancements
- add new arguments '--json-indent' and '--json-compact'
- fix poblem with invalid string chars when having garbadge in flash
- fix errors using configs for Tasmota < v6.2.1
- fix setting definition for v5.13.1/v5.14.0
---
tools/decode-config.py | 127 +++++++++++++++++++++++++++--------------
1 file changed, 83 insertions(+), 44 deletions(-)
diff --git a/tools/decode-config.py b/tools/decode-config.py
index 299f152c4..dc51e0f42 100644
--- a/tools/decode-config.py
+++ b/tools/decode-config.py
@@ -21,7 +21,7 @@
Requirements:
- Python
- - pip json pycurl urllib2 configargparse
+ - pip install json pycurl urllib2 configargparse
Instructions:
Execute command with option -d to retrieve config data from device or
@@ -31,10 +31,11 @@ Instructions:
Usage:
- decode-config.py [-h] [-f ] [-d ]
- [-u ] [-p ] [--format ]
- [--sort ] [--raw] [--unhide-pw] [-o ]
- [-c ] [-V]
+ decode-config.py [-h] [-f ] [-d ] [-u ]
+ [-p ] [--format ]
+ [--json-indent ] [--json-compact]
+ [--sort ] [--raw] [--unhide-pw] [-o ]
+ [-c ] [-V]
Decode configuration of Sonoff-Tasmota device. Args that start with '--' (eg.
-f) can also be set in a config file (specified via -c). Config file syntax
@@ -46,21 +47,27 @@ Usage:
-h, --help show this help message and exit
-c , --config
Config file, can be used instead of command parameter
- (defaults to None)
+ (default: None)
source:
-f , --file
file to retrieve Tasmota configuration from (default:
None)
- -d , --device
- device to retrieve configuration from (default: None)
+ -d , --device
+ hostname or IP address to retrieve Tasmota
+ configuration from (default: None)
-u , --username
- for -d usage: http access username (default: admin)
+ host http access username (default: admin)
-p , --password
- for -d usage: http access password (default: None)
+ host http access password (default: None)
output:
--format output format ("json" or "text", default: "json")
+ --json-indent
+ pretty-printed JSON output using indent level
+ (default: "None")
+ --json-compact compact JSON output by eliminate whitespace (default:
+ "not compact")
--sort sort result - can be "none" or "name" (default:
"name")
--raw output raw values (default: processed)
@@ -72,7 +79,7 @@ Usage:
info:
-V, --version show program's version number and exit
- Note: Either argument -d or -f must be given.
+ Either argument -d or -f must be given.
Examples:
@@ -113,7 +120,7 @@ except ImportError:
sys.exit(9)
-VER = '1.5.0008'
+VER = '1.5.0009'
PROG='{} v{} by Norbert Richter'.format(os.path.basename(sys.argv[0]),VER)
CONFIG_FILE_XOR = 0x5A
@@ -135,6 +142,8 @@ DEFAULTS = {
'output':
{
'format': 'json',
+ 'jsonindent': None,
+ 'jsoncompact': False,
'sort': 'name',
'raw': False,
'unhide-pw': False,
@@ -940,7 +949,7 @@ Setting_5_14_0 = {
'knx_CB_addr': ('3:
+ if not raw and len(fielddef)>3:
if isinstance(fielddef[3],str): # use a format string
return fielddef[3].format(value)
elif callable(fielddef[3]): # use a format function
@@ -1685,7 +1696,7 @@ def ConvertFieldValue(value, fielddef):
return value
-def GetField(dobj, fieldname, fielddef):
+def GetField(dobj, fieldname, fielddef, raw=False):
"""
Get field value from definition
@@ -1695,6 +1706,8 @@ def GetField(dobj, fieldname, fielddef):
name of the field
@param fielddef:
see Settings desc above
+ @param raw
+ return raw values (True) or converted values (False)
@return: read field value
"""
@@ -1715,13 +1728,13 @@ def GetField(dobj, fieldname, fielddef):
subfielddef = (fielddef[0], addr, None, None if len(fielddef)<4 else fielddef[3])
length = GetFieldLength(subfielddef)
if length != 0:
- result.append(GetField(dobj, fieldname, subfielddef))
+ result.append(GetField(dobj, fieldname, subfielddef, raw))
addr += length
# tuple 2 contains a list with dict
elif isinstance(fielddef[2], list) and len(fielddef[2])>0 and isinstance(fielddef[2][0], dict):
d = {}
value = struct.unpack_from(fielddef[0], dobj, fielddef[1])[0]
- d['base'] = ConvertFieldValue(value, fielddef);
+ d['base'] = ConvertFieldValue(value, fielddef, raw);
union = fielddef[2]
i = 0
for l in union:
@@ -1738,8 +1751,8 @@ def GetField(dobj, fieldname, fielddef):
if ord(result[:1])==0x00 or ord(result[:1])==0xff:
result = ''
s = str(result).split('\0')[0]
- result = s #unicode(s, errors='replace')
- result = ConvertFieldValue(result, fielddef)
+ result = unicode(s, errors='replace')
+ result = ConvertFieldValue(result, fielddef, raw)
return result
@@ -1762,40 +1775,52 @@ def DeEncrypt(obj):
def Decode(obj):
"""
- Decodes (already decrypted) binary data stream
+ Decodes binary data stream
@param obj:
- binary config data
+ binary config data (decrypted)
"""
# get header data
- cfg_size = GetField(obj, 'cfg_size', Setting_6_2_1['cfg_size'])
- version = GetField(obj, 'version', Setting_6_2_1['version'])
+ version = GetField(obj, 'version', Setting_6_2_1['version'], raw=True)
# search setting definition
- setting = None
+ template = None
for cfg in Settings:
- if version >= cfg[0] and cfg_size == cfg[1]:
+ if version >= cfg[0]:
template = cfg
break
- setting = template[2]
# if we did not found a mathching setting
- if setting is None:
- exit(2, "Can't handle Tasmota configuration data for version 0x{:x} with {} bytes".format(version, cfg_size) )
+ if template is None:
+ exit(2, "Can't handle Tasmota configuration data for version 0x{:x}".format(version) )
- if GetField(obj, 'cfg_crc', setting['cfg_crc']) != GetSettingsCrc(obj):
+ setting = template[2]
+
+ # check size if exists
+ if 'cfg_size' in setting:
+ cfg_size = GetField(obj, 'cfg_size', setting['cfg_size'], raw=True)
+ # if we did not found a mathching setting
+ if cfg_size != template[1]:
+ exit(2, "Data size does not match. Expected {} bytes, read {} bytes.".format(template[1], cfg_size) )
+
+ # check crc if exists
+ if 'cfg_crc' in setting:
+ cfg_crc = GetField(obj, 'cfg_crc', setting['cfg_crc'], raw=True)
+ else:
+ cfg_crc = GetSettingsCrc(obj)
+ if cfg_crc != GetSettingsCrc(obj):
exit(3, 'Data crc error' )
config = {}
config['version_template'] = '0x{:x}'.format(template[0])
for name in setting:
- config[name] = GetField(obj, name, setting[name])
+ config[name] = GetField(obj, name, setting[name], args.raw)
if args.sort == 'name':
config = collections.OrderedDict(sorted(config.items()))
if args.format == 'json':
- print json.dumps(config, sort_keys=args.sort=='name')
+ print json.dumps(config, sort_keys=args.sort=='name', indent=args.jsonindent, separators=(',', ':') if args.jsoncompact else (', ', ': ') )
else:
for key,value in config.items():
print '{} = {}'.format(key, repr(value))
@@ -1804,7 +1829,7 @@ def Decode(obj):
if __name__ == "__main__":
parser = configargparse.ArgumentParser(description='Decode configuration of Sonoff-Tasmota device.',
- epilog='Note: Either argument -d or -f must be given.')
+ epilog='Either argument -d or -f must be given.')
source = parser.add_argument_group('source')
source.add_argument('-f', '--file',
@@ -1813,20 +1838,20 @@ if __name__ == "__main__":
default=DEFAULTS['source']['tasmotafile'],
help='file to retrieve Tasmota configuration from (default: {})'.format(DEFAULTS['source']['tasmotafile']))
source.add_argument('-d', '--device',
- metavar='',
+ metavar='',
dest='device',
default=DEFAULTS['source']['device'],
- help='device to retrieve configuration from (default: {})'.format(DEFAULTS['source']['device']) )
+ help='hostname or IP address to retrieve Tasmota configuration from (default: {})'.format(DEFAULTS['source']['device']) )
source.add_argument('-u', '--username',
metavar='',
dest='username',
default=DEFAULTS['source']['username'],
- help='for -d usage: http access username (default: {})'.format(DEFAULTS['source']['username']))
+ help='host http access username (default: {})'.format(DEFAULTS['source']['username']))
source.add_argument('-p', '--password',
metavar='',
dest='password',
default=DEFAULTS['source']['password'],
- help='for -d usage: http access password (default: {})'.format(DEFAULTS['source']['password']))
+ help='host http access password (default: {})'.format(DEFAULTS['source']['password']))
output = parser.add_argument_group('output')
output.add_argument('--format',
@@ -1835,6 +1860,17 @@ if __name__ == "__main__":
choices=['json', 'text'],
default=DEFAULTS['output']['format'],
help='output format ("json" or "text", default: "{}")'.format(DEFAULTS['output']['format']) )
+ output.add_argument('--json-indent',
+ metavar='',
+ dest='jsonindent',
+ type=int,
+ default=DEFAULTS['output']['jsonindent'],
+ help='pretty-printed JSON output using indent level (default: "{}")'.format(DEFAULTS['output']['jsonindent']) )
+ output.add_argument('--json-compact',
+ dest='jsoncompact',
+ action='store_true',
+ default=DEFAULTS['output']['jsoncompact'],
+ help='compact JSON output by eliminate whitespace (default: "{}")'.format('compact' if DEFAULTS['output']['jsoncompact'] else 'not compact') )
output.add_argument('--sort',
metavar='',
dest='sort',
@@ -1862,7 +1898,7 @@ if __name__ == "__main__":
dest='configfile',
default=DEFAULTS['DEFAULT']['configfile'],
is_config_file=True,
- help='Config file, can be used instead of command parameter (defaults to {})'.format(DEFAULTS['DEFAULT']['configfile']) )
+ help='Config file, can be used instead of command parameter (default: {})'.format(DEFAULTS['DEFAULT']['configfile']) )
info = parser.add_argument_group('info')
info.add_argument('-V', '--version', action='version', version=PROG)
@@ -1921,4 +1957,7 @@ if __name__ == "__main__":
Decode(cfg)
else:
- exit(4, "Could not read configuration data from {} '{}'".format('device' if args.device is not None else 'file', args.device if args.device is not None else args.tasmotafile) )
\ No newline at end of file
+ exit(4, "Could not read configuration data from {} '{}'".format('device' if args.device is not None else 'file', \
+ args.device if args.device is not None else args.tasmotafile) )
+
+ sys.exit(0)
From 8022bca19cd49f63f8bfc7bf7fcb5b3d4b940090 Mon Sep 17 00:00:00 2001
From: znanev <20048364+znanev@users.noreply.github.com>
Date: Wed, 26 Sep 2018 18:27:23 +0100
Subject: [PATCH 10/18] Update Bulgarian language file
---
sonoff/language/bg-BG.h | 50 ++++++++++++++++++++---------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h
index ff7801984..d79eb5210 100644
--- a/sonoff/language/bg-BG.h
+++ b/sonoff/language/bg-BG.h
@@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele.
*
- * Updated until v6.2.0.1
+ * Updated until v6.2.1.8
\*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@@ -82,7 +82,7 @@
#define D_DNS_SERVER "DNS Сървър"
#define D_DONE "Изпълнено"
#define D_DST_TIME "DST"
-#define D_ECO2 "eCO2"
+#define D_ECO2 "eCO₂"
#define D_EMULATION "Емулация"
#define D_ENABLED "Активиран"
#define D_ERASE "Изтриване"
@@ -163,15 +163,15 @@
#define D_USER "Потребител"
#define D_UTC_TIME "UTC"
#define D_UV_INDEX "UV индекс"
-#define D_UV_INDEX_1 "Low"
-#define D_UV_INDEX_2 "Mid"
-#define D_UV_INDEX_3 "High"
-#define D_UV_INDEX_4 "Danger"
-#define D_UV_INDEX_5 "BurnL1/2"
-#define D_UV_INDEX_6 "BurnL3"
-#define D_UV_INDEX_7 "OoR"
-#define D_UV_LEVEL "Ниво на ултравиолетово излъчване"
-#define D_UV_POWER "UV Power"
+#define D_UV_INDEX_1 "Нисък"
+#define D_UV_INDEX_2 "Среден"
+#define D_UV_INDEX_3 "Висок"
+#define D_UV_INDEX_4 "Много висок"
+#define D_UV_INDEX_5 "Изгаряне 1/2 степен"
+#define D_UV_INDEX_6 "Изгаряне 3-та степен"
+#define D_UV_INDEX_7 "Извън обхват"
+#define D_UV_LEVEL "UV ниво"
+#define D_UV_POWER "UV мощност"
#define D_VERSION "Версия"
#define D_VOLTAGE "Напрежение"
#define D_WARMLIGHT "Топла"
@@ -181,8 +181,8 @@
#define D_WARNING_MINIMAL_VERSION "ПРЕДУПРЕЖДЕНИЕ Тази версия не поддържа постоянни настройки"
#define D_LEVEL_10 "ниво 1-0"
#define D_LEVEL_01 "ниво 0-1"
-#define D_SERIAL_LOGGING_DISABLED "Серийния логинг изключен"
-#define D_SYSLOG_LOGGING_REENABLED "Системния логинг активиран"
+#define D_SERIAL_LOGGING_DISABLED "Серийният лог изключен"
+#define D_SYSLOG_LOGGING_REENABLED "Системният лог активиран"
#define D_SET_BAUDRATE_TO "Задаване скорост на предаване (Baudrate)"
#define D_RECEIVED_TOPIC "Получен топик"
@@ -194,7 +194,7 @@
#define D_BLOCKED_LOOP "Блокиран цикъл"
#define D_WPS_FAILED_WITH_STATUS "WPS конфигурацията е НЕУСПЕШНА със статус"
#define D_ACTIVE_FOR_3_MINUTES "активно в течение на 3 минути"
-#define D_FAILED_TO_START "неуспешно стартиране"
+#define D_FAILED_TO_START "Неуспешно стартиране"
#define D_PATCH_ISSUE_2186 "Проблем с патч 2186"
#define D_CONNECTING_TO_AP "Свързване към точка за достъп"
#define D_IN_MODE "в режим"
@@ -241,7 +241,7 @@
#define D_CONFIGURE_WIFI "Конфигурация на WiFi"
#define D_CONFIGURE_MQTT "Конфигурация на MQTT"
#define D_CONFIGURE_DOMOTICZ "Конфигурация на Domoticz"
-#define D_CONFIGURE_LOGGING "Конфигурация на логинга"
+#define D_CONFIGURE_LOGGING "Конфигурация на лога"
#define D_CONFIGURE_OTHER "Драги конфигурации"
#define D_CONFIRM_RESET_CONFIGURATION "Потвърдете изчистването"
#define D_RESET_CONFIGURATION "Изчистване на конфигурацията"
@@ -275,7 +275,7 @@
#define D_CLIENT "Клиент"
#define D_FULL_TOPIC "Пълен топик"
-#define D_LOGGING_PARAMETERS "Параметри на логинга"
+#define D_LOGGING_PARAMETERS "Параметри на лога"
#define D_SERIAL_LOG_LEVEL "Степен на серийния лог"
#define D_WEB_LOG_LEVEL "Степен на Уеб лога"
#define D_SYS_LOG_LEVEL "Степен на системния лог"
@@ -379,13 +379,13 @@
#define D_DOMOTICZ_TEMP "Temp"
#define D_DOMOTICZ_TEMP_HUM "Temp,Hum"
#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro"
- #define D_DOMOTICZ_POWER_ENERGY "Power,Energy"
- #define D_DOMOTICZ_ILLUMINANCE "Illuminance"
- #define D_DOMOTICZ_COUNT "Count/PM1"
- #define D_DOMOTICZ_VOLTAGE "Voltage/PM2,5"
- #define D_DOMOTICZ_CURRENT "Current/PM10"
- #define D_DOMOTICZ_AIRQUALITY "AirQuality"
-#define D_DOMOTICZ_UPDATE_TIMER "Update timer"
+ #define D_DOMOTICZ_POWER_ENERGY "Мощност,Енергия"
+ #define D_DOMOTICZ_ILLUMINANCE "Осветеност"
+ #define D_DOMOTICZ_COUNT "Брояч/PM1"
+ #define D_DOMOTICZ_VOLTAGE "Напрежение/PM2,5"
+ #define D_DOMOTICZ_CURRENT "Ток/PM10"
+ #define D_DOMOTICZ_AIRQUALITY "Качество на въздуха"
+#define D_DOMOTICZ_UPDATE_TIMER "Период на опресняване"
// xdrv_09_timers.ino
#define D_CONFIGURE_TIMER "Конфигуриране на таймер"
@@ -464,7 +464,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_DFR562 "MP3 плейър"
#define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Ключ" // Suffix "1"
#define D_SENSOR_BUTTON "Бутон" // Suffix "1"
@@ -506,7 +506,7 @@
#define D_UNIT_KILOOHM "kΩ"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"
-#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m3"
+#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³"
#define D_UNIT_MICROMETER "µm"
#define D_UNIT_MICROSECOND "µs"
#define D_UNIT_MILLIAMPERE "mA"
From 9acbcc805f206dbbab0dde03d7666f6505e79e7b Mon Sep 17 00:00:00 2001
From: Erik
Date: Wed, 26 Sep 2018 20:35:39 +0200
Subject: [PATCH 11/18] Fix logic for forced light discovery
---
sonoff/xdrv_12_home_assistant.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino
index b085947ae..c4e5d833b 100644
--- a/sonoff/xdrv_12_home_assistant.ino
+++ b/sonoff/xdrv_12_home_assistant.ino
@@ -76,7 +76,7 @@ void HAssDiscoverRelay()
for (int i = 1; i <= MAX_RELAYS; i++) {
is_light = ((i == devices_present) && (light_type));
- is_topic_light = Settings.flag.hass_light;
+ is_topic_light = Settings.flag.hass_light || is_light;
mqtt_data[0] = '\0'; // Clear retained message
From 3bb8b2fe261d5c22dcce4f75dc017302bc2e0d92 Mon Sep 17 00:00:00 2001
From: Jason2866
Date: Wed, 26 Sep 2018 22:10:32 +0200
Subject: [PATCH 12/18] Update de-DE.h
---
sonoff/language/de-DE.h | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h
index 6e90ae409..07dcc9bfd 100644
--- a/sonoff/language/de-DE.h
+++ b/sonoff/language/de-DE.h
@@ -163,15 +163,15 @@
#define D_USER "Benutzer"
#define D_UTC_TIME "UTC"
#define D_UV_INDEX "UV-Index"
-#define D_UV_INDEX_1 "Low"
-#define D_UV_INDEX_2 "Mid"
-#define D_UV_INDEX_3 "High"
-#define D_UV_INDEX_4 "Danger"
-#define D_UV_INDEX_5 "BurnL1/2"
-#define D_UV_INDEX_6 "BurnL3"
-#define D_UV_INDEX_7 "OoR"
-#define D_UV_LEVEL "UV-Level"
-#define D_UV_POWER "UV Power"
+#define D_UV_INDEX_1 "Niedrig"
+#define D_UV_INDEX_2 "Mittel"
+#define D_UV_INDEX_3 "Hoch"
+#define D_UV_INDEX_4 "Intensiv"
+#define D_UV_INDEX_5 "Gefährlich"
+#define D_UV_INDEX_6 "Schädlich"
+#define D_UV_INDEX_7 "Messwert!"
+#define D_UV_LEVEL "UV-Index"
+#define D_UV_POWER "UV Intensität"
#define D_VERSION "Version"
#define D_VOLTAGE "Spannung"
#define D_WARMLIGHT "warm"
From 86b3ccf6099b85a7bd71961d737e2fd9b82a2210 Mon Sep 17 00:00:00 2001
From: Jason2866
Date: Wed, 26 Sep 2018 22:20:19 +0200
Subject: [PATCH 13/18] Update de-DE.h
---
sonoff/language/de-DE.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h
index 07dcc9bfd..72f63f9c4 100644
--- a/sonoff/language/de-DE.h
+++ b/sonoff/language/de-DE.h
@@ -170,7 +170,7 @@
#define D_UV_INDEX_5 "Gefährlich"
#define D_UV_INDEX_6 "Schädlich"
#define D_UV_INDEX_7 "Messwert!"
-#define D_UV_LEVEL "UV-Index"
+#define D_UV_LEVEL "UV-Level"
#define D_UV_POWER "UV Intensität"
#define D_VERSION "Version"
#define D_VOLTAGE "Spannung"
From a67efa0ab2c36e4c94de31c13e93d6ccbfc382aa Mon Sep 17 00:00:00 2001
From: Adrian Scillato <35405447+ascillato@users.noreply.github.com>
Date: Wed, 26 Sep 2018 23:02:55 -0300
Subject: [PATCH 14/18] Added new triggers for rules on boot time
To make it possible to trigger a rule at boot time with the state of the switches or relays (in order to take decisions), 2 new trigger types has been added:
* SWITCH1#BOOT
to be used like:
ON SWITCH1#BOOT DO ... %value% ENDON
ON SWITCH1#BOOT=0 DO .... ENDON
ON SWITCH1#BOOT=1 DO .... ENDON
and
* POWER1#BOOT
to be used like:
ON POWER1#BOOT DO ... %value% ENDON
ON POWER1#BOOT=0 DO .... ENDON
ON POWER1#BOOT=1 DO .... ENDON
---
sonoff/xdrv_10_rules.ino | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino
index 060bf085f..b13dfc771 100644
--- a/sonoff/xdrv_10_rules.ino
+++ b/sonoff/xdrv_10_rules.ino
@@ -376,6 +376,25 @@ void RulesEvery50ms()
RulesProcessEvent(json_event);
}
}
+ } else {
+ // Boot time POWER OUTPUTS (Relays) Status
+ for (byte i = 0; i < devices_present; i++) {
+ uint8_t new_state = (rules_new_power >> i) &1;
+ snprintf_P(json_event, sizeof(json_event), PSTR("{\"Power%d\":{\"Boot\":%d}}"), i +1, new_state);
+ RulesProcessEvent(json_event);
+ }
+ // Boot time SWITCHES Status
+ for (byte i = 0; i < MAX_SWITCHES; i++) {
+#ifdef USE_TM1638
+ if ((pin[GPIO_SWT1 +i] < 99) || ((pin[GPIO_TM16CLK] < 99) && (pin[GPIO_TM16DIO] < 99) && (pin[GPIO_TM16STB] < 99))) {
+#else
+ if (pin[GPIO_SWT1 +i] < 99) {
+#endif // USE_TM1638
+ boolean swm = ((FOLLOW_INV == Settings.switchmode[i]) || (PUSHBUTTON_INV == Settings.switchmode[i]) || (PUSHBUTTONHOLD_INV == Settings.switchmode[i]));
+ snprintf_P(json_event, sizeof(json_event), PSTR("{\"" D_JSON_SWITCH "%d\":{\"Boot\":%d}}"), i +1, (swm ^ lastwallswitch[i]));
+ RulesProcessEvent(json_event);
+ }
+ }
}
rules_old_power = rules_new_power;
}
From 1a4458528e1f1269062d03ad45055779e8895959 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 27 Sep 2018 18:36:42 +0200
Subject: [PATCH 15/18] Add Neo Coolcam support
Add support for Neo Coolcam Wifi Smart Power Plug
---
sonoff/_changelog.ino | 3 +++
sonoff/sonoff_template.h | 12 ++++++++++++
2 files changed, 15 insertions(+)
diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino
index 06ebd36c1..ebf1b83cb 100644
--- a/sonoff/_changelog.ino
+++ b/sonoff/_changelog.ino
@@ -2,6 +2,9 @@
* Change status JSON message providing more switch and retain information
* Change pinmode for no-pullup defined switches to pullup when configured as switchmode PUSHBUTTON (=3 and up) (#3896)
* Add delay after restart before processing rule sensor data (#3811)
+ * Fix Home Assistant forced light discovery (#3908)
+ * Add rule triggers SWITCH1#BOOT and POWER1#BOOT (#3904, #3910)
+ * Add support for Neo Coolcam Wifi Smart Power Plug
*
* 6.2.1.7 20180925
* Remove restart after ntpserver change and force NTP re-sync (#3890)
diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h
index f5e332531..8374fa09d 100644
--- a/sonoff/sonoff_template.h
+++ b/sonoff/sonoff_template.h
@@ -231,6 +231,7 @@ enum SupportedModules {
SHELLY1,
SHELLY2,
PHILIPS,
+ NEO_COOLCAM,
MAXMODULE };
/********************************************************************************************/
@@ -390,6 +391,7 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
SHELLY1,
SHELLY2,
BLITZWOLF_BWSHP2,
+ NEO_COOLCAM,
H801,
MAGICHOME,
ARILUX_LC01,
@@ -1054,6 +1056,16 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
0, 0,
GPIO_PWM1, // GPIO15 light intensity
0, 0
+ },
+ { "Neo Coolcam", // Neo Coolcam (ESP8266)
+ // https://www.banggood.com/NEO-COOLCAM-WiFi-Mini-Smart-Plug-APP-Remote-Control-Timing-Smart-Socket-EU-Plug-p-1288562.html?cur_warehouse=CN
+ 0, 0, 0, 0,
+ GPIO_LED1_INV, // GPIO13 Red Led (0 = On, 1 = Off)
+ 0,
+ 0, 0, 0, 0, 0, 0, // Flash connection
+ GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
+ GPIO_KEY1, // GPIO13 Button
+ 0, 0, 0, 0
}
};
From 1a0d630da214a180b77096f7f4129dc701562a4d Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 28 Sep 2018 11:48:55 +0200
Subject: [PATCH 16/18] Removed debug code
Removed unavailable debug code (#3917)
---
sonoff/settings.ino | 8 --------
1 file changed, 8 deletions(-)
diff --git a/sonoff/settings.ino b/sonoff/settings.ino
index 0d8fa451a..95e6ce367 100644
--- a/sonoff/settings.ino
+++ b/sonoff/settings.ino
@@ -86,20 +86,12 @@ void RtcSettingsSave()
RtcSettings.valid = RTC_MEM_VALID;
ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
rtc_settings_crc = GetRtcSettingsCrc();
-#ifdef DEBUG_THEO
- AddLog_P(LOG_LEVEL_DEBUG, PSTR("Dump: Save"));
- RtcSettingsDump();
-#endif // DEBUG_THEO
}
}
void RtcSettingsLoad()
{
ESP.rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); // 0x290
-#ifdef DEBUG_THEO
- AddLog_P(LOG_LEVEL_DEBUG, PSTR("Dump: Load"));
- RtcSettingsDump();
-#endif // DEBUG_THEO
if (RtcSettings.valid != RTC_MEM_VALID) {
memset(&RtcSettings, 0, sizeof(RTCMEM));
RtcSettings.valid = RTC_MEM_VALID;
From 4b7c797fb76cf8e6ee1a5680b5af430705fbbf65 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 28 Sep 2018 15:48:42 +0200
Subject: [PATCH 17/18] 6.2.1.9 Apparent/Reactive Power
6.2.1.9 20180928
* Add Apparent Power and Reactive Power to Energy Monitoring devices (#251)
---
sonoff/_changelog.ino | 5 +-
sonoff/sonoff_version.h | 2 +-
sonoff/support.ino | 26 +++++++
sonoff/xdrv_03_energy.ino | 146 +++++++++++++++++++++--------------
sonoff/xnrg_01_hlw8012.ino | 7 +-
sonoff/xnrg_02_cse7766.ino | 15 ++--
sonoff/xnrg_03_pzem004t.ino | 3 +-
sonoff/xnrg_04_mcp39f501.ino | 7 +-
sonoff/xnrg_05_pzem2.ino | 6 +-
9 files changed, 137 insertions(+), 80 deletions(-)
diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino
index ebf1b83cb..abf4572f6 100644
--- a/sonoff/_changelog.ino
+++ b/sonoff/_changelog.ino
@@ -1,4 +1,7 @@
-/* 6.2.1.8 20180926
+/* 6.2.1.9 20180928
+ * Add Apparent Power and Reactive Power to Energy Monitoring devices (#251)
+ *
+ * 6.2.1.8 20180926
* Change status JSON message providing more switch and retain information
* Change pinmode for no-pullup defined switches to pullup when configured as switchmode PUSHBUTTON (=3 and up) (#3896)
* Add delay after restart before processing rule sensor data (#3811)
diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h
index 915ce52d2..4f2b5c0ec 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 0x06020108
+#define VERSION 0x06020109
#define D_PROGRAMNAME "Sonoff-Tasmota"
#define D_AUTHOR "Theo Arends"
diff --git a/sonoff/support.ino b/sonoff/support.ino
index fb2b5eae3..fc73e726e 100644
--- a/sonoff/support.ino
+++ b/sonoff/support.ino
@@ -494,6 +494,32 @@ double FastPrecisePow(double a, double b)
return r * u.d;
}
+uint32_t SqrtInt(uint32_t num)
+{
+ if (num <= 1) {
+ return num;
+ }
+
+ uint32_t x = num / 2;
+ uint32_t y;
+ do {
+ y = (x + num / x) / 2;
+ if (y >= x) {
+ return x;
+ }
+ x = y;
+ } while (true);
+}
+
+uint32_t RoundSqrtInt(uint32_t num)
+{
+ uint32_t s = SqrtInt(4 * num);
+ if (s & 1) {
+ s++;
+ }
+ return s / 2;
+}
+
char* GetTextIndexed(char* destination, size_t destination_size, uint16_t index, const char* haystack)
{
// Returns empty string if not found
diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino
index 3ccad7df4..13ab1cb62 100644
--- a/sonoff/xdrv_03_energy.ino
+++ b/sonoff/xdrv_03_energy.ino
@@ -41,23 +41,25 @@ const char kEnergyCommands[] PROGMEM =
D_CMND_MAXPOWER "|" D_CMND_MAXPOWERHOLD "|" D_CMND_MAXPOWERWINDOW "|"
D_CMND_SAFEPOWER "|" D_CMND_SAFEPOWERHOLD "|" D_CMND_SAFEPOWERWINDOW ;
-float energy_voltage = 0; // 123.1 V
-float energy_current = 0; // 123.123 A
-float energy_power = 0; // 123.1 W
-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_voltage = 0; // 123.1 V
+float energy_current = 0; // 123.123 A
+float energy_active_power = 0; // 123.1 W
+float energy_apparent_power = NAN; // 123.1 VA
+float energy_reactive_power = NAN; // 123.1 VAr
+float energy_power_factor = NAN; // 0.12
+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_daily = 0; // 123.123 kWh
+float energy_total = 0; // 12345.12345 kWh
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
+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
float energy_power_last[3] = { 0 };
uint8_t energy_power_delta = 0;
+bool energy_type_dc = false;
bool energy_power_on = true;
byte energy_min_power_flag = 0;
@@ -124,15 +126,6 @@ void Energy200ms()
}
XnrgCall(FUNC_EVERY_200_MSECOND);
-
- 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;
- }
}
void EnergySaveState()
@@ -178,21 +171,21 @@ void EnergyMarginCheck()
}
if (Settings.energy_power_delta) {
- float delta = abs(energy_power_last[0] - energy_power);
+ float delta = abs(energy_power_last[0] - energy_active_power);
// Any delta compared to minimal delta
- float min_power = (energy_power_last[0] > energy_power) ? energy_power : energy_power_last[0];
+ float min_power = (energy_power_last[0] > energy_active_power) ? energy_active_power : energy_power_last[0];
if (((delta / min_power) * 100) > Settings.energy_power_delta) {
energy_power_delta = 1;
- energy_power_last[1] = energy_power; // We only want one report so reset history
- energy_power_last[2] = energy_power;
+ energy_power_last[1] = energy_active_power; // We only want one report so reset history
+ energy_power_last[2] = energy_active_power;
}
}
energy_power_last[0] = energy_power_last[1]; // Shift in history every second allowing power changes to settle for up to three seconds
energy_power_last[1] = energy_power_last[2];
- energy_power_last[2] = energy_power;
+ energy_power_last[2] = energy_active_power;
if (energy_power_on && (Settings.energy_min_power || Settings.energy_max_power || Settings.energy_min_voltage || Settings.energy_max_voltage || Settings.energy_min_current || Settings.energy_max_current)) {
- energy_power_u = (uint16_t)(energy_power);
+ energy_power_u = (uint16_t)(energy_active_power);
energy_voltage_u = (uint16_t)(energy_voltage);
energy_current_u = (uint16_t)(energy_current * 1000);
@@ -235,7 +228,7 @@ void EnergyMarginCheck()
#if FEATURE_POWER_LIMIT
// Max Power
if (Settings.energy_max_power_limit) {
- if (energy_power > Settings.energy_max_power_limit) {
+ if (energy_active_power > Settings.energy_max_power_limit) {
if (!energy_mplh_counter) {
energy_mplh_counter = Settings.energy_max_power_limit_hold;
} else {
@@ -535,6 +528,8 @@ const char HTTP_ENERGY_SNS1[] PROGMEM = "%s"
"{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}";
const char HTTP_ENERGY_SNS2[] PROGMEM = "%s"
+ "{s}" D_POWERUSAGE_APPARENT "{m}%s " D_UNIT_VA "{e}"
+ "{s}" D_POWERUSAGE_REACTIVE "{m}%s " D_UNIT_VAR "{e}"
"{s}" D_POWER_FACTOR "{m}%s{e}";
const char HTTP_ENERGY_SNS3[] PROGMEM = "%s"
@@ -548,27 +543,64 @@ const char HTTP_ENERGY_SNS4[] PROGMEM = "%s"
void EnergyShow(boolean json)
{
- char energy_total_chr[10];
+ char voltage_chr[10];
+ char current_chr[10];
+ char active_power_chr[10];
+ char apparent_power_chr[10];
+ char reactive_power_chr[10];
+ char power_factor_chr[10];
+ char frequency_chr[10];
char energy_daily_chr[10];
char energy_period_chr[10];
- 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 energy_total_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);
+ if (!energy_type_dc) {
+ float apparent_power = energy_apparent_power;
+ if (isnan(apparent_power)) {
+ apparent_power = energy_voltage * energy_current;
+ }
+ if (apparent_power < energy_active_power) { // Should be impossible
+ energy_active_power = apparent_power;
+ }
+
+ float power_factor = energy_power_factor;
+ if (isnan(power_factor)) {
+ power_factor = (energy_active_power && apparent_power) ? energy_active_power / apparent_power : 0;
+ if (power_factor > 1) power_factor = 1;
+ }
+
+ float reactive_power = energy_reactive_power;
+ if (isnan(reactive_power)) {
+ reactive_power = 0;
+ uint32_t difference = ((uint32_t)(apparent_power * 100) - (uint32_t)(energy_active_power * 100)) / 10;
+ if ((energy_current > 0.005) && ((difference > 15) || (difference > (uint32_t)(apparent_power * 100 / 1000)))) {
+ // calculating reactive power only if current is greater than 0.005A and
+ // difference between active and apparent power is greater than 1.5W or 1%
+ reactive_power = (float)(RoundSqrtInt((uint32_t)(apparent_power * apparent_power * 100) - (uint32_t)(energy_active_power * energy_active_power * 100))) / 10;
+ }
+ }
+
+ dtostrfd(apparent_power, Settings.flag2.wattage_resolution, apparent_power_chr);
+ dtostrfd(reactive_power, Settings.flag2.wattage_resolution, reactive_power_chr);
+ dtostrfd(power_factor, 2, power_factor_chr);
+ if (!isnan(energy_frequency)) {
+ dtostrfd(energy_frequency, Settings.flag2.frequency_resolution, frequency_chr);
+ snprintf_P(sfrequency, sizeof(sfrequency), PSTR(",\"" D_JSON_FREQUENCY "\":%s"), frequency_chr);
+ }
+ }
+
+ dtostrfd(energy_voltage, Settings.flag2.voltage_resolution, voltage_chr);
+ dtostrfd(energy_current, Settings.flag2.current_resolution, current_chr);
+ dtostrfd(energy_active_power, Settings.flag2.wattage_resolution, active_power_chr);
dtostrfd(energy_daily, Settings.flag2.energy_resolution, energy_daily_chr);
dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr);
+ dtostrfd(energy_total, Settings.flag2.energy_resolution, energy_total_chr);
float energy = 0;
if (show_energy_period) {
@@ -577,34 +609,30 @@ void EnergyShow(boolean json)
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);
- }
if (json) {
- 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 : "");
+ 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"),
+ mqtt_data, energy_total_chr, energy_yesterday_chr, energy_daily_chr, (show_energy_period) ? speriod : "", active_power_chr);
+ if (!energy_type_dc) {
+ snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_POWERFACTOR "\":%s%s"),
+ mqtt_data, apparent_power_chr, reactive_power_chr, power_factor_chr, (!isnan(energy_frequency)) ? sfrequency : "");
+ }
+ snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s}"), mqtt_data, voltage_chr, current_chr);
+
#ifdef USE_DOMOTICZ
if (show_energy_period) { // Only send if telemetry
dtostrfd(energy_total * 1000, 1, energy_total_chr);
- DomoticzSensorPowerEnergy((int)energy_power, energy_total_chr); // PowerUsage, EnergyToday
- DomoticzSensor(DZ_VOLTAGE, energy_voltage_chr); // Voltage
- DomoticzSensor(DZ_CURRENT, energy_current_chr); // Current
+ DomoticzSensorPowerEnergy((int)energy_active_power, energy_total_chr); // PowerUsage, EnergyToday
+ DomoticzSensor(DZ_VOLTAGE, voltage_chr); // Voltage
+ DomoticzSensor(DZ_CURRENT, current_chr); // Current
}
#endif // USE_DOMOTICZ
#ifdef USE_KNX
if (show_energy_period) {
KnxSensor(KNX_ENERGY_VOLTAGE, energy_voltage);
KnxSensor(KNX_ENERGY_CURRENT, energy_current);
- KnxSensor(KNX_ENERGY_POWER, energy_power);
- if (!isnan(energy_power_factor)) { KnxSensor(KNX_ENERGY_POWERFACTOR, energy_power_factor); }
+ KnxSensor(KNX_ENERGY_POWER, energy_active_power);
+ if (!energy_type_dc) { KnxSensor(KNX_ENERGY_POWERFACTOR, power_factor); }
KnxSensor(KNX_ENERGY_DAILY, energy_daily);
KnxSensor(KNX_ENERGY_TOTAL, energy_total);
KnxSensor(KNX_ENERGY_START, energy_start);
@@ -612,9 +640,11 @@ void EnergyShow(boolean json)
#endif // USE_KNX
#ifdef USE_WEBSERVER
} else {
- 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_SNS1, mqtt_data, voltage_chr, current_chr, active_power_chr);
+ if (!energy_type_dc) {
+ snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS2, mqtt_data, apparent_power_chr, reactive_power_chr, power_factor_chr);
+ if (!isnan(energy_frequency)) { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS3, mqtt_data, 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 5140d6596..025ccff44 100644
--- a/sonoff/xnrg_01_hlw8012.ino
+++ b/sonoff/xnrg_01_hlw8012.ino
@@ -111,9 +111,9 @@ void HlwEvery200ms()
if (hlw_cf_pulse_length && energy_power_on && !hlw_load_off) {
hlw_w = (hlw_power_ratio * Settings.energy_power_calibration) / hlw_cf_pulse_length;
- energy_power = (float)hlw_w / 10;
+ energy_active_power = (float)hlw_w / 10;
} else {
- energy_power = 0;
+ energy_active_power = 0;
}
hlw_cf1_timer++;
@@ -142,7 +142,7 @@ void HlwEvery200ms()
hlw_cf1_current_pulse_length = hlw_cf1_pulse_length;
hlw_cf1_current_max_pulse_counter = hlw_cf1_pulse_counter;
- if (hlw_cf1_current_pulse_length && energy_power) { // No current if no power being consumed
+ if (hlw_cf1_current_pulse_length && energy_active_power) { // No current if no power being consumed
hlw_i = (hlw_current_ratio * Settings.energy_current_calibration) / hlw_cf1_current_pulse_length;
energy_current = (float)hlw_i / 1000;
} else {
@@ -217,7 +217,6 @@ 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 8ba1b146e..1be231192 100644
--- a/sonoff/xnrg_02_cse7766.ino
+++ b/sonoff/xnrg_02_cse7766.ino
@@ -95,14 +95,14 @@ void CseReceived()
if (adjustement & 0x10) { // Power valid
cse_power_invalid = 0;
if ((header & 0xF2) == 0xF2) { // Power cycle exceeds range
- energy_power = 0;
+ energy_active_power = 0;
} else {
if (0 == power_cycle_first) { power_cycle_first = power_cycle; } // Skip first incomplete power_cycle
if (power_cycle_first != power_cycle) {
power_cycle_first = -1;
- energy_power = (float)(Settings.energy_power_calibration * CSE_PREF) / (float)power_cycle;
+ energy_active_power = (float)(Settings.energy_power_calibration * CSE_PREF) / (float)power_cycle;
} else {
- energy_power = 0;
+ energy_active_power = 0;
}
}
} else {
@@ -110,11 +110,11 @@ void CseReceived()
cse_power_invalid++;
} else {
power_cycle_first = 0;
- energy_power = 0; // Powered on but no load
+ energy_active_power = 0; // Powered on but no load
}
}
if (adjustement & 0x20) { // Current valid
- if (0 == energy_power) {
+ if (0 == energy_active_power) {
energy_current = 0;
} else {
energy_current = (float)Settings.energy_current_calibration / (float)current_cycle;
@@ -123,7 +123,7 @@ void CseReceived()
} else { // Powered off
power_cycle_first = 0;
energy_voltage = 0;
- energy_power = 0;
+ energy_active_power = 0;
energy_current = 0;
}
}
@@ -180,7 +180,7 @@ void CseEverySecond()
} else {
cf_frequency = cf_pulses - cf_pulses_last_time;
}
- if (cf_frequency && energy_power) {
+ if (cf_frequency && energy_active_power) {
cf_pulses_last_time = cf_pulses;
energy_kWhtoday_delta += (cf_frequency * Settings.energy_power_calibration) / 36;
EnergyUpdateToday();
@@ -194,7 +194,6 @@ 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 03581862c..3dfbc3879 100644
--- a/sonoff/xnrg_03_pzem004t.ino
+++ b/sonoff/xnrg_03_pzem004t.ino
@@ -177,7 +177,7 @@ void PzemEvery200ms()
energy_current = value;
break;
case 3: // Power as 20W
- energy_power = value;
+ energy_active_power = value;
break;
case 4: // Total energy as 99999Wh
if (!energy_start || (value < energy_start)) energy_start = value; // Init after restart and hanlde roll-over if any
@@ -215,7 +215,6 @@ 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_04_mcp39f501.ino b/sonoff/xnrg_04_mcp39f501.ino
index f2ce321bc..d962ef204 100644
--- a/sonoff/xnrg_04_mcp39f501.ino
+++ b/sonoff/xnrg_04_mcp39f501.ino
@@ -448,8 +448,8 @@ void McpParseData(void)
if (energy_power_on) { // Powered on
energy_frequency = (float)mcp_line_frequency / 1000;
energy_voltage = (float)mcp_voltage_rms / 10;
- energy_power = (float)mcp_active_power / 100;
- if (0 == energy_power) {
+ energy_active_power = (float)mcp_active_power / 100;
+ if (0 == energy_active_power) {
energy_current = 0;
} else {
energy_current = (float)mcp_current_rms / 10000;
@@ -457,7 +457,7 @@ void McpParseData(void)
} else { // Powered off
energy_frequency = 0;
energy_voltage = 0;
- energy_power = 0;
+ energy_active_power = 0;
energy_current = 0;
}
}
@@ -557,7 +557,6 @@ void McpDrvInit(void)
mcp_calibrate = 0;
mcp_timeout = 2; // Initial wait
mcp_init = 2; // Initial setup steps
- energy_calc_power_factor = 1; // Calculate power factor from data
energy_flg = XNRG_04;
}
}
diff --git a/sonoff/xnrg_05_pzem2.ino b/sonoff/xnrg_05_pzem2.ino
index b7e1eab42..bb0f4864d 100644
--- a/sonoff/xnrg_05_pzem2.ino
+++ b/sonoff/xnrg_05_pzem2.ino
@@ -141,12 +141,13 @@ void Pzem2Every200ms()
float energy = 0;
if (PZEM2_TYPES_003_017 == pzem2_type) {
+ energy_type_dc = true;
// 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_active_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;
@@ -154,12 +155,13 @@ void Pzem2Every200ms()
EnergyUpdateToday();
}
else if (PZEM2_TYPES_014_016 == pzem2_type) { // PZEM-014,016
+ energy_type_dc = false;
// 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_active_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
From f05a471e48bb0ae891df61cdde1679abab0f0f4c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 28 Sep 2018 17:02:55 +0200
Subject: [PATCH 18/18] Fix KNX compile error
---
sonoff/xdrv_03_energy.ino | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino
index 13ab1cb62..341fc71b5 100644
--- a/sonoff/xdrv_03_energy.ino
+++ b/sonoff/xdrv_03_energy.ino
@@ -560,6 +560,8 @@ void EnergyShow(boolean json)
bool show_energy_period = (0 == tele_period);
+ float power_factor = energy_power_factor;
+
if (!energy_type_dc) {
float apparent_power = energy_apparent_power;
if (isnan(apparent_power)) {
@@ -569,7 +571,6 @@ void EnergyShow(boolean json)
energy_active_power = apparent_power;
}
- float power_factor = energy_power_factor;
if (isnan(power_factor)) {
power_factor = (energy_active_power && apparent_power) ? energy_active_power / apparent_power : 0;
if (power_factor > 1) power_factor = 1;