Merge branch 'arendst/development' into development

This commit is contained in:
reloxx13 2018-10-28 15:37:28 +01:00
commit 9d0db8d7bf
32 changed files with 2858 additions and 778 deletions

View File

@ -12,6 +12,10 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute!
[![GitHub forks](https://img.shields.io/github/forks/arendst/Sonoff-Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Sonoff-Tasmota/network)
[![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/tasmota)
See [RELEASENOTES.md](https://github.com/arendst/Sonoff-Tasmota/blob/development/RELEASENOTES.md) for release information.
In addition to the [release webpage](https://github.com/arendst/Sonoff-Tasmota/releases/latest) the binaries can also be OTA downloaded from http://thehackbox.org/tasmota/release/
### Development
[![Dev Version](https://img.shields.io/badge/development%20version-6.2.1.x-blue.svg)](https://github.com/arendst/Sonoff-Tasmota)
[![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/)
@ -114,21 +118,25 @@ You can contribute to Sonoff-Tasmota by
Libraries used with Sonoff-Tasmota are:
- [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)
- [Adafruit CCS811](https://github.com/adafruit/Adafruit_CCS811)
- [Adafruit ILI9341](https://github.com/adafruit/Adafruit_ILI9341)
- [Adafruit LED Backpack](https://github.com/adafruit/Adafruit-LED-Backpack-Library)
- [Adafruit SGP30](https://github.com/adafruit/Adafruit_SGP30)
- [Adafruit SSD1306](https://github.com/adafruit/Adafruit_SSD1306)
- [Adafruit GFX](https://github.com/adafruit/Adafruit-GFX-Library)
- [ArduinoJson](https://arduinojson.org/)
- [arduino mqtt](https://github.com/256dpi/arduino-mqtt)
- [Bosch BME680](https://github.com/BoschSensortec/BME680_driver)
- [C2 Programmer](http://app.cear.ufpb.br/~lucas.hartmann/tag/efm8bb1/)
- [Esp8266MqttClient](https://github.com/tuanpmt/ESP8266MQTTClient)
- [esp-knx-ip](https://github.com/envy/esp-knx-ip)
- [esp-mqtt-arduino](https://github.com/i-n-g-o/esp-mqtt-arduino)
- [ESPAsyncUDP](https://github.com/me-no-dev/ESPAsyncUDP)
- [I2Cdevlib](https://github.com/jrowberg/i2cdevlib)
- [IRremoteEsp8266](https://github.com/markszabo/IRremoteESP8266)
- [JobaTsl2561](https://github.com/joba-1/Joba_Tsl2561)
- [Liquid Cristal](https://github.com/marcoschwartz/LiquidCrystal_I2C)
- [MultiChannelGasSensor](http://wiki.seeedstudio.com/Grove-Multichannel_Gas_Sensor/)
- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus)
- [OneWire](https://github.com/PaulStoffregen/OneWire)
- [PubSubClient](https://github.com/knolleary/pubsubclient)
- [rc-switch](https://github.com/sui77/rc-switch)
#### People inspiring me
People helping to keep the show on the road:
@ -142,16 +150,19 @@ People helping to keep the show on the road:
- Flexiti for his initial timer implementation
- reloxx13 for his [TasmoAdmin](https://github.com/reloxx13/TasmoAdmin) management tool
- Joachim Banzhaf for his TSL2561 library and driver
- Gijs Noorlander for his MHZ19 and SenseAir drivers
- Gijs Noorlander for his MHZ19, SenseAir and updated PubSubClient drivers
- Emontnemery for his HomeAssistant Discovery concept and many code tuning tips
- Aidan Mountford for his HSB support
- Daniel Ztolnai for his Serial Bridge implementation
- Gerhard Mutz for his SGP30 and Sunrise/Sunset driver
- Gerhard Mutz for his SGP30, Sunrise/Sunset and display support drivers
- Nuno Ferreira for his HC-SR04 driver
- Adrian Scillato for his (security)fixes and implementing and maintaining KNX
- Gennaro Tortone for implementing and maintaining Eastron drivers
- Raymond Mouthaan for managing Wemos Wiki information
- Norbert Richter, Frogmore42 and Jason2866 for providing many issue answers
- Norbert Richter for his decode-config.py tool
- Andre Thomas for providing [thehackbox](http://thehackbox.org/tasmota/) OTA support and daily development builds
- Joel Stein and digiblur for their Tuya research and driver
- Frogmore42 and Jason2866 for providing many issue answers
- Many more providing Tips, Pocs or PRs
### License

View File

@ -15,7 +15,7 @@ To save memory space all other binaries support **WifiManager only**.
See _changelog.ino how to enable them again.
- Define WIFI_CONFIG_TOOL now contains the default behaviour once a SSID has been configured.
- If no SSID is configured making a wifi connection impossible the new define WIFI_CONFIG_NO_SSID will be used.
- While define WIFI_CONFIG_NO_SSID is set to WIFI_WPSCONFIG in user_config.h the compiler will check for define USE_WPS and if not enabled WIFI_CONFIG_NO_SSID will default to WIFI_MANAGER using the webserver. If define USE_WEBSERVER is also not enabled WIFI_CONFIG_NO_SSID will default to WIFI_SMARTCONFIG. If define USE_SMARTCONFIG is also not enabled WIFI_CONFIG_NO_SSID will default to a new option WIFI_SERIAL allowing to enter wifi parameters to serial which is always possible.
- While define WIFI_CONFIG_NO_SSID is set to WIFI_WPSCONFIG in my_user_config.h the compiler will check for define USE_WPS and if not enabled WIFI_CONFIG_NO_SSID will default to WIFI_MANAGER using the webserver. If define USE_WEBSERVER is also not enabled WIFI_CONFIG_NO_SSID will default to WIFI_SMARTCONFIG. If define USE_SMARTCONFIG is also not enabled WIFI_CONFIG_NO_SSID will default to a new option WIFI_SERIAL allowing to enter wifi parameters to serial which is always possible.
## Provided Binary Downloads
The following binary downloads have been compiled with ESP8266/Arduino library version **2.3.0**
@ -25,6 +25,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library v
- **sonoff.bin** = The Sonoff version without Wps and SmartConfig configuration but adds more sensors.
- **sonoff-BG.bin** to **sonoff-TW.bin** = The Sonoff version without Wps and SmartConfig configuration in different languages.
- **sonoff-sensors.bin** = The Sensors version without Wps and SmartConfig configuration but adds even more useful sensors.
- **sonoff-display.bin** = The Display version without Wps and SmartConfig configuration but adds display support.
- **sonoff-knx.bin** = The Knx version without Wps and SmartConfig configuration and some other features but adds KNX support.
See [Tasmota ESP/Arduino library version related issues](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips#20180523---relation-tasmota-and-esp8266arduino-core-version) why these files are still released using ESP/Arduino library version v2.3.0.
@ -33,8 +34,8 @@ See [Tasmota ESP/Arduino library version related issues](https://github.com/aren
| Feature or Sensor | minimal | classic | sonoff | knx | sensors | Remarks
|--------------------------------|---------|---------|--------|------|---------|--------
| ESP/Arduino lib v2.3.0 | 340k | 477k | 473k | 492k | 497k |
| ESP/Arduino lib v2.4.2 | 360k | 491k | 491k | 509k | 513k | No sleep
| ESP/Arduino lib v2.3.0 | 344k | 485k | 491k | 510k | 516k |
| ESP/Arduino lib v2.4.2 | 363k | 499k | 509k | 526k | 532k | No sleep
| | | | | | |
| MY_LANGUAGE en-GB | x | x | x | x | x |
| USE_WPS | - | x | - | - | - | WPS
@ -55,7 +56,7 @@ See [Tasmota ESP/Arduino library version related issues](https://github.com/aren
| USE_SUNRISE | - | - | x | x | x |
| USE_RULES | - | - | x | x | x |
| | | | | | |
| USE_ADC_VCC | x | x | x | x | |
| USE_ADC_VCC | x | x | x | x | - |
| USE_DS18B20 | - | - | - | - | - | Single sensor
| USE_DS18x20 | - | x | x | x | x | Multiple sensors
| USE_DS18x20_LEGACY | - | - | - | - | - | Multiple sensors
@ -111,76 +112,89 @@ See [Tasmota ESP/Arduino library version related issues](https://github.com/aren
| USE_RF_FLASH | - | - | x | x | x |
| USE_TUYA_DIMMER | - | - | x | x | x |
| USE_TX20_WIND_SENSOR | - | - | x | x | x |
| USE_RC_SWITCH | - | - | x | x | x |
| USE_DISPLAY | - | - | - | - | - |
## 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)
* Change DS18B20 driver to provide better instant results
* Change some sensor drivers to provide instant results
* Change define USE_ALL_SENSORS to USE_SENSORS as it doesn't contain all sensors due to duplicate I2C addresses
* Change some sensor update timings: AdcEvery 200 -> 250, Senseair 300 -> 250, SDM120 300 -> 250, SDM630 300 -> 250
* Change default Wifi config option from WPS to Wifi Manager if WPS is disabled or Wifi Smartconfig if webserver is disabled or Wifi Serial input if Smartconfig is disabled
* Change SHT1x driver to provide better instant results and fix I2C interference
* Change DHT driver to provide better instant results and add decimals to DHT11 (#3164)
* Change DS18x20 driver to provide better instant results (#3169)
* Change CounterType 1 from milliseconds to microseconds (#3437)
* Change scheduler for better sleep support using Uptime, Delay, PulseTime and TelePeriod, Blinktime (#3581)
* Remove unused functionality from Sonoff-minimal to save space
* Remove WPS and SmartConfig from sonoff-minimal saving 56k code space
* Remove TSL2561 debug message and update library (#2415)
* Remove forced restart when sleep command is executed (#3554)
* Fix invalid response using more than 4 switches and domoticz
* Fix sonoff-minimal not using default settings
* Fix unsecure main webpage update
* Fix DHT driver mixing values for different sensors (#1797)
* Fix EnergyReset3 regression not clearing total energy (#2723)
* Fix rules once regression from v6.1.0 (#3198, #3226)
* Fix command Scale buffer overflow (#3236)
* Fix possible WDT due to long MQTT publish handling (#3313)
* Fix command TimeDst/TimeStd invalid JSON (#3322)
* Fix handling of default names when using names starting with shortcut character ",0,1 or 2 (#3392, #3600, #3618)
* Fix LM75AD I2C sensor detection (#3408)
* Fix iFan02 power on state (#3412, #3530)
* Fix some Pow R2 and S31 checksum errors using optimized re-sync (#3425)
* Fix SDM120 reporting wrong negative values to Domoticz (#3521)
* Fix MQTT reconnection detection when using TasmotaMqtt library (#3558)
* Fix OtaMagic when file path contains a dash (-) (#3563)
* Fix Sonoff Bridge data reception when using Portisch EFM8 firmware using in data buffer length (#3605)
* Add read sensor retry to DS18B20, DS18x20, DHT, SHT1X and HTU21
* Add user selection of Wifi Smartconfig as define USE_SMARTCONFIG in user_config.h
* Add boot loop detection and perform some solutions
* Add wifi and mqtt status led blinkyblinky to be disabled by SetOption31 1. Does not work when LedPower is On (deliberate) (#871, #2230, #3114, #3155)
* Add support for TM1638 switch (#2226)
* Add GPIO options ButtonXn, SwitchXn and CounterXn to select INPUT mode instead of INPUT_PULLUP (#2525)
* Add support for APDS9960 proximity sensor (#3051)
* Add support for MPR121 controller in input mode for touch buttons (#3142)
* Add support for MCP230xx for general purpose input expansion and command Sensor29 (#3188)
* Add default Wifi Configuration tool as define WIFI_CONFIG_NO_SSID in user_config.h if no SSID is configured (#3224)
* Add command Timers 0/1 to globally disable or enable armed timers (#3270)
* Add support for CCS811 sensor (#3309)
* Add Turkish language file (#3332)
* Add command SerialSend4 to send binary serial data (#3345)
* Add initial support for sensor MPU6050 (#3352)
* Add rule triggers Wifi#Connected and Wifi#Disconnected (#3359)
* Add option + to command Rule to concatenate new rule with existing rules (#3365)
* Add message when JavaScript is not enabled in webbrowser (#3388)
* Add build time setting of ButtonTopic and SwitchTopic (#3414)
* Add iFan02 Fanspeed + and Fanspeed - command options (#3415)
* Add Individual HSBColorX commands (#3430, #3615)
* Add output support on MCP23008/MCP23017 (#3436)
* Add modulo option to rules like rule1 on Time#Minute|5 do backlog power on;delay 200;power off endon (#3466)
* Add RGB support for Domoticz (#3547)
* Add all ruletimer values to command RuleTimer result message (#3571)
* Add command Publish2 for publishing retained MQTT messages (#3593)
* Add commands ButtonDebounce 40..1000 and SwitchDebounce 40..1000 to have user control over debounce timing. Default is 50mS (#3594)
* Add RuleX debug options 8,9,10 (StopOnError) to control RuleX execution status after an exception restart (#3607)
* Add rule variables %sunrise%, %sunset%, %uptime% and %time% (#3608)
* Add optional MQTT_TELE_RETAIN to Energy Margins message (#3612, 3614)
Version 6.3.0 soon
* Change web Configure Module GPIO drop down list order for better readability
* Change status JSON message providing more switch and retain information
* Change xsns_17_senseair.ino to use TasmotaModbus library
* Change MCP230xx driver
* Change PubSubClient Mqtt library to non-blocking EspEasy version
* Change energy monitoring using energy sensor driver modules
* Change Webserver page handler for easier extension (thx to Adrian Scillato)
* Change pinmode for no-pullup defined switches to pullup when configured as switchmode PUSHBUTTON (=3 and up) (#3896)
* Change default OTA Url to http://thehackbox.org/tasmota/release/sonoff.bin (#4170)
* Remove support for MQTT Client esp-mqtt-arduino by #define MQTT_LIBRARY_TYPE MQTT_ESPMQTTARDUINO
* Remove commands PowerCal, VoltageCal and CurrentCal as more functionality is provided by commands PowerSet, VoltageSet and CurrentSet
* Remove restart after ntpserver change and force NTP re-sync (#3890)
* Fix showing Period Power in energy threshold messages
* Fix header file execution order by renaming user_config.h to my_user_config.h
* Fix some TSL2561 driver issues (#3681)
* Fix KNX PA exception. Regression from 6.2.1 buffer overflow caused by subStr() (#3700, #3710)
* Fix setting and getting color temperature for Philips Hue emulation (#3733)
* Fix ButtonRetain to not use default topic for clearing retain messages (#3737)
* Fix syslog when emulation is selected (#2109, #3784)
* Fix rule trigger POWER1#STATE execution after restart and SetOption0 is 0 (#3856)
* Fix Home Assistant forced light discovery (#3908)
* Fix invalid configuration restores and decode_config.py crc error when savedata = 0 (#3918)
* Fix timer offset -00:00 causing 12:00 hour offset (#3923)
* Fix I2CScan invalid JSON error message (#3925)
* Fix exception when wrong Domoticz JSON message is received (#3963)
* Fix Sonoff Bridge RfRaw receive (#4080, #4085)
* Fix possible wifi connection error (#4044, #4083)
* Fix invalid JSON floating point result from nan (Not a Number) and inf (Infinity) into null (#4147)
* Fix rule mqtt#connected trigger when mqtt is disabled (#4149)
* Add support for LCD, Matrix, TFT and Oled displays
* Add support for Neo Coolcam Wifi Smart Power Plug
* Add support for Michael Haustein ESP Switch
* Add support for MQTT Client based on lwmqtt to be selected by #define MQTT_LIBRARY_TYPE MQTT_ARDUINOMQTT
* Add support for Neo Coolcam Wifi Smart Power Plug
* Add support for Michael Haustein ESP Switch
* Add support for MQTT Client based on lwmqtt to be selected by #define MQTT_LIBRARY_TYPE MQTT_ARDUINOMQTT
* Add support for DS3231 Real Time Clock
* Add support for HX711 Load Cell with optional web GUI scale interface to demonstrate easy GUI plug-in
* Add support for serial 8N2 communication to TasmotaModbus and TasmotaSerial libraries
* Add support for RF transceiving using library RcSwitch (#2702)
* Add support for Shelly 1 and Shelly 2 (#2789)
* Add support for La Crosse TX20 Anemometer (#2654, #3146)
* Add support for MP3 player using DFRobot RB-DFR-562 (#3723)
* Add Support for Xiaomi-Philips Bulbs (#3787)
* Add support for PCA9685 12bit 16pin hardware PWM driver (#3866)
* Add support for EXS Relay V5.0 (#3810)
* Add support for OBI Power Socket (#1988, #3944)
* Add support for Teckin Power Socket with Energy Monitoring (#3950)
* Add support for Pzem-003/017 DC Energy monitoring module (#3694)
* Add support for Pzem-014/016 AC Energy monitoring module (#3694)
* Add support for CSL Aplic WDP 303075 Power Socket with Energy Monitoring (#3991, #3996)
* Add support for Tuya Dimmer (#469, #4075)
* Add command Display to show all settings at once
* Add command SerialSend5 to send raw serial data like "A5074100545293"
* Add command WebRefresh 1000..10000 to control web page refresh in milliseconds. Default is 2345
* Add command WeightRes 0..3 to control display of decimals for kilogram
* Add command SetOption52 to control display of optional time offset from UTC in JSON messages (#3629, #3711)
* Add command RGBWWTable to support color calibration (#3933)
* Add command Reset 4 (reset to defaults but keep wifi params) and Reset 5 (as reset 4 and also erase flash) (#4061)
* Add authentication to HTTP web pages
* Add decimals as input to commands PowerSet, VoltageSet and CurrentSet
* Add tools/decode-config.py by Norbert Richter to decode configuration data. See file for information
* Add define USE_DISPLAYS for selecting image sonoff-display
* Add auto reload of main web page to some web restarts
* Add TasmotaModbus library as very basic modbus wrapper for TasmotaSerial
* Add more API callbacks and document API.md
* Add Wifi channel number to state message (#3664)
* Add user configurable GPIO02 and GPIO03 on H801 devices (#3692)
* Add network information to display start screen (#3704)
* Add toggle function RGBW lights (#3695, #3697)
* Add sleep to Nova Fitness SDS01X sensor (#2841, #3724, #3749)
* Add Analog input AD0 enabled to sonoff-sensors.bin (#3756, #3757)
* Add userid/password option to decode-status.py (#3796)
* Add power value below 5W to Sonoff Pow R2 and S31 (#3745)
* Add force_update to Home Assistant discovery (#3873)
* Add delay after restart before processing rule sensor data (#3811)
* Add rule triggers SWITCH1#BOOT and POWER1#BOOT (#3904, #3910)
* Add Apparent Power and Reactive Power to Energy Monitoring devices (#251)
* Add RF Receiver control to module MagicHome to be used on Arilux LC10 (#3792)
* Add Hebrew language file (#3960)
* Add whitespace removal from RfRaw and SerialSend5 (#4020)

View File

@ -13,6 +13,7 @@ src_dir = sonoff
; *** Uncomment one of the lines below to build/upload only one environment
env_default = sonoff
;env_default = sonoff-minimal
;env_default = sonoff-basic
;env_default = sonoff-classic
;env_default = sonoff-knx
;env_default = sonoff-sensors
@ -45,6 +46,8 @@ platform = espressif8266@1.5.0
;platform = espressif8266@1.7.3
; *** Esp8266 core for Arduino version 2.4.2
;platform = espressif8266@1.8.0
; *** Esp8266 core for Arduino version Core 2.5.0 beta tested for Tasmota
;platform = https://github.com/Jason2866/platform-espressif8266.git#Tasmota
; *** Esp8266 core for Arduino version latest beta
;platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
; *** Esp8266 core for Arduino current version (located in %USERPROFILE%\.platformio\platforms\espressif8266)
@ -130,6 +133,20 @@ upload_resetmethod = ${common.upload_resetmethod}
upload_speed = ${common.upload_speed}
extra_scripts = ${common.extra_scripts}
[env:sonoff-basic]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board}
board_build.flash_mode = ${common.board_build.flash_mode}
board_build.f_cpu = ${common.board_build.f_cpu}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DUSE_BASIC
monitor_speed = ${common.monitor_speed}
upload_port = ${common.upload_port}
upload_resetmethod = ${common.upload_resetmethod}
upload_speed = ${common.upload_speed}
extra_scripts = ${common.extra_scripts}
[env:sonoff-classic]
platform = ${common.platform}
framework = ${common.framework}
@ -165,7 +182,7 @@ board = ${common.board}
board_build.flash_mode = ${common.board_build.flash_mode}
board_build.f_cpu = ${common.board_build.f_cpu}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DUSE_ALL_SENSORS
build_flags = ${common.build_flags} -DUSE_SENSORS
monitor_speed = ${common.monitor_speed}
upload_port = ${common.upload_port}
upload_resetmethod = ${common.upload_resetmethod}

View File

@ -3,6 +3,9 @@
* Fix invalid JSON floating point result from nan (Not a Number) and inf (Infinity) into null (#4147)
* Fix rule mqtt#connected trigger when mqtt is disabled (#4149)
* Initial release of RF transceiving using library RcSwitch (#2702)
* Change default OTA Url to http://thehackbox.org/tasmota/release/sonoff.bin (#4170)
* Add Tuya Software Serial to support additional Tuya configurations (#4178)
* Add sonoff-basic.bin without most sensors
*
* 6.2.1.18 20181019
* Add more API callbacks and document API.md

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "h"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "h"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -1,3 +1,4 @@
/*
el-GR.h - localization for Greek - Greece for Sonoff-Tasmota
@ -527,6 +528,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +538,7 @@
#define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "h"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "ó"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "h"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "Godz"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "H"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "А"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "Ч"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "кОм"
#define D_UNIT_KILOWATTHOUR "кВт"
#define D_UNIT_LUX "лк"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "A"
@ -534,7 +536,7 @@
#define D_UNIT_HOUR "Hr"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kOhm"
#define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "lx"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "А"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "Г"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "кОм"
#define D_UNIT_KILOWATTHOUR "кВт"
#define D_UNIT_LUX "лк"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "安"
@ -534,7 +536,7 @@
#define D_UNIT_HOUR "时"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "千欧"
#define D_UNIT_KILOWATTHOUR "千瓦时"
#define D_UNIT_LUX "勒克斯"

View File

@ -527,6 +527,8 @@
#define D_SENSOR_TX20_TX "TX20"
#define D_SENSOR_RFSEND "RFSend"
#define D_SENSOR_RFRECV "RFrecv"
#define D_SENSOR_TUYA_TX "Tuya Tx"
#define D_SENSOR_TUYA_RX "Tuya Rx"
// Units
#define D_UNIT_AMPERE "安"
@ -535,7 +537,7 @@
#define D_UNIT_HOUR "時"
#define D_UNIT_INCREMENTS "inc"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "千歐"
#define D_UNIT_KILOWATTHOUR "千瓦時"
#define D_UNIT_LUX "勒克斯"

View File

@ -79,7 +79,7 @@
#define WEB_LOG_LEVEL LOG_LEVEL_INFO // [WebLog] (LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE)
// -- Ota -----------------------------------------
#define OTA_URL "http://sonoff.maddox.co.uk/tasmota/sonoff.bin" // [OtaUrl]
#define OTA_URL "http://thehackbox.org/tasmota/release/sonoff.bin" // [OtaUrl]
// -- MQTT ----------------------------------------
#define MQTT_USE 1 // [SetOption3] Select default MQTT use (0 = Off, 1 = On)
@ -353,6 +353,8 @@
#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)
#define USE_TUYA_DIMMER // Add support for Tuya Serial Dimmer
#define TUYA_DIMMER_ID 3 // Default dimmer Id
// Power monitoring sensors -----------------------
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
@ -379,12 +381,9 @@
#define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+3k code)
#define USE_TUYA_DIMMER // Add support for Tuya Serial Dimmer
#define TUYA_DIMMER_ID 3 // Default dimmer Id
#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k code)
#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code)
#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram)
/*********************************************************************************************\
* Debug features are only supported in development branch
@ -399,6 +398,7 @@
\*********************************************************************************************/
//#define USE_CLASSIC // Create sonoff-classic with initial configuration tools WPS, SmartConfig and WifiManager
//#define USE_BASIC // Create sonoff-basic with no sensors
//#define USE_SENSORS // Create sonoff-sensors with useful sensors enabled
//#define USE_KNX_NO_EMULATION // Create sonoff-knx with KNX but without Emulation
//#define USE_DISPLAYS // Create sonoff-display with display drivers enabled

View File

@ -57,10 +57,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#ifdef USE_SENSORS
#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
#undef USE_ADC_VCC // Add 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)
@ -80,7 +77,17 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code)
#define USE_MGS // Add I2C code for Xadow and Grove Mutichannel Gas sensor using library Multichannel_Gas_Sensor (+10k code)
//#define USE_APDS9960 // Add I2C code for APDS9960 Proximity Sensor. Disables SHT and VEML6070 (+4k7 code)
//#define USE_MCP230xx // Enable MCP23008/MCP23017 - Must define I2C Address in #define USE_MCP230xx_ADDR below - range 0x20 - 0x27 (+4k7 code)
// #define USE_MCP230xx_ADDR 0x20 // Enable MCP23008/MCP23017 I2C Address to use (Must be within range 0x20 through 0x27 - set according to your wired setup)
// #define USE_MCP230xx_OUTPUT // Enable MCP23008/MCP23017 OUTPUT support through sensor29 commands (+1k5 code)
// #define USE_MCP230xx_DISPLAYOUTPUT // Enable MCP23008/MCP23017 to display state of OUTPUT pins on Web UI (+0k2 code)
//#define USE_PCA9685 // Enable PCA9685 I2C HW PWM Driver - Must define I2C Address in #define USE_PCA9685_ADDR below - range 0x40 - 0x47 (+1k4 code)
// #define USE_PCA9685_ADDR 0x40 // Enable PCA9685 I2C Address to use (Must be within range 0x40 through 0x47 - set according to your wired setup)
// #define USE_PCA9685_FREQ 50 // Define default PWM frequency in Hz to be used (must be within 24 to 1526) - If other value is used, it will rever to 50Hz
//#define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons (+1k3 code)
//#define USE_CCS811 // Add I2C code for CCS811 sensor (+2k2 code)
//#define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+2k6 code)
//#define USE_DS3231 // Enable DS3231 external RTC in case no Wifi is avaliable. See docs in the source file (+1k2 code)
#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
#ifndef CO2_LOW
@ -91,10 +98,17 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#endif
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code)
#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)
#define USE_TUYA_DIMMER // Add support for Tuya Serial Dimmer
#define TUYA_DIMMER_ID 3 // Default dimmer Id
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
#define USE_PZEM_AC // Add support for PZEM014,016 Energy monitor (+1k1 code)
#define USE_PZEM_DC // Add support for PZEM003,017 Energy monitor (+1k1 code)
#define USE_MCP39F501 // Add support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code)
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
#define USE_IR_HVAC // Support for HVAC system using IR (+2k code)
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)
@ -105,6 +119,12 @@ void KNX_CB_Action(message_t const &msg, void *arg);
// #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow
#define USE_ARILUX_RF // Add support for Arilux RF remote controller (+0k8 code, 252 iram (non 2.3.0))
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code)
#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
//#define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code)
#define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+3k code)
#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k code)
#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram)
#endif // USE_SENSORS
/*********************************************************************************************\
@ -141,6 +161,8 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#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
#undef USE_MP3_PLAYER // Disable DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer
#undef USE_IR_REMOTE // Disable IR remote commands using library IRremoteESP8266 and ArduinoJson
#undef USE_IR_RECEIVE // Disable support for IR receiver
#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller
@ -148,8 +170,8 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
#undef USE_HX711 // Disable support for HX711 load cell
#undef USE_RF_FLASH // Disable support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB
#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
#undef DEBUG_THEO // Disable debug code
#undef USE_DEBUG_DRIVER // Disable debug code
#endif // USE_CLASSIC
@ -200,6 +222,62 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#define USE_DS18B20 // Default DS18B20 sensor needs no external library
#endif
/*********************************************************************************************\
* [sonoff-basic.bin]
* Provide an image without sensors
\*********************************************************************************************/
#ifdef USE_BASIC
//#undef USE_ENERGY_SENSOR // Disable energy sensors
#undef USE_ARDUINO_OTA // Disable support for Arduino OTA
#undef USE_WPS // Disable support for WPS as initial wifi configuration tool
#undef USE_SMARTCONFIG // Disable support for Wifi SmartConfig as initial wifi configuration tool
#undef USE_DOMOTICZ // Disable Domoticz
#undef USE_HOME_ASSISTANT // Disable Home Assistant
#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set
#undef USE_KNX // Disable KNX IP Protocol Support
//#undef USE_WEBSERVER // Disable Webserver
//#undef USE_EMULATION // Disable Wemo or Hue emulation
#undef USE_CUSTOM // Disable Custom features
#undef USE_DISCOVERY // Disable Discovery services for both MQTT and web server
//#undef USE_TIMERS // Disable support for up to 16 timers
//#undef USE_TIMERS_WEB // Disable support for timer webpage
//#undef USE_SUNRISE // Disable support for Sunrise and sunset tools
//#undef USE_RULES // Disable support for rules
#undef USE_DHT // Disable internal DHT sensor
#undef USE_DS18x20 // Disable DS18x20 sensor
#undef USE_DS18x20_LEGACY // Disable DS18x20 sensor
#undef USE_DS18B20 // Disable internal DS18B20 sensor
#undef USE_I2C // Disable all I2C sensors and devices
#undef USE_SPI // Disable all SPI devices
#undef USE_DISPLAY // Disable Display support
#undef USE_MHZ19 // Disable support for MH-Z19 CO2 sensor
#undef USE_SENSEAIR // Disable support for SenseAir K30, K70 and S8 CO2 sensor
#undef USE_PMS5003 // Disable support for PMS5003 and PMS7003 particle concentration sensor
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
#undef USE_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
#undef USE_MP3_PLAYER // Disable DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
//#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer
#undef USE_PZEM004T // Disable PZEM004T energy sensor
#undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor
#undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor
//#undef USE_MCP39F501 // Disable MCP39F501 Energy monitor as used in Shelly 2
#undef USE_IR_REMOTE // Disable IR driver
#undef USE_WS2812 // Disable WS2812 Led string
#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller
#undef USE_SR04 // Disable support for for HC-SR04 ultrasonic devices
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
#undef USE_HX711 // Disable support for HX711 load cell
#undef USE_RF_FLASH // Disable support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
#undef DEBUG_THEO // Disable debug code
#undef USE_DEBUG_DRIVER // Disable debug code
#endif // USE_BASIC
/*********************************************************************************************\
* [sonoff-minimal.bin]
* Provide the smallest image possible while still enabling a webserver for intermediate image load
@ -216,9 +294,9 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set
#undef USE_KNX // Disable KNX IP Protocol Support
//#undef USE_WEBSERVER // Disable Webserver
#undef USE_EMULATION // Disable Wemo or Hue emulation
#undef USE_CUSTOM // Disable Custom features
#undef USE_DISCOVERY // Disable Discovery services for both MQTT and web server
#undef USE_EMULATION // Disable Wemo or Hue emulation
#undef USE_TIMERS // Disable support for up to 16 timers
#undef USE_TIMERS_WEB // Disable support for timer webpage
#undef USE_SUNRISE // Disable support for Sunrise and sunset tools
@ -234,10 +312,15 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#undef USE_SENSEAIR // Disable support for SenseAir K30, K70 and S8 CO2 sensor
#undef USE_PMS5003 // Disable support for PMS5003 and PMS7003 particle concentration sensor
#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor
#undef USE_PZEM004T // Disable PZEM004T energy sensor
#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
#undef USE_MP3_PLAYER // Disable DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer
#undef USE_PZEM004T // Disable PZEM004T energy sensor
#undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor
#undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor
#undef USE_MCP39F501 // Disable MCP39F501 Energy monitor as used in Shelly 2
#undef USE_IR_REMOTE // Disable IR driver
#undef USE_WS2812 // Disable WS2812 Led string
#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller
@ -245,8 +328,8 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8
#undef USE_HX711 // Disable support for HX711 load cell
#undef USE_RF_FLASH // Disable support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB
#undef USE_TUYA_DIMMER // Disable support for Tuya Serial Dimmer
#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer
#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch
#undef DEBUG_THEO // Disable debug code
#undef USE_DEBUG_DRIVER // Disable debug code
#endif // BE_MINIMAL

View File

@ -131,6 +131,8 @@ enum UserSelectablePins {
GPIO_TX20_TXD_BLACK, // TX20 Transmission Pin
GPIO_RFSEND, // RF transmitter
GPIO_RFRECV, // RF receiver
GPIO_TUYA_TX, // Tuya Serial interface
GPIO_TUYA_RX, // Tuya Serial interface
GPIO_SENSOR_END };
// Programmer selectable GPIO functionality offset by user selectable GPIOs
@ -187,7 +189,8 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_DFR562 "|" D_SENSOR_SDS0X1_TX "|"
D_SENSOR_HX711_SCK "|" D_SENSOR_HX711_DAT "|"
D_SENSOR_TX20_TX "|"
D_SENSOR_RFSEND "|" D_SENSOR_RFRECV;
D_SENSOR_RFSEND "|" D_SENSOR_RFRECV "|"
D_SENSOR_TUYA_TX "|" D_SENSOR_TUYA_RX;
/********************************************************************************************/
@ -371,7 +374,9 @@ const uint8_t kGpioNiceList[GPIO_SENSOR_END] PROGMEM = {
GPIO_SDM630_RX, // SDM630 Serial interface
GPIO_PMS5003, // Plantower PMS5003 Serial interface
GPIO_TX20_TXD_BLACK, // TX20 Transmission Pin
GPIO_MP3_DFR562 // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface
GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface
GPIO_TUYA_TX, // Tuya Serial interface
GPIO_TUYA_RX // Tuya Serial interface
};
const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
@ -1150,9 +1155,9 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
{ "Tuya Dimmer", // Tuya Dimmer (ESP8266 w/ separate MCU dimmer)
// https://www.amazon.com/gp/product/B07CTNSZZ8/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1
GPIO_KEY1, // Virtual Button (controlled by MCU)
GPIO_TXD, // GPIO01 MCU serial control
GPIO_USER, // GPIO01 MCU serial control
GPIO_USER,
GPIO_RXD, // GPIO03 MCU serial control
GPIO_USER, // GPIO03 MCU serial control
GPIO_USER,
GPIO_USER,
0, 0, 0, 0, 0, 0, // Flash connection

View File

@ -22,6 +22,11 @@
#ifndef TUYA_DIMMER_ID
#define TUYA_DIMMER_ID 3
#endif
#define TUYA_BUFFER_SIZE 256
#include <TasmotaSerial.h>
TasmotaSerial *TuyaSerial = nullptr;
uint8_t tuya_new_dim = 0; // Tuya dimmer value temp
boolean tuya_ignore_dim = false; // Flag to skip serial send to prevent looping when processing inbound states from the faceplate interaction
@ -29,6 +34,9 @@ uint8_t tuya_cmd_status = 0; // Current status of serial-read
uint8_t tuya_cmd_checksum = 0; // Checksum of tuya command
uint8_t tuya_data_len = 0; // Data lenght of command
char tuya_buffer[TUYA_BUFFER_SIZE]; // Serial receive buffer
int tuya_byte_counter = 0; // Index in serial receive buffer
boolean TuyaSetPower()
{
boolean status = false;
@ -36,24 +44,24 @@ boolean TuyaSetPower()
uint8_t rpower = XdrvMailbox.index;
int16_t source = XdrvMailbox.payload;
if (source != SRC_SWITCH ) { // ignore to prevent loop from pushing state from faceplate interaction
if (source != SRC_SWITCH && TuyaSerial) { // ignore to prevent loop from pushing state from faceplate interaction
snprintf_P(log_data, sizeof(log_data), PSTR("TYA: SetDevicePower.rpower=%d"), rpower);
AddLog(LOG_LEVEL_DEBUG);
Serial.write(0x55); // Tuya header 55AA
Serial.write(0xAA);
Serial.write(0x00); // version 00
Serial.write(0x06); // Tuya command 06
Serial.write(0x00);
Serial.write(0x05); // following data length 0x05
Serial.write(0x01); // relay number 1,2,3
Serial.write(0x01);
Serial.write(0x00);
Serial.write(0x01);
Serial.write(rpower); // status
Serial.write(0x0D + rpower); // checksum sum of all bytes in packet mod 256
Serial.flush();
TuyaSerial->write((uint8_t)0x55); // Tuya header 55AA
TuyaSerial->write((uint8_t)0xAA);
TuyaSerial->write((uint8_t)0x00); // version 00
TuyaSerial->write((uint8_t)0x06); // Tuya command 06
TuyaSerial->write((uint8_t)0x00);
TuyaSerial->write((uint8_t)0x05); // following data length 0x05
TuyaSerial->write((uint8_t)0x01); // relay number 1,2,3
TuyaSerial->write((uint8_t)0x01);
TuyaSerial->write((uint8_t)0x00);
TuyaSerial->write((uint8_t)0x01);
TuyaSerial->write((uint8_t)rpower); // status
TuyaSerial->write((uint8_t)0x0D + rpower); // checksum sum of all bytes in packet mod 256
TuyaSerial->flush();
status = true;
}
@ -62,26 +70,26 @@ boolean TuyaSetPower()
void LightSerialDuty(uint8_t duty)
{
if (duty > 0 && !tuya_ignore_dim ) {
if (duty > 0 && !tuya_ignore_dim && TuyaSerial) {
if (duty < 25) {
duty = 25; // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself
}
Serial.write(0x55); // Tuya header 55AA
Serial.write(0xAA);
Serial.write(0x00); // version 00
Serial.write(0x06); // Tuya command 06 - send order
Serial.write(0x00);
Serial.write(0x08); // following data length 0x08
Serial.write(Settings.param[P_TUYA_DIMMER_ID]); // dimmer id
Serial.write(0x02); // type=value
Serial.write(0x00); // length hi
Serial.write(0x04); // length low
Serial.write(0x00); //
Serial.write(0x00); //
Serial.write(0x00); //
Serial.write( duty ); // dim value (0-255)
Serial.write( byte(Settings.param[P_TUYA_DIMMER_ID] + 19 + duty) ); // checksum:sum of all bytes in packet mod 256
Serial.flush();
TuyaSerial->write((uint8_t)0x55); // Tuya header 55AA
TuyaSerial->write((uint8_t)0xAA);
TuyaSerial->write((uint8_t)0x00); // version 00
TuyaSerial->write((uint8_t)0x06); // Tuya command 06 - send order
TuyaSerial->write((uint8_t)0x00);
TuyaSerial->write((uint8_t)0x08); // following data length 0x08
TuyaSerial->write((uint8_t)Settings.param[P_TUYA_DIMMER_ID]); // dimmer id
TuyaSerial->write((uint8_t)0x02); // type=value
TuyaSerial->write((uint8_t)0x00); // length hi
TuyaSerial->write((uint8_t)0x04); // length low
TuyaSerial->write((uint8_t)0x00); //
TuyaSerial->write((uint8_t)0x00); //
TuyaSerial->write((uint8_t)0x00); //
TuyaSerial->write((uint8_t) duty ); // dim value (0-255)
TuyaSerial->write((uint8_t) byte(Settings.param[P_TUYA_DIMMER_ID] + 19 + duty) ); // checksum:sum of all bytes in packet mod 256
TuyaSerial->flush();
snprintf_P(log_data, sizeof(log_data), PSTR( "TYA: Send Serial Packet Dim Value=%d (id=%d)"), duty, Settings.param[P_TUYA_DIMMER_ID]);
AddLog(LOG_LEVEL_DEBUG);
@ -99,27 +107,27 @@ void TuyaPacketProcess()
{
char scmnd[20];
snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Packet Size=%d"), serial_in_byte_counter);
snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Packet Size=%d"), tuya_byte_counter);
AddLog(LOG_LEVEL_DEBUG);
if (serial_in_byte_counter == 7 && serial_in_buffer[3] == 14 ) { // heartbeat packet
if (tuya_byte_counter == 7 && tuya_buffer[3] == 14 ) { // heartbeat packet
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Heartbeat"));
}
else if (serial_in_byte_counter == 12 && serial_in_buffer[3] == 7 && serial_in_buffer[5] == 5) { // on/off packet
else if (tuya_byte_counter == 12 && tuya_buffer[3] == 7 && tuya_buffer[5] == 5) { // on/off packet
snprintf_P(log_data, sizeof(log_data),PSTR("TYA: Rcvd - %s State"),serial_in_buffer[10]?"On":"Off");
snprintf_P(log_data, sizeof(log_data),PSTR("TYA: Rcvd - %s State"),tuya_buffer[10]?"On":"Off");
AddLog(LOG_LEVEL_DEBUG);
if((power || Settings.light_dimmer > 0) && (power != serial_in_buffer[10])) {
ExecuteCommandPower(1, serial_in_buffer[10], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
if((power || Settings.light_dimmer > 0) && (power != tuya_buffer[10])) {
ExecuteCommandPower(1, tuya_buffer[10], SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
}
}
else if (serial_in_byte_counter == 15 && serial_in_buffer[3] == 7 && serial_in_buffer[5] == 8) { // dim packet
else if (tuya_byte_counter == 15 && tuya_buffer[3] == 7 && tuya_buffer[5] == 8) { // dim packet
snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Rcvd Dim State=%d"), serial_in_buffer[13]);
snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Rcvd Dim State=%d"), tuya_buffer[13]);
AddLog(LOG_LEVEL_DEBUG);
tuya_new_dim = round(serial_in_buffer[13] * (100. / 255.));
tuya_new_dim = round(tuya_buffer[13] * (100. / 255.));
if((power) && (tuya_new_dim > 0) && (abs(tuya_new_dim - Settings.light_dimmer) > 2)) {
snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Send CMND_DIMMER=%d"), tuya_new_dim );
@ -134,7 +142,7 @@ void TuyaPacketProcess()
ExecuteCommand(scmnd, SRC_SWITCH);
}
}
else if (serial_in_byte_counter == 8 && serial_in_buffer[3] == 5 && serial_in_buffer[5] == 1 && serial_in_buffer[7] == 5 ) { // reset WiFi settings packet - to do: reset red MCU LED after WiFi is up
else if (tuya_byte_counter == 8 && tuya_buffer[3] == 5 && tuya_buffer[5] == 1 && tuya_buffer[7] == 5 ) { // reset WiFi settings packet - to do: reset red MCU LED after WiFi is up
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: WiFi Reset Rcvd"));
@ -145,16 +153,16 @@ void TuyaPacketProcess()
void TuyaSerialInput()
{
while (Serial.available()) {
while (TuyaSerial->available()) {
yield();
serial_in_byte = Serial.read();
byte serial_in_byte = TuyaSerial->read();
//snprintf_P(log_data, sizeof(log_data), PSTR("TYA: serial_in_byte %d, tuya_cmd_status %d, tuya_cmd_checksum %d, tuya_data_len %d, serial_in_byte_counter %d"), serial_in_byte, tuya_cmd_status, tuya_cmd_checksum, tuya_data_len, serial_in_byte_counter);
//snprintf_P(log_data, sizeof(log_data), PSTR("TYA: serial_in_byte %d, tuya_cmd_status %d, tuya_cmd_checksum %d, tuya_data_len %d, tuya_byte_counter %d"), serial_in_byte, tuya_cmd_status, tuya_cmd_checksum, tuya_data_len, tuya_byte_counter);
//AddLog(LOG_LEVEL_DEBUG);
if (serial_in_byte == 0x55) { // Start TUYA Packet
tuya_cmd_status = 1;
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
tuya_buffer[tuya_byte_counter++] = serial_in_byte;
tuya_cmd_checksum += serial_in_byte;
}
else if (tuya_cmd_status == 1 && serial_in_byte == 0xAA){ // Only packtes with header 0x55AA are valid
@ -162,40 +170,40 @@ void TuyaSerialInput()
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: 0x55AA Packet Start"));
serial_in_byte_counter = 0;
serial_in_buffer[serial_in_byte_counter++] = 0x55;
serial_in_buffer[serial_in_byte_counter++] = 0xAA;
tuya_byte_counter = 0;
tuya_buffer[tuya_byte_counter++] = 0x55;
tuya_buffer[tuya_byte_counter++] = 0xAA;
tuya_cmd_checksum = 0xFF;
}
else if (tuya_cmd_status == 2){
if(serial_in_byte_counter == 5){ // Get length of data
if(tuya_byte_counter == 5){ // Get length of data
tuya_cmd_status = 3;
tuya_data_len = serial_in_byte;
}
tuya_cmd_checksum += serial_in_byte;
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
tuya_buffer[tuya_byte_counter++] = serial_in_byte;
}
else if ((tuya_cmd_status == 3) && (serial_in_byte_counter == (6 + tuya_data_len)) && (tuya_cmd_checksum == serial_in_byte)){ // Compare checksum and process packet
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
else if ((tuya_cmd_status == 3) && (tuya_byte_counter == (6 + tuya_data_len)) && (tuya_cmd_checksum == serial_in_byte)){ // Compare checksum and process packet
tuya_buffer[tuya_byte_counter++] = serial_in_byte;
snprintf_P(log_data, sizeof(log_data), PSTR("TYA: 0x55 Packet End: \""));
for (int i = 0; i < serial_in_byte_counter; i++) {
snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, serial_in_buffer[i]);
for (int i = 0; i < tuya_byte_counter; i++) {
snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, tuya_buffer[i]);
}
snprintf_P(log_data, sizeof(log_data), PSTR("%s\""), log_data);
AddLog(LOG_LEVEL_DEBUG);
TuyaPacketProcess();
serial_in_byte_counter = 0;
tuya_byte_counter = 0;
tuya_cmd_status = 0;
tuya_cmd_checksum = 0;
tuya_data_len = 0;
} // read additional packets from TUYA
else if(serial_in_byte_counter < INPUT_BUFFER_SIZE -1) { // add char to string if it still fits
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
else if(tuya_byte_counter < TUYA_BUFFER_SIZE -1) { // add char to string if it still fits
tuya_buffer[tuya_byte_counter++] = serial_in_byte;
tuya_cmd_checksum += serial_in_byte;
} else {
serial_in_byte_counter = 0;
tuya_byte_counter = 0;
tuya_cmd_status = 0;
tuya_cmd_checksum = 0;
tuya_data_len = 0;
@ -205,7 +213,10 @@ void TuyaSerialInput()
boolean TuyaModuleSelected()
{
baudrate = 9600;
if (!(pin[GPIO_TUYA_RX] < 99) || !(pin[GPIO_TUYA_TX] < 99)) { // fallback to hardware-serial if not explicitly selected
pin[GPIO_TUYA_RX] = 1;
pin[GPIO_TUYA_TX] = 3;
}
light_type = LT_SERIAL;
return true;
}
@ -215,20 +226,23 @@ void TuyaInit()
if (!Settings.param[P_TUYA_DIMMER_ID]) {
Settings.param[P_TUYA_DIMMER_ID] = TUYA_DIMMER_ID;
}
Serial.setDebugOutput(false);
ClaimSerial();
TuyaSerial = new TasmotaSerial(pin[GPIO_TUYA_RX], pin[GPIO_TUYA_TX], 1);
if (TuyaSerial->begin(9600)) {
if (TuyaSerial->hardwareSerial()) { ClaimSerial(); }
// Get current status of MCU
snprintf_P(log_data, sizeof(log_data), "TYA: Request MCU state");
AddLog(LOG_LEVEL_DEBUG);
Serial.write(0x55); // header 55AA
Serial.write(0xAA);
Serial.write(0x00); // version 00
Serial.write(0x08); // command 08 - get status
Serial.write(0x00);
Serial.write(0x00); // following data length 0x00
Serial.write(0x07); // checksum:sum of all bytes in packet mod 256
Serial.flush();
TuyaSerial->write((uint8_t)0x55); // header 55AA
TuyaSerial->write((uint8_t)0xAA);
TuyaSerial->write((uint8_t)0x00); // version 00
TuyaSerial->write((uint8_t)0x08); // command 08 - get status
TuyaSerial->write((uint8_t)0x00);
TuyaSerial->write((uint8_t)0x00); // following data length 0x00
TuyaSerial->write((uint8_t)0x07); // checksum:sum of all bytes in packet mod 256
TuyaSerial->flush();
}
}
boolean TuyaButtonPressed()
@ -266,7 +280,7 @@ boolean Xdrv16(byte function)
TuyaInit();
break;
case FUNC_LOOP:
TuyaSerialInput();
if (TuyaSerial) { TuyaSerialInput(); }
break;
case FUNC_SET_DEVICE_POWER:
result = TuyaSetPower();

View File

@ -19,7 +19,7 @@
#ifdef USE_RC_SWITCH
/*********************************************************************************************\
* RF send and receive using RCSwitch library
* RF send and receive using RCSwitch library https://github.com/sui77/rc-switch/
\*********************************************************************************************/
#define D_JSON_RF_PROTOCOL "Protocol"
@ -34,39 +34,38 @@
RCSwitch mySwitch = RCSwitch();
#define RF_TIME_AVOID_DUPLICATE 500 // Milliseconds
#define RF_TIME_AVOID_DUPLICATE 1000 // Milliseconds
unsigned long rf_lasttime = 0;
uint32_t rf_lasttime = 0;
void RfReceiveCheck()
{
if (mySwitch.available()) {
unsigned long value = mySwitch.getReceivedValue();
unsigned int bit_length = mySwitch.getReceivedBitlength();
unsigned int delay = mySwitch.getReceivedDelay();
unsigned int protocol = mySwitch.getReceivedProtocol();
unsigned long data = mySwitch.getReceivedValue();
unsigned int bits = mySwitch.getReceivedBitlength();
int protocol = mySwitch.getReceivedProtocol();
int delay = mySwitch.getReceivedDelay();
snprintf_P(log_data, sizeof(log_data), PSTR("RFR: BitLen %d, Delay %d, Protocol %d, Value %lX (%u)"),
bit_length, delay, protocol, value, value);
snprintf_P(log_data, sizeof(log_data), PSTR("RFR: Data %lX (%u), Bits %d, Protocol %d, Delay %d"), data, data, bits, protocol, delay);
AddLog(LOG_LEVEL_DEBUG);
unsigned long now = millis();
if ((now - rf_lasttime > RF_TIME_AVOID_DUPLICATE) && (value > 0)) {
uint32_t now = millis();
if ((now - rf_lasttime > RF_TIME_AVOID_DUPLICATE) && (data > 0)) {
rf_lasttime = now;
char stemp[16];
if (Settings.flag.rf_receive_decimal) {
snprintf_P(stemp, sizeof(stemp), PSTR("%u"), (uint32_t)value);
if (Settings.flag.rf_receive_decimal) { // SetOption28 (0 = hexadecimal, 1 = decimal)
snprintf_P(stemp, sizeof(stemp), PSTR("%u"), (uint32_t)data);
} else {
snprintf_P(stemp, sizeof(stemp), PSTR("\"%lX\""), (uint32_t)value);
snprintf_P(stemp, sizeof(stemp), PSTR("\"%lX\""), (uint32_t)data);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_RF_PROTOCOL "\":%d,\"" D_JSON_RF_BITS "\":%d,\"" D_JSON_RF_DATA "\":%s}}"),
protocol, bit_length, stemp);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_RF_DATA "\":%s,\"" D_JSON_RF_BITS "\":%d,\"" D_JSON_RF_PROTOCOL "\":%d}}"),
stemp, bits, protocol);
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED));
XdrvRulesProcess();
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_COUNT, value); // Send value as Domoticz Counter value
DomoticzSensor(DZ_COUNT, data); // Send data as Domoticz Counter value
#endif // USE_DOMOTICZ
}
mySwitch.resetAvailable();
@ -87,42 +86,54 @@ void RfInit()
* Commands
\*********************************************************************************************/
/*
* ArduinoJSON entry used to calculate jsonBuf: JSON_OBJECT_SIZE(3) + 40 = 96
RFsend:
{ "protocol":1, "pulse":320, "repeat":15, "bits":24, "data":551502015 }
*/
boolean RfSendCommand()
{
boolean serviced = true;
boolean error = false;
char dataBufUc[XdrvMailbox.data_len];
uint32_t protocol = 0;
uint32_t pulse = 0;
uint32_t repeat = 0;
uint32_t bits = 0;
uint32_t data = 0;
UpperCase(dataBufUc, XdrvMailbox.data);
if (!strcasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_RFSEND))) {
if (XdrvMailbox.data_len) {
StaticJsonBuffer<128> jsonBuf;
JsonObject &root = jsonBuf.parseObject(dataBufUc);
if (!root.success()) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFSEND "\":\"" D_JSON_INVALID_JSON "\"}")); // JSON decode failed
}
else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFSEND "\":\"" D_JSON_DONE "\"}"));
unsigned long data = 0;
unsigned int bits = 24;
int protocol = 1;
int repeat = 10;
int pulse = 350;
char dataBufUc[XdrvMailbox.data_len];
UpperCase(dataBufUc, XdrvMailbox.data);
StaticJsonBuffer<150> jsonBuf; // ArduinoJSON entry used to calculate jsonBuf: JSON_OBJECT_SIZE(5) + 40 = 134
JsonObject &root = jsonBuf.parseObject(dataBufUc);
if (root.success()) {
// RFsend {"data":0x501014,"bits":24,"protocol":1,"repeat":10,"pulse":350}
char parm_uc[10];
protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_PROTOCOL))];
pulse = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_PULSE))];
repeat = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_REPEAT))];
data = strtoul(root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_DATA))], NULL, 0); // Allow decimal (5246996) and hexadecimal (0x501014) input
bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_BITS))];
data = strtoul(root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_DATA))], NULL, 0);
protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_PROTOCOL))];
repeat = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_REPEAT))];
pulse = root[UpperCase_P(parm_uc, PSTR(D_JSON_RF_PULSE))];
} else {
// RFsend data, bits, protocol, repeat, pulse
char *p;
byte i = 0;
for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 5; str = strtok_r(NULL, ", ", &p)) {
switch (i++) {
case 0:
data = strtoul(str, NULL, 0); // Allow decimal (5246996) and hexadecimal (0x501014) input
break;
case 1:
bits = atoi(str);
break;
case 2:
protocol = atoi(str);
break;
case 3:
repeat = atoi(str);
break;
case 4:
pulse = atoi(str);
}
}
}
if (!protocol) { protocol = 1; }
mySwitch.setProtocol(protocol);
@ -133,17 +144,15 @@ boolean RfSendCommand()
if (!bits) { bits = 24; } // Default 24 bits
if (data) {
mySwitch.send(data, bits);
}
else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFSEND "\":\"" D_JSON_DONE "\"}"));
} else {
error = true;
}
}
}
else {
} else {
error = true;
}
if (error) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFSEND "\":\"" D_JSON_NO " " D_JSON_RF_PROTOCOL ", " D_JSON_RF_PULSE ", " D_JSON_RF_REPEAT ", " D_JSON_RF_BITS " " D_JSON_OR " " D_JSON_RF_DATA "\"}"));
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFSEND "\":\"" D_JSON_NO " " D_JSON_RF_DATA ", " D_JSON_RF_BITS ", " D_JSON_RF_PROTOCOL ", " D_JSON_RF_REPEAT " " D_JSON_OR " " D_JSON_RF_PULSE "\"}"));
}
}
else serviced = false; // Unknown command

230
tools/decode-config.html Normal file
View File

@ -0,0 +1,230 @@
<h1 id="decode-config-py">decode-config.py</h1>
<p><em>decode-config.py</em> backup and restore Sonoff-Tasmota configuration.</p>
<p>Comparing backup files created by <em>decode-config.py</em> and *.dmp files created by Tasmota &quot;Backup/Restore Configuration&quot;: </p>
<table>
<thead>
<tr>
<th>&nbsp;</th>
<th style="text-align:center">decode-config.py<br />*.json file</th>
<th style="text-align:center">Sonoff-Tasmota<br />*.dmp file</th>
</tr>
</thead>
<tbody>
<tr>
<td>Encrypted</td>
<td style="text-align:center">No</td>
<td style="text-align:center">Yes</td>
</tr>
<tr>
<td>Readable</td>
<td style="text-align:center">Yes</td>
<td style="text-align:center">No</td>
</tr>
<tr>
<td>Simply editable</td>
<td style="text-align:center">Yes</td>
<td style="text-align:center">No</td>
</tr>
<tr>
<td>Simply batch processing</td>
<td style="text-align:center">Yes</td>
<td style="text-align:center">No</td>
</tr>
</tbody>
</table>
<p><em>decode-config.py</em> handles Tasmota configurations for release version since 5.10.0 up to now.</p>
<h1 id="content">Content</h1>
<ul>
<li><a href="decode-config.html#prerequisite">Prerequisite</a></li>
<li><a href="decode-config.html#file-types">File Types</a><ul>
<li><a href="decode-config.html#-dmp-file-format">.dmp File Format</a></li>
<li><a href="decode-config.html#-json-file-format">.json File Format</a></li>
<li><a href="decode-config.html#-bin-file-format">.bin File Format</a><ul>
<li><a href="decode-config.html#file-extensions">File extensions</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="decode-config.html#usage">Usage</a><ul>
<li><a href="decode-config.html#basics">Basics</a></li>
<li><a href="decode-config.html#save-backup-file">Save backup file</a></li>
<li><a href="decode-config.html#restore-backup-file">Restore backup file</a></li>
<li><a href="decode-config.html#configuration-file">Configuration file</a></li>
<li><a href="decode-config.html#more-program-arguments">More program arguments</a></li>
<li><a href="decode-config.html#examples">Examples</a><ul>
<li><a href="decode-config.html#config-file">Config file</a></li>
<li><a href="decode-config.html#using-tasmota-binary-configuration-files">Using Tasmota binary configuration files</a></li>
<li><a href="decode-config.html#use-batch-processing">Use batch processing</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="prerequisite">Prerequisite</h2>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Python_(programming_language">Python</a>)<br>This program is written in <a href="https://en.wikipedia.org/wiki/Python_(programming_language">Python</a>) so you need to install a python environment (for details see <a href="https://docs.python.org/2.7/using/index.html">Python Setup and Usage</a>)</li>
<li><a href="https://github.com/arendst/Sonoff-Tasmota">Sonoff-Tasmota</a> <a href="https://github.com/arendst/Sonoff-Tasmota/releases">Firmware</a> with enabled Web-Server<br>To backup or restore configurations from/to a Sonoff-Tasmota device you need a firmare with enabled web-server in admin mode (command <a href="https://github.com/arendst/Sonoff-Tasmota/wiki/Commands#wifi">WebServer 2</a>).
<br />Only self compiled firmware may do not have a web-server sod if you use your own compiled firmware be aware to enable the web-server, otherwise you can only use the <code>--file</code> parameter as source.</li>
</ul>
<h2 id="file-types">File Types</h2>
<p><em>decode-config.py</em> can handle the following backup file types: </p>
<h3 id="-dmp-format">.dmp Format</h3>
<p>Configuration data as used by Tasmota &quot;Backup/Restore Configuration&quot; web interface.<br>This format is binary and encrypted.</p>
<h3 id="-json-format">.json Format</h3>
<p>Configuration data in <a href="http://www.json.org/">JSON</a>-format.<br>This format is decrypted, human readable and editable and can also be used for the <code>--restore-file</code> command.<br>This file will becreated by <em>decode-config.py</em> using <code>--backup-file</code> with <code>--backup-type json</code> parameter (default).</p>
<h3 id="-bin-format">.bin Format</h3>
<p>Configuration data in binary format.<br>This format is binary decryptet, editable (e.g. using a hex editor) and can also be used for <code>--restore-file</code> command.<br>It will be created by <em>decode-config.py</em> using <code>--backup-file</code> with <code>--backup-type bin</code>.<br>Note:<br>This file is 4 byte longer than an original .dmp file due to an prefix header at the beginning. The file data starting at address position 4 are containing the same as the <strong>struct SYSCFG</strong> from Tasmota <a href="https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/settings.h">settings.h</a> in decrypted format.</p>
<h4 id="file-extensions">File extensions</h4>
<p><em>decode-config.py</em> uses auto extension as default for backup filenames; you don&#39;t need to append extensions to your backup file, it will be selected based on <code>--backup-type</code> argument.<br>If you want using your own extension use the <code>--no-extension</code> argument.</p>
<h2 id="usage">Usage</h2>
<p>After download don&#39;t forget to set exec flag under linux with <code>chmod +x decode-config.py</code> or call the program using <code>python decode-config.py...</code>.</p>
<h3 id="basics">Basics</h3>
<p>At least pass a source where you want to read the configuration data from using <code>-f &lt;filename&gt;</code> or <code>-d &lt;host&gt;</code>:</p>
<p>The source can be either </p>
<ul>
<li>a Tasmota device hostname or IP by passing it using the <code>-d &lt;host&gt;</code> arg</li>
<li>or a previously stored Tasmota *.dmp<code>configuration file by passing the filename using</code>-f <filename>` arg</li>
</ul>
<p>Example: </p>
<pre><code>decode-config<span class="hljs-selector-class">.py</span> -d sonoff-<span class="hljs-number">4281</span>
</code></pre><p>will output a human readable configuration in <a href="http://www.json.org/">JSON</a>-format:</p>
<pre><code>{
<span class="hljs-string">"altitude"</span>: <span class="hljs-number">112</span>,
<span class="hljs-string">"baudrate"</span>: <span class="hljs-number">115200</span>,
<span class="hljs-string">"blinkcount"</span>: <span class="hljs-number">10</span>,
<span class="hljs-string">"blinktime"</span>: <span class="hljs-number">10</span>,
...
<span class="hljs-string">"ws_width"</span>: [
<span class="hljs-number">1</span>,
<span class="hljs-number">3</span>,
<span class="hljs-number">5</span>
]
}
</code></pre><h3 id="save-backup-file">Save backup file</h3>
<p>To save the output as backup file <code>--backup-file &lt;filename&gt;</code>, you can use placeholder for Version, Friendlyname and Hostname: </p>
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">sonoff-4281</span> <span class="hljs-selector-tag">--backup-file</span> <span class="hljs-selector-tag">Config_</span>@<span class="hljs-keyword">f_</span>@<span class="hljs-keyword">v</span>
</code></pre><p>If you have setup a WebPassword within Tasmota, use</p>
<pre><code>decode-config<span class="hljs-selector-class">.py</span> -d sonoff-<span class="hljs-number">4281</span> -<span class="hljs-selector-tag">p</span> &lt;yourpassword&gt; --backup-file Config_@f_@v
</code></pre><p>will create a file like <code>Config_Sonoff_x.x.x.json</code>. Because it is in JSON format, you can read and edit the file with any raw text editor.</p>
<h3 id="restore-backup-file">Restore backup file</h3>
<p>Reading back a saved (and possible changed) backup file use the <code>--restore-file &lt;filename&gt;</code> arg. This will read the (changed) configuration data from this file and send it back to the source device or filename.</p>
<p>To restore the previously save backup file <code>Config_Sonoff_6.2.1.json</code> to device <code>sonoff-4281</code> use: </p>
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">sonoff-4281</span> <span class="hljs-selector-tag">--restore-file</span> <span class="hljs-selector-tag">Config_Sonoff_6</span><span class="hljs-selector-class">.2</span><span class="hljs-selector-class">.1</span><span class="hljs-selector-class">.json</span>
</code></pre><p>with password set by WebPassword:</p>
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">sonoff-4281</span> <span class="hljs-selector-tag">-p</span> &lt;<span class="hljs-selector-tag">yourpassword</span>&gt; <span class="hljs-selector-tag">--restore-file</span> <span class="hljs-selector-tag">Config_Sonoff_6</span><span class="hljs-selector-class">.2</span><span class="hljs-selector-class">.1</span><span class="hljs-selector-class">.json</span>
</code></pre><h3 id="configuration-file">Configuration file</h3>
<p>Each argument that start with <code>--</code> (eg. <code>--file</code>) can also be set in a config file (specified via -c). Config file syntax allows: key=value, flag=true, stuff=[a,b,c] (for details, see syntax at <a href="https://pypi.org/project/ConfigArgParse/">https://pypi.org/project/ConfigArgParse</a>).</p>
<p>If an argument is specified in more than one place, then commandline values override config file values which override defaults. This is usefull if you always use the same argument or a basic set of arguments.</p>
<p>The http authentication credentials <code>--username</code> and <code>--password</code> is predestinated to store it in a file instead using it on your command line as argument:</p>
<p>e.g. my.conf:</p>
<pre><code><span class="hljs-section">[source]</span>
<span class="hljs-attr">username</span> = admin
<span class="hljs-attr">password</span> = myPaszxwo!z
</code></pre><p>To make a backup file from example above you can now pass the config file instead using the password on command line:</p>
<pre><code><span class="hljs-selector-tag">decode-config</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">-d</span> <span class="hljs-selector-tag">sonoff-4281</span> <span class="hljs-selector-tag">-c</span> <span class="hljs-selector-tag">my</span><span class="hljs-selector-class">.conf</span> <span class="hljs-selector-tag">--backup-file</span> <span class="hljs-selector-tag">Config_</span>@<span class="hljs-keyword">f_</span>@<span class="hljs-keyword">v</span>
</code></pre><h3 id="more-program-arguments">More program arguments</h3>
<p>For better reading your porgram arguments each short written arg (minus sign <code>-</code>) has a corresponding readable long version (two minus signs <code>--</code>), eg. <code>--device</code> for <code>-d</code> or <code>--file</code> for <code>-f</code> (note: not even all <code>--</code> arg has a corresponding <code>-</code> one).</p>
<p>A short list of possible program args is displayed using <code>-h</code> or <code>--help</code>.</p>
<p>For advanced help use <code>-H</code> or <code>--full-help</code>:</p>
<pre><code>usage: decode-config.py [-f &lt;filename&gt;] [-d &lt;host&gt;] [-P &lt;<span class="hljs-keyword">port</span>&gt;]
[-u &lt;username&gt;] [-p &lt;password&gt;] [-i &lt;filename&gt;]
[-o &lt;filename&gt;] [-F json|bin|dmp] [-E] [-e]
[<span class="hljs-comment">--json-indent &lt;indent&gt;] [--json-compact]</span>
[<span class="hljs-comment">--json-hide-pw] [--json-unhide-pw] [-h] [-H] [-v]</span>
[-V] [-c &lt;filename&gt;] [<span class="hljs-comment">--ignore-warnings]</span>
Backup/Restore Sonoff-Tasmota <span class="hljs-keyword">configuration</span> data. Args that start <span class="hljs-keyword">with</span> '<span class="hljs-comment">--'</span>
(eg. -f) can also be set <span class="hljs-keyword">in</span> a config <span class="hljs-keyword">file</span> (specified via -c). Config <span class="hljs-keyword">file</span>
syntax allows: key=value, flag=<span class="hljs-literal">true</span>, stuff=[a,b,c] (<span class="hljs-keyword">for</span> details, see syntax at
https://goo.gl/R74nmi). <span class="hljs-keyword">If</span> an arg <span class="hljs-keyword">is</span> specified <span class="hljs-keyword">in</span> more than one place, <span class="hljs-keyword">then</span>
commandline values override config <span class="hljs-keyword">file</span> values which override defaults.
optional arguments:
-c, <span class="hljs-comment">--config &lt;filename&gt;</span>
program config <span class="hljs-keyword">file</span> - can be used <span class="hljs-keyword">to</span> set <span class="hljs-keyword">default</span>
command args (<span class="hljs-keyword">default</span>: None)
<span class="hljs-comment">--ignore-warnings do not exit on warnings. Not recommended, used by your</span>
own responsibility!
Source:
Read/Write Tasmota <span class="hljs-keyword">configuration</span> from/<span class="hljs-keyword">to</span>
-f, <span class="hljs-comment">--file, --tasmota-file &lt;filename&gt;</span>
<span class="hljs-keyword">file</span> <span class="hljs-keyword">to</span> retrieve/write Tasmota <span class="hljs-keyword">configuration</span> from/<span class="hljs-keyword">to</span>
(<span class="hljs-keyword">default</span>: None)'
-d, <span class="hljs-comment">--device, --host &lt;host&gt;</span>
hostname <span class="hljs-keyword">or</span> IP address <span class="hljs-keyword">to</span> retrieve/send Tasmota
<span class="hljs-keyword">configuration</span> from/<span class="hljs-keyword">to</span> (<span class="hljs-keyword">default</span>: None)
-P, <span class="hljs-comment">--port &lt;port&gt; TCP/IP port number to use for the host connection</span>
(<span class="hljs-keyword">default</span>: <span class="hljs-number">80</span>)
-u, <span class="hljs-comment">--username &lt;username&gt;</span>
host HTTP <span class="hljs-keyword">access</span> username (<span class="hljs-keyword">default</span>: admin)
-p, <span class="hljs-comment">--password &lt;password&gt;</span>
host HTTP <span class="hljs-keyword">access</span> password (<span class="hljs-keyword">default</span>: None)
Backup/Restore:
Backup/Restore <span class="hljs-keyword">configuration</span> <span class="hljs-keyword">file</span> specification
-i, <span class="hljs-comment">--restore-file &lt;filename&gt;</span>
<span class="hljs-keyword">file</span> <span class="hljs-keyword">to</span> restore <span class="hljs-keyword">configuration</span> from (<span class="hljs-keyword">default</span>: None).
Replacements: @v=firmware version, @f=device friendly
name, @h=device hostname
-o, <span class="hljs-comment">--backup-file &lt;filename&gt;</span>
<span class="hljs-keyword">file</span> <span class="hljs-keyword">to</span> backup <span class="hljs-keyword">configuration</span> <span class="hljs-keyword">to</span> (<span class="hljs-keyword">default</span>: None).
Replacements: @v=firmware version, @f=device friendly
name, @h=device hostname
-F, <span class="hljs-comment">--backup-type json|bin|dmp</span>
backup filetype (<span class="hljs-keyword">default</span>: <span class="hljs-symbol">'json</span>')
-E, <span class="hljs-comment">--extension append filetype extension for -i and -o filename</span>
(<span class="hljs-keyword">default</span>)
-e, <span class="hljs-comment">--no-extension do not append filetype extension, use -i and -o</span>
filename as passed
JSON:
JSON backup format specification
<span class="hljs-comment">--json-indent &lt;indent&gt;</span>
pretty-printed JSON output using indent level
(<span class="hljs-keyword">default</span>: <span class="hljs-symbol">'None</span>'). -<span class="hljs-number">1</span> disables indent.
<span class="hljs-comment">--json-compact compact JSON output by eliminate whitespace</span>
<span class="hljs-comment">--json-hide-pw hide passwords (default)</span>
<span class="hljs-comment">--json-unhide-pw unhide passwords</span>
Info:
additional information
-h, <span class="hljs-comment">--help show usage help message and exit</span>
-H, <span class="hljs-comment">--full-help show full help message and exit</span>
-v, <span class="hljs-comment">--verbose produce more output about what the program does</span>
-V, <span class="hljs-comment">--version show program's version number and exit</span>
Either argument -d &lt;host&gt; <span class="hljs-keyword">or</span> -f &lt;filename&gt; must be given.
</code></pre><h3 id="examples">Examples</h3>
<p>The most of the examples are for linux command line. Under Windows call the program using <code>python decode-config.py ...</code>.</p>
<h4 id="config-file">Config file</h4>
<p>Note: The example contains .ini style sections <code>[...]</code>. Sections are always treated as comment and serves as clarity only.
For further details of config file syntax see <a href="https://pypi.org/project/ConfigArgParse/">https://pypi.org/project/ConfigArgParse</a>.</p>
<p><em>my.conf</em></p>
<pre><code><span class="hljs-string">[Source]</span>
username = admin
password = myPaszxwo!z
<span class="hljs-string">[JSON]</span>
json-indent <span class="hljs-number">2</span>
</code></pre><h4 id="using-tasmota-binary-configuration-files">Using Tasmota binary configuration files</h4>
<ol>
<li><p>Restore a Tasmota configuration file</p>
<p> <code>decode-config.py -c my.conf -d sonoff --restore-file Config_Sonoff_6.2.1.dmp</code></p>
</li>
<li><p>Backup device using Tasmota configuration compatible format</p>
<p>a) use file extension to choice the file format</p>
<p> <code>decode-config.py -c my.conf -d sonoff --backup-file Config_@f_@v.dmp</code></p>
<p>b) use args to choice the file format</p>
<p> <code>decode-config.py -c my.conf -d sonoff --backup-type dmp --backup-file Config_@f_@v</code></p>
</li>
</ol>
<h4 id="use-batch-processing">Use batch processing</h4>
<pre><code><span class="hljs-keyword">for</span> device <span class="hljs-keyword">in</span> sonoff1 sonoff2 sonoff3; <span class="hljs-keyword">do</span> ./decode-config.py -c my.conf -d <span class="hljs-variable">$device</span> -o Config<span class="hljs-number">_</span><span class="hljs-variable">@f_</span><span class="hljs-variable">@v</span>
</code></pre><p>or under windows</p>
<pre><code><span class="hljs-keyword">for</span> device <span class="hljs-keyword">in</span> (sonoff1 sonoff2 sonoff3) <span class="hljs-keyword">do</span> <span class="hljs-keyword">python</span> decode-config.py -c my.conf -d %device -o Config_@f_@v
</code></pre><p>will produce JSON configuration files for host sonoff1, sonoff2 and sonoff3 using friendly name and Tasmota firmware version for backup filenames.</p>

253
tools/decode-config.md Normal file
View File

@ -0,0 +1,253 @@
# decode-config.py
_decode-config.py_ backup and restore Sonoff-Tasmota configuration.
Comparing backup files created by *decode-config.py* and *.dmp files created by Tasmota "Backup/Restore Configuration":
| &nbsp; | decode-config.py<br />*.json file | Sonoff-Tasmota<br />*.dmp file |
|-------------------------|:-------------------------------:|:-----------------------------------:|
| Encrypted | No | Yes |
| Readable | Yes | No |
| Simply editable | Yes | No |
| Simply batch processing | Yes | No |
_decode-config.py_ handles Tasmota configurations for release version since 5.10.0 up to now.
# Content
* [Prerequisite](decode-config.md#prerequisite)
* [File Types](decode-config.md#file-types)
* [.dmp File Format](decode-config.md#-dmp-file-format)
* [.json File Format](decode-config.md#-json-file-format)
* [.bin File Format](decode-config.md#-bin-file-format)
* [File extensions](decode-config.md#file-extensions)
* [Usage](decode-config.md#usage)
* [Basics](decode-config.md#basics)
* [Save backup file](decode-config.md#save-backup-file)
* [Restore backup file](decode-config.md#restore-backup-file)
* [Configuration file](decode-config.md#configuration-file)
* [More program arguments](decode-config.md#more-program-arguments)
* [Examples](decode-config.md#examples)
* [Config file](decode-config.md#config-file)
* [Using Tasmota binary configuration files](decode-config.md#using-tasmota-binary-configuration-files)
* [Use batch processing](decode-config.md#use-batch-processing)
## Prerequisite
* [Python](https://en.wikipedia.org/wiki/Python_(programming_language))
This program is written in [Python](https://en.wikipedia.org/wiki/Python_(programming_language)) so you need to install a python environment (for details see [Python Setup and Usage](https://docs.python.org/2.7/using/index.html))
* [Sonoff-Tasmota](https://github.com/arendst/Sonoff-Tasmota) [Firmware](https://github.com/arendst/Sonoff-Tasmota/releases) with enabled Web-Server
To backup or restore configurations from/to a Sonoff-Tasmota device you need a firmare with enabled web-server in admin mode (command [WebServer 2](https://github.com/arendst/Sonoff-Tasmota/wiki/Commands#wifi)).
<br />Only self compiled firmware may do not have a web-server sod if you use your own compiled firmware be aware to enable the web-server, otherwise you can only use the `--file` parameter as source.
## File Types
_decode-config.py_ can handle the following backup file types:
### .dmp Format
Configuration data as used by Tasmota "Backup/Restore Configuration" web interface.
This format is binary and encrypted.
### .json Format
Configuration data in [JSON](http://www.json.org/)-format.
This format is decrypted, human readable and editable and can also be used for the `--restore-file` command.
This file will becreated by _decode-config.py_ using `--backup-file` with `--backup-type json` parameter (default).
### .bin Format
Configuration data in binary format.
This format is binary decryptet, editable (e.g. using a hex editor) and can also be used for `--restore-file` command.
It will be created by _decode-config.py_ using `--backup-file` with `--backup-type bin`.
Note:
This file is 4 byte longer than an original .dmp file due to an prefix header at the beginning. The file data starting at address position 4 are containing the same as the **struct SYSCFG** from Tasmota [settings.h](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/settings.h) in decrypted format.
#### File extensions
_decode-config.py_ uses auto extension as default for backup filenames; you don't need to append extensions to your backup file, it will be selected based on `--backup-type` argument.
If you want using your own extension use the `--no-extension` argument.
## Usage
After download don't forget to set exec flag under linux with `chmod +x decode-config.py` or call the program using `python decode-config.py...`.
### Basics
At least pass a source where you want to read the configuration data from using `-f <filename>` or `-d <host>`:
The source can be either
* a Tasmota device hostname or IP by passing it using the `-d <host>` arg
* or a previously stored Tasmota *.dmp` configuration file by passing the filename using `-f <filename>` arg
Example:
decode-config.py -d sonoff-4281
will output a human readable configuration in [JSON](http://www.json.org/)-format:
{
"altitude": 112,
"baudrate": 115200,
"blinkcount": 10,
"blinktime": 10,
...
"ws_width": [
1,
3,
5
]
}
### Save backup file
To save the output as backup file `--backup-file <filename>`, you can use placeholder for Version, Friendlyname and Hostname:
decode-config.py -d sonoff-4281 --backup-file Config_@f_@v
If you have setup a WebPassword within Tasmota, use
decode-config.py -d sonoff-4281 -p <yourpassword> --backup-file Config_@f_@v
will create a file like `Config_Sonoff_x.x.x.json`. Because it is in JSON format, you can read and edit the file with any raw text editor.
### Restore backup file
Reading back a saved (and possible changed) backup file use the `--restore-file <filename>` arg. This will read the (changed) configuration data from this file and send it back to the source device or filename.
To restore the previously save backup file `Config_Sonoff_6.2.1.json` to device `sonoff-4281` use:
decode-config.py -d sonoff-4281 --restore-file Config_Sonoff_6.2.1.json
with password set by WebPassword:
decode-config.py -d sonoff-4281 -p <yourpassword> --restore-file Config_Sonoff_6.2.1.json
### Configuration file
Each argument that start with `--` (eg. `--file`) can also be set in a config file (specified via -c). Config file syntax allows: key=value, flag=true, stuff=[a,b,c] (for details, see syntax at [https://pypi.org/project/ConfigArgParse](https://pypi.org/project/ConfigArgParse/)).
If an argument is specified in more than one place, then commandline values override config file values which override defaults. This is usefull if you always use the same argument or a basic set of arguments.
The http authentication credentials `--username` and `--password` is predestinated to store it in a file instead using it on your command line as argument:
e.g. my.conf:
[source]
username = admin
password = myPaszxwo!z
To make a backup file from example above you can now pass the config file instead using the password on command line:
decode-config.py -d sonoff-4281 -c my.conf --backup-file Config_@f_@v
### More program arguments
For better reading your porgram arguments each short written arg (minus sign `-`) has a corresponding readable long version (two minus signs `--`), eg. `--device` for `-d` or `--file` for `-f` (note: not even all `--` arg has a corresponding `-` one).
A short list of possible program args is displayed using `-h` or `--help`.
For advanced help use `-H` or `--full-help`:
usage: decode-config.py [-f <filename>] [-d <host>] [-P <port>]
[-u <username>] [-p <password>] [-i <filename>]
[-o <filename>] [-F json|bin|dmp] [-E] [-e]
[--json-indent <indent>] [--json-compact]
[--json-hide-pw] [--json-unhide-pw] [-h] [-H] [-v]
[-V] [-c <filename>] [--ignore-warnings]
Backup/Restore Sonoff-Tasmota configuration data. Args that start with '--'
(eg. -f) can also be set in a config file (specified via -c). Config file
syntax allows: key=value, flag=true, stuff=[a,b,c] (for details, see syntax at
https://goo.gl/R74nmi). If an arg is specified in more than one place, then
commandline values override config file values which override defaults.
optional arguments:
-c, --config <filename>
program config file - can be used to set default
command args (default: None)
--ignore-warnings do not exit on warnings. Not recommended, used by your
own responsibility!
Source:
Read/Write Tasmota configuration from/to
-f, --file, --tasmota-file <filename>
file to retrieve/write Tasmota configuration from/to
(default: None)'
-d, --device, --host <host>
hostname or IP address to retrieve/send Tasmota
configuration from/to (default: None)
-P, --port <port> TCP/IP port number to use for the host connection
(default: 80)
-u, --username <username>
host HTTP access username (default: admin)
-p, --password <password>
host HTTP access password (default: None)
Backup/Restore:
Backup/Restore configuration file specification
-i, --restore-file <filename>
file to restore configuration from (default: None).
Replacements: @v=firmware version, @f=device friendly
name, @h=device hostname
-o, --backup-file <filename>
file to backup configuration to (default: None).
Replacements: @v=firmware version, @f=device friendly
name, @h=device hostname
-F, --backup-type json|bin|dmp
backup filetype (default: 'json')
-E, --extension append filetype extension for -i and -o filename
(default)
-e, --no-extension do not append filetype extension, use -i and -o
filename as passed
JSON:
JSON backup format specification
--json-indent <indent>
pretty-printed JSON output using indent level
(default: 'None'). -1 disables indent.
--json-compact compact JSON output by eliminate whitespace
--json-hide-pw hide passwords (default)
--json-unhide-pw unhide passwords
Info:
additional information
-h, --help show usage help message and exit
-H, --full-help show full help message and exit
-v, --verbose produce more output about what the program does
-V, --version show program's version number and exit
Either argument -d <host> or -f <filename> must be given.
### Examples
The most of the examples are for linux command line. Under Windows call the program using `python decode-config.py ...`.
#### Config file
Note: The example contains .ini style sections `[...]`. Sections are always treated as comment and serves as clarity only.
For further details of config file syntax see [https://pypi.org/project/ConfigArgParse](https://pypi.org/project/ConfigArgParse/).
*my.conf*
[Source]
username = admin
password = myPaszxwo!z
[JSON]
json-indent 2
#### Using Tasmota binary configuration files
1. Restore a Tasmota configuration file
`decode-config.py -c my.conf -d sonoff --restore-file Config_Sonoff_6.2.1.dmp`
2. Backup device using Tasmota configuration compatible format
a) use file extension to choice the file format
`decode-config.py -c my.conf -d sonoff --backup-file Config_@f_@v.dmp`
b) use args to choice the file format
`decode-config.py -c my.conf -d sonoff --backup-type dmp --backup-file Config_@f_@v`
#### Use batch processing
for device in sonoff1 sonoff2 sonoff3; do ./decode-config.py -c my.conf -d $device -o Config_@f_@v
or under windows
for device in (sonoff1 sonoff2 sonoff3) do python decode-config.py -c my.conf -d %device -o Config_@f_@v
will produce JSON configuration files for host sonoff1, sonoff2 and sonoff3 using friendly name and Tasmota firmware version for backup filenames.

1898
tools/decode-config.py Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,492 @@
:020000040000FA
:1000000002142AED24F8FEEFD39E4015ED2408FDDE
:10001000E433FCC3EF9DEC6480F874809850028058
:1000200001C32202139A7597A522220218387EFF77
:10003000EFD394004022EF9480501DE4FDED75F065
:1000400005A4240CF582E4341EF583E493B507047B
:10005000AE0580040DBD06E5AF06220215CD121DCA
:100060004053D87853DBFE121D04E4900085F02243
:10007000D2DE2202188BD202121ABAC290C296D2D3
:1000800080E4FBFD7F10121CEB1206CE74A4F0D2AC
:10009000AFE4F53BF53CD296053CE53C7002053BF0
:1000A000B410F3E53BB427EEC296120026300209E5
:1000B0001219F48E3E8F3F8006753E01753F00E5B4
:1000C0003F7004E53E640170409000CCE07007F59D
:1000D0003BF53C02028D053CE53C7002053BD394A8
:1000E00010E53B94274002D296D3E53C9430E53BA3
:1000F0009475500302028DE4F53BF53C9000CCF082
:100100009000CBF0C29602028DE4F53BF53C9000E6
:10011000CCE014602A14700302025F147003020220
:100120001D1470030202332404600302028DE53FB4
:1001300064AA600302028D9000CC04F002028DE5F7
:100140003F9000CBF0A37402F0E53F120C3902059A
:10015000A00173A10185A501A9A601BDA701C6A89B
:1001600001E2A901C9B001D2B1019AC0028DFF001C
:100170000002141206879000A87401F0E490007544
:10018000F07FA1806E12005E9000CC7404F0753D8B
:1001900008E4F54175400902028D9000CC7404F02A
:1001A000E4F54175400202028DE49000A8F0900051
:1001B00075F07FA612071174A6F002028D1206CE0A
:1001C00074A4F002028D753D089000CC7403F00217
:1001D000028D9000757401F07FB1120711EFF002EB
:1001E000028D1206879000A8E0F53AE4F0900075C1
:1001F000F07FA91219B790007CEFF07D307C75126A
:10020000070002028D1206EE90007CEFF0E49000F1
:10021000CCF08079E49000CBF0A3F08070E4F5415D
:10022000E53FF540E540D394009000CC402C7404A9
:10023000F0805A74042541F582E43400F583E53FEB
:10024000F00541E541B540059000CC800DE541C386
:10025000947040397540709000CC7402F0802EE5A7
:100260003F645570289000CCF0C2029000CBE0248F
:1002700060601824FC600F24FE600B14600824F6F4
:100280006004241070077FA0121CB8D2029000CB2B
:10029000E0120C3902B6A102E0A402F2A503DAA62C
:1002A00003F6A805C0A905FDB00670B103A6C003FA
:1002B000C8FF000000AA900084E030E70F7DC87CF2
:1002C000001206B77FA312192E0205DA121CFC4099
:1002D000030200AA7DE87C031206B77FA20205F59F
:1002E000900084E020E7030200AA7FA412192E02E6
:1002F00003EE9000CCE060030200AA900085E024A9
:10030000FC6070240460030200AA153D900008E020
:10031000FEA3E0FF7C007D64120C5FC006C00712E4
:100320001573D007D006120BA78F4B900006E0FE86
:10033000A3E0FF8E4CF54D7C007D64120C5FC0067F
:10034000C007121573D007D006120BA78F4E754F3A
:1003500018900008E0FAA3E0FB900004E0FCA3E0A2
:10036000FDA3E0FEA3E0FF1217569000747406F0A0
:100370000204B97F0112002E12159960030200AA2F
:10038000E53D601A7F0112002EEF12154912158DFE
:1003900050030205B81206E2121D2E0205B812061D
:1003A000EE7FA00205F59000CCE060030200AA9069
:1003B0000004E0FCA3E0FD120700D296121D2EC23D
:1003C000967FA0121CB8800A7F01121CB8E490002E
:1003D000CCF0D2021206F70200AA900084E020E7D7
:1003E000030200AA547FF543FD7FA61214B9E490DE
:1003F0000084F00200AA9000CCE060030200AA9002
:100400000085E024FC7003020569240460030200F7
:10041000AA900004E0FF2480600804700DE4F51D3C
:100420008003751D017542FF800F12002E8F42E57B
:1004300042F46005121599F51D153D12005EE51D8B
:1004400014607C0460030200AA900004E0647F70E2
:1004500024A31215BAA3E0FAA3E0FBA3E0F54BA393
:10046000E0F54CA3E0F54DA3E0F54EA3E01207083C
:10047000740CF0803BE542F46031121547F5828E32
:10048000831215AA740593FA740693FB740993F505
:100490004B740793F54C740893F54D740A93F54E1D
:1004A000740B931207087401F08005E49000CBF000
:1004B0009000CBE070030200AA121BF00200AA9089
:1004C0000004E06480704E900074740CF090000B97
:1004D000E0FF7E00900009E0FCA3E0FD120A47C0A7
:1004E00006C00790000C1215C6C007C00690000D8C
:1004F0001215C6AA06AB0790000E1215C68E4F8FB6
:10050000508A4D8B4ED04BD04C9000051215BA90AE
:10051000000FE08048E542F4700302062F121547F1
:100520009000747401F08544828E83740612156401
:10053000C006C0077407121564C007C0067408120D
:100540001564AA06AB0774091215648E4F8F508A82
:100550004D8B4ED04BD04C1215AA740A93F551D046
:1005600003D0021217D00200AAE53D70101206F760
:100570007FA0121CB8D202E4F51D0200AAE51D14EA
:10058000601B0460030200AAE542F4600E121547E6
:1005900012158D40061206E2121D2E801BE542F454
:1005A000601612154712158D400EEFFD7C007F017D
:1005B0007E00121B0D121D2EE4900085F00200AA91
:1005C000900084E0FF30E71C547FF5437DC87C0039
:1005D00012069AAD437FAB1214B9E4900084F0D2B6
:1005E000020200AA121CFC40030200AA7DE87C0360
:1005F00012069A7FAA121CB8D2020200AA90000426
:10060000E025E0F5439000CCE060030200AA9000F2
:1006100085E0700512005E800B900085E064046048
:10062000030200AAE5436007E540C394045008E4D0
:100630009000CBF00200AA74062543F9E43400755B
:100640004801F549894AC3E540954324FEF54B909E
:100650000005E0F54C7B017A0079061216527FA066
:10066000121CB890007CE0FF1219B7D2020200AA57
:10067000900084E020E7030200AA7FB11216D4E4C0
:10068000900084F00200AA7D327C007F017E00127F
:100690001B0DD296121D2EC296227F017E00121BC8
:1006A0000DD296121D2EC2969000A8E53AF0900049
:1006B0007CE0FF1219B7227F017E00121B0DD2963B
:1006C000121D2EC29690007CE0FF1219B7229000F6
:1006D000A87401F0E4900075F07FA41219B790009F
:1006E0007C22EFFD7C007F017E00121B0D2290001A
:1006F0007CE0FF1219B72290007CE0FF1219B722AC
:100700007F017E00121B0D22F54F121756900074C8
:10071000221219B790007C22AFE9AEEA120DB68E14
:10072000088F092093030209A285080A85090BC3D3
:10073000E509950DF511E508950CF510900075E0AB
:1007400014700302099C0460030209C3900085E051
:100750001460650460030209C3900084E060030232
:1007600009C39000A8E0FFAB11AA10AD0FAC0E12A8
:1007700010558F1AE51A648070030209C390007F38
:10078000120E6B900002E510F0A3E511120DC1E40A
:10079000900074F0900077F090007EF0F51BF51C4F
:1007A000FE7F70FD7B017A007904120C8CE49000CE
:1007B0007DF090008504F022E51A120D998E23F544
:1007C00024E51A120DFA70030208D004600302092E
:1007D000C3900004120CBBFFD39400400B90007E2A
:1007E000E09F5004E004F022120E13AE10AF11ABE4
:1007F00007AA06E50F2BFFE50E3AFEE433FDE433CE
:10080000FCC004A905AA06AB07AE0EAF0F120E730B
:10081000D000120BA78F22120D80FD120003401989
:1008200090000A120D83FDAF22120003400B120C40
:10083000B8120E646003020954120D80FDAF22123B
:1008400000035009120CB8C3120E444013D3E50F35
:10085000951CE50E951B402B120CB8120E647023EC
:10086000900086120E6B120CC4C083C082120E0B55
:100870007401A806088002C333D8FC4FD082D0830D
:10088000F0801790007A120E6BC290D3951CE50E83
:10089000951B4006850E1B850F1C900088E0700D8F
:1008A000120CC6120D78FF121C4D120DBD120CB8A1
:1008B000120E6460030209C3121CF45005E4900098
:1008C00083F0120D7570030209941209D70209947E
:1008D000120CB8FF7E00900004120AE4FDACF01286
:1008E0000A47120DE18E258F26120E13E4850F158F
:1008F000850E14F513F512851119851018F517F5E5
:1009000016900006120CF81209C4500F900007123E
:100910000CF21209F55004C2908043900008120CAA
:10092000F21209C4502EAA23A9247BFF90000912B9
:100930000CF81209F5501D120CC4C083C082120EAF
:100940000B7401A806088002C333D8FC4FD082D0B4
:1009500083F0800AE4900084F0C290A3F02290001B
:1009600088E0700D120CC6120D78FF121C4D120D8E
:10097000BDAA23A9247BFF90000A120A08120E6464
:100980007041121CF45005E4900083F0120D756064
:10099000031209D7C290E4900085F022AF11AE1087
:1009A000801E85080C85090DC3E509950BF50FE53B
:1009B00008950AF50E900075E0147007AF0FAE0EA3
:1009C000120E9B22E5159FFFE5149EFE121CACC380
:1009D000EF9526EE952522121D047D207C037F01D4
:1009E0007E00121AE490007DE0900083F0A3E51AE7
:1009F000F04480F022E5199FFFE5189EFE121CAC22
:100A0000C3EF9526EE952522BB010CE58229F582E0
:100A1000E5833AF583E0225006E92582F8E622BB19
:100A2000FE06E92582F8E222E58229F582E5833A8D
:100A3000F583E49322BB010689828A83F022500267
:100A4000F722BBFE01F322EF8DF0A4A8F0CF8CF0CB
:100A5000A428CE8DF0A42EFE22BC000BBE0029EFF0
:100A60008DF084FFADF022E4CCF875F008EF2FFF95
:100A7000EE33FEEC33FCEE9DEC984005FCEE9DFE63
:100A80000FD5F0E9E4CEFD22EDF8F5F0EE8420D2AA
:100A90001CFEADF075F008EF2FFFED33FD40079819
:100AA0005006D5F0F222C398FD0FD5F0EA22C2D548
:100AB000EC30E709B2D5E4C39DFDE49CFCEE30E7E1
:100AC00015B2D5E4C39FFFE49EFE120A59C3E49D0C
:100AD000FDE49CFC8003120A5930D507C3E49FFF54
:100AE000E49EFE22BB0110E58229F582E5833AF5FA
:100AF00083E0F5F0A3E0225009E92582F886F008AA
:100B0000E622BBFE0AE92582F8E2F5F008E222E5DA
:100B1000832AF583E993F5F0A3E99322E88FF0A403
:100B2000CC8BF0A42CFCE98EF0A42CFC8AF0EDA474
:100B30002CFCEA8EF0A4CDA8F08BF0A42DCC3825A7
:100B4000F0FDE98FF0A42CCD35F0FCEB8EF0A4FE87
:100B5000A9F0EB8FF0A4CFC5F02ECD39FEE43CFC1C
:100B6000EAA42DCE35F0FDE43CFC2275F008758238
:100B700000EF2FFFEE33FECD33CDCC33CCC5823327
:100B8000C5829BED9AEC99E58298400CF582EE9B2C
:100B9000FEED9AFDEC99FC0FD5F0D6E4CEFBE4CD4A
:100BA000FAE4CCF9A88222B800C1B90059BA002DE4
:100BB000EC8BF084CFCECDFCE5F0CBF97818EF2F9D
:100BC000FFEE33FEED33FDEC33FCEB33FB10D703CC
:100BD000994004EB99FB0FD8E5E4F9FA227818EF75
:100BE0002FFFEE33FEED33FDEC33FCC933C910D7D4
:100BF000059BE99A4007EC9BFCE99AF90FD8E0E4E1
:100C0000C9FAE4CCFB2275F010EF2FFFEE33FEEDB6
:100C100033FDCC33CCC833C810D7079BEC9AE89986
:100C2000400AED9BFDEC9AFCE899F80FD5F0DAE468
:100C3000CDFBE4CCFAE4C8F922D083D082F8E49367
:100C40007012740193700DA3A393F8740193F5824D
:100C50008883E4737402936860EFA3A3A380DFEC3E
:100C60008EF0A4CCC5F0CCCDF8EFA4CEC5F02DFD10
:100C7000E43CFCE8A42EC8C5F03DFDE43CFCEFA438
:100C8000FFE5F028FEE43DFDE43CFC22EF4E60125F
:100C9000EF60010EEDBB010B89828A83F0A3DFFCBC
:100CA000DEFA2289F05007F709DFFCA9F022BBFE2B
:100CB000FCF309DFFCA9F02290000BAA23A9247BF6
:100CC000FF020A08D290900077E024FFFFE434FF8F
:100CD000FE7C007D08120AAE74042FF58274003E7B
:100CE000F58322FF900074E02404F582E43400F5DB
:100CF0008322AA23A9247BFF120A08FD7C0090000E
:100D000004120AE4FFAEF0120A47C322120BA7AB8B
:100D100007AA06E4F9F87F407E427D0FFC120BA77C
:100D2000E47BFFFAF9F8120B1CA804A905AA06AB8C
:100D3000077F207ED77D757C01120BA7EFF404227C
:100D4000E53725E0248AF582E43400F58322AE2AD3
:100D5000AF2B7C007D1F120A598E2E8F2F7C007DB9
:100D600005120A59C3E52F9FFDE52E9EFCD3E52908
:100D70009DE5289C22900083E0FF90007DE06F229B
:100D8000900009AA23A9247BFF020A0853DBFE5323
:100D9000DAFE53F7DF53F7BF2275F005A4240EF5F2
:100DA00082E4341EF583E4740193FA740293AE0274
:100DB000227D64120A597C007D0A020A4790007D58
:100DC000EFF09000887408F022C3E5379FFDE53608
:100DD0009ED3FCE5339DE5329C2275F0FFA4FFAE67
:100DE000F07C007D64020A59AA2EA92F7BFF900097
:100DF00002120AE4F53785F0362275F005A4240DB9
:100E0000F582E4341EF583E4931422E0FF90008819
:100E1000E0FE22900088E014F0900077E004F022D9
:100E2000E52F2FFFE52E3EFEC3E5299FE5289E22F4
:100E3000AB48AA49A94A854D82758300020A0890E9
:100E40000081E0D3FF900077E09F22900078E527B3
:100E5000F0A3E528F022852F82852E83E493FA748F
:100E60000193FB22FF900077E06F22E50EF0A3E5EF
:100E70000FF0227C007D64020C5F540F75F002A419
:100E8000F58285F083227B007A007929AF28AE278E
:100E900022D3E52B9494E52A9411228E278F289053
:100EA0000085E0146035147003020F802402600393
:100EB000021054C290900084E06003021054AF28E6
:100EC000AE27121C7A4003021054E4900001F01285
:100ED0000E4B9000857401F0D29022900078E0FCD7
:100EE000A3E0FDAE047802CEC313CE13D8F92DFFD4
:100EF000EC3EFED3E5289FE5279E4009120E4BE409
:100F0000900001F022AF28AE271218DE501F90008B
:100F100001E094004017E4900074F090008874049D
:100F2000F0E490007DF09000857402F022C3E52883
:100F30009464E52794005003020FE6120E86121106
:100F4000BE5020E529120D42E0FEA3E02528FFE572
:100F5000273EC313FEEF13FFE529120D42EEF0A367
:100F6000EFF022900001E0120D42120E4E900001AF
:100F7000E004F0E0D3940F5003021054E402104553
:100F8000B290AF28AE271218DE505E121CF4500546
:100F9000E4900083F0120D75604A121D047DF47C0C
:100FA000017F017E00121AE490007DE0900083F042
:100FB000900088E07019120CE4C083C082E0FF90BA
:100FC0000001E0540FFEEF4ED082D083F0800E90EF
:100FD0000001E0C454F0440F120CE3EFF0900084E1
:100FE000E04480F0C290E48067120E8612126450D2
:100FF00057900088E0B40410E529C454F0120CE3C3
:10100000EFF0E4900088F022900074E0FF120CE80A
:10101000E0FEE529540FFDEE4DF074042F120CEAAA
:10102000120D78FF121C4DEFF0900074E004F09068
:1010300000887404F0900074E0D394704016121D80
:1010400004E4900001F08008121D04E4900001F017
:10105000900085F0228F278C288D298A2A8B2B756A
:101060002C80E5277071E4F52D7F0112002EEF65CD
:101070002D701B120E914054E52B9450E52A944696
:10108000504A120D4E4045120E2050408073E52DFF
:10109000120D998E2EF52FE52D120DFA60180470A1
:1010A0002B120E56C002C003120DE8D003D002125C
:1010B000110750188013120E56C002C003120DE81B
:1010C000D003D0021211075003852D2C052DE52DDC
:1010D000C394064094802DAF2712002E8F2D7F01E0
:1010E00012002EEF652D701C120E914017E52B9407
:1010F00050E52A9446500D120D4E4008120E205015
:1011000003852D2CAF2C22AD2BAC2AAF29AE281293
:101110001113228E308F318C328D33C2007C007DD2
:1011200064AF03AE02120DB38F828E83AE36AF373B
:10113000120DB1D3E58294F4E583940140050C7D52
:10114000F48004AC83AD828C838D82D3EF94F4EE73
:10115000940140067C017DF48004AC06AD07AE042A
:10116000AF05D3EB9400EA94004038EB9582FDEA9A
:101170009583FCD3E5319DE5309C403FEB2582FD16
:10118000EA3583FCC3E5319DE5309C502E120DC934
:101190004029E5372FFDE5363EC3120DD2501CD253
:1011A000008018120DC94013E5372FFFE5363EFECB
:1011B000C3E5339FE5329E5002D200A200228E2A60
:1011C0008F2B8B2C8A2D892EC2001212645005D2CF
:1011D00000021261E52BAE2A7803CEC313CE13D8DA
:1011E000F9FDAC06E52BAE2A7802CEC313CE13D898
:1011F000F92DFDEE3CFCE52AC4F854F0C868FEE584
:101200002BC4540F482DF531EC3EF530E4F52F900A
:101210000001E0FFE52FC39F5047C3E52B9531FF49
:10122000E52A9530FEE52F120D42E0FCA3E0FDD348
:101230009FEC9E4028E52B2531FFE52A3530FEC383
:10124000ED9FEC9E5017E52E452D452C600BAB2CE9
:10125000AA2DA92EE52F120A35D2008004052F8071
:10126000AEA200228E328F338B348A358936C2018A
:10127000E4F537900001E0FFE537C39F4003021318
:1012800005E533AE327803CEC313CE13D8F9FDACE7
:1012900006E533AE327802CEC313CE13D8F92DF55E
:1012A00039EE3CF538120D40E0FEA3E0FFC395395E
:1012B000EE953850028004AE38AF398E388F39122F
:1012C0000D40E0FEA3E0FFC39539FDEE9538FCC369
:1012D000ED9533EC95325028E5392FFFE5383EFE89
:1012E000C3E5339FE5329E5017E5364535453460FA
:1012F0000BAB34AA35A936E537120A35D201800581
:101300000537021273A201224200C700004200C347
:1013100000004200C900004200C500004100CC00AE
:101320004100CB00011D00410084004100850041C7
:1013300000A8004100750041007C00410076564144
:101340000089AB410000004100820042007F0000A4
:101350004200020000420086000042007A00004184
:10136000008100410088004100770041007E00417B
:101370000074004100830041007D004100010041F4
:1013800000C0004100C1004100BE004100BF00415B
:1013900000C2004100BD00C10300C0E0C0F0C08336
:1013A000C082C0D075D000C000C001C002C003C060
:1013B00004C005C006C007E5985403F55AF45298D6
:1013C000E55A30E017121D499000C0121A52EFF092
:1013D0009000C0E004F0E0B41402E4F0E55A30E11B
:1013E0002E9000C2E0D39400401A9000BFE0245B2E
:1013F000F8E6FF121D469000BFE004F09000C2E046
:1014000014F08002D2039000BFE0B42002E4F0D0D8
:1014100007D006D005D004D003D002D001D000D030
:10142000D0D082D083D0F0D0E032121D4F787FE44C
:10143000F6D8FD75817A021474020076E493A3F85D
:10144000E493A34003F68001F208DFF48029E493DB
:10145000A3F85407240CC8C333C4540F4420C883D2
:101460004004F456800146F6DFE4800B01020408D4
:1014700010204080901308E47E019360BCA3FF54C9
:101480003F30E509541FFEE493A360010ECF54C022
:1014900025E060A840B8E493A3FAE493A3F8E493AA
:1014A000A3C8C582C8CAC583CAF0A3C8C582C8CAB2
:1014B000C583CADFE9DEE780BE8F458D46E4FEFDC9
:1014C000F547121A3F247AF582E4341EF58374013D
:1014D00093FA7402938A48F5497FAA121BB0AF456C
:1014E000121A3C2479F582E4341EF583E4931460E7
:1014F0000E047019AA48A9497BFF90000B8009AA25
:1015000048A9497BFF90000A120A08F547EEC395E7
:1015100047500774082EFE0D80F3ED04FF121A3CAD
:101520002478F582E4341EF583E493FF121BB0E4C3
:10153000FEEEC39D500974042E121A2A0E80F27F0B
:1015400055121BB0021D43E54275F005A424A2F517
:1015500082E4341DF583740193FA740293AE028E13
:1015600043F5442293FF7E00740493FC740593FDBD
:10157000020A47900006E0FEA3E0FF900009E02F7A
:10158000FF900008E03EAB07FAE4F9F822F5828EFE
:1015900083740C93FFD3940022EF75F005A424A16B
:1015A000F582E4341DF583E49322E493FE74019301
:1015B000FF740293FC740393FD22E0FEA3E0FFA3FB
:1015C000E0FCA3E0FD22E0FF7E00020A47C0E0C08D
:1015D000F0C083C082C0D075D000C000C001C0027E
:1015E000C003C004C005C006C007E5D85487F52174
:1015F000F452D8E5F730E508E5F730E603121A5D56
:1016000053F7DFE52130E708E5D930E003121D503C
:10161000E52130E008E5DA30E003121B5DE521301A
:10162000E108E5DB30E003120718E52130E208E5C8
:10163000DC30E003121D51D007D006D005D004D015
:1016400003D002D001D000D0D0D082D083D0F0D04F
:10165000E0328B458A468947120D8C53E2FDE4F552
:101660004DE54DC3954B504FAB45AA46A947C00326
:10167000C002C001120E30C4120E7AD001D002D0C6
:1016800003120AE4F54F85F04ED2801216C6AB4520
:10169000AA46A947C003C002C001120E30120E7A3A
:1016A000D001D002D003120AE4F54F85F04EC2807B
:1016B0001216C6054D80AAB290AF4C154CEF709E25
:1016C00043E202C29022FDAC4E7F0A7E00121A8EC7
:1016D000121D2E22AE07E4F545121BA9900001E071
:1016E00004FF121BB012174F900001E0FFE545C345
:1016F0009F5012121A46121A2F121A46F583121A06
:1017000036054580E3900078E0FF121BB09000782A
:10171000121A3612174FE4F545900074E02401FFC9
:10172000E433FEC3E5459FEE6480F874809850175B
:1017300074042545121A2A0545E545541F70DA122E
:101740001D43121D3C80D27F55121BB0021D431257
:101750001D43121D3C228E458F468C478D48AE029C
:10176000AF03120E73C007AF4BAB07E4FAF9F8D022
:1017700007120D0C900000F0AE4CAF4D120E73C06E
:1017800007AF4EAB07E4FAF9F8D007120D0C900042
:1017900082F0E54B120DDA900076EFF0E54E120D77
:1017A000DA900089EFF090007FE545F0A3E546F080
:1017B000900002E547F0A3E548F0900081E54FF086
:1017C00043DA0153F7DF43F74053DBFE75F9FF229D
:1017D0008A498B4A755380120D8C53E2FD90007F2D
:1017E000EEF0A3EFF0900002ECF0A3EDF0121B3648
:1017F000E4F552E552C395515032120CE4E05553D2
:10180000600AAD50AC4FAF4EAE4D8008AD4CAC4B06
:10181000AF4AAE49121BCCE553C313F55370099080
:101820000074E004F0755380055280C743E202C2A1
:10183000909000857404F022C0E0C083C082C0D0C4
:1018400075D000C004C005C006C00753C87F900013
:10185000C7E0FEA3E0FF4E700353C8FB9000C31225
:1018600019AC50099000C7E4F0A3F0800DC39000BC
:10187000C8E09DF09000C7E09CF0D007D006D005EE
:10188000D004D0D0D082D083D0E032C0E0C083C0BA
:1018900082C0D075D000C004C005C006C0075391F7
:1018A0007F9000C9E0FEA3E0FF4E70035391FB90D0
:1018B00000C51219AC50099000C9E4F0A3F0800DE6
:1018C000C39000CAE09DF09000C9E09CF0D007D022
:1018D00006D005D004D0D0D082D083D0E032AB0780
:1018E000AA06900078E0FEA3E0FF7C00120DB1D3C1
:1018F000EF94F4EE940140050C7DF48004AC06AD49
:1019000007AE04AF05C3900079E09FFD900078E03A
:101910009EFCC3ED9BEC9A5013A3E02FFF90007840
:10192000E03EFEC3EB9FEA9E50028001C322AE0759
:10193000E4FDF545121BA9900002E0FF121BB090D8
:101940000002121A3690007AE0FF121BB090007A63
:10195000121A36900086E0FF121BB0900086121A11
:101960003674042D121A2A0DBD03F67F55121BB0D2
:10197000021D43AB07AA06E4F9F87F407E427D0FC3
:10198000FC120BA7A804A905AA06AB077F207ED7E7
:101990007D757C01120BA7C3E49FFFE49EFE22AB82
:1019A00007AA06E4F9F87FE87E03FD22E0FCA3E045
:1019B000FDC3EF9DEE9C228F4590007CE0F5467FB5
:1019C0000B121D4C43DB01120D8F1200707D0A7C3F
:1019D000007F017E00121B0D121D2E43E202E490D7
:1019E0000085F0900084F09000CBE545F090007CFD
:1019F000F0AF46229000C0E0FF9000BEE0B50705C2
:101A00007E017F00229000BE121A52E0FD7C009001
:101A100000BEE004F0E0B41402E4F09000BDE0FE8B
:101A2000EE4204E4F0AE04AF0522F582E43400F5A2
:101A300083E0FF021BB0A3E0FF021BB0121BB0E566
:101A40004675F005A422E54525E0248AF582E434B4
:101A50000022E024A9F582E43400F58322120E3F2F
:101A60004003021C2F120CE4120E0BEFA806088094
:101A700002C313D8FC30E00B900000E0FF121D4CB5
:101A8000D29022900082E0FF121D4CC290228E560E
:101A90008F578C588D59121973121C94E55924BF15
:101AA0009000CAF0E55834FF9000C9F09000C5E5F9
:101AB00056F0A3E557F04391042212002A121D0BA1
:101AC000121D12121CC3121D34121C64121CE112CE
:101AD0001CCD121CD7121CA0121D19121D20121D84
:101AE00038021D278E2A8F2B8C2C8D2D12199F12B8
:101AF0001980121C889000C7E52CF0A3E52DF0900A
:101B000000C3E52AF0A3E52BF043C804228E478FDB
:101B1000488C498D4A12199F121980121C9490000A
:101B2000C9E549F0A3E54AF09000C5E547F0A3E513
:101B300048F043910422D290D28090007F121B5033
:101B4000121D2EC290C280900002121B50021D2E48
:101B5000E0FCA3E0FD7F0A7E00121A8E229000882E
:101B6000E07008900074E004120DC1120E1990008C
:101B700088E014F0120E3F5003021B8253E2FDC2B4
:101B80008022120CE4120E0BEFA806088002C31389
:101B9000D8FC30E0059000768003900089E07D005D
:101BA000FCE4FF121C1122AE077FAA121BB0AF0685
:101BB000C2039000C1E0B42002E4F09000C1E02430
:101BC0005BF8A607E004F0A3E004F0228C548D55E6
:101BD000D280AD07AC067F0A7E00121A8E121D2E2F
:101BE000C280AD55AC547F0A7E00121A8E021D2EA3
:101BF000120DC2E014F09000777401F0900085742B
:101C000003F0121B8253E2FD121B3643E202020074
:101C100070AB07AF04EB14600C14600E2402700E5E
:101C20008DFB8FFC228DE98FEA228DEB8FEC22E475
:101C3000FDFCFF121C11120D8F121D4053D878535A
:101C4000E2FDC280C2909000857404F0227E1DE403
:101C5000FDEF30E70625E06EFF8004EF25E0FF0D85
:101C6000BD08EE22AF885388AF758CA0758DCBEF81
:101C70005440FEEF54104E428822C3EF94ACEE94D1
:101C80000D4003D38001C322AD07AC06ECF5CBAF0A
:101C9000058FCA22AD07AC06ECF593AF058F9222F3
:101CA000C2DE75D90575F9FF75960122EE30E7079A
:101CB000C3E49FFFE49EFE22121BA77F55121BB0B8
:101CC000021D4375E34075E10175E20222E591547E
:101CD000045391FB429122758E547589224388509A
:101CE00022E5C8540453C8FB42C82253984FEB4F17
:101CF0004DF59822E5C8C320E201D322E591C32027
:101D0000E201D32253C8FB53C87F2275A41175D4B6
:101D1000CE2275A54175D5772253F77F75DA4A2211
:101D200053F77F75DB302275E69075A8B022E591F8
:101D300020E2FB22E4F5A922439810223003FD2281
:101D4000C2DE22D299228F9922AF99228F8C222231
:101D500022220190307000064001904B19180012A9
:101D6000C005DC0002BC012C461E28080BB8232845
:101D700000044C01904B191800251C0BB80003847B
:101D80000140461E1800000072D80702BC012C2634
:101D90004040000BB81C520190010303011846009B
:101DA0000100FF1D520200FF1D5F0300FF1D6C04B8
:101DB00000FF1D790500FF1D860601FF1D930190A0
:101DC000307000064001904B19180012C005DC006D
:101DD00002BC012C461E28080BB8232800044C0125
:101DE000904B191800251C0BB80003840140461EB7
:101DF0001800000072D80702BC012C264040000BDE
:101E0000B81C520190010303011846000100FF1D98
:101E1000BE0200FF1DCB0300FF1DD80400FF1DE51F
:101E20000500FF1DF20601FF1DFF01903070000646
:101E30004001904B19180012C005DC0002BC012CB7
:101E4000461E28080BB8232800044C01904B191893
:101E500000251C0BB80003840140461E180000003A
:101E600072D80702BC012C264040000BB81C52015E
:101E700090010303011846000100FF1E2A0200FF23
:101E80001E370300FF1E440400FF1E510500FF1E05
:061E90005E0601FF1E6B5F
:00000001FF