Merge branch 'arendst/development' into development

This commit is contained in:
reloxx13 2018-09-15 14:36:01 +02:00
commit 36ebd4d4ec
51 changed files with 1039 additions and 233 deletions

View File

@ -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) [![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/tasmota)
### Development ### 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/) [![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) [![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota)
@ -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) - [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/) - [Luani HVIO board](https://luani.de/projekte/esp8266-hvio/)
- Xiaomi-Phillips Bulbs
- Wemos D1 mini, NodeMcu and Ledunia - Wemos D1 mini, NodeMcu and Ledunia
### Contribute ### Contribute

View File

@ -104,6 +104,12 @@ See [Tasmota ESP/Arduino library version related issues](https://github.com/aren
| USE_RF_FLASH | - | - | x | x | x | | USE_RF_FLASH | - | - | x | x | x |
## Changelog ## Changelog
Version 6.2.1 20180905
* Fix possible ambiguity on command parameters if StateText contains numbers only (#3656)
* Fix Wemo emulation to select the first relay when more than one relay is present (#3657)
* Fix possible exception due to buffer overflow (#3659)
* Fix lost energy today and total energy value after power cycle (#3689)
Version 6.2.0 20180901 Version 6.2.0 20180901
* Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561) * Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561)
* Disable wifi sleep for both Esp8266/Arduino core 2.4.1 and 2.4.2 to solve device freeze caused by Espressif SDK bug (#3554) * Disable wifi sleep for both Esp8266/Arduino core 2.4.1 and 2.4.2 to solve device freeze caused by Espressif SDK bug (#3554)

View File

@ -61,6 +61,7 @@ build_unflags = -Wall
build_flags = build_flags =
-Wl,-Tesp8266.flash.1m0.ld -Wl,-Tesp8266.flash.1m0.ld
-mtarget-align
; -DUSE_CONFIG_OVERRIDE ; -DUSE_CONFIG_OVERRIDE
; lwIP 1.4 (Default) ; lwIP 1.4 (Default)
; -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH ; -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH

View File

@ -1,13 +1,32 @@
/* 6.2.0.2 20180904 /* 6.2.1.3 20180907
* Rewrite energy monitoring using energy sensor driver modules * Change web Configure Module GPIO drop down list order for better readability
* Fix lost today and total energy value after power cycle (#3689) * 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, #3749)
* Add Analog input AD0 enabled to sonoff-sensors.bin (#3756, #3757)
* Add Support to Xiaomi-Phillips Bulbs
* *
* 6.2.0.1 20180902 * 6.2.1.2 20180906
* Fix possible ambiguity on command parameters if StateText contains numbers only (#3656) * Fix KNX PA exception. Regression from 6.2.1 buffer overflow caused by subStr() (#3700, #3710)
* Fix possible exception due to buffer overflow (#3659) * 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
* Add Wifi channel number to state message (#3664) * 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) * 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)
* 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 * 6.2.0 20180901
* Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561) * Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561)

View File

@ -181,6 +181,7 @@
#define D_CMND_PRESSURE_RESOLUTION "PressRes" #define D_CMND_PRESSURE_RESOLUTION "PressRes"
#define D_CMND_POWER_RESOLUTION "WattRes" #define D_CMND_POWER_RESOLUTION "WattRes"
#define D_CMND_VOLTAGE_RESOLUTION "VoltRes" #define D_CMND_VOLTAGE_RESOLUTION "VoltRes"
#define D_CMND_FREQUENCY_RESOLUTION "FreqRes"
#define D_CMND_CURRENT_RESOLUTION "AmpRes" #define D_CMND_CURRENT_RESOLUTION "AmpRes"
#define D_CMND_ENERGY_RESOLUTION "EnergyRes" #define D_CMND_ENERGY_RESOLUTION "EnergyRes"
#define D_CMND_MODULE "Module" #define D_CMND_MODULE "Module"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Ключ" // Suffix "1" #define D_SENSOR_SWITCH "Ключ" // Suffix "1"
#define D_SENSOR_BUTTON "Бутон" // Suffix "1" #define D_SENSOR_BUTTON "Бутон" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "Подсветка" #define D_SENSOR_BACKLIGHT "Подсветка"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -94,7 +94,7 @@
#define D_FALSE "Nepravda" #define D_FALSE "Nepravda"
#define D_FILE "Soubor" #define D_FILE "Soubor"
#define D_FREE_MEMORY "Volná paměť" #define D_FREE_MEMORY "Volná paměť"
#define D_FREQUENCY "Frequency" #define D_FREQUENCY "Kmitočet"
#define D_GAS "Plyn" #define D_GAS "Plyn"
#define D_GATEWAY "Výchozí brána" #define D_GATEWAY "Výchozí brána"
#define D_GROUP "Skupina" #define D_GROUP "Skupina"
@ -128,7 +128,7 @@
#define D_POWERUSAGE_APPARENT "Apparent Power" #define D_POWERUSAGE_APPARENT "Apparent Power"
#define D_POWERUSAGE_REACTIVE "Reactive Power" #define D_POWERUSAGE_REACTIVE "Reactive Power"
#define D_PRESSURE "Tlak" #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_FLASH_SIZE "Velikost paměti flash"
#define D_PROGRAM_SIZE "Velikost programu" #define D_PROGRAM_SIZE "Velikost programu"
#define D_PROJECT "Projekt" #define D_PROJECT "Projekt"
@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Spínač" // Suffix "1" #define D_SENSOR_SWITCH "Spínač" // Suffix "1"
#define D_SENSOR_BUTTON "Tlačítko" // Suffix "1" #define D_SENSOR_BUTTON "Tlačítko" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRSend" #define D_SENSOR_IRSEND "IRSend"
#define D_SENSOR_SWITCH "Switch " // Suffix "1" #define D_SENSOR_SWITCH "Switch " // Suffix "1"
#define D_SENSOR_BUTTON "Button " // Suffix "1" #define D_SENSOR_BUTTON "Button " // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Διακόπτης" // Suffix "1" #define D_SENSOR_SWITCH "Διακόπτης" // Suffix "1"
#define D_SENSOR_BUTTON "Κουμπί" // Suffix "1" #define D_SENSOR_BUTTON "Κουμπί" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_SWITCH "Switch" // Suffix "1"
#define D_SENSOR_BUTTON "Button" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IR TX" #define D_SENSOR_IRSEND "IR TX"
#define D_SENSOR_SWITCH "Llave" // Suffix "1" #define D_SENSOR_SWITCH "Llave" // Suffix "1"
#define D_SENSOR_BUTTON "Botón" // Suffix "1" #define D_SENSOR_BUTTON "Botón" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "ÉmetIR" #define D_SENSOR_IRSEND "ÉmetIR"
#define D_SENSOR_SWITCH "Inter." // Suffix "1" #define D_SENSOR_SWITCH "Inter." // Suffix "1"
#define D_SENSOR_BUTTON "Bouton" // Suffix "1" #define D_SENSOR_BUTTON "Bouton" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "RétroÉcl" #define D_SENSOR_BACKLIGHT "RétroÉcl"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRadó" #define D_SENSOR_IRSEND "IRadó"
#define D_SENSOR_SWITCH "Kapcsoló" // Suffix "1" #define D_SENSOR_SWITCH "Kapcsoló" // Suffix "1"
#define D_SENSOR_BUTTON "Gomb" // Suffix "1" #define D_SENSOR_BUTTON "Gomb" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "Háttérvil" #define D_SENSOR_BACKLIGHT "Háttérvil"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_SWITCH "Switch" // Suffix "1"
#define D_SENSOR_BUTTON "Button" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Speler"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_SWITCH "Switch" // Suffix "1"
#define D_SENSOR_BUTTON "Button" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Przela" // Suffix "1" #define D_SENSOR_SWITCH "Przela" // Suffix "1"
#define D_SENSOR_BUTTON "Przyci" // Suffix "1" #define D_SENSOR_BUTTON "Przyci" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Interruptor" // Suffix "1" #define D_SENSOR_SWITCH "Interruptor" // Suffix "1"
#define D_SENSOR_BUTTON "Botão" // Suffix "1" #define D_SENSOR_BUTTON "Botão" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "Luz de fundo" #define D_SENSOR_BACKLIGHT "Luz de fundo"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Interruptor" // Suffix "1" #define D_SENSOR_SWITCH "Interruptor" // Suffix "1"
#define D_SENSOR_BUTTON "Botão" // Suffix "1" #define D_SENSOR_BUTTON "Botão" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "Luz negra" #define D_SENSOR_BACKLIGHT "Luz negra"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Свич" // Suffix "1" #define D_SENSOR_SWITCH "Свич" // Suffix "1"
#define D_SENSOR_BUTTON "Кнопка" // Suffix "1" #define D_SENSOR_BUTTON "Кнопка" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_SWITCH "Switch" // Suffix "1"
#define D_SENSOR_BUTTON "Button" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1"
@ -475,6 +476,8 @@
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_SDS0X1 "SDS0X1" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Перемикач" // Suffix "1" #define D_SENSOR_SWITCH "Перемикач" // Suffix "1"
#define D_SENSOR_BUTTON "Кнопка" // Suffix "1" #define D_SENSOR_BUTTON "Кнопка" // Suffix "1"
@ -475,6 +476,8 @@
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_SDS0X1 "SDS0X1" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_SWITCH "Switch" // Suffix "1"
#define D_SENSOR_BUTTON "Button" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -456,6 +456,7 @@
#define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_DFR562 "MP3 Player"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Switch" // Suffix "1" #define D_SENSOR_SWITCH "Switch" // Suffix "1"
#define D_SENSOR_BUTTON "Button" // Suffix "1" #define D_SENSOR_BUTTON "Button" // Suffix "1"
@ -474,7 +475,8 @@
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight" #define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003" #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_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_TRIG "SR04 Tri"

View File

@ -64,8 +64,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t data; // Allow bit manipulation using SetOption uint32_t data; // Allow bit manipulation using SetOption
struct { // SetOption50 .. SetOption81 struct { // SetOption50 .. SetOption81
uint32_t timers_enable : 1; // bit 0 (v6.1.1b) 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 time_append_timezone : 1; // bit 2 (v6.2.1.2)
uint32_t spare03 : 1; uint32_t spare03 : 1;
uint32_t spare04 : 1; uint32_t spare04 : 1;
uint32_t spare05 : 1; uint32_t spare05 : 1;
@ -94,7 +94,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t spare28 : 1; uint32_t spare28 : 1;
uint32_t spare29 : 1; uint32_t spare29 : 1;
uint32_t spare30 : 1; uint32_t spare30 : 1;
uint32_t user_esp8285_enable : 1; // bit 31 (v6.1.1.14) uint32_t spare31 : 1;
}; };
} SysBitfield3; } SysBitfield3;
@ -112,8 +112,7 @@ typedef union {
uint32_t spare08 : 1; uint32_t spare08 : 1;
uint32_t spare09 : 1; uint32_t spare09 : 1;
uint32_t spare10 : 1; uint32_t spare10 : 1;
uint32_t spare11 : 1; uint32_t frequency_resolution : 2;
uint32_t spare12 : 1;
uint32_t axis_resolution : 2; uint32_t axis_resolution : 2;
uint32_t current_resolution : 2; uint32_t current_resolution : 2;
uint32_t voltage_resolution : 2; uint32_t voltage_resolution : 2;

View File

@ -170,7 +170,7 @@ enum WeekInMonthOptions {Last, First, Second, Third, Fourth};
enum DayOfTheWeekOptions {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat}; 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 MonthNamesOptions {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
enum HemisphereOptions {North, South}; 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}; enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};

View File

@ -77,8 +77,8 @@
enum TasmotaCommands { enum TasmotaCommands {
CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_FANSPEED, CMND_STATUS, CMND_STATE, CMND_POWERONSTATE, CMND_PULSETIME, 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_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_PRESSURE_RESOLUTION, CMND_POWER_RESOLUTION, CMND_VOLTAGE_RESOLUTION, CMND_FREQUENCY_RESOLUTION, CMND_CURRENT_RESOLUTION, CMND_ENERGY_RESOLUTION,
CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE, 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_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_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME,
CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE,
@ -87,8 +87,8 @@ enum TasmotaCommands {
const char kTasmotaCommands[] PROGMEM = 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_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_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_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_FREQUENCY_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|"
D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|" 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_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_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 "|" D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|"
@ -134,7 +134,7 @@ int ota_state_flag = 0; // OTA state flag
int ota_result = 0; // OTA result int ota_result = 0; // OTA result
int restart_flag = 0; // Sonoff restart flag int restart_flag = 0; // Sonoff restart flag
int wifi_state_flag = WIFI_RESTART; // Wifi state 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 int blinks = 201; // Number of LED blinks
uint32_t uptime = 0; // Counting every second until 4294967295 = 130 year uint32_t uptime = 0; // Counting every second until 4294967295 = 130 year
uint32_t global_update = 0; // Timestamp of last global temperature and humidity update uint32_t global_update = 0; // Timestamp of last global temperature and humidity update
@ -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); 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) { else if (CMND_CURRENT_RESOLUTION == command_code) {
if ((payload >= 0) && (payload <= 3)) { if ((payload >= 0) && (payload <= 3)) {
Settings.flag2.current_resolution = payload; Settings.flag2.current_resolution = payload;
@ -843,9 +849,9 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
else if ((CMND_GPIO == command_code) && (index < MAX_GPIO_PIN)) { else if ((CMND_GPIO == command_code) && (index < MAX_GPIO_PIN)) {
mytmplt cmodule; mytmplt cmodule;
memcpy_P(&cmodule, &kModules[Settings.module], sizeof(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++) { 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; Settings.my_gp.io[i] = 0;
} }
} }
@ -854,7 +860,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{")); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
for (byte i = 0; i < MAX_GPIO_PIN; i++) { 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); if (jsflg) snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
jsflg = 1; jsflg = 1;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_GPIO "%d\":\"%d (%s)\""), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_GPIO "%d\":\"%d (%s)\""),
@ -998,7 +1004,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
else if (CMND_SYSLOG == command_code) { else if (CMND_SYSLOG == command_code) {
if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) { if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
Settings.syslog_level = payload; Settings.syslog_level = payload;
syslog_level = (Settings.flag2.emulation) ? 0 : payload; syslog_level = payload;
syslog_timer = 0; syslog_timer = 0;
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, command, Settings.syslog_level, syslog_level); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, command, Settings.syslog_level, syslog_level);
@ -1418,7 +1424,7 @@ void PublishStatus(uint8_t payload)
if ((0 == payload) || (1 == 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\"}}"), 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")); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
} }
@ -1509,7 +1515,7 @@ void MqttShowState()
{ {
char stemp1[33]; 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 #ifdef USE_ADC_VCC
dtostrfd((double)ESP.getVcc()/1000, 3, stemp1); dtostrfd((double)ESP.getVcc()/1000, 3, stemp1);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1);
@ -1590,7 +1596,7 @@ void PerformEverySecond()
if (syslog_timer) { // Restore syslog level if (syslog_timer) { // Restore syslog level
syslog_timer--; syslog_timer--;
if (!syslog_timer) { if (!syslog_timer) {
syslog_level = (Settings.flag2.emulation) ? 0 : Settings.syslog_level; syslog_level = Settings.syslog_level;
if (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) AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SYSLOG_LOGGING_REENABLED)); // Might trigger disable again (on purpose)
} }
@ -1626,7 +1632,7 @@ void PerformEverySecond()
if ((2 == RtcTime.minute) && latest_uptime_flag) { if ((2 == RtcTime.minute) && latest_uptime_flag) {
latest_uptime_flag = false; 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)); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_UPTIME));
} }
if ((3 == RtcTime.minute) && !latest_uptime_flag) latest_uptime_flag = true; if ((3 == RtcTime.minute) && !latest_uptime_flag) latest_uptime_flag = true;
@ -2347,7 +2353,7 @@ void GpioInit()
if (mpin) pin[mpin] = i; if (mpin) pin[mpin] = i;
} }
if (2 == pin[GPIO_TXD]) 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) analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h)
analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c) analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
@ -2507,7 +2513,7 @@ void setup()
#ifndef USE_EMULATION #ifndef USE_EMULATION
Settings.flag2.emulation = 0; Settings.flag2.emulation = 0;
#endif // USE_EMULATION #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; stop_flash_rotate = Settings.flag.stop_flash_rotate;
save_data_counter = Settings.save_data; save_data_counter = Settings.save_data;
sleep = Settings.sleep; sleep = Settings.sleep;
@ -2540,19 +2546,19 @@ void setup()
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BOOT_COUNT " %d"), Settings.bootcount); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BOOT_COUNT " %d"), Settings.bootcount);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
GpioInit();
SetSerialBaudrate(baudrate);
Format(mqtt_client, Settings.mqtt_client, sizeof(mqtt_client)); Format(mqtt_client, Settings.mqtt_client, sizeof(mqtt_client));
Format(mqtt_topic, Settings.mqtt_topic, sizeof(mqtt_topic)); Format(mqtt_topic, Settings.mqtt_topic, sizeof(mqtt_topic));
if (strstr(Settings.hostname, "%")) { if (strstr(Settings.hostname, "%")) {
strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(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); snprintf_P(my_hostname, sizeof(my_hostname)-1, Settings.hostname, mqtt_topic, ESP.getChipId() & 0x1FFF);
} else { } else {
snprintf_P(my_hostname, sizeof(my_hostname)-1, Settings.hostname); snprintf_P(my_hostname, sizeof(my_hostname)-1, Settings.hostname);
} }
GpioInit();
SetSerialBaudrate(baudrate);
WifiConnect(); WifiConnect();
if (MOTOR == Settings.module) Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo! if (MOTOR == Settings.module) Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo!

View File

@ -62,7 +62,10 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#ifdef USE_SENSORS #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 // 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_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) #define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)
@ -137,6 +140,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_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_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
#undef USE_PZEM004T // Disable PZEM004T energy 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_SERIAL_BRIDGE // Disable support for software Serial Bridge
#undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter #undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter
#undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy meter #undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy meter

View File

@ -21,6 +21,8 @@
#define _SONOFF_TEMPLATE_H_ #define _SONOFF_TEMPLATE_H_
// User selectable GPIO functionality // 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 { enum UserSelectablePins {
GPIO_NONE, // Not used GPIO_NONE, // Not used
GPIO_DHT11, // DHT11 GPIO_DHT11, // DHT11
@ -92,7 +94,7 @@ enum UserSelectablePins {
GPIO_SPI_DC, // SPI Data Direction GPIO_SPI_DC, // SPI Data Direction
GPIO_BACKLIGHT, // Display backlight control GPIO_BACKLIGHT, // Display backlight control
GPIO_PMS5003, // Plantower PMS5003 Serial interface GPIO_PMS5003, // Plantower PMS5003 Serial interface
GPIO_SDS0X1, // Nova Fitness SDS011 Serial interface GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface
GPIO_SBR_TX, // Serial Bridge Serial interface GPIO_SBR_TX, // Serial Bridge Serial interface
GPIO_SBR_RX, // Serial Bridge Serial interface GPIO_SBR_RX, // Serial Bridge Serial interface
GPIO_SR04_TRIG, // SR04 Trigger pin GPIO_SR04_TRIG, // SR04 Trigger pin
@ -120,6 +122,10 @@ enum UserSelectablePins {
GPIO_CNTR2_NP, GPIO_CNTR2_NP,
GPIO_CNTR3_NP, GPIO_CNTR3_NP,
GPIO_CNTR4_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_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player
GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface
GPIO_SENSOR_END }; GPIO_SENSOR_END };
// Programmer selectable GPIO functionality offset by user selectable GPIOs // Programmer selectable GPIO functionality offset by user selectable GPIOs
@ -136,9 +142,6 @@ enum ProgramSelectablePins {
GPIO_DI, // my92x1 PWM input GPIO_DI, // my92x1 PWM input
GPIO_DCKI, // my92x1 CLK input GPIO_DCKI, // my92x1 CLK input
GPIO_ARIRFRCV, // AliLux RF Receive 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_USER, // User configurable
GPIO_MAX }; GPIO_MAX };
@ -164,7 +167,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|" D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|"
D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|" D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|"
D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|"
D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1 "|" D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1_RX "|"
D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|" D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|"
D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|" D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|"
D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|" D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|"
@ -172,7 +175,9 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_TM1638_CLK "|" D_SENSOR_TM1638_DIO "|" D_SENSOR_TM1638_STB "|" 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_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_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 "|"
D_SENSOR_DFR562 "|" D_SENSOR_SDS0X1_TX;
/********************************************************************************************/ /********************************************************************************************/
@ -225,6 +230,7 @@ enum SupportedModules {
BLITZWOLF_BWSHP2, BLITZWOLF_BWSHP2,
SHELLY1, SHELLY1,
SHELLY2, SHELLY2,
PHILIPS,
MAXMODULE }; MAXMODULE };
/********************************************************************************************/ /********************************************************************************************/
@ -242,7 +248,112 @@ typedef struct MYTMPLT {
myio gp; myio gp;
} mytmplt; } 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_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
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_BASIC,
SONOFF_RF, SONOFF_RF,
SONOFF_TH, SONOFF_TH,
@ -289,7 +400,8 @@ const uint8_t kNiceList[MAXMODULE] PROGMEM = {
KMC_70011, KMC_70011,
AILIGHT, AILIGHT,
WEMOS, WEMOS,
WITTY WITTY,
PHILIPS
}; };
// Default module settings // Default module settings
@ -550,8 +662,8 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
{ "H801", // Lixada H801 Wifi (ESP8266) { "H801", // Lixada H801 Wifi (ESP8266)
GPIO_USER, // GPIO00 E-FW Button GPIO_USER, // GPIO00 E-FW Button
GPIO_LED1, // GPIO01 Green LED GPIO_LED1, // GPIO01 Green LED
GPIO_TXD, // GPIO02 RX - Pin next to TX on the PCB GPIO_USER, // GPIO02 TX and Optional sensor - Pin next to TX on the PCB
GPIO_RXD, // GPIO03 TX - Pin next to GND on the PCB GPIO_USER, // GPIO03 RX and Optional sensor - Pin next to GND on the PCB
GPIO_PWM5, // GPIO04 W2 - PWM5 GPIO_PWM5, // GPIO04 W2 - PWM5
GPIO_LED2_INV, // GPIO05 Red LED GPIO_LED2_INV, // GPIO05 Red LED
0, 0, 0, 0, 0, 0, // Flash connection 0, 0, 0, 0, 0, 0, // Flash connection
@ -923,16 +1035,24 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
}, },
{ "Shelly 2", // Shelly2 (ESP8266 - 2MB) - https://shelly.cloud/shelly2/ { "Shelly 2", // Shelly2 (ESP8266 - 2MB) - https://shelly.cloud/shelly2/
0, 0,
GPIO_MCP39_RX, // GPIO01 MCP39F501 Serial input GPIO_TXD, // GPIO01 MCP39F501 Serial input
0, 0,
GPIO_MCP39_TX, // GPIO03 MCP39F501 Serial output GPIO_RXD, // GPIO03 MCP39F501 Serial output
GPIO_REL1, // GPIO04 GPIO_REL1, // GPIO04
GPIO_REL2, // GPIO05 GPIO_REL2, // GPIO05
0, 0, 0, 0, 0, 0, // Flash connection 0, 0, 0, 0, 0, 0, // Flash connection
GPIO_SWT1_NP, // GPIO12 GPIO_SWT1_NP, // GPIO12
0, 0,
GPIO_SWT2_NP, // GPIO14 GPIO_SWT2_NP, // GPIO14
GPIO_MCP39_RST, // GPIO15 MCP39F501 Reset 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 0, 0
} }
}; };
@ -1002,7 +1122,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
0, 0 0, 0
} }
{ "Ledunia", // Ledunia (ESP8266) - http://ledunia.de/ { "Ledunia", // Ledunia (ESP8266 - 32MB) - http://ledunia.de/
GPIO_USER, // GPIO00 (D0) GPIO_USER, // GPIO00 (D0)
GPIO_USER, // GPIO01 (D7) Serial RXD GPIO_USER, // GPIO01 (D7) Serial RXD
GPIO_USER, // GPIO02 (D2) GPIO_USER, // GPIO02 (D2)
@ -1019,4 +1139,4 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
} }
*/ */
#endif // _SONOFF_TEMPLATE_H_ #endif // _SONOFF_TEMPLATE_H_

