mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-24 14:57:16 +00:00
Merge branch 'arendst/development' into development
This commit is contained in:
commit
36ebd4d4ec
@ -13,7 +13,7 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute!
|
||||
[](https://paypal.me/tasmota)
|
||||
|
||||
### Development
|
||||
[](https://github.com/arendst/Sonoff-Tasmota)
|
||||
[](https://github.com/arendst/Sonoff-Tasmota)
|
||||
[](http://thehackbox.org/tasmota/)
|
||||
[](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)
|
||||
- [BlitzWolf BW-SHP2 Smart Socket with Energy Monitoring](https://www.banggood.com/BlitzWolf-BW-SHP2-Smart-WIFI-Socket-EU-Plug-220V-16A-Work-with-Amazon-Alexa-Google-Assistant-p-1292899.html)
|
||||
- [Luani HVIO board](https://luani.de/projekte/esp8266-hvio/)
|
||||
- Xiaomi-Phillips Bulbs
|
||||
- Wemos D1 mini, NodeMcu and Ledunia
|
||||
|
||||
### Contribute
|
||||
|
@ -104,6 +104,12 @@ See [Tasmota ESP/Arduino library version related issues](https://github.com/aren
|
||||
| USE_RF_FLASH | - | - | x | x | x |
|
||||
|
||||
## Changelog
|
||||
Version 6.2.1 20180905
|
||||
* Fix possible ambiguity on command parameters if StateText contains numbers only (#3656)
|
||||
* Fix Wemo emulation to select the first relay when more than one relay is present (#3657)
|
||||
* Fix possible exception due to buffer overflow (#3659)
|
||||
* Fix lost energy today and total energy value after power cycle (#3689)
|
||||
|
||||
Version 6.2.0 20180901
|
||||
* Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561)
|
||||
* Disable wifi sleep for both Esp8266/Arduino core 2.4.1 and 2.4.2 to solve device freeze caused by Espressif SDK bug (#3554)
|
||||
|
@ -61,6 +61,7 @@ build_unflags = -Wall
|
||||
|
||||
build_flags =
|
||||
-Wl,-Tesp8266.flash.1m0.ld
|
||||
-mtarget-align
|
||||
; -DUSE_CONFIG_OVERRIDE
|
||||
; lwIP 1.4 (Default)
|
||||
; -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
|
||||
|
@ -1,13 +1,32 @@
|
||||
/* 6.2.0.2 20180904
|
||||
* Rewrite energy monitoring using energy sensor driver modules
|
||||
* Fix lost today and total energy value after power cycle (#3689)
|
||||
/* 6.2.1.3 20180907
|
||||
* Change web Configure Module GPIO drop down list order for better readability
|
||||
* Fix showing Period Power in energy threshold messages
|
||||
* Fix ButtonRetain to not use default topic for clearing retain messages (#3737)
|
||||
* 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
|
||||
* Fix possible ambiguity on command parameters if StateText contains numbers only (#3656)
|
||||
* Fix possible exception due to buffer overflow (#3659)
|
||||
* 6.2.1.2 20180906
|
||||
* Fix KNX PA exception. Regression from 6.2.1 buffer overflow caused by subStr() (#3700, #3710)
|
||||
* Add command SetOption52 to control display of optional time offset from UTC in JSON messages (#3629, #3711)
|
||||
* Add experimental support for PZEM-003,014,016,017 Energy monitoring (#3694)
|
||||
* Add basic support for MP3 player using DFRobot RB-DFR-562 (#3723)
|
||||
* Fix setting and getting color temperature for Philips Hue emulation (#3733)
|
||||
*
|
||||
* 6.2.1.1 20180905
|
||||
* Rewrite energy monitoring using energy sensor driver modules
|
||||
* 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 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
|
||||
* Allow user override of define MAX_RULE_VARS and MAX_RULE_TIMERS (#3561)
|
||||
|
@ -181,6 +181,7 @@
|
||||
#define D_CMND_PRESSURE_RESOLUTION "PressRes"
|
||||
#define D_CMND_POWER_RESOLUTION "WattRes"
|
||||
#define D_CMND_VOLTAGE_RESOLUTION "VoltRes"
|
||||
#define D_CMND_FREQUENCY_RESOLUTION "FreqRes"
|
||||
#define D_CMND_CURRENT_RESOLUTION "AmpRes"
|
||||
#define D_CMND_ENERGY_RESOLUTION "EnergyRes"
|
||||
#define D_CMND_MODULE "Module"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Ключ" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Бутон" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "Подсветка"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -94,7 +94,7 @@
|
||||
#define D_FALSE "Nepravda"
|
||||
#define D_FILE "Soubor"
|
||||
#define D_FREE_MEMORY "Volná paměť"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_FREQUENCY "Kmitočet"
|
||||
#define D_GAS "Plyn"
|
||||
#define D_GATEWAY "Výchozí brána"
|
||||
#define D_GROUP "Skupina"
|
||||
@ -128,7 +128,7 @@
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "Tlak"
|
||||
#define D_PRESSUREATSEALEVEL "Tlak na úrovni hladiny moře"
|
||||
#define D_PRESSUREATSEALEVEL "Tlak na hladině moře"
|
||||
#define D_PROGRAM_FLASH_SIZE "Velikost paměti flash"
|
||||
#define D_PROGRAM_SIZE "Velikost programu"
|
||||
#define D_PROJECT "Projekt"
|
||||
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Spínač" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Tlačítko" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRSend"
|
||||
#define D_SENSOR_SWITCH "Switch " // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Button " // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Διακόπτης" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Κουμπί" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Switch" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Button" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IR TX"
|
||||
#define D_SENSOR_SWITCH "Llave" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Botón" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "ÉmetIR"
|
||||
#define D_SENSOR_SWITCH "Inter." // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Bouton" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "RétroÉcl"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRadó"
|
||||
#define D_SENSOR_SWITCH "Kapcsoló" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Gomb" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "Háttérvil"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Switch" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Button" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Speler"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Switch" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Button" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Przela" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Przyci" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Interruptor" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Botão" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "Luz de fundo"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Interruptor" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Botão" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "Luz negra"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Свич" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Кнопка" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Switch" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Button" // Suffix "1"
|
||||
@ -475,6 +476,8 @@
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Перемикач" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Кнопка" // Suffix "1"
|
||||
@ -475,6 +476,8 @@
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Switch" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Button" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -456,6 +456,7 @@
|
||||
#define D_SENSOR_I2C_SCL "I2C SCL"
|
||||
#define D_SENSOR_I2C_SDA "I2C SDA"
|
||||
#define D_SENSOR_WS2812 "WS2812"
|
||||
#define D_SENSOR_DFR562 "MP3 Player"
|
||||
#define D_SENSOR_IRSEND "IRsend"
|
||||
#define D_SENSOR_SWITCH "Switch" // Suffix "1"
|
||||
#define D_SENSOR_BUTTON "Button" // Suffix "1"
|
||||
@ -474,7 +475,8 @@
|
||||
#define D_SENSOR_SPI_DC "SPI DC"
|
||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||
#define D_SENSOR_PMS5003 "PMS5003"
|
||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
|
||||
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
|
||||
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||
#define D_SENSOR_SR04_TRIG "SR04 Tri"
|
||||
|
@ -64,8 +64,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||
uint32_t data; // Allow bit manipulation using SetOption
|
||||
struct { // SetOption50 .. SetOption81
|
||||
uint32_t timers_enable : 1; // bit 0 (v6.1.1b)
|
||||
uint32_t spare01 : 1;
|
||||
uint32_t spare02 : 1;
|
||||
uint32_t user_esp8285_enable : 1; // bit 1 (v6.1.1.14)
|
||||
uint32_t time_append_timezone : 1; // bit 2 (v6.2.1.2)
|
||||
uint32_t spare03 : 1;
|
||||
uint32_t spare04 : 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 spare29 : 1;
|
||||
uint32_t spare30 : 1;
|
||||
uint32_t user_esp8285_enable : 1; // bit 31 (v6.1.1.14)
|
||||
uint32_t spare31 : 1;
|
||||
};
|
||||
} SysBitfield3;
|
||||
|
||||
@ -112,8 +112,7 @@ typedef union {
|
||||
uint32_t spare08 : 1;
|
||||
uint32_t spare09 : 1;
|
||||
uint32_t spare10 : 1;
|
||||
uint32_t spare11 : 1;
|
||||
uint32_t spare12 : 1;
|
||||
uint32_t frequency_resolution : 2;
|
||||
uint32_t axis_resolution : 2;
|
||||
uint32_t current_resolution : 2;
|
||||
uint32_t voltage_resolution : 2;
|
||||
|
@ -170,7 +170,7 @@ enum WeekInMonthOptions {Last, First, Second, Third, Fourth};
|
||||
enum DayOfTheWeekOptions {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat};
|
||||
enum MonthNamesOptions {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
|
||||
enum HemisphereOptions {North, South};
|
||||
enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART, DT_UPTIME };
|
||||
enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART };
|
||||
|
||||
enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
||||
|
||||
|
@ -77,8 +77,8 @@
|
||||
enum TasmotaCommands {
|
||||
CMND_BACKLOG, CMND_DELAY, CMND_POWER, CMND_FANSPEED, CMND_STATUS, CMND_STATE, CMND_POWERONSTATE, CMND_PULSETIME,
|
||||
CMND_BLINKTIME, CMND_BLINKCOUNT, CMND_SENSOR, CMND_SAVEDATA, CMND_SETOPTION, CMND_TEMPERATURE_RESOLUTION, CMND_HUMIDITY_RESOLUTION,
|
||||
CMND_PRESSURE_RESOLUTION, CMND_POWER_RESOLUTION, CMND_VOLTAGE_RESOLUTION, CMND_CURRENT_RESOLUTION, CMND_ENERGY_RESOLUTION, CMND_MODULE, CMND_MODULES,
|
||||
CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE,
|
||||
CMND_PRESSURE_RESOLUTION, CMND_POWER_RESOLUTION, CMND_VOLTAGE_RESOLUTION, CMND_FREQUENCY_RESOLUTION, CMND_CURRENT_RESOLUTION, CMND_ENERGY_RESOLUTION,
|
||||
CMND_MODULE, CMND_MODULES, CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE,
|
||||
CMND_COUNTERDEBOUNCE, CMND_BUTTONDEBOUNCE, CMND_SWITCHDEBOUNCE, CMND_SLEEP, CMND_UPGRADE, CMND_UPLOAD, CMND_OTAURL, CMND_SERIALLOG, CMND_SYSLOG,
|
||||
CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME,
|
||||
CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE,
|
||||
@ -87,8 +87,8 @@ enum TasmotaCommands {
|
||||
const char kTasmotaCommands[] PROGMEM =
|
||||
D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_FANSPEED "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|"
|
||||
D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SENSOR "|" D_CMND_SAVEDATA "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|"
|
||||
D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|" D_CMND_MODULE "|" D_CMND_MODULES "|"
|
||||
D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|"
|
||||
D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_FREQUENCY_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|"
|
||||
D_CMND_MODULE "|" D_CMND_MODULES "|" D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|"
|
||||
D_CMND_COUNTERDEBOUNCE "|" D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_SYSLOG "|"
|
||||
D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|"
|
||||
D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|"
|
||||
@ -134,7 +134,7 @@ int ota_state_flag = 0; // OTA state flag
|
||||
int ota_result = 0; // OTA result
|
||||
int restart_flag = 0; // Sonoff restart flag
|
||||
int wifi_state_flag = WIFI_RESTART; // Wifi state flag
|
||||
int tele_period = 0; // Tele period timer
|
||||
int tele_period = 1; // Tele period timer
|
||||
int blinks = 201; // Number of LED blinks
|
||||
uint32_t uptime = 0; // Counting every second until 4294967295 = 130 year
|
||||
uint32_t global_update = 0; // Timestamp of last global temperature and humidity update
|
||||
@ -794,6 +794,12 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.voltage_resolution);
|
||||
}
|
||||
else if (CMND_FREQUENCY_RESOLUTION == command_code) {
|
||||
if ((payload >= 0) && (payload <= 3)) {
|
||||
Settings.flag2.frequency_resolution = payload;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.frequency_resolution);
|
||||
}
|
||||
else if (CMND_CURRENT_RESOLUTION == command_code) {
|
||||
if ((payload >= 0) && (payload <= 3)) {
|
||||
Settings.flag2.current_resolution = payload;
|
||||
@ -843,9 +849,9 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
else if ((CMND_GPIO == command_code) && (index < MAX_GPIO_PIN)) {
|
||||
mytmplt cmodule;
|
||||
memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule));
|
||||
if ((GPIO_USER == cmodule.gp.io[index]) && (payload >= 0) && (payload < GPIO_SENSOR_END)) {
|
||||
if ((GPIO_USER == ValidGPIO(index, cmodule.gp.io[index])) && (payload >= 0) && (payload < GPIO_SENSOR_END)) {
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
if ((GPIO_USER == cmodule.gp.io[i]) && (Settings.my_gp.io[i] == payload)) {
|
||||
if ((GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) && (Settings.my_gp.io[i] == payload)) {
|
||||
Settings.my_gp.io[i] = 0;
|
||||
}
|
||||
}
|
||||
@ -854,7 +860,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
if (GPIO_USER == cmodule.gp.io[i]) {
|
||||
if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) {
|
||||
if (jsflg) snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
||||
jsflg = 1;
|
||||
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) {
|
||||
if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
|
||||
Settings.syslog_level = payload;
|
||||
syslog_level = (Settings.flag2.emulation) ? 0 : payload;
|
||||
syslog_level = payload;
|
||||
syslog_timer = 0;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, command, Settings.syslog_level, syslog_level);
|
||||
@ -1418,7 +1424,7 @@ void PublishStatus(uint8_t payload)
|
||||
|
||||
if ((0 == payload) || (1 == payload)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_JSON_BAUDRATE "\":%d,\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"),
|
||||
baudrate, Settings.mqtt_grptopic, Settings.ota_url, GetResetReason().c_str(), GetDateAndTime(DT_UPTIME).c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
|
||||
baudrate, Settings.mqtt_grptopic, Settings.ota_url, GetResetReason().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
|
||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
|
||||
}
|
||||
|
||||
@ -1509,7 +1515,7 @@ void MqttShowState()
|
||||
{
|
||||
char stemp1[33];
|
||||
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\""), mqtt_data, GetDateAndTime(DT_LOCAL).c_str(), GetDateAndTime(DT_UPTIME).c_str());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\""), mqtt_data, GetDateAndTime(DT_LOCAL).c_str(), GetUptime().c_str());
|
||||
#ifdef USE_ADC_VCC
|
||||
dtostrfd((double)ESP.getVcc()/1000, 3, stemp1);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1);
|
||||
@ -1590,7 +1596,7 @@ void PerformEverySecond()
|
||||
if (syslog_timer) { // Restore syslog level
|
||||
syslog_timer--;
|
||||
if (!syslog_timer) {
|
||||
syslog_level = (Settings.flag2.emulation) ? 0 : Settings.syslog_level;
|
||||
syslog_level = Settings.syslog_level;
|
||||
if (Settings.syslog_level) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SYSLOG_LOGGING_REENABLED)); // Might trigger disable again (on purpose)
|
||||
}
|
||||
@ -1626,7 +1632,7 @@ void PerformEverySecond()
|
||||
|
||||
if ((2 == RtcTime.minute) && latest_uptime_flag) {
|
||||
latest_uptime_flag = false;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\"}"), GetDateAndTime(DT_LOCAL).c_str(), GetDateAndTime(DT_UPTIME).c_str());
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\"}"), GetDateAndTime(DT_LOCAL).c_str(), GetUptime().c_str());
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_UPTIME));
|
||||
}
|
||||
if ((3 == RtcTime.minute) && !latest_uptime_flag) latest_uptime_flag = true;
|
||||
@ -2347,7 +2353,7 @@ void GpioInit()
|
||||
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)
|
||||
analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
|
||||
@ -2507,7 +2513,7 @@ void setup()
|
||||
#ifndef USE_EMULATION
|
||||
Settings.flag2.emulation = 0;
|
||||
#endif // USE_EMULATION
|
||||
syslog_level = (Settings.flag2.emulation) ? 0 : Settings.syslog_level;
|
||||
syslog_level = Settings.syslog_level;
|
||||
stop_flash_rotate = Settings.flag.stop_flash_rotate;
|
||||
save_data_counter = Settings.save_data;
|
||||
sleep = Settings.sleep;
|
||||
@ -2540,19 +2546,19 @@ void setup()
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BOOT_COUNT " %d"), Settings.bootcount);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
GpioInit();
|
||||
|
||||
SetSerialBaudrate(baudrate);
|
||||
|
||||
Format(mqtt_client, Settings.mqtt_client, sizeof(mqtt_client));
|
||||
Format(mqtt_topic, Settings.mqtt_topic, sizeof(mqtt_topic));
|
||||
|
||||
if (strstr(Settings.hostname, "%")) {
|
||||
strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname));
|
||||
snprintf_P(my_hostname, sizeof(my_hostname)-1, Settings.hostname, mqtt_topic, ESP.getChipId() & 0x1FFF);
|
||||
} else {
|
||||
snprintf_P(my_hostname, sizeof(my_hostname)-1, Settings.hostname);
|
||||
}
|
||||
|
||||
GpioInit();
|
||||
|
||||
SetSerialBaudrate(baudrate);
|
||||
|
||||
WifiConnect();
|
||||
|
||||
if (MOTOR == Settings.module) Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo!
|
||||
|
@ -62,7 +62,10 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
||||
|
||||
#ifdef USE_SENSORS
|
||||
|
||||
#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices
|
||||
#ifdef USE_ADC_VCC
|
||||
#undef USE_ADC_VCC
|
||||
#endif
|
||||
//#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices
|
||||
#define USE_DS18x20 // For more than one DS18x20 sensors with id sort, single scan and read retry (+1k3 code)
|
||||
//#define USE_DS18x20_LEGACY // For more than one DS18x20 sensors with dynamic scan using library OneWire (+1k5 code)
|
||||
#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)
|
||||
@ -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_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
|
||||
#undef USE_PZEM004T // Disable PZEM004T energy sensor
|
||||
#undef USE_PZEM2 // Disable PZEM003,014,016,017 Energy monitor
|
||||
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
|
||||
#undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter
|
||||
#undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy meter
|
||||
|
@ -21,6 +21,8 @@
|
||||
#define _SONOFF_TEMPLATE_H_
|
||||
|
||||
// User selectable GPIO functionality
|
||||
// ATTENTION: Only add at the end of this list just before GPIO_SENSOR_END
|
||||
// Then add the same name(s) in a nice location in array kGpioNiceList
|
||||
enum UserSelectablePins {
|
||||
GPIO_NONE, // Not used
|
||||
GPIO_DHT11, // DHT11
|
||||
@ -92,7 +94,7 @@ enum UserSelectablePins {
|
||||
GPIO_SPI_DC, // SPI Data Direction
|
||||
GPIO_BACKLIGHT, // Display backlight control
|
||||
GPIO_PMS5003, // Plantower PMS5003 Serial interface
|
||||
GPIO_SDS0X1, // Nova Fitness SDS011 Serial interface
|
||||
GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface
|
||||
GPIO_SBR_TX, // Serial Bridge Serial interface
|
||||
GPIO_SBR_RX, // Serial Bridge Serial interface
|
||||
GPIO_SR04_TRIG, // SR04 Trigger pin
|
||||
@ -120,6 +122,10 @@ enum UserSelectablePins {
|
||||
GPIO_CNTR2_NP,
|
||||
GPIO_CNTR3_NP,
|
||||
GPIO_CNTR4_NP,
|
||||
GPIO_PZEM2_TX, // PZEM-003,014,016,017 Serial interface
|
||||
GPIO_PZEM2_RX, // PZEM-003,014,016,017 Serial interface
|
||||
GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player
|
||||
GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
// Programmer selectable GPIO functionality offset by user selectable GPIOs
|
||||
@ -136,9 +142,6 @@ enum ProgramSelectablePins {
|
||||
GPIO_DI, // my92x1 PWM input
|
||||
GPIO_DCKI, // my92x1 CLK input
|
||||
GPIO_ARIRFRCV, // AliLux RF Receive input
|
||||
GPIO_MCP39_TX, // MCP39F501 Serial output
|
||||
GPIO_MCP39_RX, // MCP39F501 Serial input
|
||||
GPIO_MCP39_RST, // MCP39F501 Serial reset
|
||||
GPIO_USER, // User configurable
|
||||
GPIO_MAX };
|
||||
|
||||
@ -164,7 +167,7 @@ const char kSensorNames[] PROGMEM =
|
||||
D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|"
|
||||
D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|"
|
||||
D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|"
|
||||
D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1 "|"
|
||||
D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1_RX "|"
|
||||
D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|"
|
||||
D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|"
|
||||
D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|"
|
||||
@ -172,7 +175,9 @@ const char kSensorNames[] PROGMEM =
|
||||
D_SENSOR_TM1638_CLK "|" D_SENSOR_TM1638_DIO "|" D_SENSOR_TM1638_STB "|"
|
||||
D_SENSOR_SWITCH "1n|" D_SENSOR_SWITCH "2n|" D_SENSOR_SWITCH "3n|" D_SENSOR_SWITCH "4n|" D_SENSOR_SWITCH "5n|" D_SENSOR_SWITCH "6n|" D_SENSOR_SWITCH "7n|" D_SENSOR_SWITCH "8n|"
|
||||
D_SENSOR_BUTTON "1n|" D_SENSOR_BUTTON "2n|" D_SENSOR_BUTTON "3n|" D_SENSOR_BUTTON "4n|"
|
||||
D_SENSOR_COUNTER "1n|" D_SENSOR_COUNTER "2n|" D_SENSOR_COUNTER "3n|" D_SENSOR_COUNTER "4n|";
|
||||
D_SENSOR_COUNTER "1n|" D_SENSOR_COUNTER "2n|" D_SENSOR_COUNTER "3n|" D_SENSOR_COUNTER "4n|"
|
||||
D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|"
|
||||
D_SENSOR_DFR562 "|" D_SENSOR_SDS0X1_TX;
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
@ -225,6 +230,7 @@ enum SupportedModules {
|
||||
BLITZWOLF_BWSHP2,
|
||||
SHELLY1,
|
||||
SHELLY2,
|
||||
PHILIPS,
|
||||
MAXMODULE };
|
||||
|
||||
/********************************************************************************************/
|
||||
@ -242,7 +248,112 @@ typedef struct MYTMPLT {
|
||||
myio gp;
|
||||
} mytmplt;
|
||||
|
||||
const uint8_t kNiceList[MAXMODULE] PROGMEM = {
|
||||
const uint8_t kGpioNiceList[GPIO_SENSOR_END] PROGMEM = {
|
||||
GPIO_NONE, // Not used
|
||||
GPIO_KEY1, // Buttons
|
||||
GPIO_KEY1_NP,
|
||||
GPIO_KEY2,
|
||||
GPIO_KEY2_NP,
|
||||
GPIO_KEY3,
|
||||
GPIO_KEY3_NP,
|
||||
GPIO_KEY4,
|
||||
GPIO_KEY4_NP,
|
||||
GPIO_SWT1, // User connected external switches
|
||||
GPIO_SWT1_NP,
|
||||
GPIO_SWT2,
|
||||
GPIO_SWT2_NP,
|
||||
GPIO_SWT3,
|
||||
GPIO_SWT3_NP,
|
||||
GPIO_SWT4,
|
||||
GPIO_SWT4_NP,
|
||||
GPIO_SWT5,
|
||||
GPIO_SWT5_NP,
|
||||
GPIO_SWT6,
|
||||
GPIO_SWT6_NP,
|
||||
GPIO_SWT7,
|
||||
GPIO_SWT7_NP,
|
||||
GPIO_SWT8,
|
||||
GPIO_SWT8_NP,
|
||||
GPIO_REL1, // Relays
|
||||
GPIO_REL1_INV,
|
||||
GPIO_REL2,
|
||||
GPIO_REL2_INV,
|
||||
GPIO_REL3,
|
||||
GPIO_REL3_INV,
|
||||
GPIO_REL4,
|
||||
GPIO_REL4_INV,
|
||||
GPIO_REL5,
|
||||
GPIO_REL5_INV,
|
||||
GPIO_REL6,
|
||||
GPIO_REL6_INV,
|
||||
GPIO_REL7,
|
||||
GPIO_REL7_INV,
|
||||
GPIO_REL8,
|
||||
GPIO_REL8_INV,
|
||||
GPIO_LED1, // Leds
|
||||
GPIO_LED1_INV,
|
||||
GPIO_LED2,
|
||||
GPIO_LED2_INV,
|
||||
GPIO_LED3,
|
||||
GPIO_LED3_INV,
|
||||
GPIO_LED4,
|
||||
GPIO_LED4_INV,
|
||||
GPIO_PWM1, // RGB Red or C Cold White
|
||||
GPIO_PWM1_INV,
|
||||
GPIO_PWM2, // RGB Green or CW Warm White
|
||||
GPIO_PWM2_INV,
|
||||
GPIO_PWM3, // RGB Blue
|
||||
GPIO_PWM3_INV,
|
||||
GPIO_PWM4, // RGBW (Cold) White
|
||||
GPIO_PWM4_INV,
|
||||
GPIO_PWM5, // RGBCW Warm White
|
||||
GPIO_PWM5_INV,
|
||||
GPIO_CNTR1, // Counters
|
||||
GPIO_CNTR1_NP,
|
||||
GPIO_CNTR2,
|
||||
GPIO_CNTR2_NP,
|
||||
GPIO_CNTR3,
|
||||
GPIO_CNTR3_NP,
|
||||
GPIO_CNTR4,
|
||||
GPIO_CNTR4_NP,
|
||||
GPIO_I2C_SCL, // I2C SCL
|
||||
GPIO_I2C_SDA, // I2C SDA
|
||||
GPIO_SPI_CS, // SPI Chip Select
|
||||
GPIO_SPI_DC, // SPI Data Direction
|
||||
GPIO_BACKLIGHT, // Display backlight control
|
||||
GPIO_DHT11, // DHT11
|
||||
GPIO_DHT22, // DHT21, DHT22, AM2301, AM2302, AM2321
|
||||
GPIO_SI7021, // iTead SI7021
|
||||
GPIO_DSB, // Single wire DS18B20 or DS18S20
|
||||
GPIO_WS2812, // WS2812 Led string
|
||||
GPIO_IRSEND, // IR remote
|
||||
GPIO_IRRECV, // IR receiver
|
||||
GPIO_SR04_TRIG, // SR04 Trigger pin
|
||||
GPIO_SR04_ECHO, // SR04 Echo pin
|
||||
GPIO_TM16CLK, // TM1638 Clock
|
||||
GPIO_TM16DIO, // TM1638 Data I/O
|
||||
GPIO_TM16STB, // TM1638 Strobe
|
||||
GPIO_SBR_TX, // Serial Bridge Serial interface
|
||||
GPIO_SBR_RX, // Serial Bridge Serial interface
|
||||
GPIO_MHZ_TXD, // MH-Z19 Serial interface
|
||||
GPIO_MHZ_RXD, // MH-Z19 Serial interface
|
||||
GPIO_SAIR_TX, // SenseAir Serial interface
|
||||
GPIO_SAIR_RX, // SenseAir Serial interface
|
||||
GPIO_SDS0X1_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_RF,
|
||||
SONOFF_TH,
|
||||
@ -289,7 +400,8 @@ const uint8_t kNiceList[MAXMODULE] PROGMEM = {
|
||||
KMC_70011,
|
||||
AILIGHT,
|
||||
WEMOS,
|
||||
WITTY
|
||||
WITTY,
|
||||
PHILIPS
|
||||
};
|
||||
|
||||
// Default module settings
|
||||
@ -550,8 +662,8 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
||||
{ "H801", // Lixada H801 Wifi (ESP8266)
|
||||
GPIO_USER, // GPIO00 E-FW Button
|
||||
GPIO_LED1, // GPIO01 Green LED
|
||||
GPIO_TXD, // GPIO02 RX - Pin next to TX on the PCB
|
||||
GPIO_RXD, // GPIO03 TX - Pin next to GND on the PCB
|
||||
GPIO_USER, // GPIO02 TX and Optional sensor - Pin next to TX on the PCB
|
||||
GPIO_USER, // GPIO03 RX and Optional sensor - Pin next to GND on the PCB
|
||||
GPIO_PWM5, // GPIO04 W2 - PWM5
|
||||
GPIO_LED2_INV, // GPIO05 Red LED
|
||||
0, 0, 0, 0, 0, 0, // Flash connection
|
||||
@ -923,16 +1035,24 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
||||
},
|
||||
{ "Shelly 2", // Shelly2 (ESP8266 - 2MB) - https://shelly.cloud/shelly2/
|
||||
0,
|
||||
GPIO_MCP39_RX, // GPIO01 MCP39F501 Serial input
|
||||
GPIO_TXD, // GPIO01 MCP39F501 Serial input
|
||||
0,
|
||||
GPIO_MCP39_TX, // GPIO03 MCP39F501 Serial output
|
||||
GPIO_RXD, // GPIO03 MCP39F501 Serial output
|
||||
GPIO_REL1, // GPIO04
|
||||
GPIO_REL2, // GPIO05
|
||||
0, 0, 0, 0, 0, 0, // Flash connection
|
||||
GPIO_SWT1_NP, // GPIO12
|
||||
0,
|
||||
GPIO_SWT2_NP, // GPIO14
|
||||
GPIO_MCP39_RST, // GPIO15 MCP39F501 Reset
|
||||
0, // GPIO15 MCP39F501 Reset
|
||||
0, 0
|
||||
},
|
||||
{ "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
|
||||
}
|
||||
};
|
||||
@ -1002,7 +1122,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
||||
0, 0
|
||||
}
|
||||
|
||||
{ "Ledunia", // Ledunia (ESP8266) - http://ledunia.de/
|
||||
{ "Ledunia", // Ledunia (ESP8266 - 32MB) - http://ledunia.de/
|
||||
GPIO_USER, // GPIO00 (D0)
|
||||
GPIO_USER, // GPIO01 (D7) Serial RXD
|
||||
GPIO_USER, // GPIO02 (D2)
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef _SONOFF_VERSION_H_
|
||||
#define _SONOFF_VERSION_H_
|
||||
|
||||
#define VERSION 0x06020002
|
||||
#define VERSION 0x06020103
|
||||
|
||||
#define D_PROGRAMNAME "Sonoff-Tasmota"
|
||||
#define D_AUTHOR "Theo Arends"
|
||||
|
@ -143,7 +143,7 @@ char* subStr(char* dest, char* str, const char *delim, int index)
|
||||
int i;
|
||||
|
||||
// Since strtok consumes the first arg, make a copy
|
||||
strlcpy(dest, str, strlen(str));
|
||||
strncpy(dest, str, strlen(str)+1);
|
||||
for (i = 1, act = dest; i <= index; i++, act = NULL) {
|
||||
sub = strtok_r(act, delim, &ptr);
|
||||
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_RX == val) { return true; }
|
||||
#endif
|
||||
#ifndef USE_PZEM2
|
||||
if (GPIO_PZEM2_TX == val) { return true; }
|
||||
if (GPIO_PZEM2_RX == val) { return true; }
|
||||
#endif
|
||||
#ifndef USE_SENSEAIR
|
||||
if (GPIO_SAIR_TX == val) { return true; }
|
||||
if (GPIO_SAIR_RX == val) { return true; }
|
||||
@ -624,7 +628,8 @@ boolean GetUsedInModule(byte val, uint8_t *arr)
|
||||
if (GPIO_PMS5003 == val) { return true; }
|
||||
#endif
|
||||
#ifndef USE_NOVA_SDS
|
||||
if (GPIO_SDS0X1 == val) { return true; }
|
||||
if (GPIO_SDS0X1_TX == val) { return true; }
|
||||
if (GPIO_SDS0X1_RX == val) { return true; }
|
||||
#endif
|
||||
#ifndef USE_SERIAL_BRIDGE
|
||||
if (GPIO_SBR_TX == val) { return true; }
|
||||
@ -931,8 +936,20 @@ void GetFeatures()
|
||||
#ifdef USE_DISPLAY_SH1106
|
||||
feature_drv2 |= 0x00001000; // xdsp_06_sh1106.ino
|
||||
#endif
|
||||
#ifdef USE_MP3_PLAYER
|
||||
feature_drv2 |= 0x00002000; // xdrv_14_mp3.ino
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef NO_EXTRA_4K_HEAP
|
||||
feature_drv2 |= 0x00800000; // sonoff_post.h
|
||||
#endif
|
||||
#ifdef VTABLES_IN_IRAM
|
||||
feature_drv2 |= 0x01000000; // platformio.ini
|
||||
#endif
|
||||
#ifdef VTABLES_IN_DRAM
|
||||
feature_drv2 |= 0x02000000; // platformio.ini
|
||||
#endif
|
||||
#ifdef VTABLES_IN_FLASH
|
||||
feature_drv2 |= 0x04000000; // platformio.ini
|
||||
#endif
|
||||
@ -965,7 +982,7 @@ void GetFeatures()
|
||||
feature_sns1 |= 0x00000004; // xdrv_03_energy.ino
|
||||
#endif
|
||||
#ifdef USE_PZEM004T
|
||||
feature_sns1 |= 0x00000008; // xdrv_03_energy.ino
|
||||
feature_sns1 |= 0x00000008; // xnrg_03_pzem004t.ino
|
||||
#endif
|
||||
#ifdef USE_DS18B20
|
||||
feature_sns1 |= 0x00000010; // xsns_05_ds18b20.ino
|
||||
@ -1074,6 +1091,19 @@ void GetFeatures()
|
||||
#ifdef USE_MCP230xx_DISPLAYOUTPUT
|
||||
feature_sns2 |= 0x00000020; // xsns_29_mcp230xx.ino
|
||||
#endif
|
||||
#ifdef USE_HLW8012
|
||||
feature_sns2 |= 0x00000040; // xnrg_01_hlw8012.ino
|
||||
#endif
|
||||
#ifdef USE_CSE7766
|
||||
feature_sns2 |= 0x00000080; // xnrg_02_cse7766.ino
|
||||
#endif
|
||||
#ifdef USE_MCP39F501
|
||||
feature_sns2 |= 0x00000100; // xnrg_04_mcp39f501.ino
|
||||
#endif
|
||||
#ifdef USE_PZEM2
|
||||
feature_sns2 |= 0x00000200; // xnrg_05_pzem2.ino
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
@ -1802,26 +1832,23 @@ String GetBuildDateAndTime()
|
||||
return String(bdt);
|
||||
}
|
||||
|
||||
/*
|
||||
* timestamps in https://en.wikipedia.org/wiki/ISO_8601 format
|
||||
*
|
||||
* DT_UTC - current data and time in Greenwich, England (aka GMT)
|
||||
* DT_LOCAL - current date and time taking timezone into account
|
||||
* DT_RESTART - the date and time this device last started, in local timezone
|
||||
*
|
||||
* Format:
|
||||
* "2017-03-07T11:08:02-07:00" - if DT_LOCAL and SetOption52 = 1
|
||||
* "2017-03-07T11:08:02" - otherwise
|
||||
*/
|
||||
String GetDateAndTime(byte time_type)
|
||||
{
|
||||
// enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART, DT_UPTIME };
|
||||
// "2017-03-07T11:08:02" - ISO8601:2004
|
||||
char dt[21];
|
||||
// "2017-03-07T11:08:02-07:00" - ISO8601:2004
|
||||
char dt[27];
|
||||
TIME_T tmpTime;
|
||||
|
||||
if (DT_UPTIME == time_type) {
|
||||
if (restart_time) {
|
||||
BreakTime(utc_time - restart_time, tmpTime);
|
||||
} else {
|
||||
BreakTime(uptime, tmpTime);
|
||||
}
|
||||
// "P128DT14H35M44S" - ISO8601:2004 - https://en.wikipedia.org/wiki/ISO_8601 Durations
|
||||
// snprintf_P(dt, sizeof(dt), PSTR("P%dDT%02dH%02dM%02dS"), ut.days, ut.hour, ut.minute, ut.second);
|
||||
// "128 14:35:44" - OpenVMS
|
||||
// "128T14:35:44" - Tasmota
|
||||
snprintf_P(dt, sizeof(dt), PSTR("%dT%02d:%02d:%02d"),
|
||||
tmpTime.days, tmpTime.hour, tmpTime.minute, tmpTime.second);
|
||||
} else {
|
||||
switch (time_type) {
|
||||
case DT_UTC:
|
||||
BreakTime(utc_time, tmpTime);
|
||||
@ -1837,9 +1864,14 @@ String GetDateAndTime(byte time_type)
|
||||
default:
|
||||
tmpTime = RtcTime;
|
||||
}
|
||||
|
||||
snprintf_P(dt, sizeof(dt), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
|
||||
tmpTime.year, tmpTime.month, tmpTime.day_of_month, tmpTime.hour, tmpTime.minute, tmpTime.second);
|
||||
|
||||
if (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);
|
||||
}
|
||||
|
||||
|
@ -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 USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
|
||||
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
|
||||
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||
#define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes
|
||||
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
|
||||
//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
|
||||
#define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud)
|
||||
//#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code)
|
||||
#define SDM630_SPEED 9600 // SDM630-Modbus RS485 serial speed (default: 9600 baud)
|
||||
//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
|
||||
// #define MP3_VOLUME 10 // Set the startup volume on init, the range can be 0..30(max)
|
||||
|
||||
// Power monitoring sensors -----------------------
|
||||
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||
#define USE_PZEM2 // Add support for PZEM003,014,016,017 Energy monitor (+1k1 code)
|
||||
|
||||
// -- Low level interface devices -----------------
|
||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
||||
|
@ -380,9 +380,7 @@ void MqttConnected()
|
||||
MqttPublishPowerState(i);
|
||||
if (SONOFF_IFAN02 == Settings.module) { break; } // Only report status of light relay
|
||||
}
|
||||
if (Settings.tele_period) {
|
||||
tele_period = Settings.tele_period -9;
|
||||
}
|
||||
if (Settings.tele_period) { tele_period = Settings.tele_period -9; } // Enable TelePeriod in 9 seconds
|
||||
rules_flag.system_boot = 1;
|
||||
XdrvCall(FUNC_MQTT_INIT);
|
||||
}
|
||||
@ -718,7 +716,6 @@ bool MqttCommand()
|
||||
}
|
||||
else if (CMND_BUTTONRETAIN == command_code) {
|
||||
if ((payload >= 0) && (payload <= 1)) {
|
||||
strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic));
|
||||
if (!payload) {
|
||||
for(i = 1; i <= MAX_KEYS; i++) {
|
||||
SendKey(0, i, 9); // Clear MQTT retain in broker
|
||||
@ -730,7 +727,6 @@ bool MqttCommand()
|
||||
}
|
||||
else if (CMND_SWITCHRETAIN == command_code) {
|
||||
if ((payload >= 0) && (payload <= 1)) {
|
||||
strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic));
|
||||
if (!payload) {
|
||||
for(i = 1; i <= MAX_SWITCHES; i++) {
|
||||
SendKey(1, i, 9); // Clear MQTT retain in broker
|
||||
|
@ -768,7 +768,7 @@ void HandleModuleConfiguration()
|
||||
page.replace(F("{v}"), FPSTR(S_CONFIGURE_MODULE));
|
||||
page += FPSTR(HTTP_SCRIPT_MODULE1);
|
||||
for (byte i = 0; i < MAXMODULE; i++) {
|
||||
midx = pgm_read_byte(kNiceList + i);
|
||||
midx = pgm_read_byte(kModuleNiceList + i);
|
||||
snprintf_P(stemp, sizeof(stemp), kModules[midx].name);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, midx, midx +1, stemp);
|
||||
page += mqtt_data;
|
||||
@ -779,10 +779,10 @@ void HandleModuleConfiguration()
|
||||
|
||||
mytmplt cmodule;
|
||||
memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule));
|
||||
|
||||
for (byte j = 0; j < GPIO_SENSOR_END; j++) {
|
||||
if (!GetUsedInModule(j, cmodule.gp.io)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, j, j, GetTextIndexed(stemp, sizeof(stemp), j, kSensorNames));
|
||||
midx = pgm_read_byte(kGpioNiceList + j);
|
||||
if (!GetUsedInModule(midx, cmodule.gp.io)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SCRIPT_MODULE2, midx, midx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames));
|
||||
page += mqtt_data;
|
||||
}
|
||||
}
|
||||
@ -805,7 +805,7 @@ void HandleModuleConfiguration()
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) {
|
||||
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<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);
|
||||
page += mqtt_data;
|
||||
}
|
||||
@ -1193,7 +1193,7 @@ void HandleSaveSettings()
|
||||
if (Settings.last_module != new_module) {
|
||||
Settings.my_gp.io[i] = 0;
|
||||
} else {
|
||||
if (GPIO_USER == cmodule.gp.io[i]) {
|
||||
if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), i);
|
||||
WebGetArg(stemp, tmp, sizeof(tmp));
|
||||
Settings.my_gp.io[i] = (!strlen(tmp)) ? 0 : atoi(tmp);
|
||||
@ -1292,7 +1292,7 @@ void HandleInformation()
|
||||
func += F(D_PROGRAM_VERSION "}2"); func += my_version;
|
||||
func += F("}1" D_BUILD_DATE_AND_TIME "}2"); func += GetBuildDateAndTime();
|
||||
func += F("}1" D_CORE_AND_SDK_VERSION "}2" ARDUINO_ESP8266_RELEASE "/"); func += String(ESP.getSdkVersion());
|
||||
func += F("}1" D_UPTIME "}2"); func += GetDateAndTime(DT_UPTIME);
|
||||
func += F("}1" D_UPTIME "}2"); func += GetUptime();
|
||||
snprintf_P(stopic, sizeof(stopic), PSTR(" at %X"), GetSettingsAddress());
|
||||
func += F("}1" D_FLASH_WRITE_COUNT "}2"); func += String(Settings.save_flag); func += stopic;
|
||||
func += F("}1" D_BOOT_COUNT "}2"); func += String(Settings.bootcount);
|
||||
|
@ -44,10 +44,13 @@ const char kEnergyCommands[] PROGMEM =
|
||||
float energy_voltage = 0; // 123.1 V
|
||||
float energy_current = 0; // 123.123 A
|
||||
float energy_power = 0; // 123.1 W
|
||||
float energy_power_factor = 0; // 0.12
|
||||
float energy_power_factor = NAN; // 0.12
|
||||
int energy_calc_power_factor = 0; // Do not calculate power factor from data
|
||||
float energy_frequency = NAN; // 123.1 Hz
|
||||
float energy_start = 0; // 12345.12345 kWh total previous
|
||||
|
||||
float energy_daily = 0; // 123.123 kWh
|
||||
float energy_total = 0; // 12345.12345 kWh
|
||||
float energy_start = 0; // 12345.12345 kWh total previous
|
||||
unsigned long energy_kWhtoday_delta = 0; // 1212312345 Wh 10^-5 (deca micro Watt hours) - Overflows to energy_kWhtoday (HLW and CSE only)
|
||||
unsigned long energy_kWhtoday; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = energy_daily
|
||||
unsigned long energy_period = 0; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = energy_daily
|
||||
@ -122,6 +125,7 @@ void Energy200ms()
|
||||
|
||||
XnrgCall(FUNC_EVERY_200_MSECOND);
|
||||
|
||||
if (energy_calc_power_factor) {
|
||||
float power_factor = 0;
|
||||
if (energy_voltage && energy_current && energy_power) {
|
||||
power_factor = energy_power / (energy_voltage * energy_current);
|
||||
@ -129,6 +133,7 @@ void Energy200ms()
|
||||
}
|
||||
energy_power_factor = power_factor;
|
||||
}
|
||||
}
|
||||
|
||||
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}}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str());
|
||||
int tele_period_save = tele_period;
|
||||
tele_period = 2;
|
||||
EnergyShow(1);
|
||||
tele_period = tele_period_save;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
|
||||
energy_power_delta = 0;
|
||||
@ -536,11 +544,18 @@ void EnergySnsInit()
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_ENERGY_SNS[] PROGMEM = "%s"
|
||||
const char HTTP_ENERGY_SNS1[] PROGMEM = "%s"
|
||||
"{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
|
||||
"{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
|
||||
"{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}"
|
||||
"{s}" D_POWER_FACTOR "{m}%s{e}"
|
||||
"{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}";
|
||||
|
||||
const char HTTP_ENERGY_SNS2[] PROGMEM = "%s"
|
||||
"{s}" D_POWER_FACTOR "{m}%s{e}";
|
||||
|
||||
const char HTTP_ENERGY_SNS3[] PROGMEM = "%s"
|
||||
"{s}" D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}";
|
||||
|
||||
const char HTTP_ENERGY_SNS4[] PROGMEM = "%s"
|
||||
"{s}" D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
|
||||
"{s}" D_ENERGY_YESTERDAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
|
||||
"{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
@ -554,31 +569,43 @@ void EnergyShow(boolean json)
|
||||
char energy_power_chr[10];
|
||||
char energy_voltage_chr[10];
|
||||
char energy_current_chr[10];
|
||||
char energy_frequency_chr[10];
|
||||
char energy_power_factor_chr[10];
|
||||
char energy_yesterday_chr[10];
|
||||
char speriod[20];
|
||||
char spfactor[20];
|
||||
char sfrequency[20];
|
||||
|
||||
bool show_energy_period = (0 == tele_period);
|
||||
|
||||
dtostrfd(energy_power, Settings.flag2.wattage_resolution, energy_power_chr);
|
||||
dtostrfd(energy_voltage, Settings.flag2.voltage_resolution, energy_voltage_chr);
|
||||
dtostrfd(energy_current, Settings.flag2.current_resolution, energy_current_chr);
|
||||
dtostrfd(energy_total, Settings.flag2.energy_resolution, energy_total_chr);
|
||||
dtostrfd(energy_daily, Settings.flag2.energy_resolution, energy_daily_chr);
|
||||
dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr);
|
||||
|
||||
float energy = 0;
|
||||
if (show_energy_period) {
|
||||
if (energy_period) energy = (float)(energy_kWhtoday - energy_period) / 100;
|
||||
energy_period = energy_kWhtoday;
|
||||
dtostrfd(energy, Settings.flag2.wattage_resolution, energy_period_chr);
|
||||
snprintf_P(speriod, sizeof(speriod), PSTR(",\"" D_JSON_PERIOD "\":%s"), energy_period_chr);
|
||||
}
|
||||
if (!isnan(energy_frequency)) {
|
||||
dtostrfd(energy_frequency, Settings.flag2.frequency_resolution, energy_frequency_chr);
|
||||
snprintf_P(sfrequency, sizeof(sfrequency), PSTR(",\"" D_JSON_FREQUENCY "\":%s"), energy_frequency_chr);
|
||||
}
|
||||
if (!isnan(energy_power_factor)) {
|
||||
dtostrfd(energy_power_factor, 2, energy_power_factor_chr);
|
||||
snprintf_P(spfactor, sizeof(spfactor), PSTR(",\"" D_JSON_POWERFACTOR "\":%s"), energy_power_factor_chr);
|
||||
}
|
||||
|
||||
dtostrfd(energy_total, Settings.flag2.energy_resolution, energy_total_chr);
|
||||
dtostrfd(energy_daily, Settings.flag2.energy_resolution, energy_daily_chr);
|
||||
dtostrfd(energy, Settings.flag2.wattage_resolution, energy_period_chr);
|
||||
dtostrfd(energy_power, Settings.flag2.wattage_resolution, energy_power_chr);
|
||||
dtostrfd(energy_voltage, Settings.flag2.voltage_resolution, energy_voltage_chr);
|
||||
dtostrfd(energy_current, Settings.flag2.current_resolution, energy_current_chr);
|
||||
dtostrfd(energy_power_factor, 2, energy_power_factor_chr);
|
||||
dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr);
|
||||
|
||||
if (json) {
|
||||
snprintf_P(speriod, sizeof(speriod), PSTR(",\"" D_JSON_PERIOD "\":%s"), energy_period_chr);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s%s,\"" D_JSON_POWERUSAGE "\":%s,\"" D_JSON_POWERFACTOR "\":%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s}"),
|
||||
mqtt_data, energy_total_chr, energy_yesterday_chr, energy_daily_chr, (show_energy_period) ? speriod : "", energy_power_chr, energy_power_factor_chr, energy_voltage_chr, energy_current_chr);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s%s,\""
|
||||
D_JSON_POWERUSAGE "\":%s%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s%s}"),
|
||||
mqtt_data, energy_total_chr, energy_yesterday_chr, energy_daily_chr, (show_energy_period) ? speriod : "",
|
||||
energy_power_chr, (!isnan(energy_power_factor)) ? spfactor : "", energy_voltage_chr, energy_current_chr, (!isnan(energy_frequency)) ? sfrequency : "");
|
||||
#ifdef USE_DOMOTICZ
|
||||
if (show_energy_period) { // Only send if telemetry
|
||||
dtostrfd(energy_total * 1000, 1, energy_total_chr);
|
||||
@ -592,7 +619,7 @@ void EnergyShow(boolean json)
|
||||
KnxSensor(KNX_ENERGY_VOLTAGE, energy_voltage);
|
||||
KnxSensor(KNX_ENERGY_CURRENT, energy_current);
|
||||
KnxSensor(KNX_ENERGY_POWER, energy_power);
|
||||
KnxSensor(KNX_ENERGY_POWERFACTOR, energy_power_factor);
|
||||
if (!isnan(energy_power_factor)) { KnxSensor(KNX_ENERGY_POWERFACTOR, energy_power_factor); }
|
||||
KnxSensor(KNX_ENERGY_DAILY, energy_daily);
|
||||
KnxSensor(KNX_ENERGY_TOTAL, energy_total);
|
||||
KnxSensor(KNX_ENERGY_START, energy_start);
|
||||
@ -600,7 +627,10 @@ void EnergyShow(boolean json)
|
||||
#endif // USE_KNX
|
||||
#ifdef USE_WEBSERVER
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS, mqtt_data, energy_voltage_chr, energy_current_chr, energy_power_chr, energy_power_factor_chr, energy_daily_chr, energy_yesterday_chr, energy_total_chr);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS1, mqtt_data, energy_voltage_chr, energy_current_chr, energy_power_chr);
|
||||
if (!isnan(energy_power_factor)) { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS2, mqtt_data, energy_power_factor_chr); }
|
||||
if (!isnan(energy_frequency)) { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS3, mqtt_data, energy_frequency_chr); }
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS4, mqtt_data, energy_daily_chr, energy_yesterday_chr, energy_total_chr);
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,12 @@ struct LRgbColor {
|
||||
const LRgbColor kFixedColor[MAX_FIXED_COLOR] PROGMEM =
|
||||
{ 255,0,0, 0,255,0, 0,0,255, 228,32,0, 0,228,32, 0,32,228, 188,64,0, 0,160,96, 160,32,240, 255,255,0, 255,0,170, 255,255,255 };
|
||||
|
||||
struct LWColor {
|
||||
uint8_t W;
|
||||
};
|
||||
#define MAX_FIXED_WHITE 4
|
||||
const LWColor kFixedWhite[MAX_FIXED_WHITE] PROGMEM = { 0, 255, 128, 32 };
|
||||
|
||||
struct LCwColor {
|
||||
uint8_t C, W;
|
||||
};
|
||||
@ -421,6 +427,11 @@ void LightSetColorTemp(uint16_t ct)
|
||||
}
|
||||
uint16_t icold = (100 * (347 - my_ct)) / 136;
|
||||
uint16_t iwarm = (100 * my_ct) / 136;
|
||||
if (PHILIPS == Settings.module) {
|
||||
// Xiaomi Philips bulbs follow a different scheme:
|
||||
// channel 0=intensity, channel2=temperature
|
||||
Settings.light_color[1] = (uint8_t)icold;
|
||||
} else
|
||||
if (LST_RGBWC == light_subtype) {
|
||||
Settings.light_color[0] = 0;
|
||||
Settings.light_color[1] = 0;
|
||||
@ -452,6 +463,15 @@ void LightSetDimmer(uint8_t myDimmer)
|
||||
{
|
||||
float temp;
|
||||
|
||||
if (PHILIPS == Settings.module) {
|
||||
// Xiaomi Philips bulbs use two PWM channels with a different scheme:
|
||||
float dimmer = 100 / (float)myDimmer;
|
||||
temp = (float)Settings.light_color[0] / dimmer; // channel 1 is intensity
|
||||
light_current_color[0] = (uint8_t)temp;
|
||||
temp = (float)Settings.light_color[1]; // channel 2 is temperature
|
||||
light_current_color[1] = (uint8_t)temp;
|
||||
return;
|
||||
}
|
||||
if (LT_PWM1 == light_type) {
|
||||
Settings.light_color[0] = 255; // One PWM channel only supports Dimmer but needs max color
|
||||
}
|
||||
@ -551,7 +571,7 @@ void LightState(uint8_t append)
|
||||
if (light_subtype > LST_SINGLE) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor));
|
||||
// Add status for HSB
|
||||
LightGetHsb(&hsb[0],&hsb[1],&hsb[2]);
|
||||
LightGetHsb(&hsb[0],&hsb[1],&hsb[2], false);
|
||||
// Scale these percentages up to the numbers expected by the client
|
||||
h = round(hsb[0] * 360);
|
||||
s = round(hsb[1] * 100);
|
||||
@ -905,13 +925,15 @@ void LightHsbToRgb()
|
||||
light_current_color[0] = (uint8_t)(r * 255.0f);
|
||||
light_current_color[1] = (uint8_t)(g * 255.0f);
|
||||
light_current_color[2] = (uint8_t)(b * 255.0f);
|
||||
light_current_color[3] = 0;
|
||||
light_current_color[4] = 0;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void LightGetHsb(float *hue, float *sat, float *bri)
|
||||
void LightGetHsb(float *hue, float *sat, float *bri, bool gotct)
|
||||
{
|
||||
if (light_subtype > LST_COLDWARM) {
|
||||
if (light_subtype > LST_COLDWARM && !gotct) {
|
||||
LightRgbToHsb();
|
||||
*hue = light_hue;
|
||||
*sat = light_saturation;
|
||||
@ -919,16 +941,19 @@ void LightGetHsb(float *hue, float *sat, float *bri)
|
||||
} else {
|
||||
*hue = 0;
|
||||
*sat = 0;
|
||||
// *bri = (2.54f * (float)Settings.light_dimmer);
|
||||
*bri = (0.01f * (float)Settings.light_dimmer);
|
||||
}
|
||||
}
|
||||
|
||||
void LightSetHsb(float hue, float sat, float bri, uint16_t ct)
|
||||
void LightSetHsb(float hue, float sat, float bri, uint16_t ct, bool gotct)
|
||||
{
|
||||
if (light_subtype > LST_COLDWARM) {
|
||||
if ((LST_RGBWC == light_subtype) && (ct > 0)) {
|
||||
if ((LST_RGBWC == light_subtype) && (gotct)) {
|
||||
uint8_t tmp = (uint8_t)(bri * 100);
|
||||
Settings.light_dimmer = tmp;
|
||||
if (ct > 0) {
|
||||
LightSetColorTemp(ct);
|
||||
}
|
||||
} else {
|
||||
light_hue = hue;
|
||||
light_saturation = sat;
|
||||
@ -1006,7 +1031,11 @@ boolean LightColorEntry(char *buffer, uint8_t buffer_length)
|
||||
entry_type = 1; // Hexadecimal
|
||||
}
|
||||
else if ((value > 199) && (value <= 199 + MAX_FIXED_COLD_WARM)) {
|
||||
if (LST_COLDWARM == light_subtype) {
|
||||
if (LST_RGBW == light_subtype) {
|
||||
memcpy_P(&light_entry_color[3], &kFixedWhite[value -200], 1);
|
||||
entry_type = 1; // Hexadecimal
|
||||
}
|
||||
else if (LST_COLDWARM == light_subtype) {
|
||||
memcpy_P(&light_entry_color, &kFixedColdWarm[value -200], 2);
|
||||
entry_type = 1; // Hexadecimal
|
||||
}
|
||||
@ -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)
|
||||
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[1] = round(hsb[1] * 100);
|
||||
HSB[2] = round(hsb[2] * 100);
|
||||
@ -1120,7 +1149,8 @@ boolean LightCommand()
|
||||
LightSetHsb(( (HSB[0]>360) ? (HSB[0] % 360) : HSB[0] ) /360.0,
|
||||
( (HSB[1]>100) ? (HSB[1] % 100) : HSB[1] ) /100.0,
|
||||
( (HSB[2]>100) ? (HSB[2] % 100) : HSB[2] ) /100.0,
|
||||
0);
|
||||
0,
|
||||
false);
|
||||
}
|
||||
} else {
|
||||
LightState(0);
|
||||
|
@ -426,7 +426,7 @@ void RulesEvery100ms()
|
||||
{
|
||||
if (Settings.rule_enabled) { // Any rule enabled
|
||||
mqtt_data[0] = '\0';
|
||||
uint16_t tele_period_save = tele_period;
|
||||
int tele_period_save = tele_period;
|
||||
tele_period = 2; // Do not allow HA updates during next function call
|
||||
XsnsNextCall(FUNC_JSON_APPEND); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||
tele_period = tele_period_save;
|
||||
|
@ -1156,7 +1156,7 @@ boolean KnxCommand()
|
||||
else if (CMND_KNX_PA == command_code) {
|
||||
if (XdrvMailbox.data_len) {
|
||||
if (strstr(XdrvMailbox.data, ".")) { // Process parameter entry
|
||||
char sub_string[XdrvMailbox.data_len +1];
|
||||
char sub_string[XdrvMailbox.data_len];
|
||||
|
||||
int pa_area = atoi(subStr(sub_string, XdrvMailbox.data, ".", 1));
|
||||
int pa_line = atoi(subStr(sub_string, XdrvMailbox.data, ".", 2));
|
||||
@ -1183,7 +1183,7 @@ boolean KnxCommand()
|
||||
else if ((CMND_KNX_GA == command_code) && (index > 0) && (index <= MAX_KNX_GA)) {
|
||||
if (XdrvMailbox.data_len) {
|
||||
if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry
|
||||
char sub_string[XdrvMailbox.data_len +1];
|
||||
char sub_string[XdrvMailbox.data_len];
|
||||
|
||||
int ga_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
||||
int ga_area = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
@ -1232,7 +1232,7 @@ boolean KnxCommand()
|
||||
else if ((CMND_KNX_CB == command_code) && (index > 0) && (index <= MAX_KNX_CB)) {
|
||||
if (XdrvMailbox.data_len) {
|
||||
if (strstr(XdrvMailbox.data, ",")) { // Process parameter entry
|
||||
char sub_string[XdrvMailbox.data_len +1];
|
||||
char sub_string[XdrvMailbox.data_len];
|
||||
|
||||
int cb_option = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1));
|
||||
int cb_area = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
|
@ -49,10 +49,10 @@ enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_E
|
||||
|
||||
enum DisplayInitModes { DISPLAY_INIT_MODE, DISPLAY_INIT_PARTIAL, DISPLAY_INIT_FULL };
|
||||
|
||||
enum DisplayCommands { CMND_DISP_MODEL, CMND_DISP_MODE, CMND_DISP_REFRESH, CMND_DISP_DIMMER, CMND_DISP_COLS, CMND_DISP_ROWS,
|
||||
enum DisplayCommands { CMND_DISPLAY, CMND_DISP_MODEL, CMND_DISP_MODE, CMND_DISP_REFRESH, CMND_DISP_DIMMER, CMND_DISP_COLS, CMND_DISP_ROWS,
|
||||
CMND_DISP_SIZE, CMND_DISP_FONT, CMND_DISP_ROTATE, CMND_DISP_TEXT, CMND_DISP_ADDRESS };
|
||||
const char kDisplayCommands[] PROGMEM =
|
||||
D_CMND_DISP_MODEL "|" D_CMND_DISP_MODE "|" D_CMND_DISP_REFRESH "|" D_CMND_DISP_DIMMER "|" D_CMND_DISP_COLS "|" D_CMND_DISP_ROWS "|"
|
||||
"|" D_CMND_DISP_MODEL "|" D_CMND_DISP_MODE "|" D_CMND_DISP_REFRESH "|" D_CMND_DISP_DIMMER "|" D_CMND_DISP_COLS "|" D_CMND_DISP_ROWS "|"
|
||||
D_CMND_DISP_SIZE "|" D_CMND_DISP_FONT "|" D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS ;
|
||||
|
||||
const char S_JSON_DISPLAY_COMMAND_VALUE[] PROGMEM = "{\"" D_CMND_DISPLAY "%s\":\"%s\"}";
|
||||
@ -626,11 +626,24 @@ void DisplayLogBufferInit()
|
||||
|
||||
DisplayReAllocLogBuffer();
|
||||
|
||||
char buffer[20];
|
||||
char buffer[40];
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_VERSION " %s"), my_version);
|
||||
DisplayLogBufferAdd(buffer);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR("Display mode %d"), Settings.display_mode);
|
||||
DisplayLogBufferAdd(buffer);
|
||||
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_CMND_HOSTNAME " %s"), my_hostname);
|
||||
DisplayLogBufferAdd(buffer);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), Settings.sta_ssid[Settings.sta_active]);
|
||||
DisplayLogBufferAdd(buffer);
|
||||
snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), WiFi.macAddress().c_str());
|
||||
DisplayLogBufferAdd(buffer);
|
||||
if (!global_state.wifi_down && (static_cast<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) {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
else if (CMND_DISPLAY == command_code) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DISPLAY "\":{\"" D_CMND_DISP_MODEL "\":%d,\"" D_CMND_DISP_MODE "\":%d,\"" D_CMND_DISP_DIMMER "\":%d,\""
|
||||
D_CMND_DISP_SIZE "\":%d,\"" D_CMND_DISP_FONT "\":%d,\"" D_CMND_DISP_ROTATE "\":%d,\"" D_CMND_DISP_REFRESH "\":%d,\"" D_CMND_DISP_COLS "\":[%d,%d],\"" D_CMND_DISP_ROWS "\":%d}}"),
|
||||
Settings.display_model, Settings.display_mode, Settings.display_dimmer, Settings.display_size, Settings.display_font, Settings.display_rotate, Settings.display_refresh,
|
||||
Settings.display_cols[0], Settings.display_cols[1], Settings.display_rows);
|
||||
}
|
||||
else if (CMND_DISP_MODEL == command_code) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < DISPLAY_MAX_DRIVERS)) {
|
||||
uint8_t last_display_model = Settings.display_model;
|
||||
@ -915,8 +934,8 @@ boolean DisplayCommand()
|
||||
if (last_display_mode && !Settings.display_mode) { // Switch to mode 0
|
||||
DisplayInit(DISPLAY_INIT_MODE);
|
||||
DisplayClear();
|
||||
}
|
||||
if (!last_display_mode && Settings.display_mode) { // Switch to non mode 0
|
||||
} else {
|
||||
// if (!last_display_mode && Settings.display_mode) { // Switch to non mode 0
|
||||
DisplayLogBufferInit();
|
||||
DisplayInit(DISPLAY_INIT_MODE);
|
||||
}
|
||||
|
196
sonoff/xdrv_14_mp3.ino
Normal file
196
sonoff/xdrv_14_mp3.ino
Normal 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
|
@ -182,6 +182,7 @@ void CpuLoadLoop()
|
||||
|
||||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1)
|
||||
// All version before core 2.4.2
|
||||
// https://github.com/esp8266/Arduino/issues/2557
|
||||
|
||||
extern "C" {
|
||||
#include <cont.h>
|
||||
@ -190,7 +191,6 @@ extern "C" {
|
||||
|
||||
void DebugFreeMem()
|
||||
{
|
||||
// https://github.com/esp8266/Arduino/issues/2557
|
||||
register uint32_t *sp asm("a1");
|
||||
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d, UnmodifiedStack %d (%s)"),
|
||||
@ -213,7 +213,6 @@ extern "C" {
|
||||
|
||||
void DebugFreeMem()
|
||||
{
|
||||
// https://github.com/esp8266/Arduino/issues/2557
|
||||
register uint32_t *sp asm("a1");
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"),
|
||||
|
@ -243,7 +243,8 @@ void MatrixPrintLog(uint8_t direction)
|
||||
uint8_t space = 0;
|
||||
uint8_t max_cols = (disp_log_buffer_cols < MTX_MAX_SCREEN_BUFFER) ? disp_log_buffer_cols : MTX_MAX_SCREEN_BUFFER;
|
||||
mtx_buffer[0] = '\0';
|
||||
for (byte i = 0; i < max_cols; i++) {
|
||||
uint8_t i = 0;
|
||||
while ((txt[i] != '\0') && (i < max_cols)) {
|
||||
if (txt[i] == ' ') {
|
||||
space++;
|
||||
} else {
|
||||
@ -252,6 +253,7 @@ void MatrixPrintLog(uint8_t direction)
|
||||
if (space < 2) {
|
||||
strncat(mtx_buffer, (const char*)txt +i, 1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "[%s]"), mtx_buffer);
|
||||
|
@ -188,7 +188,7 @@ boolean Xdsp05(byte function)
|
||||
if (FUNC_DISPLAY_INIT_DRIVER == function) {
|
||||
EpdInitDriver();
|
||||
}
|
||||
else if (XDSP_04 == Settings.display_model) {
|
||||
else if (XDSP_05 == Settings.display_model) {
|
||||
|
||||
if (!dsp_color) { dsp_color = COLORED; }
|
||||
|
||||
|
@ -41,26 +41,26 @@
|
||||
|
||||
#define HLW_POWER_PROBE_TIME 10 // Number of seconds to probe for power before deciding none used
|
||||
|
||||
static byte hlw_select_ui_flag;
|
||||
static byte hlw_ui_flag = 1;
|
||||
static byte hlw_load_off;
|
||||
static byte hlw_cf1_timer;
|
||||
static unsigned long hlw_cf_pulse_length;
|
||||
static unsigned long hlw_cf_pulse_last_time;
|
||||
static unsigned long hlw_cf1_pulse_length;
|
||||
static unsigned long hlw_cf1_pulse_last_time;
|
||||
static unsigned long hlw_cf1_summed_pulse_length;
|
||||
static unsigned long hlw_cf1_pulse_counter;
|
||||
static unsigned long hlw_cf1_voltage_pulse_length;
|
||||
static unsigned long hlw_cf1_current_pulse_length;
|
||||
static unsigned long hlw_energy_period_counter;
|
||||
byte hlw_select_ui_flag;
|
||||
byte hlw_ui_flag = 1;
|
||||
byte hlw_load_off;
|
||||
byte hlw_cf1_timer;
|
||||
unsigned long hlw_cf_pulse_length;
|
||||
unsigned long hlw_cf_pulse_last_time;
|
||||
unsigned long hlw_cf1_pulse_length;
|
||||
unsigned long hlw_cf1_pulse_last_time;
|
||||
unsigned long hlw_cf1_summed_pulse_length;
|
||||
unsigned long hlw_cf1_pulse_counter;
|
||||
unsigned long hlw_cf1_voltage_pulse_length;
|
||||
unsigned long hlw_cf1_current_pulse_length;
|
||||
unsigned long hlw_energy_period_counter;
|
||||
|
||||
static unsigned long hlw_power_ratio = 0;
|
||||
static unsigned long hlw_voltage_ratio = 0;
|
||||
static unsigned long hlw_current_ratio = 0;
|
||||
unsigned long hlw_power_ratio = 0;
|
||||
unsigned long hlw_voltage_ratio = 0;
|
||||
unsigned long hlw_current_ratio = 0;
|
||||
|
||||
static unsigned long hlw_cf1_voltage_max_pulse_counter;
|
||||
static unsigned long hlw_cf1_current_max_pulse_counter;
|
||||
unsigned long hlw_cf1_voltage_max_pulse_counter;
|
||||
unsigned long hlw_cf1_current_max_pulse_counter;
|
||||
|
||||
#ifndef USE_WS2812_DMA // Collides with Neopixelbus but solves exception
|
||||
void HlwCfInterrupt() ICACHE_RAM_ATTR;
|
||||
@ -217,6 +217,7 @@ void HlwDrvInit()
|
||||
{
|
||||
if (!energy_flg) {
|
||||
if ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99)) { // Sonoff Pow or any HLW8012 based device
|
||||
energy_calc_power_factor = 1; // Calculate power factor from data
|
||||
energy_flg = XNRG_01;
|
||||
}
|
||||
}
|
||||
|
@ -185,6 +185,7 @@ void CseDrvInit()
|
||||
if ((SONOFF_S31 == Settings.module) || (SONOFF_POW_R2 == Settings.module)) { // Sonoff S31 or Sonoff Pow R2
|
||||
baudrate = 4800;
|
||||
serial_config = SERIAL_8E1;
|
||||
energy_calc_power_factor = 1; // Calculate power factor from data
|
||||
energy_flg = XNRG_02;
|
||||
}
|
||||
}
|
||||
|
@ -215,6 +215,7 @@ void PzemDrvInit()
|
||||
{
|
||||
if (!energy_flg) {
|
||||
if ((pin[GPIO_PZEM_RX] < 99) && (pin[GPIO_PZEM_TX] < 99)) { // Any device with a Pzem004T
|
||||
energy_calc_power_factor = 1; // Calculate power factor from data
|
||||
energy_flg = XNRG_03;
|
||||
}
|
||||
}
|
||||
|
228
sonoff/xnrg_05_pzem2.ino
Normal file
228
sonoff/xnrg_05_pzem2.ino
Normal 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
|
@ -17,6 +17,9 @@
|
||||
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)
|
||||
/*********************************************************************************************\
|
||||
* 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
|
||||
ExecuteCommandPower(device, power, SRC_WEMO);
|
||||
}
|
||||
|
||||
}
|
||||
else if(request.indexOf(F("GetBinaryState")) > 0){
|
||||
state_xml.replace(F("Set"), F("Get"));
|
||||
@ -463,10 +465,10 @@ const char HUE_LIGHTS_STATUS_JSON[] PROGMEM =
|
||||
"\"hue\":{h},"
|
||||
"\"sat\":{s},"
|
||||
"\"xy\":[0.5, 0.5],"
|
||||
"\"ct\":500,"
|
||||
"\"ct\":{t},"
|
||||
"\"alert\":\"none\","
|
||||
"\"effect\":\"none\","
|
||||
"\"colormode\":\"hs\","
|
||||
"\"colormode\":\"{m}\","
|
||||
"\"reachable\":true}";
|
||||
const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM =
|
||||
",\"type\":\"Extended color light\","
|
||||
@ -560,20 +562,26 @@ void HueConfig(String *path)
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
|
||||
}
|
||||
|
||||
bool g_gotct = false;
|
||||
|
||||
void HueLightStatus1(byte device, String *response)
|
||||
{
|
||||
float hue = 0;
|
||||
float sat = 0;
|
||||
float bri = 0;
|
||||
uint16_t ct = 500;
|
||||
|
||||
if (light_type) {
|
||||
LightGetHsb(&hue, &sat, &bri);
|
||||
LightGetHsb(&hue, &sat, &bri, g_gotct);
|
||||
ct = LightGetColorTemp();
|
||||
}
|
||||
*response += FPSTR(HUE_LIGHTS_STATUS_JSON);
|
||||
response->replace("{state}", (power & (1 << (device-1))) ? "true" : "false");
|
||||
response->replace("{h}", String((uint16_t)(65535.0f * hue)));
|
||||
response->replace("{s}", String((uint8_t)(254.0f * sat)));
|
||||
response->replace("{b}", String((uint8_t)(254.0f * bri)));
|
||||
response->replace("{t}", String(ct));
|
||||
response->replace("{m}", g_gotct?"ct":"hs");
|
||||
}
|
||||
|
||||
void HueLightStatus2(byte device, String *response)
|
||||
@ -679,11 +687,13 @@ void HueLights(String *path)
|
||||
}
|
||||
|
||||
if (light_type) {
|
||||
LightGetHsb(&hue, &sat, &bri);
|
||||
LightGetHsb(&hue, &sat, &bri, g_gotct);
|
||||
}
|
||||
|
||||
if (hue_json.containsKey("bri")) {
|
||||
if (hue_json.containsKey("bri")) { // Brightness is a scale from 1 (the minimum the light is capable of) to 254 (the maximum). Note: a brightness of 1 is not off.
|
||||
tmp = hue_json["bri"];
|
||||
tmp = max(tmp, 1);
|
||||
tmp = min(tmp, 254);
|
||||
bri = (float)tmp / 254.0f;
|
||||
if (resp) {
|
||||
response += ",";
|
||||
@ -695,7 +705,7 @@ void HueLights(String *path)
|
||||
resp = true;
|
||||
change = true;
|
||||
}
|
||||
if (hue_json.containsKey("hue")) {
|
||||
if (hue_json.containsKey("hue")) { // The hue value is a wrapping value between 0 and 65535. Both 0 and 65535 are red, 25500 is green and 46920 is blue.
|
||||
tmp = hue_json["hue"];
|
||||
hue = (float)tmp / 65535.0f;
|
||||
if (resp) {
|
||||
@ -705,11 +715,14 @@ void HueLights(String *path)
|
||||
response.replace("{id", String(device));
|
||||
response.replace("{cm", "hue");
|
||||
response.replace("{re", String(tmp));
|
||||
g_gotct = false;
|
||||
resp = true;
|
||||
change = true;
|
||||
}
|
||||
if (hue_json.containsKey("sat")) {
|
||||
if (hue_json.containsKey("sat")) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white).
|
||||
tmp = hue_json["sat"];
|
||||
tmp = max(tmp, 0);
|
||||
tmp = min(tmp, 254);
|
||||
sat = (float)tmp / 254.0f;
|
||||
if (resp) {
|
||||
response += ",";
|
||||
@ -718,6 +731,8 @@ void HueLights(String *path)
|
||||
response.replace("{id", String(device));
|
||||
response.replace("{cm", "sat");
|
||||
response.replace("{re", String(tmp));
|
||||
g_gotct = false;
|
||||
resp = true;
|
||||
change = true;
|
||||
}
|
||||
if (hue_json.containsKey("ct")) { // Color temperature 153 (Cold) to 500 (Warm)
|
||||
@ -729,11 +744,12 @@ void HueLights(String *path)
|
||||
response.replace("{id", String(device));
|
||||
response.replace("{cm", "ct");
|
||||
response.replace("{re", String(ct));
|
||||
g_gotct = true;
|
||||
change = true;
|
||||
}
|
||||
if (change) {
|
||||
if (light_type) {
|
||||
LightSetHsb(hue, sat, bri, ct);
|
||||
LightSetHsb(hue, sat, bri, ct, g_gotct);
|
||||
}
|
||||
change = false;
|
||||
}
|
||||
|
@ -27,20 +27,59 @@
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
#ifndef WORKING_PERIOD
|
||||
#define WORKING_PERIOD 5
|
||||
#endif
|
||||
|
||||
TasmotaSerial *NovaSdsSerial;
|
||||
|
||||
uint8_t novasds_type = 1;
|
||||
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 {
|
||||
uint16_t pm100;
|
||||
uint16_t pm25;
|
||||
} 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()
|
||||
{
|
||||
if (! NovaSdsSerial->available()) return false;
|
||||
|
||||
NovaSdsSerial->write(novasds_querydata, sizeof(novasds_querydata));
|
||||
NovaSdsSerial->flush();
|
||||
|
||||
while ((NovaSdsSerial->peek() != 0xAA) && NovaSdsSerial->available()) {
|
||||
NovaSdsSerial->read();
|
||||
}
|
||||
@ -83,11 +122,14 @@ void NovaSdsSecond() // Every second
|
||||
void NovaSdsInit()
|
||||
{
|
||||
novasds_type = 0;
|
||||
if (pin[GPIO_SDS0X1] < 99) {
|
||||
NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1], -1, 1);
|
||||
if (pin[GPIO_SDS0X1_RX] < 99 && pin[GPIO_SDS0X1_TX] < 99) {
|
||||
NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1_RX], pin[GPIO_SDS0X1_TX], 1);
|
||||
if (NovaSdsSerial->begin(9600)) {
|
||||
if (NovaSdsSerial->hardwareSerial()) { ClaimSerial(); }
|
||||
if (NovaSdsSerial->hardwareSerial()) {
|
||||
ClaimSerial();
|
||||
}
|
||||
novasds_type = 1;
|
||||
NovaSdsSetWorkPeriod();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ void SDM120Show(boolean json)
|
||||
dtostrfd(sdm120_apparent_power, Settings.flag2.wattage_resolution, apparent_power);
|
||||
dtostrfd(sdm120_reactive_power, Settings.flag2.wattage_resolution, reactive_power);
|
||||
dtostrfd(sdm120_power_factor, 2, power_factor);
|
||||
dtostrfd(sdm120_frequency, 2, frequency);
|
||||
dtostrfd(sdm120_frequency, Settings.flag2.frequency_resolution, frequency);
|
||||
dtostrfd(sdm120_energy_total, Settings.flag2.energy_resolution, energy_total);
|
||||
|
||||
if (json) {
|
||||
|
@ -300,7 +300,7 @@ void MCP230xx_CheckForInterrupt(void) {
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, mqtt_data);
|
||||
}
|
||||
if (int_event) {
|
||||
char command[18];
|
||||
char command[19]; // Theoretical max = 'event MCPINT_D16=1' so 18 + 1 (for the \n)
|
||||
sprintf(command,"event MCPINT_D%i=%i",intp+(mcp230xx_port*8),((mcp230xx_intcap >> intp) & 0x01));
|
||||
ExecuteCommand(command, SRC_RULE);
|
||||
}
|
||||
@ -421,10 +421,11 @@ bool MCP230xx_Command(void) {
|
||||
uint8_t paramcount = 0;
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
paramcount=1;
|
||||
sprintf(XdrvMailbox.data,"%s,",XdrvMailbox.data); // need a trailing comma to make substr work properly with last variable - bug? dunno?
|
||||
XdrvMailbox.data_len++;
|
||||
} else {
|
||||
serviced = false;
|
||||
return serviced;
|
||||
}
|
||||
char sub_string[XdrvMailbox.data_len +1];
|
||||
char sub_string[XdrvMailbox.data_len];
|
||||
for (uint8_t ca=0;ca<XdrvMailbox.data_len;ca++) {
|
||||
if ((' ' == XdrvMailbox.data[ca]) || ('=' == XdrvMailbox.data[ca])) { XdrvMailbox.data[ca] = ','; }
|
||||
if (',' == XdrvMailbox.data[ca]) { paramcount++; }
|
||||
@ -441,7 +442,7 @@ bool MCP230xx_Command(void) {
|
||||
#endif // USE_MCP230xx_OUTPUT
|
||||
|
||||
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));
|
||||
if ((intpri >= 0) && (intpri <= 20)) {
|
||||
Settings.mcp230xx_int_prio = intpri;
|
||||
@ -455,7 +456,7 @@ bool MCP230xx_Command(void) {
|
||||
}
|
||||
|
||||
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTTIMER")) {
|
||||
if (paramcount > 2) {
|
||||
if (paramcount > 1) {
|
||||
uint8_t inttim = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
if ((inttim >= 0) && (inttim <= 3600)) {
|
||||
Settings.mcp230xx_int_timer = inttim;
|
||||
@ -470,7 +471,7 @@ bool MCP230xx_Command(void) {
|
||||
}
|
||||
|
||||
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTDEF")) {
|
||||
if (paramcount > 2) {
|
||||
if (paramcount > 1) {
|
||||
uint8_t pin = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
if (pin < mcp230xx_pincount) {
|
||||
if (pin == 0) {
|
||||
@ -480,7 +481,7 @@ bool MCP230xx_Command(void) {
|
||||
}
|
||||
}
|
||||
if (validpin) {
|
||||
if (paramcount > 3) {
|
||||
if (paramcount > 2) {
|
||||
uint8_t intdef = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3));
|
||||
if ((intdef >= 0) && (intdef <= 15)) {
|
||||
Settings.mcp230xx_config[pin].int_report_defer=intdef;
|
||||
@ -510,7 +511,7 @@ bool MCP230xx_Command(void) {
|
||||
}
|
||||
|
||||
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTCNT")) {
|
||||
if (paramcount > 2) {
|
||||
if (paramcount > 1) {
|
||||
uint8_t pin = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
if (pin < mcp230xx_pincount) {
|
||||
if (pin == 0) {
|
||||
@ -520,7 +521,7 @@ bool MCP230xx_Command(void) {
|
||||
}
|
||||
}
|
||||
if (validpin) {
|
||||
if (paramcount > 3) {
|
||||
if (paramcount > 2) {
|
||||
uint8_t intcnt = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3));
|
||||
if ((intcnt >= 0) && (intcnt <= 1)) {
|
||||
Settings.mcp230xx_config[pin].int_count_en=intcnt;
|
||||
@ -567,7 +568,7 @@ bool MCP230xx_Command(void) {
|
||||
validpin=true;
|
||||
}
|
||||
}
|
||||
if (validpin && (paramcount > 2)) {
|
||||
if (validpin && (paramcount > 1)) {
|
||||
if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 2), "?")) {
|
||||
uint8_t port = 0;
|
||||
if (pin > 7) { port = 1; }
|
||||
@ -606,13 +607,13 @@ bool MCP230xx_Command(void) {
|
||||
uint8_t pinmode = 0;
|
||||
uint8_t pullup = 0;
|
||||
uint8_t intmode = 0;
|
||||
if (paramcount > 2) {
|
||||
if (paramcount > 1) {
|
||||
pinmode = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2));
|
||||
}
|
||||
if (paramcount > 3) {
|
||||
if (paramcount > 2) {
|
||||
pullup = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3));
|
||||
}
|
||||
if (paramcount > 4) {
|
||||
if (paramcount > 3) {
|
||||
intmode = atoi(subStr(sub_string, XdrvMailbox.data, ",", 4));
|
||||
}
|
||||
#ifdef USE_MCP230xx_OUTPUT
|
||||
|
@ -28,12 +28,13 @@ Instructions:
|
||||
and store it in file status.json
|
||||
|
||||
Usage:
|
||||
./decode-status.py -d <hostname or IP address>
|
||||
./decode-status.py -d <hostname or IP address> [-u username] [-p password]
|
||||
or
|
||||
./decode-status.py -f <JSON status information file>
|
||||
|
||||
Example:
|
||||
./decode-status.py -d sonoff1
|
||||
./decode-status.py -d sonoff1 -p 12345678
|
||||
or
|
||||
./decode-status.py -f status.json
|
||||
"""
|
||||
@ -42,6 +43,7 @@ import io
|
||||
import os.path
|
||||
import json
|
||||
import pycurl
|
||||
import urllib2
|
||||
from sys import exit
|
||||
from optparse import OptionParser
|
||||
from StringIO import StringIO
|
||||
@ -83,7 +85,9 @@ a_setoption = [[
|
||||
"Do not show Wifi and Mqtt state using Led"
|
||||
],[
|
||||
"Timers enabled",
|
||||
"","","",
|
||||
"Generic ESP8285 GPIO enabled",
|
||||
"Add UTC time offset to JSON message",
|
||||
"",
|
||||
"","","","",
|
||||
"","","","",
|
||||
"","","","",
|
||||
@ -106,10 +110,10 @@ a_features = [[
|
||||
"USE_CONFIG_OVERRIDE","BE_MINIMAL","USE_SENSORS","USE_CLASSIC",
|
||||
"USE_KNX_NO_EMULATION","USE_DISPLAY_MODES1TO5","USE_DISPLAY_GRAPH","USE_DISPLAY_LCD",
|
||||
"USE_DISPLAY_SSD1306","USE_DISPLAY_MATRIX","USE_DISPLAY_ILI9341","USE_DISPLAY_EPAPER",
|
||||
"USE_DISPLAY_SH1106","","","",
|
||||
"USE_DISPLAY_SH1106","USE_MP3_PLAYER","","",
|
||||
"","","","",
|
||||
"","","","",
|
||||
"","","VTABLES_IN_FLASH","PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH",
|
||||
"","","","NO_EXTRA_4K_HEAP",
|
||||
"VTABLES_IN_IRAM","VTABLES_IN_DRAM","VTABLES_IN_FLASH","PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH",
|
||||
"PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY","PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH","DEBUG_THEO","USE_DEBUG_DRIVER"
|
||||
],[
|
||||
"","USE_ADC_VCC","USE_ENERGY_SENSOR","USE_PZEM004T",
|
||||
@ -122,8 +126,8 @@ a_features = [[
|
||||
"USE_SDM630","USE_LM75AD","USE_APDS9960","USE_TM1638"
|
||||
],[
|
||||
"USE_MCP230xx","USE_MPR121","USE_CCS811","USE_MPU6050",
|
||||
"USE_MCP230xx_OUTPUT","USE_MCP230xx_DISPLAYOUTPUT","","",
|
||||
"","","","",
|
||||
"USE_MCP230xx_OUTPUT","USE_MCP230xx_DISPLAYOUTPUT","USE_HLW8012","USE_CSE7766",
|
||||
"USE_MCP39F501","USE_PZEM2","","",
|
||||
"","","","",
|
||||
"","","","",
|
||||
"","","","",
|
||||
@ -134,13 +138,20 @@ usage = "usage: decode-status {-d | -f} arg"
|
||||
parser = OptionParser(usage)
|
||||
parser.add_option("-d", "--dev", action="store", type="string",
|
||||
dest="device", help="device to retrieve status from")
|
||||
parser.add_option("-u", "--username", action="store", type="string",
|
||||
dest="username", help="username for login", default="admin")
|
||||
parser.add_option("-p", "--password", action="store", type="string",
|
||||
dest="password", help="password for login", default=None)
|
||||
parser.add_option("-f", "--file", metavar="FILE",
|
||||
dest="jsonfile", default="status.json", help="status json file (default: status.json)")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if (options.device):
|
||||
buffer = StringIO()
|
||||
url = str("http://{}/cm?cmnd=status%200".format(options.device))
|
||||
loginstr = ""
|
||||
if options.password is not None:
|
||||
loginstr = "user={}&password={}&".format(urllib2.quote(options.username), urllib2.quote(options.password))
|
||||
url = str("http://{}/cm?{}cmnd=status%200".format(options.device, loginstr))
|
||||
c = pycurl.Curl()
|
||||
c.setopt(c.URL, url)
|
||||
c.setopt(c.WRITEDATA, buffer)
|
||||
|
Loading…
x
Reference in New Issue
Block a user