View File

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

View File

@ -143,7 +143,7 @@ char* subStr(char* dest, char* str, const char *delim, int index)
int i; int i;
// Since strtok consumes the first arg, make a copy // Since strtok consumes the first arg, make a copy
strlcpy(dest, str, strlen(str)); strncpy(dest, str, strlen(str)+1);
for (i = 1, act = dest; i <= index; i++, act = NULL) { for (i = 1, act = dest; i <= index; i++, act = NULL) {
sub = strtok_r(act, delim, &ptr); sub = strtok_r(act, delim, &ptr);
if (sub == NULL) break; if (sub == NULL) break;
@ -609,6 +609,10 @@ boolean GetUsedInModule(byte val, uint8_t *arr)
if (GPIO_PZEM_TX == val) { return true; } if (GPIO_PZEM_TX == val) { return true; }
if (GPIO_PZEM_RX == val) { return true; } if (GPIO_PZEM_RX == val) { return true; }
#endif #endif
#ifndef USE_PZEM2
if (GPIO_PZEM2_TX == val) { return true; }
if (GPIO_PZEM2_RX == val) { return true; }
#endif
#ifndef USE_SENSEAIR #ifndef USE_SENSEAIR
if (GPIO_SAIR_TX == val) { return true; } if (GPIO_SAIR_TX == val) { return true; }
if (GPIO_SAIR_RX == val) { return true; } if (GPIO_SAIR_RX == val) { return true; }
@ -624,7 +628,8 @@ boolean GetUsedInModule(byte val, uint8_t *arr)
if (GPIO_PMS5003 == val) { return true; } if (GPIO_PMS5003 == val) { return true; }
#endif #endif
#ifndef USE_NOVA_SDS #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 #endif
#ifndef USE_SERIAL_BRIDGE #ifndef USE_SERIAL_BRIDGE
if (GPIO_SBR_TX == val) { return true; } if (GPIO_SBR_TX == val) { return true; }
@ -931,8 +936,20 @@ void GetFeatures()
#ifdef USE_DISPLAY_SH1106 #ifdef USE_DISPLAY_SH1106
feature_drv2 |= 0x00001000; // xdsp_06_sh1106.ino feature_drv2 |= 0x00001000; // xdsp_06_sh1106.ino
#endif #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 #ifdef VTABLES_IN_FLASH
feature_drv2 |= 0x04000000; // platformio.ini feature_drv2 |= 0x04000000; // platformio.ini
#endif #endif
@ -965,7 +982,7 @@ void GetFeatures()
feature_sns1 |= 0x00000004; // xdrv_03_energy.ino feature_sns1 |= 0x00000004; // xdrv_03_energy.ino
#endif #endif
#ifdef USE_PZEM004T #ifdef USE_PZEM004T
feature_sns1 |= 0x00000008; // xdrv_03_energy.ino feature_sns1 |= 0x00000008; // xnrg_03_pzem004t.ino
#endif #endif
#ifdef USE_DS18B20 #ifdef USE_DS18B20
feature_sns1 |= 0x00000010; // xsns_05_ds18b20.ino feature_sns1 |= 0x00000010; // xsns_05_ds18b20.ino
@ -1074,6 +1091,19 @@ void GetFeatures()
#ifdef USE_MCP230xx_DISPLAYOUTPUT #ifdef USE_MCP230xx_DISPLAYOUTPUT
feature_sns2 |= 0x00000020; // xsns_29_mcp230xx.ino feature_sns2 |= 0x00000020; // xsns_29_mcp230xx.ino
#endif #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
} }
/*********************************************************************************************\ /*********************************************************************************************\
@ -1802,44 +1832,46 @@ String GetBuildDateAndTime()
return String(bdt); 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 SetOption52 = 1
* "2017-03-07T11:08:02" - otherwise
*/
String GetDateAndTime(byte time_type) String GetDateAndTime(byte time_type)
{ {
// enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART, DT_UPTIME }; // "2017-03-07T11:08:02-07:00" - ISO8601:2004
// "2017-03-07T11:08:02" - ISO8601:2004 char dt[27];
char dt[21];
TIME_T tmpTime; TIME_T tmpTime;
if (DT_UPTIME == time_type) { switch (time_type) {
if (restart_time) { case DT_UTC:
BreakTime(utc_time - restart_time, tmpTime); BreakTime(utc_time, tmpTime);
} else { tmpTime.year += 1970;
BreakTime(uptime, tmpTime); break;
} case DT_RESTART:
// "P128DT14H35M44S" - ISO8601:2004 - https://en.wikipedia.org/wiki/ISO_8601 Durations if (restart_time == 0) {
// snprintf_P(dt, sizeof(dt), PSTR("P%dDT%02dH%02dM%02dS"), ut.days, ut.hour, ut.minute, ut.second); return "";
// "128 14:35:44" - OpenVMS }
// "128T14:35:44" - Tasmota BreakTime(restart_time, tmpTime);
snprintf_P(dt, sizeof(dt), PSTR("%dT%02d:%02d:%02d"), tmpTime.year += 1970;
tmpTime.days, tmpTime.hour, tmpTime.minute, tmpTime.second); break;
} else { default:
switch (time_type) { tmpTime = RtcTime;
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);
} }
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 (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); return String(dt);
} }

View File

@ -137,20 +137,20 @@
#define NTP_SERVER3 "0.nl.pool.ntp.org" // [NtpServer3] Select third NTP server by name or IP address (93.94.224.67) #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 // -- 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_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_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_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_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_HOUR 2 // Hour (0 to 23)
#define TIME_DST_OFFSET +120 // Offset from UTC in minutes (-780 to +780) #define TIME_DST_OFFSET +120 // Offset from UTC in minutes (-780 to +780)
// -- Time - Start Standard Time and timezone offset from UTC in minutes // -- 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_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_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_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_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_HOUR 3 // Hour (0 to 23)
#define TIME_STD_OFFSET +60 // Offset from UTC in minutes (-780 to +780) #define TIME_STD_OFFSET +60 // Offset from UTC in minutes (-780 to +780)
// -- Location ------------------------------------ // -- Location ------------------------------------
#define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset #define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset
@ -335,12 +335,18 @@
#define CO2_HIGH 1200 // Above this CO2 value show red light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1) #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_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_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 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_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 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 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 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 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)
#define USE_PZEM2 // Add support for PZEM003,014,016,017 Energy monitor (+1k1 code)
// -- Low level interface devices ----------------- // -- 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_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)

View File

@ -380,9 +380,7 @@ void MqttConnected()
MqttPublishPowerState(i); MqttPublishPowerState(i);
if (SONOFF_IFAN02 == Settings.module) { break; } // Only report status of light relay if (SONOFF_IFAN02 == Settings.module) { break; } // Only report status of light relay
} }
if (Settings.tele_period) { if (Settings.tele_period) { tele_period = Settings.tele_period -9; } // Enable TelePeriod in 9 seconds
tele_period = Settings.tele_period -9;
}
rules_flag.system_boot = 1; rules_flag.system_boot = 1;
XdrvCall(FUNC_MQTT_INIT); XdrvCall(FUNC_MQTT_INIT);
} }
@ -718,7 +716,6 @@ bool MqttCommand()
} }
else if (CMND_BUTTONRETAIN == command_code) { else if (CMND_BUTTONRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) { if ((payload >= 0) && (payload <= 1)) {
strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic));
if (!payload) { if (!payload) {
for(i = 1; i <= MAX_KEYS; i++) { for(i = 1; i <= MAX_KEYS; i++) {
SendKey(0, i, 9); // Clear MQTT retain in broker SendKey(0, i, 9); // Clear MQTT retain in broker
@ -730,7 +727,6 @@ bool MqttCommand()
} }
else if (CMND_SWITCHRETAIN == command_code) { else if (CMND_SWITCHRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) { if ((payload >= 0) && (payload <= 1)) {
strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic));
if (!payload) { if (!payload) {
for(i = 1; i <= MAX_SWITCHES; i++) { for(i = 1; i <= MAX_SWITCHES; i++) {
SendKey(1, i, 9); // Clear MQTT retain in broker SendKey(1, i, 9); // Clear MQTT retain in broker

View File

@ -768,7 +768,7 @@ void HandleModuleConfiguration()
page.replace(F("{v}"), FPSTR(S_CONFIGURE_MODULE)); page.replace(F("{v}"), FPSTR(S_CONFIGURE_MODULE));
page += FPSTR(HTTP_SCRIPT_MODULE1); page += FPSTR(HTTP_SCRIPT_MODULE1);
for (byte i = 0; i < MAXMODULE; i++) { 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(stemp, sizeof(stemp), kModules[midx].name);
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, midx, midx +1, stemp); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, midx, midx +1, stemp);
page += mqtt_data; page += mqtt_data;
@ -779,10 +779,10 @@ void HandleModuleConfiguration()
mytmplt cmodule; mytmplt cmodule;
memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule)); memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule));
for (byte j = 0; j < GPIO_SENSOR_END; j++) { for (byte j = 0; j < GPIO_SENSOR_END; j++) {
if (!GetUsedInModule(j, cmodule.gp.io)) { midx = pgm_read_byte(kGpioNiceList + j);
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, j, j, GetTextIndexed(stemp, sizeof(stemp), j, kSensorNames)); 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; page += mqtt_data;
} }
} }
@ -805,7 +805,7 @@ void HandleModuleConfiguration()
for (byte i = 0; i < MAX_GPIO_PIN; i++) { for (byte i = 0; i < MAX_GPIO_PIN; i++) {
if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) { if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) {
snprintf_P(stemp, 3, PINS_WEMOS +i*2); snprintf_P(stemp, 3, PINS_WEMOS +i*2);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:146px'><select id='g%d' name='g%d'></select></td></tr>"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:160px'><select id='g%d' name='g%d'></select></td></tr>"),
(WEMOS==Settings.module)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(9==i)? "<font color='red'>ESP8285</font>" :(10==i)? "<font color='red'>ESP8285</font>" :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i); (WEMOS==Settings.module)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(9==i)? "<font color='red'>ESP8285</font>" :(10==i)? "<font color='red'>ESP8285</font>" :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
page += mqtt_data; page += mqtt_data;
} }
@ -1193,7 +1193,7 @@ void HandleSaveSettings()
if (Settings.last_module != new_module) { if (Settings.last_module != new_module) {
Settings.my_gp.io[i] = 0; Settings.my_gp.io[i] = 0;
} else { } 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); snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), i);
WebGetArg(stemp, tmp, sizeof(tmp)); WebGetArg(stemp, tmp, sizeof(tmp));
Settings.my_gp.io[i] = (!strlen(tmp)) ? 0 : atoi(tmp); Settings.my_gp.io[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
@ -1292,7 +1292,7 @@ void HandleInformation()
func += F(D_PROGRAM_VERSION "}2"); func += my_version; func += F(D_PROGRAM_VERSION "}2"); func += my_version;
func += F("}1" D_BUILD_DATE_AND_TIME "}2"); func += GetBuildDateAndTime(); 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_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()); 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_FLASH_WRITE_COUNT "}2"); func += String(Settings.save_flag); func += stopic;
func += F("}1" D_BOOT_COUNT "}2"); func += String(Settings.bootcount); func += F("}1" D_BOOT_COUNT "}2"); func += String(Settings.bootcount);

View File

@ -44,10 +44,13 @@ const char kEnergyCommands[] PROGMEM =
float energy_voltage = 0; // 123.1 V float energy_voltage = 0; // 123.1 V
float energy_current = 0; // 123.123 A float energy_current = 0; // 123.123 A
float energy_power = 0; // 123.1 W float energy_power = 0; // 123.1 W
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_daily = 0; // 123.123 kWh
float energy_total = 0; // 12345.12345 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_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_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_period = 0; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = energy_daily
@ -122,12 +125,14 @@ void Energy200ms()
XnrgCall(FUNC_EVERY_200_MSECOND); XnrgCall(FUNC_EVERY_200_MSECOND);
float power_factor = 0; if (energy_calc_power_factor) {
if (energy_voltage && energy_current && energy_power) { float power_factor = 0;
power_factor = energy_power / (energy_voltage * energy_current); if (energy_voltage && energy_current && energy_power) {
if (power_factor > 1) power_factor = 1; 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() void EnergySaveState()
@ -299,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}} // {"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()); 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); EnergyShow(1);
tele_period = tele_period_save;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
energy_power_delta = 0; energy_power_delta = 0;
@ -536,11 +544,18 @@ void EnergySnsInit()
} }
#ifdef USE_WEBSERVER #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_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
"{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}" "{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
"{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}" "{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}";
"{s}" D_POWER_FACTOR "{m}%s{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_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
"{s}" D_ENERGY_YESTERDAY "{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} = <tr><th>, {m} = </th><td>, {e} = </td></tr> "{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
@ -554,31 +569,43 @@ void EnergyShow(boolean json)
char energy_power_chr[10]; char energy_power_chr[10];
char energy_voltage_chr[10]; char energy_voltage_chr[10];
char energy_current_chr[10]; char energy_current_chr[10];
char energy_frequency_chr[10];
char energy_power_factor_chr[10]; char energy_power_factor_chr[10];
char energy_yesterday_chr[10]; char energy_yesterday_chr[10];
char speriod[20]; char speriod[20];
char spfactor[20];
char sfrequency[20];
bool show_energy_period = (0 == tele_period); 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; float energy = 0;
if (show_energy_period) { if (show_energy_period) {
if (energy_period) energy = (float)(energy_kWhtoday - energy_period) / 100; if (energy_period) energy = (float)(energy_kWhtoday - energy_period) / 100;
energy_period = energy_kWhtoday; 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) { 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,\""
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}"), 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, energy_power_factor_chr, energy_voltage_chr, energy_current_chr); 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 #ifdef USE_DOMOTICZ
if (show_energy_period) { // Only send if telemetry if (show_energy_period) { // Only send if telemetry
dtostrfd(energy_total * 1000, 1, energy_total_chr); dtostrfd(energy_total * 1000, 1, energy_total_chr);
@ -592,7 +619,7 @@ void EnergyShow(boolean json)
KnxSensor(KNX_ENERGY_VOLTAGE, energy_voltage); KnxSensor(KNX_ENERGY_VOLTAGE, energy_voltage);
KnxSensor(KNX_ENERGY_CURRENT, energy_current); KnxSensor(KNX_ENERGY_CURRENT, energy_current);
KnxSensor(KNX_ENERGY_POWER, energy_power); 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_DAILY, energy_daily);
KnxSensor(KNX_ENERGY_TOTAL, energy_total); KnxSensor(KNX_ENERGY_TOTAL, energy_total);
KnxSensor(KNX_ENERGY_START, energy_start); KnxSensor(KNX_ENERGY_START, energy_start);
@ -600,7 +627,10 @@ void EnergyShow(boolean json)
#endif // USE_KNX #endif // USE_KNX
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} else { } 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 #endif // USE_WEBSERVER
} }
} }

View File

@ -69,6 +69,12 @@ struct LRgbColor {
const LRgbColor kFixedColor[MAX_FIXED_COLOR] PROGMEM = 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 }; { 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 4
const LWColor kFixedWhite[MAX_FIXED_WHITE] PROGMEM = { 0, 255, 128, 32 };
struct LCwColor { struct LCwColor {
uint8_t C, W; uint8_t C, W;
}; };
@ -421,6 +427,11 @@ void LightSetColorTemp(uint16_t ct)
} }
uint16_t icold = (100 * (347 - my_ct)) / 136; uint16_t icold = (100 * (347 - my_ct)) / 136;
uint16_t iwarm = (100 * 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) { if (LST_RGBWC == light_subtype) {
Settings.light_color[0] = 0; Settings.light_color[0] = 0;
Settings.light_color[1] = 0; Settings.light_color[1] = 0;
@ -452,6 +463,15 @@ void LightSetDimmer(uint8_t myDimmer)
{ {
float temp; 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) { if (LT_PWM1 == light_type) {
Settings.light_color[0] = 255; // One PWM channel only supports Dimmer but needs max color Settings.light_color[0] = 255; // One PWM channel only supports Dimmer but needs max color
} }
@ -551,8 +571,8 @@ void LightState(uint8_t append)
if (light_subtype > LST_SINGLE) { if (light_subtype > LST_SINGLE) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor));
// Add status for HSB // Add status for HSB
LightGetHsb(&hsb[0],&hsb[1],&hsb[2]); LightGetHsb(&hsb[0],&hsb[1],&hsb[2], false);
// Scale these percentages up to the numbers expected byt he client // Scale these percentages up to the numbers expected by the client
h = round(hsb[0] * 360); h = round(hsb[0] * 360);
s = round(hsb[1] * 100); s = round(hsb[1] * 100);
b = round(hsb[2] * 100); b = round(hsb[2] * 100);
@ -905,13 +925,15 @@ void LightHsbToRgb()
light_current_color[0] = (uint8_t)(r * 255.0f); light_current_color[0] = (uint8_t)(r * 255.0f);
light_current_color[1] = (uint8_t)(g * 255.0f); light_current_color[1] = (uint8_t)(g * 255.0f);
light_current_color[2] = (uint8_t)(b * 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(); LightRgbToHsb();
*hue = light_hue; *hue = light_hue;
*sat = light_saturation; *sat = light_saturation;
@ -919,16 +941,19 @@ void LightGetHsb(float *hue, float *sat, float *bri)
} else { } else {
*hue = 0; *hue = 0;
*sat = 0; *sat = 0;
// *bri = (2.54f * (float)Settings.light_dimmer);
*bri = (0.01f * (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 (light_subtype > LST_COLDWARM) {
if ((LST_RGBWC == light_subtype) && (ct > 0)) { if ((LST_RGBWC == light_subtype) && (gotct)) {
LightSetColorTemp(ct); uint8_t tmp = (uint8_t)(bri * 100);
Settings.light_dimmer = tmp;
if (ct > 0) {
LightSetColorTemp(ct);
}
} else { } else {
light_hue = hue; light_hue = hue;
light_saturation = sat; light_saturation = sat;
@ -1006,7 +1031,11 @@ boolean LightColorEntry(char *buffer, uint8_t buffer_length)
entry_type = 1; // Hexadecimal entry_type = 1; // Hexadecimal
} }
else if ((value > 199) && (value <= 199 + MAX_FIXED_COLD_WARM)) { 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); memcpy_P(&light_entry_color, &kFixedColdWarm[value -200], 2);
entry_type = 1; // Hexadecimal entry_type = 1; // Hexadecimal
} }
@ -1104,7 +1133,7 @@ boolean LightCommand()
} else { // Command with only 1 parameter, Hue (0<H<360), Saturation (0<S<100) OR Brightness (0<B<100) } else { // Command with only 1 parameter, Hue (0<H<360), Saturation (0<S<100) OR Brightness (0<B<100)
float hsb[3]; float hsb[3];
LightGetHsb(&hsb[0],&hsb[1],&hsb[2]); LightGetHsb(&hsb[0],&hsb[1],&hsb[2], false);
HSB[0] = round(hsb[0] * 360); HSB[0] = round(hsb[0] * 360);
HSB[1] = round(hsb[1] * 100); HSB[1] = round(hsb[1] * 100);
HSB[2] = round(hsb[2] * 100); HSB[2] = round(hsb[2] * 100);
@ -1120,7 +1149,8 @@ boolean LightCommand()
LightSetHsb(( (HSB[0]>360) ? (HSB[0] % 360) : HSB[0] ) /360.0, LightSetHsb(( (HSB[0]>360) ? (HSB[0] % 360) : HSB[0] ) /360.0,
( (HSB[1]>100) ? (HSB[1] % 100) : HSB[1] ) /100.0, ( (HSB[1]>100) ? (HSB[1] % 100) : HSB[1] ) /100.0,
( (HSB[2]>100) ? (HSB[2] % 100) : HSB[2] ) /100.0, ( (HSB[2]>100) ? (HSB[2] % 100) : HSB[2] ) /100.0,
0); 0,
false);
} }
} else { } else {
LightState(0); LightState(0);

View File

@ -426,7 +426,7 @@ void RulesEvery100ms()
{ {
if (Settings.rule_enabled) { // Any rule enabled if (Settings.rule_enabled) { // Any rule enabled
mqtt_data[0] = '\0'; 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 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} XsnsNextCall(FUNC_JSON_APPEND); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
tele_period = tele_period_save; tele_period = tele_period_save;

View File

@ -1156,7 +1156,7 @@ boolean KnxCommand()
else if (CMND_KNX_PA == command_code) { else if (CMND_KNX_PA == command_code) {
if (XdrvMailbox.data_len) { if (XdrvMailbox.data_len) {
if (strstr(XdrvMailbox.data, ".")) { // Process parameter entry 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_area = atoi(subStr(sub_string, XdrvMailbox.data, ".", 1));
int pa_line = atoi(subStr(sub_string, XdrvMailbox.data, ".", 2)); 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)) { else if ((CMND_KNX_GA == command_code) && (index > 0) && (index <= MAX_KNX_GA)) {
if (XdrvMailbox.data_len) { if (XdrvMailbox.data_len) {
if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry 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_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1));
int ga_area = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); 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)) { else if ((CMND_KNX_CB == command_code) && (index > 0) && (index <= MAX_KNX_CB)) {
if (XdrvMailbox.data_len) { if (XdrvMailbox.data_len) {
if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry 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_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1));
int cb_area = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); int cb_area = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));

View File

@ -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 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 }; CMND_DISP_SIZE, CMND_DISP_FONT, CMND_DISP_ROTATE, CMND_DISP_TEXT, CMND_DISP_ADDRESS };
const char kDisplayCommands[] PROGMEM = 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 ; 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\"}"; const char S_JSON_DISPLAY_COMMAND_VALUE[] PROGMEM = "{\"" D_CMND_DISPLAY "%s\":\"%s\"}";
@ -626,11 +626,24 @@ void DisplayLogBufferInit()
DisplayReAllocLogBuffer(); DisplayReAllocLogBuffer();
char buffer[20]; char buffer[40];
snprintf_P(buffer, sizeof(buffer), PSTR(D_VERSION " %s"), my_version); snprintf_P(buffer, sizeof(buffer), PSTR(D_VERSION " %s"), my_version);
DisplayLogBufferAdd(buffer); DisplayLogBufferAdd(buffer);
snprintf_P(buffer, sizeof(buffer), PSTR("Display mode %d"), Settings.display_mode); snprintf_P(buffer, sizeof(buffer), PSTR("Display mode %d"), Settings.display_mode);
DisplayLogBufferAdd(buffer); 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<uint32_t>(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);
}
} }
} }
@ -885,6 +898,12 @@ boolean DisplayCommand()
if (-1 == command_code) { if (-1 == command_code) {
serviced = false; // Unknown command 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) { else if (CMND_DISP_MODEL == command_code) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < DISPLAY_MAX_DRIVERS)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < DISPLAY_MAX_DRIVERS)) {
uint8_t last_display_model = Settings.display_model; uint8_t last_display_model = Settings.display_model;
@ -915,8 +934,8 @@ boolean DisplayCommand()
if (last_display_mode && !Settings.display_mode) { // Switch to mode 0 if (last_display_mode && !Settings.display_mode) { // Switch to mode 0
DisplayInit(DISPLAY_INIT_MODE); DisplayInit(DISPLAY_INIT_MODE);
DisplayClear(); DisplayClear();
} } else {
if (!last_display_mode && Settings.display_mode) { // Switch to non mode 0 // if (!last_display_mode && Settings.display_mode) { // Switch to non mode 0
DisplayLogBufferInit(); DisplayLogBufferInit();
DisplayInit(DISPLAY_INIT_MODE); DisplayInit(DISPLAY_INIT_MODE);
} }

196
sonoff/xdrv_14_mp3.ino Normal file
View File

@ -0,0 +1,196 @@
/*
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 <http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------
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 <TasmotaSerial.h> 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
/*********************************************************************************************\
* MP3 control for RB-DFR-562 DFRobot mini MP3 player
* https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299
\*********************************************************************************************/
#include <TasmotaSerial.h>
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\"}";
const char kMP3_Commands[] PROGMEM = "Track|Play|Pause|Stop|Volume|EQ|Device";
// 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
// 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;
for (uint8_t i = 0; i < 6; i++) {
checksum += array[i];
}
checksum = checksum^0xffff;
return checksum+1;
}
// init player, define serial tx port
// fixed with 9600 baud
//
void MP3PlayerInit() {
MP3Player = new TasmotaSerial(-1, pin[GPIO_MP3_DFR562]);
// 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}; // 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
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + disp_len, kMP3_Commands);
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;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XDRV_14
boolean Xdrv14(byte function)
{
boolean result = false;
switch (function) {
case FUNC_PRE_INIT:
MP3PlayerInit(); // init and start communication
break;
case FUNC_COMMAND:
result = MP3PlayerCmd(); // return result from mp3 player command
break;
}
return result;
}
#endif // USE_MP3_PLAYER

View File

@ -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) #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 // All version before core 2.4.2
// https://github.com/esp8266/Arduino/issues/2557
extern "C" { extern "C" {
#include <cont.h> #include <cont.h>
@ -190,7 +191,6 @@ extern "C" {
void DebugFreeMem() void DebugFreeMem()
{ {
// https://github.com/esp8266/Arduino/issues/2557
register uint32_t *sp asm("a1"); register uint32_t *sp asm("a1");
// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d, UnmodifiedStack %d (%s)"), // 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() void DebugFreeMem()
{ {
// https://github.com/esp8266/Arduino/issues/2557
register uint32_t *sp asm("a1"); register uint32_t *sp asm("a1");
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"), snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"),

View File

@ -243,7 +243,8 @@ void MatrixPrintLog(uint8_t direction)
uint8_t space = 0; uint8_t space = 0;
uint8_t max_cols = (disp_log_buffer_cols < MTX_MAX_SCREEN_BUFFER) ? disp_log_buffer_cols : MTX_MAX_SCREEN_BUFFER; uint8_t max_cols = (disp_log_buffer_cols < MTX_MAX_SCREEN_BUFFER) ? disp_log_buffer_cols : MTX_MAX_SCREEN_BUFFER;
mtx_buffer[0] = '\0'; 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] == ' ') { if (txt[i] == ' ') {
space++; space++;
} else { } else {
@ -252,6 +253,7 @@ void MatrixPrintLog(uint8_t direction)
if (space < 2) { if (space < 2) {
strncat(mtx_buffer, (const char*)txt +i, 1); strncat(mtx_buffer, (const char*)txt +i, 1);
} }
i++;
} }
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "[%s]"), mtx_buffer); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "[%s]"), mtx_buffer);

View File

@ -188,7 +188,7 @@ boolean Xdsp05(byte function)
if (FUNC_DISPLAY_INIT_DRIVER == function) { if (FUNC_DISPLAY_INIT_DRIVER == function) {
EpdInitDriver(); EpdInitDriver();
} }
else if (XDSP_04 == Settings.display_model) { else if (XDSP_05 == Settings.display_model) {
if (!dsp_color) { dsp_color = COLORED; } if (!dsp_color) { dsp_color = COLORED; }

View File

@ -41,26 +41,26 @@
#define HLW_POWER_PROBE_TIME 10 // Number of seconds to probe for power before deciding none used #define HLW_POWER_PROBE_TIME 10 // Number of seconds to probe for power before deciding none used
static byte hlw_select_ui_flag; byte hlw_select_ui_flag;
static byte hlw_ui_flag = 1; byte hlw_ui_flag = 1;
static byte hlw_load_off; byte hlw_load_off;
static byte hlw_cf1_timer; byte hlw_cf1_timer;
static unsigned long hlw_cf_pulse_length; unsigned long hlw_cf_pulse_length;
static unsigned long hlw_cf_pulse_last_time; unsigned long hlw_cf_pulse_last_time;
static unsigned long hlw_cf1_pulse_length; unsigned long hlw_cf1_pulse_length;
static unsigned long hlw_cf1_pulse_last_time; unsigned long hlw_cf1_pulse_last_time;
static unsigned long hlw_cf1_summed_pulse_length; unsigned long hlw_cf1_summed_pulse_length;
static unsigned long hlw_cf1_pulse_counter; unsigned long hlw_cf1_pulse_counter;
static unsigned long hlw_cf1_voltage_pulse_length; unsigned long hlw_cf1_voltage_pulse_length;
static unsigned long hlw_cf1_current_pulse_length; unsigned long hlw_cf1_current_pulse_length;
static unsigned long hlw_energy_period_counter; unsigned long hlw_energy_period_counter;
static unsigned long hlw_power_ratio = 0; unsigned long hlw_power_ratio = 0;
static unsigned long hlw_voltage_ratio = 0; unsigned long hlw_voltage_ratio = 0;
static unsigned long hlw_current_ratio = 0; unsigned long hlw_current_ratio = 0;
static unsigned long hlw_cf1_voltage_max_pulse_counter; unsigned long hlw_cf1_voltage_max_pulse_counter;
static unsigned long hlw_cf1_current_max_pulse_counter; unsigned long hlw_cf1_current_max_pulse_counter;
#ifndef USE_WS2812_DMA // Collides with Neopixelbus but solves exception #ifndef USE_WS2812_DMA // Collides with Neopixelbus but solves exception
void HlwCfInterrupt() ICACHE_RAM_ATTR; void HlwCfInterrupt() ICACHE_RAM_ATTR;
@ -217,6 +217,7 @@ void HlwDrvInit()
{ {
if (!energy_flg) { 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 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; energy_flg = XNRG_01;
} }
} }

View File

@ -185,6 +185,7 @@ void CseDrvInit()
if ((SONOFF_S31 == Settings.module) || (SONOFF_POW_R2 == Settings.module)) { // Sonoff S31 or Sonoff Pow R2 if ((SONOFF_S31 == Settings.module) || (SONOFF_POW_R2 == Settings.module)) { // Sonoff S31 or Sonoff Pow R2
baudrate = 4800; baudrate = 4800;
serial_config = SERIAL_8E1; serial_config = SERIAL_8E1;
energy_calc_power_factor = 1; // Calculate power factor from data
energy_flg = XNRG_02; energy_flg = XNRG_02;
} }
} }

View File

@ -215,6 +215,7 @@ void PzemDrvInit()
{ {
if (!energy_flg) { if (!energy_flg) {
if ((pin[GPIO_PZEM_RX] < 99) && (pin[GPIO_PZEM_TX] < 99)) { // Any device with a Pzem004T 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; energy_flg = XNRG_03;
} }
} }

228
sonoff/xnrg_05_pzem2.ino Normal file
View File

@ -0,0 +1,228 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#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.h>
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, uint8_t register_count)
{
// 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) && (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
}
}
}
AddLogSerial(LOG_LEVEL_DEBUG_MORE, buffer, len);
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) { return 9; } // 9 = crc error
return 0; // 0 = No error
}
/*********************************************************************************************/
uint8_t pzem2_sendRetry = 0;
void Pzem2Every200ms()
{
bool data_ready = Pzem2ModbusReceiveReady();
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;
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_05 == energy_flg) {
switch (function) {
case FUNC_INIT:
Pzem2SnsInit();
break;
case FUNC_EVERY_200_MSECOND:
Pzem2Every200ms();
break;
}
}
return result;
}
#endif // USE_PZEM2
#endif // USE_ENERGY_SENSOR

View File

@ -17,6 +17,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#if defined(USE_WEBSERVER) && defined(USE_EMULATION) #if defined(USE_WEBSERVER) && defined(USE_EMULATION)
/*********************************************************************************************\ /*********************************************************************************************\
* Belkin WeMo and Philips Hue bridge emulation * Belkin WeMo and Philips Hue bridge emulation
@ -397,7 +400,6 @@ void HandleUpnpEvent()
uint8_t device = (light_type) ? devices_present : 1; // Select either a configured light or relay1 uint8_t device = (light_type) ? devices_present : 1; // Select either a configured light or relay1
ExecuteCommandPower(device, power, SRC_WEMO); ExecuteCommandPower(device, power, SRC_WEMO);
} }
} }
else if(request.indexOf(F("GetBinaryState")) > 0){ else if(request.indexOf(F("GetBinaryState")) > 0){
state_xml.replace(F("Set"), F("Get")); state_xml.replace(F("Set"), F("Get"));
@ -463,10 +465,10 @@ const char HUE_LIGHTS_STATUS_JSON[] PROGMEM =
"\"hue\":{h}," "\"hue\":{h},"
"\"sat\":{s}," "\"sat\":{s},"
"\"xy\":[0.5, 0.5]," "\"xy\":[0.5, 0.5],"
"\"ct\":500," "\"ct\":{t},"
"\"alert\":\"none\"," "\"alert\":\"none\","
"\"effect\":\"none\"," "\"effect\":\"none\","
"\"colormode\":\"hs\"," "\"colormode\":\"{m}\","
"\"reachable\":true}"; "\"reachable\":true}";
const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM = const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM =
",\"type\":\"Extended color light\"," ",\"type\":\"Extended color light\","
@ -560,20 +562,26 @@ void HueConfig(String *path)
WebServer->send(200, FPSTR(HDR_CTYPE_JSON), response); WebServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
} }
bool g_gotct = false;
void HueLightStatus1(byte device, String *response) void HueLightStatus1(byte device, String *response)
{ {
float hue = 0; float hue = 0;
float sat = 0; float sat = 0;
float bri = 0; float bri = 0;
uint16_t ct = 500;
if (light_type) { if (light_type) {
LightGetHsb(&hue, &sat, &bri); LightGetHsb(&hue, &sat, &bri, g_gotct);
ct = LightGetColorTemp();
} }
*response += FPSTR(HUE_LIGHTS_STATUS_JSON); *response += FPSTR(HUE_LIGHTS_STATUS_JSON);
response->replace("{state}", (power & (1 << (device-1))) ? "true" : "false"); response->replace("{state}", (power & (1 << (device-1))) ? "true" : "false");
response->replace("{h}", String((uint16_t)(65535.0f * hue))); response->replace("{h}", String((uint16_t)(65535.0f * hue)));
response->replace("{s}", String((uint8_t)(254.0f * sat))); response->replace("{s}", String((uint8_t)(254.0f * sat)));
response->replace("{b}", String((uint8_t)(254.0f * bri))); 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) void HueLightStatus2(byte device, String *response)
@ -679,11 +687,13 @@ void HueLights(String *path)
} }
if (light_type) { 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 = hue_json["bri"];
tmp = max(tmp, 1);
tmp = min(tmp, 254);
bri = (float)tmp / 254.0f; bri = (float)tmp / 254.0f;
if (resp) { if (resp) {
response += ","; response += ",";
@ -695,7 +705,7 @@ void HueLights(String *path)
resp = true; resp = true;
change = 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"]; tmp = hue_json["hue"];
hue = (float)tmp / 65535.0f; hue = (float)tmp / 65535.0f;
if (resp) { if (resp) {
@ -705,11 +715,14 @@ void HueLights(String *path)
response.replace("{id", String(device)); response.replace("{id", String(device));
response.replace("{cm", "hue"); response.replace("{cm", "hue");
response.replace("{re", String(tmp)); response.replace("{re", String(tmp));
g_gotct = false;
resp = true; resp = true;
change = 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 = hue_json["sat"];
tmp = max(tmp, 0);
tmp = min(tmp, 254);
sat = (float)tmp / 254.0f; sat = (float)tmp / 254.0f;
if (resp) { if (resp) {
response += ","; response += ",";
@ -718,6 +731,8 @@ void HueLights(String *path)
response.replace("{id", String(device)); response.replace("{id", String(device));
response.replace("{cm", "sat"); response.replace("{cm", "sat");
response.replace("{re", String(tmp)); response.replace("{re", String(tmp));
g_gotct = false;
resp = true;
change = true; change = true;
} }
if (hue_json.containsKey("ct")) { // Color temperature 153 (Cold) to 500 (Warm) if (hue_json.containsKey("ct")) { // Color temperature 153 (Cold) to 500 (Warm)
@ -729,11 +744,12 @@ void HueLights(String *path)
response.replace("{id", String(device)); response.replace("{id", String(device));
response.replace("{cm", "ct"); response.replace("{cm", "ct");
response.replace("{re", String(ct)); response.replace("{re", String(ct));
g_gotct = true;
change = true; change = true;
} }
if (change) { if (change) {
if (light_type) { if (light_type) {
LightSetHsb(hue, sat, bri, ct); LightSetHsb(hue, sat, bri, ct, g_gotct);
} }
change = false; change = false;
} }

View File

@ -27,20 +27,59 @@
#include <TasmotaSerial.h> #include <TasmotaSerial.h>
#ifndef WORKING_PERIOD
#define WORKING_PERIOD 5
#endif
TasmotaSerial *NovaSdsSerial; TasmotaSerial *NovaSdsSerial;
uint8_t novasds_type = 1; uint8_t novasds_type = 1;
uint8_t novasds_valid = 0; uint8_t novasds_valid = 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 { struct sds011data {
uint16_t pm100; uint16_t pm100;
uint16_t pm25; uint16_t pm25;
} novasds_data; } novasds_data;
void NovaSdsSetWorkPeriod()
{
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() bool NovaSdsReadData()
{ {
if (! NovaSdsSerial->available()) return false; 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(); NovaSdsSerial->read();
} }
@ -83,11 +122,14 @@ void NovaSdsSecond() // Every second
void NovaSdsInit() void NovaSdsInit()
{ {
novasds_type = 0; novasds_type = 0;
if (pin[GPIO_SDS0X1] < 99) { if (pin[GPIO_SDS0X1_RX] < 99 && pin[GPIO_SDS0X1_TX] < 99) {
NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1], -1, 1); NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1_RX], pin[GPIO_SDS0X1_TX], 1);
if (NovaSdsSerial->begin(9600)) { if (NovaSdsSerial->begin(9600)) {
if (NovaSdsSerial->hardwareSerial()) { ClaimSerial(); } if (NovaSdsSerial->hardwareSerial()) {
ClaimSerial();
}
novasds_type = 1; novasds_type = 1;
NovaSdsSetWorkPeriod();
} }
} }
} }
@ -154,4 +196,4 @@ boolean Xsns20(byte function)
return result; return result;
} }
#endif // USE_NOVA_SDS #endif // USE_NOVA_SDS

View File

@ -246,7 +246,7 @@ void SDM120Show(boolean json)
dtostrfd(sdm120_apparent_power, Settings.flag2.wattage_resolution, apparent_power); dtostrfd(sdm120_apparent_power, Settings.flag2.wattage_resolution, apparent_power);
dtostrfd(sdm120_reactive_power, Settings.flag2.wattage_resolution, reactive_power); dtostrfd(sdm120_reactive_power, Settings.flag2.wattage_resolution, reactive_power);
dtostrfd(sdm120_power_factor, 2, power_factor); 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); dtostrfd(sdm120_energy_total, Settings.flag2.energy_resolution, energy_total);
if (json) { if (json) {

View File

@ -300,7 +300,7 @@ void MCP230xx_CheckForInterrupt(void) {
MqttPublishPrefixTopic_P(RESULT_OR_STAT, mqtt_data); MqttPublishPrefixTopic_P(RESULT_OR_STAT, mqtt_data);
} }
if (int_event) { 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)); sprintf(command,"event MCPINT_D%i=%i",intp+(mcp230xx_port*8),((mcp230xx_intcap >> intp) & 0x01));
ExecuteCommand(command, SRC_RULE); ExecuteCommand(command, SRC_RULE);
} }
@ -421,10 +421,11 @@ bool MCP230xx_Command(void) {
uint8_t paramcount = 0; uint8_t paramcount = 0;
if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len > 0) {
paramcount=1; paramcount=1;
sprintf(XdrvMailbox.data,"%s,",XdrvMailbox.data); // need a trailing comma to make substr work properly with last variable - bug? dunno? } else {
XdrvMailbox.data_len++; serviced = false;
return serviced;
} }
char sub_string[XdrvMailbox.data_len +1]; char sub_string[XdrvMailbox.data_len];
for (uint8_t ca=0;ca<XdrvMailbox.data_len;ca++) { for (uint8_t ca=0;ca<XdrvMailbox.data_len;ca++) {
if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; } if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; }
if (',' == XdrvMailbox.data[ca]) { paramcount++; } if (',' == XdrvMailbox.data[ca]) { paramcount++; }
@ -441,7 +442,7 @@ bool MCP230xx_Command(void) {
#endif // USE_MCP230xx_OUTPUT #endif // USE_MCP230xx_OUTPUT
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTPRI")) { if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTPRI")) {
if (paramcount > 2) { if (paramcount > 1) {
uint8_t intpri = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); uint8_t intpri = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
if ((intpri >= 0) && (intpri <= 20)) { if ((intpri >= 0) && (intpri <= 20)) {
Settings.mcp230xx_int_prio = intpri; Settings.mcp230xx_int_prio = intpri;
@ -455,7 +456,7 @@ bool MCP230xx_Command(void) {
} }
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTTIMER")) { 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)); uint8_t inttim = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
if ((inttim >= 0) && (inttim <= 3600)) { if ((inttim >= 0) && (inttim <= 3600)) {
Settings.mcp230xx_int_timer = inttim; Settings.mcp230xx_int_timer = inttim;
@ -470,7 +471,7 @@ bool MCP230xx_Command(void) {
} }
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTDEF")) { 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)); uint8_t pin = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
if (pin < mcp230xx_pincount) { if (pin < mcp230xx_pincount) {
if (pin == 0) { if (pin == 0) {
@ -480,7 +481,7 @@ bool MCP230xx_Command(void) {
} }
} }
if (validpin) { if (validpin) {
if (paramcount > 3) { if (paramcount > 2) {
uint8_t intdef = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3)); uint8_t intdef = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3));
if ((intdef >= 0) && (intdef <= 15)) { if ((intdef >= 0) && (intdef <= 15)) {
Settings.mcp230xx_config[pin].int_report_defer=intdef; 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 (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTCNT")) {
if (paramcount > 2) { if (paramcount > 1) {
uint8_t pin = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); uint8_t pin = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
if (pin < mcp230xx_pincount) { if (pin < mcp230xx_pincount) {
if (pin == 0) { if (pin == 0) {
@ -520,7 +521,7 @@ bool MCP230xx_Command(void) {
} }
} }
if (validpin) { if (validpin) {
if (paramcount > 3) { if (paramcount > 2) {
uint8_t intcnt = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3)); uint8_t intcnt = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3));
if ((intcnt >= 0) && (intcnt <= 1)) { if ((intcnt >= 0) && (intcnt <= 1)) {
Settings.mcp230xx_config[pin].int_count_en=intcnt; Settings.mcp230xx_config[pin].int_count_en=intcnt;
@ -567,7 +568,7 @@ bool MCP230xx_Command(void) {
validpin=true; validpin=true;
} }
} }
if (validpin && (paramcount > 2)) { if (validpin && (paramcount > 1)) {
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 2), "?")) { if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 2), "?")) {
uint8_t port = 0; uint8_t port = 0;
if (pin > 7) { port = 1; } if (pin > 7) { port = 1; }
@ -606,13 +607,13 @@ bool MCP230xx_Command(void) {
uint8_t pinmode = 0; uint8_t pinmode = 0;
uint8_t pullup = 0; uint8_t pullup = 0;
uint8_t intmode = 0; uint8_t intmode = 0;
if (paramcount > 2) { if (paramcount > 1) {
pinmode = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); pinmode = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
} }
if (paramcount > 3) { if (paramcount > 2) {
pullup = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3)); pullup = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3));
} }
if (paramcount > 4) { if (paramcount > 3) {
intmode = atoi(subStr(sub_string, XdrvMailbox.data, ",", 4)); intmode = atoi(subStr(sub_string, XdrvMailbox.data, ",", 4));
} }
#ifdef USE_MCP230xx_OUTPUT #ifdef USE_MCP230xx_OUTPUT

View File

@ -28,12 +28,13 @@ Instructions:
and store it in file status.json and store it in file status.json
Usage: Usage:
./decode-status.py -d <hostname or IP address> ./decode-status.py -d <hostname or IP address> [-u username] [-p password]
or or
./decode-status.py -f <JSON status information file> ./decode-status.py -f <JSON status information file>
Example: Example:
./decode-status.py -d sonoff1 ./decode-status.py -d sonoff1
./decode-status.py -d sonoff1 -p 12345678
or or
./decode-status.py -f status.json ./decode-status.py -f status.json
""" """
@ -42,6 +43,7 @@ import io
import os.path import os.path
import json import json
import pycurl import pycurl
import urllib2
from sys import exit from sys import exit
from optparse import OptionParser from optparse import OptionParser
from StringIO import StringIO from StringIO import StringIO
@ -83,7 +85,9 @@ a_setoption = [[
"Do not show Wifi and Mqtt state using Led" "Do not show Wifi and Mqtt state using Led"
],[ ],[
"Timers enabled", "Timers enabled",
"","","", "Generic ESP8285 GPIO enabled",
"Add UTC time offset to JSON message",
"",
"","","","", "","","","",
"","","","", "","","","",
"","","","", "","","","",
@ -106,10 +110,10 @@ a_features = [[
"USE_CONFIG_OVERRIDE","BE_MINIMAL","USE_SENSORS","USE_CLASSIC", "USE_CONFIG_OVERRIDE","BE_MINIMAL","USE_SENSORS","USE_CLASSIC",
"USE_KNX_NO_EMULATION","USE_DISPLAY_MODES1TO5","USE_DISPLAY_GRAPH","USE_DISPLAY_LCD", "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_SSD1306","USE_DISPLAY_MATRIX","USE_DISPLAY_ILI9341","USE_DISPLAY_EPAPER",
"USE_DISPLAY_SH1106","","","", "USE_DISPLAY_SH1106","USE_MP3_PLAYER","","",
"","","","", "","","","",
"","","","", "","","","NO_EXTRA_4K_HEAP",
"","","VTABLES_IN_FLASH","PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH", "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" "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", "","USE_ADC_VCC","USE_ENERGY_SENSOR","USE_PZEM004T",
@ -122,8 +126,8 @@ a_features = [[
"USE_SDM630","USE_LM75AD","USE_APDS9960","USE_TM1638" "USE_SDM630","USE_LM75AD","USE_APDS9960","USE_TM1638"
],[ ],[
"USE_MCP230xx","USE_MPR121","USE_CCS811","USE_MPU6050", "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","","",
"","","","", "","","","",
"","","","", "","","","",
"","","","", "","","","",
@ -134,13 +138,20 @@ usage = "usage: decode-status {-d | -f} arg"
parser = OptionParser(usage) parser = OptionParser(usage)
parser.add_option("-d", "--dev", action="store", type="string", parser.add_option("-d", "--dev", action="store", type="string",
dest="device", help="device to retrieve status from") 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", parser.add_option("-f", "--file", metavar="FILE",
dest="jsonfile", default="status.json", help="status json file (default: status.json)") dest="jsonfile", default="status.json", help="status json file (default: status.json)")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
if (options.device): if (options.device):
buffer = StringIO() 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 = pycurl.Curl()
c.setopt(c.URL, url) c.setopt(c.URL, url)
c.setopt(c.WRITEDATA, buffer) c.setopt(c.WRITEDATA, buffer)
@ -215,4 +226,4 @@ if __name__ == "__main__":
try: try:
StartDecode() StartDecode()
except Exception as e: except Exception as e:
print("E: {}".format(e)) print("E: {}".format(e))