Merge branch 'development' of https://github.com/arendst/Tasmota into development

This commit is contained in:
Luis Teixeira 2019-12-04 22:57:25 +00:00
commit 18f514384d
18 changed files with 1592 additions and 5793 deletions

View File

@ -38,7 +38,7 @@ _Make sure your have performed every step and checked the applicable boxes befor
- [ ] Self-compiled
- [ ] IDE / Compiler used: _____
- [ ] Flashing tools used: _____
- [ ] Provide the output of command: ``Backlog Template; Module; GPIO``:
- [ ] Provide the output of command: ``Backlog Template; Module; GPIO 255``:
```
Configuration output here:

80
MODULES.md Normal file
View File

@ -0,0 +1,80 @@
## Supported Modules
The following hardware modules are supported.
Module | Description
------------------|-----------------------
01 Sonoff Basic | Sonoff Basic Wifi Smart Switch
02 Sonoff RF | Sonoff RF Wifi Smart Switch with RF (434MHz) receiver
03 Sonoff SV | Sonoff SV Safe Voltage Wifi Smart Switch
04 Sonoff TH | Sonoff TH10/TH16 Wifi Smart Switch with Sensor connection
05 Sonoff Dual | Sonoff Dual Wifi Smart Switch
06 Sonoff Pow | Sonoff Pow Wifi Smart Switch with Energy Monitoring
07 Sonoff 4CH | Sonoff 4CH 4-gang Wifi Smart Switch
08 Sonoff S2X | Sonoff S20/S26 Wifi Smart Socket
09 Slampher | Sonoff Slampher Wifi Smart Light Bulb Socket with RF (434MHz) receiver
10 Sonoff Touch | Sonoff Touch Wifi Light Switch
11 Sonoff LED | Sonoff Led Wifi Led Pack (Retired)
12 1 Channel | 1 Channel Inching/Self Locking Wifi Switch 5V/12V
13 4 Channel | 4 Channel Inching/Self Locking Wifi Switch (Retired)
14 Motor C/AC | Motor Clockwise/Antoclockwise Wifi Switch (Retired)
15 ElectroDragon | Electrodragon Wifi IoT Board
16 EXS Relay(s) | Electronic Experience Store 1 or 2-gang Wifi Module
17 WiOn | WiOn Wifi Smart Socket
18 Generic | Any ESP8266/ESP8285 device like WeMos and NodeMCU
19 Sonoff Dev | Sonoff Dev Wifi Development Board
20 H801 | H801 Wifi RGBWW Led Controller
21 Sonoff SC | Sonoff SC Wifi Environmental Monitor
22 Sonoff BN-SZ | Sonoff BN-SZ01 Wifi Ceiling Led (Retired)
23 Sonoff 4CH Pro | Sonoff 4CH Pro 4-gang Wifi Smart Switch
24 Huafan SS | HuaFan Wifi Smart Socket
25 Sonoff Bridge | Sonoff RF (434MHz) transceive to Wifi Bridge
26 Sonoff B1 | Sonoff B1 Wifi RGBWW Led Bulb
27 AiLight | Ai-Thinker RGBW Led Bulb
28 Sonoff T1 1CH | Sonoff T1 1-gang Wifi Light Switch
29 Sonoff T1 2CH | Sonoff T1 2-gang Wifi Light Switch
30 Sonoff T1 3CH | Sonoff T1 3-gang Wifi Light Switch
31 Supla Espablo | 2-gang Wifi Module
32 Witty Cloud | Witty Cloud ESP8266 Wifi Development Board
33 Yunshan Relay | ESP8266 Wifi Network Relay Module
34 MagicHome | MagicHome, Flux-light and some Arilux LC10 RGB(W) Led Controller
35 Luani HVIO | Luani ESP8266 Wifi I/O Module
36 KMC 70011 | KMC Wifi Smart Socket with Energy Monitoring
37 Arilux LC01 | Arilux AL-LC01 RGB Led Controller
38 Arilux LC11 | Arilux AL-LC11 RGBWW Led Controller
39 Sonoff Dual R2 | Sonoff Dual R2 Wifi Smart Switch
40 Arilux LC06 | Arilux AL-LC06 RGB(WW) Led Controller
41 Sonoff S31 | Sonoff S31 Wifi Smart Socket with Energy Monitoring
42 Zengge WF017 | Zengge WF017 Wifi RGB(W) Led Controller
43 Sonoff Pow R2 | Sonoff Pow R2 Wifi Smart Switch with Energy Monitoring
44 Sonoff iFan02 | Sonoff iFan02 Wifi Smart Ceiling Fan with Light
45 BlitzWolf SHP | BlitzWolf BW-SHP2, BW-SHP6, HomeCube SP1, Gosund SP111, Teckin SP22 Wifi Smart Switch with Energy Monitoring
46 Shelly 1 | Shelly 1 Open Source Wifi Relay Module
47 Shelly 2 | Shelly 2 Wifi 2-gang Relay Module with Energy Monitoring
48 Xiaomi Philips | Xiaomi Philips Wifi WW Led Bulb
49 Neo Coolcam | Neo Coolcam Wifi Smart Socket
50 ESP Switch | ESP Switch 4-gang Wifi Switch with Leds
51 OBI Socket | OBI Wifi Smart Socket
52 Teckin | Teckin SP22 Wifi Smart Switch with Energy Monitoring
53 AplicWDP303075 | Aplic WDP 303075 CSL Wifi Smart Switch with Energy Monitoring
54 Tuya Dimmer | MIUO (and other Tuya based) Wifi Dimmer for Incandescent Lights and Led
55 Gosund SP1 v23 | Gosund SP1 v2.3 Wifi Smart Switch with Energy Monitoring
56 ARMTR Dimmer | ARMtronix Wifi dimmer for Incandescent Lights and Led
57 SK03 Outdoor | SK03 Outdoor Wifi Smart Switch with Energy Monitoring
58 PS-16-DZ | PS-16-DZ Wifi dimmer for Incandescent Lights and Led
59 Teckin US | Teckin SP20 and ZooZee SA102 Wifi Smart Switch with Energy Monitoring
60 Manzoku strip | Manzoku Wifi Smart Power Strip with four Relays
61 OBI Socket 2 | OBI 2 Wifi Smart Socket
62 YTF IR Bridge | YTF Infra Red Wifi Bridge
63 Digoo DG-SP202 | Digoo DG-SP202 Dual Wifi Smart Switch with Energy Monitoring
64 KA10 | Smanergy KA10 Wifi Smart Wall Switch with Energy Monitoring
65 Luminea ZX2820 | Luminea ZX2820 Wifi Smart Switch with Energy Monitoring
66 Mi Desk Lamp | Mi Desk Lamp with rotary switch and Wifi
67 SP10 | Tuya SP10 Wifi Smart Switch with Energy Monitoring
68 WAGA CHCZ02MB | WAGA life CHCZ02MB Wifi Smart Switch with Energy Monitoring
69 SYF05 | Sunyesmart SYF05 RGBWW Wifi Led Bulb
70 Sonoff L1 | Sonoff L1 light strip
71 Sonoff iFan03 | Sonoff iFan03 Wifi Smart Ceiling Fan with Light
72 EXS Dimmer | EXS Wifi Dimmer v4
Over 600 additional devices are supported using [templates](TEMPLATES.md).

View File

@ -20,7 +20,7 @@ In addition to the [release webpage](https://github.com/arendst/Tasmota/releases
## Development
[![Dev Version](https://img.shields.io/badge/development%20version-v7.1.0.x-blue.svg)](https://github.com/arendst/Tasmota)
[![Dev Version](https://img.shields.io/badge/development%20version-v7.1.1.x-blue.svg)](https://github.com/arendst/Tasmota)
[![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/)
[![Build Status](https://img.shields.io/travis/arendst/Tasmota.svg)](https://travis-ci.org/arendst/Tasmota)
@ -76,19 +76,19 @@ For a database of supported devices see [Tasmota Device Templates Repository](ht
If you're looking for support on **Tasmota** there are some options available:
### Documentation:
### Documentation
* [Documentation Site](https://tasmota.github.io/docs): For information on how to flash Tasmota, configure, use and expand it
* [FAQ and Troubleshooting](https://tasmota.github.io/docs/#/help/): For information on common problems and solutions.
* [Commands Information](https://tasmota.github.io/docs/#/Commands): For information on all the commands supported by Tasmota.
### Support's Community:
### Support's Community
* [Tasmota Forum](https://groups.google.com/d/forum/sonoffusers): For usage and discussions.
* [Tasmota Support Chat](https://discord.gg/Ks2Kzd4): For support, troubleshooting and general questions. You have better chances to get fast answers from members of the Tasmota Community.
* [Search in Issues](https://github.com/arendst/Tasmota/issues): You might find an answer to your question by searching current or closed issues.
### Developers' Community:
### Developers' Community
* [Bug Report](https://github.com/arendst/Tasmota/issues/new?template=Bug_report.md): For reporting Bugs of Tasmota Software.
* [Feature Request](https://github.com/arendst/Tasmota/issues/new?template=Feature_request.md): For requesting features/functions to Tasmota Software.

View File

@ -28,87 +28,6 @@ To save resources when TLS is enabled mDNS needs to be disabled. In addition to
For initial configuration this release supports Webserver based **WifiManager** or **Serial** based command interface only. Support for **WPS** and **SmartConfig** has been removed.
## Supported Modules
The following hardware modules are supported.
Module | Description
------------------|-----------------------
01 Sonoff Basic | Sonoff Basic Wifi Smart Switch
02 Sonoff RF | Sonoff RF Wifi Smart Switch with RF (434MHz) receiver
03 Sonoff SV | Sonoff SV Safe Voltage Wifi Smart Switch
04 Sonoff TH | Sonoff TH10/TH16 Wifi Smart Switch with Sensor connection
05 Sonoff Dual | Sonoff Dual Wifi Smart Switch
06 Sonoff Pow | Sonoff Pow Wifi Smart Switch with Energy Monitoring
07 Sonoff 4CH | Sonoff 4CH 4-gang Wifi Smart Switch
08 Sonoff S2X | Sonoff S20/S26 Wifi Smart Socket
09 Slampher | Sonoff Slampher Wifi Smart Light Bulb Socket with RF (434MHz) receiver
10 Sonoff Touch | Sonoff Touch Wifi Light Switch
11 Sonoff LED | Sonoff Led Wifi Led Pack (Retired)
12 1 Channel | 1 Channel Inching/Self Locking Wifi Switch 5V/12V
13 4 Channel | 4 Channel Inching/Self Locking Wifi Switch (Retired)
14 Motor C/AC | Motor Clockwise/Antoclockwise Wifi Switch (Retired)
15 ElectroDragon | Electrodragon Wifi IoT Board
16 EXS Relay(s) | Electronic Experience Store 1 or 2-gang Wifi Module
17 WiOn | WiOn Wifi Smart Socket
18 Generic | Any ESP8266/ESP8285 device like WeMos and NodeMCU
19 Sonoff Dev | Sonoff Dev Wifi Development Board
20 H801 | H801 Wifi RGBWW Led Controller
21 Sonoff SC | Sonoff SC Wifi Environmental Monitor
22 Sonoff BN-SZ | Sonoff BN-SZ01 Wifi Ceiling Led (Retired)
23 Sonoff 4CH Pro | Sonoff 4CH Pro 4-gang Wifi Smart Switch
24 Huafan SS | HuaFan Wifi Smart Socket
25 Sonoff Bridge | Sonoff RF (434MHz) transceive to Wifi Bridge
26 Sonoff B1 | Sonoff B1 Wifi RGBWW Led Bulb
27 AiLight | Ai-Thinker RGBW Led Bulb
28 Sonoff T1 1CH | Sonoff T1 1-gang Wifi Light Switch
29 Sonoff T1 2CH | Sonoff T1 2-gang Wifi Light Switch
30 Sonoff T1 3CH | Sonoff T1 3-gang Wifi Light Switch
31 Supla Espablo | 2-gang Wifi Module
32 Witty Cloud | Witty Cloud ESP8266 Wifi Development Board
33 Yunshan Relay | ESP8266 Wifi Network Relay Module
34 MagicHome | MagicHome, Flux-light and some Arilux LC10 RGB(W) Led Controller
35 Luani HVIO | Luani ESP8266 Wifi I/O Module
36 KMC 70011 | KMC Wifi Smart Socket with Energy Monitoring
37 Arilux LC01 | Arilux AL-LC01 RGB Led Controller
38 Arilux LC11 | Arilux AL-LC11 RGBWW Led Controller
39 Sonoff Dual R2 | Sonoff Dual R2 Wifi Smart Switch
40 Arilux LC06 | Arilux AL-LC06 RGB(WW) Led Controller
41 Sonoff S31 | Sonoff S31 Wifi Smart Socket with Energy Monitoring
42 Zengge WF017 | Zengge WF017 Wifi RGB(W) Led Controller
43 Sonoff Pow R2 | Sonoff Pow R2 Wifi Smart Switch with Energy Monitoring
44 Sonoff iFan02 | Sonoff iFan02 Wifi Smart Ceiling Fan with Light
45 BlitzWolf SHP | BlitzWolf BW-SHP2, BW-SHP6, HomeCube SP1, Gosund SP111, Teckin SP22 Wifi Smart Switch with Energy Monitoring
46 Shelly 1 | Shelly 1 Open Source Wifi Relay Module
47 Shelly 2 | Shelly 2 Wifi 2-gang Relay Module with Energy Monitoring
48 Xiaomi Philips | Xiaomi Philips Wifi WW Led Bulb
49 Neo Coolcam | Neo Coolcam Wifi Smart Socket
50 ESP Switch | ESP Switch 4-gang Wifi Switch with Leds
51 OBI Socket | OBI Wifi Smart Socket
52 Teckin | Teckin SP22 Wifi Smart Switch with Energy Monitoring
53 AplicWDP303075 | Aplic WDP 303075 CSL Wifi Smart Switch with Energy Monitoring
54 Tuya Dimmer | MIUO (and other Tuya based) Wifi Dimmer for Incandescent Lights and Led
55 Gosund SP1 v23 | Gosund SP1 v2.3 Wifi Smart Switch with Energy Monitoring
56 ARMTR Dimmer | ARMtronix Wifi dimmer for Incandescent Lights and Led
57 SK03 Outdoor | SK03 Outdoor Wifi Smart Switch with Energy Monitoring
58 PS-16-DZ | PS-16-DZ Wifi dimmer for Incandescent Lights and Led
59 Teckin US | Teckin SP20 and ZooZee SA102 Wifi Smart Switch with Energy Monitoring
60 Manzoku strip | Manzoku Wifi Smart Power Strip with four Relays
61 OBI Socket 2 | OBI 2 Wifi Smart Socket
62 YTF IR Bridge | YTF Infra Red Wifi Bridge
63 Digoo DG-SP202 | Digoo DG-SP202 Dual Wifi Smart Switch with Energy Monitoring
64 KA10 | Smanergy KA10 Wifi Smart Wall Switch with Energy Monitoring
65 Luminea ZX2820 | Luminea ZX2820 Wifi Smart Switch with Energy Monitoring
66 Mi Desk Lamp | Mi Desk Lamp with rotary switch and Wifi
67 SP10 | Tuya SP10 Wifi Smart Switch with Energy Monitoring
68 WAGA CHCZ02MB | WAGA life CHCZ02MB Wifi Smart Switch with Energy Monitoring
69 SYF05 | Sunyesmart SYF05 RGBWW Wifi Led Bulb
70 Sonoff L1 | Sonoff L1 light strip
71 Sonoff iFan03 | Sonoff iFan03 Wifi Smart Ceiling Fan with Light
72 EXS Dimmer | EXS Wifi Dimmer v4
Over 500 additional devices are supported using [templates](TEMPLATES.md).
## Provided Binary Downloads
The following binary downloads have been compiled with ESP8266/Arduino library core version **2.6.1**.
@ -122,46 +41,14 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
- **tasmota-display.bin** = The Display version without Energy Monitoring but adds display support.
- **tasmota-minimal.bin** = The Minimal version allows intermediate OTA uploads to support larger versions and does NOT change any persistent parameter. This version **should NOT be used for initial installation**.
[List](MODULES.md) of embedded modules.
[Complete list](BUILDS.md) of available feature and sensors.
## Changelog
### Version 7.1.0 Betty
### Version 7.1.2 Betty
- Remove update support for versions before 6.0
- Remove driver xsns_12_ads1115_i2cdev replaced by xsns_12_ads1115
- Remove most IR protocols from non dedicated IR firmware except NEC, RC5 and RC6
- Change repository name from Sonoff-Tasmota to Tasmota and all code references from Sonoff to Tasmota
- Change documentation from wiki to [documentation repository](https://tasmota.github.io/docs/) by @Blakadder
- Change default GUI to dark theme
- Change ArduinoSlave to TasmotaSlave
- Change IRremoteESP8266 library to v2.7.1
- Change supported PCF8574 I2C address range to 0x20 - 0x26 allowing other I2C devices with address 0x27 to be used at the same time
- Change supported PCF8574A I2C address range to 0x39 - 0x3F allowing other I2C devices with address 0x38 to be used at the same time
- Change supported MCP230xx I2C address range to 0x20 - 0x26 allowing other I2C devices with address 0x27 to be used at the same time
- Change Reset erase end address from as seen by SDK (getFlashChipSize) to full flash size (getFlashChipRealSize)
- Change new Fade system much smoother, Speed now up to 40 (#6942, #3714)
- Fix better control of RGB/White when ``SetOption37`` >128, added ``Dimmer1`` and ``Dimmer2`` commands (#6714)
- Fix random crash caused by UPNP flood
- Fix check deepsleep for valid values in Settings (#6961)
- Fix Wifi instability when light is on, due to ``Sleep 0`` (#6961, #6608)
- Fix auto-power on/off when setting channel to non-zero or zero value, when ``SetOption68 1``
- Fix postpone saving settings to flash until Fade is complete, avoids pause in Fade
- Add support for Tuya battery powered devices (#6735)
- Add support for Honeywell I2C HIH series Humidity and Temperetaure sensor (#6808)
- Add support for Honeywell HPMA115S0 particle concentration sensor by David Hunt (#6843)
- Add support for I2C sensor TLS2591 Light Intensity sensor (#6873)
- Add command ``SetOption73 0/1`` to re-enable HTTP Cross-Origin Resource Sharing (CORS) now default disabled (#6767)
- Add command ``SetOption74 0/1`` to enable DS18x20 internal pull-up and remove define DS18B20_INTERNAL_PULLUP (#6795)
- Add command ``SetOption75 0/1`` to switch between grouptopic (0) using fulltopic replacing %topic% or (1) is cmnd/\<grouptopic\> (#6779)
- Add command ``SetOption76 0/1`` to enable incrementing bootcount when deepsleep is enabled (#6930)
- Add command ``SetOption77 0/1`` to keep power on when slider is far left
- Add command ``I2cDriver`` for I2C driver runtime control using document I2CDEVICES.md
- Add command ``TempOffset -12.6 .. 12.6`` to set global temperature sensor offset (#6958)
- Add command ``WebColor19`` to control color of Module and Name (#6811)
- Add command ``WifiPower 0 .. 20.5`` to set Wifi Output Power which will be default set to 17dBm
- Add frequency to ADE7953 energy monitor as used in Shelly 2.5 by ljakob (#6778)
- Add hide Alexa objects with friendlyname starting with '$' (#6722, #6762)
- Add Zigbee command support, considered as v1.0 for full Zigbee support
- Add hardware detection to be overruled with ``SetOption51`` (#6969)
- Add Colorpicker to WebUI by Christian Staars (#6984)
- Fix lost functionality of GPIO9 and GPIO10 on some devices (#7080)
- Fix Zigbee uses Hardware Serial if GPIO 1/3 or GPIO 13/15 and SerialLog 0 (#7071)
- Change light color schemes 2, 3 and 4 from color wheel to Hue driven

View File

@ -85,11 +85,11 @@ build_flags = ${esp82xx_defaults.build_flags}
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221
; NONOSDK22x_190313
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190313
; NONOSDK22x_190703 = 2.2.2-dev(38a443e) (Tasmota default)
; NONOSDK22x_190703 = 2.2.1+100-dev(38a443e) (Tasmota default) (Firmware 2K smaller than NONOSDK22x_191105)
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
; NONOSDK22x_191024 = 2.2.2-dev(5ab15d1)
; NONOSDK22x_191024 = 2.2.1+111-dev(5ab15d1)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191024
; NONOSDK22x_191105 = 2.2.2-dev(bb83b9b)
; NONOSDK22x_191105 = 2.2.1+113-dev(bb83b9b)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191105
; NONOSDK3V0 (known issues)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK3
@ -129,11 +129,11 @@ build_flags = ${esp82xx_defaults.build_flags}
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221
; NONOSDK22x_190313
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190313
; NONOSDK22x_190703 = 2.2.2-dev(38a443e) (Tasmota default)
; NONOSDK22x_190703 = 2.2.1+100-dev(38a443e) (Tasmota default) (Firmware 2K smaller than NONOSDK22x_191105)
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
; NONOSDK22x_191024 = 2.2.2-dev(5ab15d1)
; NONOSDK22x_191024 = 2.2.1+111-dev(5ab15d1)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191024
; NONOSDK22x_191105 = 2.2.2-dev(bb83b9b)
; NONOSDK22x_191105 = 2.2.1+113-dev(bb83b9b)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191105
; NONOSDK3V0 (known issues)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK3
@ -173,12 +173,14 @@ build_flags = ${esp82xx_defaults.build_flags}
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221
; NONOSDK22x_190313
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190313
; NONOSDK22x_190703 (Tasmota default)
; NONOSDK22x_190703 = 2.2.1+100-dev(38a443e) (Tasmota default) (Firmware 2K smaller than NONOSDK22x_191105)
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
; NONOSDK22x_191024
; NONOSDK22x_191024 = 2.2.1+111-dev(5ab15d1)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191024
; NONOSDK22x_191105
; NONOSDK22x_191105 = 2.2.1+113-dev(bb83b9b)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191105
; NONOSDK22x_191122 = 2.2.1+119-dev(a58da79)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191122
; NONOSDK3V0 (known issues)
; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK3
; lwIP 1.4

View File

@ -1,5 +1,18 @@
## Unreleased (development)
### 7.1.1.1 20191201
- Fix lost functionality of GPIO9 and GPIO10 on some devices (#7080)
- Fix Zigbee uses Hardware Serial if GPIO 1/3 or GPIO 13/15 and SerialLog 0 (#7071)
- Fix WS2812 power control (#7090)
- Change light color schemes 2, 3 and 4 from color wheel to Hue driven
## Released
### 7.1.1 20191201
- Maintenance Release
### 7.1.0.1 20191130
- Fix slider for devices with one or two channels like only white or white/yellow
@ -7,8 +20,6 @@
- Fix light scheme 4 speed (#7072)
- Add support for TasmotaSlave executing commands on Tasmota
## Released
### 7.1.0 20191129
- Release

View File

@ -521,7 +521,7 @@ char* GetPowerDevice(char* dest, uint32_t idx, size_t size)
return GetPowerDevice(dest, idx, size, 0);
}
bool IsEsp8285(void)
void GetEspHardwareType(void)
{
// esptool.py get_efuses
uint32_t efuse1 = *(uint32_t*)(0x3FF00050);
@ -529,17 +529,16 @@ bool IsEsp8285(void)
// uint32_t efuse3 = *(uint32_t*)(0x3FF00058);
// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C);
bool is_8285 = ( (efuse1 & (1 << 4)) || (efuse2 & (1 << 16)) );
is_8285 = ( (efuse1 & (1 << 4)) || (efuse2 & (1 << 16)) );
if (is_8285 && (ESP.getFlashChipRealSize() > 1048576)) {
is_8285 = false; // ESP8285 can only have 1M flash
}
return is_8285;
}
String GetDeviceHardware(void)
{
char buff[10];
if (IsEsp8285()) {
if (is_8285) {
strcpy_P(buff, PSTR("ESP8285"));
} else {
strcpy_P(buff, PSTR("ESP8266EX"));
@ -1063,18 +1062,18 @@ bool FlashPin(uint32_t pin)
uint8_t ValidPin(uint32_t pin, uint32_t gpio)
{
uint8_t result = gpio;
if (FlashPin(pin)) {
result = GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11
return GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11
}
if (!IsEsp8285() && !Settings.flag3.user_esp8285_enable) { // SetOption51 - Enable ESP8285 user GPIO's
// if (!is_8285 && !Settings.flag3.user_esp8285_enable) { // SetOption51 - Enable ESP8285 user GPIO's
if ((WEMOS == Settings.module) && !Settings.flag3.user_esp8285_enable) { // SetOption51 - Enable ESP8285 user GPIO's
if ((pin == 9) || (pin == 10)) {
result = GPIO_NONE; // Disable possible flash GPIO9 and GPIO10
return GPIO_NONE; // Disable possible flash GPIO9 and GPIO10
}
}
return result;
return gpio;
}
bool ValidGPIO(uint32_t pin, uint32_t gpio)

1339
tasmota/support_tasmota.ino Normal file

File diff suppressed because it is too large Load Diff

View File

@ -118,8 +118,10 @@ void WifiSetMode(WiFiMode_t wifi_mode)
delay(100);
}
if (!WiFi.mode(wifi_mode)) {
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI "Cannot set Mode"));
uint32_t retry = 2;
while (!WiFi.mode(wifi_mode) && retry--) {
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR("Retry set Mode..."));
delay(100);
}
if (wifi_mode == WIFI_OFF) {

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
const uint32_t VERSION = 0x07010001;
const uint32_t VERSION = 0x07010101;
#endif // _TASMOTA_VERSION_H_

View File

@ -1510,33 +1510,6 @@ void LightPreparePower(power_t channels = 0xFFFFFFFF) { // 1 = only RGB, 2 =
LightState(0);
}
void LightWheel(uint8_t wheel_pos)
{
wheel_pos = 255 - wheel_pos;
if (wheel_pos < 85) {
Light.entry_color[0] = 255 - wheel_pos * 3;
Light.entry_color[1] = 0;
Light.entry_color[2] = wheel_pos * 3;
} else if (wheel_pos < 170) {
wheel_pos -= 85;
Light.entry_color[0] = 0;
Light.entry_color[1] = wheel_pos * 3;
Light.entry_color[2] = 255 - wheel_pos * 3;
} else {
wheel_pos -= 170;
Light.entry_color[0] = wheel_pos * 3;
Light.entry_color[1] = 255 - wheel_pos * 3;
Light.entry_color[2] = 0;
}
Light.entry_color[3] = 0;
Light.entry_color[4] = 0;
float dimmer = 100 / (float)Settings.light_dimmer;
for (uint32_t i = 0; i < LST_RGB; i++) {
float temp = (float)Light.entry_color[i] / dimmer + 0.5f;
Light.entry_color[i] = (uint8_t)temp;
}
}
void LightCycleColor(int8_t direction)
{
if (Light.strip_timer_counter % (Settings.light_speed * 2)) {
@ -1547,12 +1520,17 @@ void LightCycleColor(int8_t direction)
if (Light.random == Light.wheel) {
Light.random = random(255);
}
Light.wheel += (Light.random < Light.wheel) ? -1 : 1;
} else {
Light.wheel += direction;
direction = (Light.random < Light.wheel) ? -1 : 1;
}
LightWheel(Light.wheel);
memcpy(Light.new_color, Light.entry_color, sizeof(Light.new_color));
Light.wheel += direction;
uint16_t hue = changeUIntScale(Light.wheel, 0, 255, 0, 359); // Scale to hue to keep amount of steps low (max 255 instead of 359)
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: random %d, wheel %d, hue %d"), Light.random, Light.wheel, hue);
uint8_t sat;
light_state.getHSB(nullptr, &sat, nullptr); // Allow user control over Saturation
light_state.setHS(hue, sat);
light_controller.calcLevels(Light.new_color);
}
void LightSetPower(void)
@ -1593,6 +1571,7 @@ void LightAnimate(void)
{
uint8_t cur_col[LST_MAX];
uint16_t light_still_on = 0;
bool power_off = false;
Light.strip_timer_counter++;
if (!Light.power) { // All channels powered off
@ -1600,6 +1579,9 @@ void LightAnimate(void)
if (!Light.fade_running) {
sleep = Settings.sleep;
}
if (Settings.light_scheme >= LS_MAX) {
power_off = true;
}
} else {
if (Settings.sleep > PWM_MAX_SLEEP) {
sleep = PWM_MAX_SLEEP; // set a maxumum value of 50 milliseconds to ensure that animations are smooth
@ -1651,7 +1633,7 @@ void LightAnimate(void)
}
}
if (Settings.light_scheme < LS_MAX) { // exclude WS281X Neopixel
if ((Settings.light_scheme < LS_MAX) || power_off) { // exclude WS281X Neopixel schemes
// Apply power modifiers to Light.new_color
LightApplyPower(Light.new_color, Light.power);
@ -1736,7 +1718,7 @@ void LightAnimate(void)
cur_col_10bits[i] = orig_col_10bits[Light.color_remap[i]];
}
if (!Settings.light_fade) { // no fade
if (!Settings.light_fade || power_off) { // no fade
// record the current value for a future Fade
memcpy(Light.fade_start_8, cur_col, sizeof(Light.fade_start_8));
memcpy(Light.fade_start_10, cur_col_10bits, sizeof(Light.fade_start_10));

View File

@ -452,6 +452,7 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved)
RulesVarReplace(commands, F("%TIME%"), String(MinutesPastMidnight()));
RulesVarReplace(commands, F("%UPTIME%"), String(MinutesUptime()));
RulesVarReplace(commands, F("%TIMESTAMP%"), GetDateAndTime(DT_LOCAL));
RulesVarReplace(commands, F("%TOPIC%"), Settings.mqtt_topic);
#if defined(USE_TIMERS) && defined(USE_SUNRISE)
RulesVarReplace(commands, F("%SUNRISE%"), String(SunMinutes(0)));
RulesVarReplace(commands, F("%SUNSET%"), String(SunMinutes(1)));

View File

@ -25,16 +25,8 @@ const uint32_t ZIGBEE_BUFFER_SIZE = 256; // Max ZNP frame is SOF+LEN+CMD1+CMD2+
const uint8_t ZIGBEE_SOF = 0xFE;
const uint8_t ZIGBEE_SOF_ALT = 0xFF;
//#define Z_USE_SOFTWARE_SERIAL
#ifdef Z_USE_SOFTWARE_SERIAL
#include <SoftwareSerial.h>
SoftwareSerial *ZigbeeSerial = nullptr;
#else
#include <TasmotaSerial.h>
TasmotaSerial *ZigbeeSerial = nullptr;
#endif
const char kZigbeeCommands[] PROGMEM = "|"
D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEE_PERMITJOIN "|"
@ -185,9 +177,7 @@ void ZigbeeInput(void)
char hex_char[(zigbee_buffer->len() * 2) + 2];
ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char));
#ifndef Z_USE_SOFTWARE_SERIAL
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric());
#endif
// buffer received, now check integrity
if (zigbee_buffer->len() != zigbee_frame_len) {
// Len is not correct, log and reject frame
@ -224,21 +214,16 @@ void ZigbeeInit(void)
zigbee.active = false;
if ((pin[GPIO_ZIGBEE_RX] < 99) && (pin[GPIO_ZIGBEE_TX] < 99)) {
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("Zigbee: GPIOs Rx:%d Tx:%d"), pin[GPIO_ZIGBEE_RX], pin[GPIO_ZIGBEE_TX]);
#ifdef Z_USE_SOFTWARE_SERIAL
ZigbeeSerial = new SoftwareSerial();
ZigbeeSerial->begin(115200, pin[GPIO_ZIGBEE_RX], pin[GPIO_ZIGBEE_TX], SWSERIAL_8N1, false, 256); // ZNP is 115200, RTS/CTS (ignored), 8N1
ZigbeeSerial->enableIntTx(false);
zigbee_buffer = new SBuffer(ZIGBEE_BUFFER_SIZE);
#else
ZigbeeSerial = new TasmotaSerial(pin[GPIO_ZIGBEE_RX], pin[GPIO_ZIGBEE_TX], 0, 0, 256); // set a receive buffer of 256 bytes
// if seriallog_level is 0, we allow GPIO 13/15 to switch to Hardware Serial
ZigbeeSerial = new TasmotaSerial(pin[GPIO_ZIGBEE_RX], pin[GPIO_ZIGBEE_TX], seriallog_level ? 1 : 2, 0, 256); // set a receive buffer of 256 bytes
ZigbeeSerial->begin(115200);
if (ZigbeeSerial->hardwareSerial()) {
ClaimSerial();
zigbee_buffer = new PreAllocatedSBuffer(sizeof(serial_in_buffer), serial_in_buffer);
uint32_t aligned_buffer = ((uint32_t)serial_in_buffer + 3) & ~3;
zigbee_buffer = new PreAllocatedSBuffer(sizeof(serial_in_buffer) - 3, (char*) aligned_buffer);
} else {
zigbee_buffer = new SBuffer(ZIGBEE_BUFFER_SIZE);
}
#endif
zigbee.active = true;
zigbee.init_phase = true; // start the state machine
zigbee.state_machine = true; // start the state machine

View File

@ -37,10 +37,13 @@
#define D_CMND_SHUTTER_INVERT "Invert"
#define D_CMND_SHUTTER_CLIBRATION "Calibration"
#define D_CMND_SHUTTER_MOTORDELAY "MotorDelay"
#define D_CMND_SHUTTER_FREQUENCY "Frequency"
#define D_SHUTTER "SHUTTER"
const uint16_t MOTOR_STOP_TIME = 500; // in mS
const uint16_t MOTOR_STOP_TIME = 500; // in mS
uint8_t calibrate_pos[6] = {0,30,50,70,90,100};
uint16_t messwerte[5] = {30,50,70,90,100};
@ -51,12 +54,13 @@ const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|"
D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|"
D_CMND_SHUTTER_OPENTIME "|" D_CMND_SHUTTER_CLOSETIME "|" D_CMND_SHUTTER_RELAY "|"
D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|"
D_CMND_SHUTTER_MOTORDELAY;
D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY;
void (* const ShutterCommand[])(void) PROGMEM = {
&CmndShutterOpen, &CmndShutterClose, &CmndShutterStop, &CmndShutterPosition,
&CmndShutterOpenTime, &CmndShutterCloseTime, &CmndShutterRelay,
&CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay};
&CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay,
&CmndShutterFrequency};
const char JSON_SHUTTER_POS[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Position\":%d,\"direction\":%d}";
@ -68,23 +72,24 @@ struct SHUTTER {
power_t mask = 0; // bit mask with 11 at the position of relays that belong to at least ONE shutter
power_t old_power = 0; // preserve old bitmask for power to extract the relay that changes.
power_t switched_relay = 0; // bitmatrix that contain the relays that was lastly changed.
uint32_t time[MAX_SHUTTERS];
uint32_t time[MAX_SHUTTERS]; // operating time of the shutter in 0.05sec
int32_t open_max[MAX_SHUTTERS]; // max value on maximum open calculated
int32_t target_position[MAX_SHUTTERS]; // position to go to
int32_t start_position[MAX_SHUTTERS];
int32_t start_position[MAX_SHUTTERS]; // position before a movement is started. init at start
int32_t real_position[MAX_SHUTTERS]; // value between 0 and Shutter.open_max
uint16_t open_time[MAX_SHUTTERS]; // duration to open the shutter
uint16_t close_time[MAX_SHUTTERS]; // duration to close the shutter
uint16_t open_time[MAX_SHUTTERS]; // duration to open the shutter. 112 = 11.2sec
uint16_t close_time[MAX_SHUTTERS]; // duration to close the shutter. 112 = 11.2sec
uint16_t close_velocity[MAX_SHUTTERS]; // in relation to open velocity. higher value = faster
uint16_t operations[MAX_SHUTTERS];
int8_t direction[MAX_SHUTTERS]; // 1 == UP , 0 == stop; -1 == down
uint8_t mode = 0; // operation mode definition. see enum type above SHT_OFF_OPEN__OFF_CLOSE, SHT_OFF_ON__OPEN_CLOSE, SHT_PULSE_OPEN__PULSE_CLOSE
uint8_t motordelay[MAX_SHUTTERS]; // initial motorstarttime in 0.05sec.
uint8_t motordelay[MAX_SHUTTERS]; // initial motorstarttime in 0.05sec.
uint16_t pwm_frequency; // frequency of PWN for stepper motors
uint16_t max_pwm_frequency = 1000;
} Shutter;
void ShutterRtc50mS(void)
{
for (uint32_t i = 0; i < MAX_SHUTTERS; i++) {
for (uint32_t i = 0; i < shutters_present; i++) {
Shutter.time[i]++;
}
}
@ -189,6 +194,11 @@ void ShutterInit(void)
}
} else {
Shutter.mode = SHT_OFF_ON__OPEN_CLOSE;
if (pin[GPIO_PWM1 ]+i < 99) {
Shutter.pwm_frequency = 0;
analogWriteFreq(Shutter.pwm_frequency);
analogWrite(pin[GPIO_PWM1]+i, 50);
}
}
TickerShutter.attach_ms(50, ShutterRtc50mS );
@ -237,45 +247,32 @@ void ShutterUpdatePosition(void)
{
char scommand[CMDSZ];
char stopic[TOPSZ];
char stemp2[10];
for (uint32_t i = 0; i < shutters_present; i++) {
if (Shutter.direction[i] != 0) {
//char stemp1[20];
// frequency start at 0. Stepper will start moving with first change of the Speed
// Counter should be initiated to 0 to count movement.
// 0..1000 in step 100 = 10 steps with 0.05 sec = 0.5sec total ramp time from start to
// full speed.
if (pin[GPIO_PWM1]+i < 99 && Shutter.pwm_frequency != Shutter.max_pwm_frequency) {
Shutter.pwm_frequency += Shutter.max_pwm_frequency/20;
Shutter.pwm_frequency = (Shutter.pwm_frequency > Shutter.max_pwm_frequency ? Shutter.max_pwm_frequency : Shutter.pwm_frequency);
analogWriteFreq(Shutter.pwm_frequency);
analogWrite(pin[GPIO_PWM1]+i, 50);
}
Shutter.real_position[i] = Shutter.start_position[i] + ( (Shutter.time[i] - Shutter.motordelay[i]) * (Shutter.direction[i] > 0 ? 100 : -Shutter.close_velocity[i]));
// avoid real position leaving the boundaries.
Shutter.real_position[i] = Shutter.real_position[i] < 0 ? 0 : (Shutter.real_position[i] > Shutter.open_max[i] ? Shutter.open_max[i] : Shutter.real_position[i]) ;
// Add additional runtime, if shutter did not reach the endstop for some time.
if (Shutter.target_position[i] == Shutter.real_position[i] && Shutter.target_position[i] == 0) {
// for every operation add 5x50ms = 250ms to stop position
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Adding additional runtime"));
Shutter.real_position[i] += 500 * Shutter.operations[i] ;
Shutter.operations[i] = 0;
}
if (Shutter.real_position[i] * Shutter.direction[i] >= Shutter.target_position[i] * Shutter.direction[i] ) {
// calculate relay number responsible for current movement.
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Stop Condition detected: real: %d, Target: %d, direction: %d"),Shutter.real_position[i], Shutter.target_position[i],Shutter.direction[i]);
uint8_t cur_relay = Settings.shutter_startrelay[i] + (Shutter.direction[i] == 1 ? 0 : 1) ;
char stemp2[10];
Settings.shutter_position[i] = ShutterRealToPercentPosition(Shutter.real_position[i], i);
//Settings.shutter_position[i] = Settings.shuttercoeff[2][i] * 5 > Shutter.real_position[i] ? (Shutter.real_position[i] * 10 / Settings.shuttercoeff[2][i] + 4)/10 : ((Shutter.real_position[i]-Settings.shuttercoeff[0,i]) *10 / Settings.shuttercoeff[1][i] +4) / 10;
if (0 < Settings.shutter_position[i] && Settings.shutter_position[i] < 100) {
Shutter.operations[i]++;
} else {
Shutter.operations[i] = 0;
}
dtostrfd((float)Shutter.time[i] / 20, 1, stemp2);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Real Pos. %d, Stoppos: %ld, relay: %d, direction %d, pulsetimer: %d, rtcshutter: %s [s], operationtime %d"), i, Shutter.real_position[i], Settings.shutter_position[i], cur_relay -1, Shutter.direction[i], Settings.pulse_timer[cur_relay -1], stemp2, Shutter.operations[i]);
Shutter.start_position[i] = Shutter.real_position[i];
// sending MQTT result to broker
snprintf_P(scommand, sizeof(scommand),PSTR(D_SHUTTER "%d"), i+1);
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
Response_P("%d", Settings.shutter_invert[i] ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i]);
MqttPublish(stopic, Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN
switch (Shutter.mode) {
case SHT_PULSE_OPEN__PULSE_CLOSE:
@ -288,8 +285,30 @@ void ShutterUpdatePosition(void)
break;
case SHT_OFF_ON__OPEN_CLOSE:
// This is a failsafe configuration. Relay1 ON/OFF Relay2 -1/1 direction
// Only allow PWM microstepping if PWM and COUNTER are defined.
// see wiki to connect PWM and COUNTER
if (pin[GPIO_PWM1 ]+i < 99 && pin[GPIO_CNTR1 ]+i < 99 ) {
int16_t missing_steps = ((Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) - RtcSettings.pulse_counter[i];
Shutter.pwm_frequency = 0;
//slow down for acurate position
analogWriteFreq(500);
analogWrite(pin[GPIO_PWM1]+i, 50);
//prepare for stop PWM
Shutter.motordelay[i] = -2 + Shutter.motordelay[i] + missing_steps/(Shutter.max_pwm_frequency/20);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Missing steps %d, adjust motordelay %d, counter %d, temp realpos %d"), missing_steps, Shutter.motordelay[i],RtcSettings.pulse_counter[i] ,Shutter.real_position[i]);
Settings.shutter_motordelay[i]=Shutter.motordelay[i];
analogWriteFreq(0);
while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) {
delay(1);
}
analogWrite(pin[GPIO_PWM1]+i, 0);
Shutter.real_position[i] = ((int32_t)RtcSettings.pulse_counter[i]*Shutter.direction[i]*2000 / Shutter.max_pwm_frequency)+Shutter.start_position[i];
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT:Realpos %d, pulsecount %d, startpos %d, int32 %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i], ((int32_t)RtcSettings.pulse_counter[i]*Shutter.direction[i]*2000 / Shutter.max_pwm_frequency));
}
if ((1 << (Settings.shutter_startrelay[i]-1)) & power) {
ExecuteCommandPower(Settings.shutter_startrelay[i], 0, SRC_SHUTTER);
ExecuteCommandPower(Settings.shutter_startrelay[i]+1, 0, SRC_SHUTTER);
}
break;
case SHT_OFF_OPEN__OFF_CLOSE:
@ -300,6 +319,18 @@ void ShutterUpdatePosition(void)
}
break;
}
Settings.shutter_position[i] = ShutterRealToPercentPosition(Shutter.real_position[i], i);
dtostrfd((float)Shutter.time[i] / 20, 1, stemp2);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Real Pos. %d, Stoppos: %ld, relay: %d, direction %d, pulsetimer: %d, motordelay %d, rtcshutter: %s [s]"), i, Shutter.real_position[i], Settings.shutter_position[i], cur_relay -1, Shutter.direction[i], Settings.pulse_timer[cur_relay -1], Shutter.motordelay[i],stemp2);
Shutter.start_position[i] = Shutter.real_position[i];
// sending MQTT result to broker
snprintf_P(scommand, sizeof(scommand),PSTR(D_SHUTTER "%d"), i+1);
GetTopic_P(stopic, STAT, mqtt_topic, scommand);
Response_P("%d", Settings.shutter_invert[i] ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i]);
MqttPublish(stopic, Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN
Shutter.direction[i] = 0;
uint8_t position = Settings.shutter_invert[i] ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i];
Response_P(PSTR("{"));
@ -326,6 +357,15 @@ void ShutterStartInit(uint8_t index, uint8_t direction, int32_t target_pos)
Shutter.target_position[index] = target_pos;
Shutter.start_position[index] = Shutter.real_position[index];
Shutter.time[index] = 0;
if (pin[GPIO_PWM1]+index < 99) {
Shutter.pwm_frequency = 0;
analogWriteFreq(Shutter.pwm_frequency);
analogWrite(pin[GPIO_PWM1]+index, 0);
// can be operated without counter, but then not that acurate.
if (pin[GPIO_CNTR1]+index < 99) {
RtcSettings.pulse_counter[index] = 0;
}
}
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start shutter: %d from %d to %d in directin %d"), index, Shutter.start_position[index], Shutter.target_position[index], Shutter.direction[index]);
}
@ -342,10 +382,10 @@ void ShutterReportPosition(void)
if (Shutter.direction[i] != 0) {
char stemp1[20];
char stemp2[10];
dtostrfd((float)Shutter.time[i] / 20, 1, stemp2);
dtostrfd((float)Shutter.time[i] / 20, 2, stemp2);
shutter_moving = 1;
//Settings.shutter_position[i] = Settings.shuttercoeff[2][i] * 5 > Shutter.real_position[i] ? Shutter.real_position[i] / Settings.shuttercoeff[2][i] : (Shutter.real_position[i]-Settings.shuttercoeff[0,i]) / Settings.shuttercoeff[1][i];
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d: Real Pos: %d, Target %d, source: %s, start-pos: %d %%, direction: %d, rtcshutter: %s [s]"), i,Shutter.real_position[i], Shutter.target_position[i], GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), Settings.shutter_position[i], Shutter.direction[i], stemp2 );
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d: Real Pos: %d, Target %d, source: %s, start-pos: %d %%, direction: %d, motordelay %d, rtcshutter: %s [s]"), i,Shutter.real_position[i], Shutter.target_position[i], GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), Settings.shutter_position[i], Shutter.direction[i], Shutter.motordelay[i], stemp2 );
}
}
if (rules_flag.shutter_moving > shutter_moving) {
@ -406,12 +446,6 @@ void ShutterRelayChanged(void)
}
}
///////////////////////////////////////////////////////////////////////////////////
// Shutter specific functions
// TODO: move to shutter driver and make them accessible in a generic way
// device: 1..<numberOfShutters>
// position: 0-100
void ShutterSetPosition(uint8_t device, uint8_t position)
{
char svalue[32]; // Command and number parameter
@ -426,7 +460,6 @@ void ShutterSetPosition(uint8_t device, uint8_t position)
void CmndShutterOpen(void)
{
XdrvMailbox.payload = 100;
XdrvMailbox.data_len = 3;
last_source = SRC_WEBGUI;
CmndShutterPosition();
}
@ -434,7 +467,7 @@ void CmndShutterOpen(void)
void CmndShutterClose(void)
{
XdrvMailbox.payload = 0;
XdrvMailbox.data_len = 1;
XdrvMailbox.data_len = 0;
last_source = SRC_WEBGUI;
CmndShutterPosition();
}
@ -445,8 +478,8 @@ void CmndShutterStop(void)
uint32_t index = XdrvMailbox.index -1;
if (Shutter.direction[index] != 0) {
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Stop moving shutter %d: direction: %d"), XdrvMailbox.index, Shutter.direction[index]);
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Stop moving shutter %d: direction: %d"), XdrvMailbox.index, Shutter.direction[index]);
// set stop position 10 steps ahead (0.5sec to allow normal stop)
int32_t temp_realpos = Shutter.start_position[index] + ( (Shutter.time[index]+10) * (Shutter.direction[index] > 0 ? 100 : -Shutter.close_velocity[index]));
XdrvMailbox.payload = ShutterRealToPercentPosition(temp_realpos, index);
//XdrvMailbox.payload = Settings.shuttercoeff[2][index] * 5 > temp_realpos ? temp_realpos / Settings.shuttercoeff[2][index] : (temp_realpos-Settings.shuttercoeff[0,index]) / Settings.shuttercoeff[1][index];
@ -472,7 +505,7 @@ void CmndShutterPosition(void)
if (!strcmp(XdrvMailbox.data,"STOP")) { CmndShutterStop(); }
return;
}
int8_t target_pos_percent = XdrvMailbox.payload < 0 ? 0 : (XdrvMailbox.payload > 100 ? 100 : XdrvMailbox.payload);
// webgui still send also on inverted shutter the native position.
target_pos_percent = Settings.shutter_invert[index] && SRC_WEBGUI != last_source ? 100 - target_pos_percent : target_pos_percent;
@ -497,7 +530,6 @@ void CmndShutterPosition(void)
}
if (Shutter.direction[index] != new_shutterdirection ) {
ShutterStartInit(index, new_shutterdirection, Shutter.target_position[index]);
Shutter.operations[index]++;
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE) {
ExecuteCommandPower(Settings.shutter_startrelay[index], 0, SRC_SHUTTER);
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay5 5s, xdrv %d"), XdrvMailbox.payload);
@ -556,7 +588,7 @@ void CmndShutterMotorDelay(void)
ShutterInit();
}
char time_chr[10];
dtostrfd((float)(Settings.shutter_motordelay[XdrvMailbox.index -1]) / 20, 1, time_chr);
dtostrfd((float)(Settings.shutter_motordelay[XdrvMailbox.index -1]) / 20, 2, time_chr);
ResponseCmndIdxChar(time_chr);
}
}
@ -593,6 +625,16 @@ void CmndShutterSetHalfway(void)
}
}
void CmndShutterFrequency(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 10000)) {
Shutter.max_pwm_frequency = XdrvMailbox.payload;
ResponseCmndNumber(XdrvMailbox.payload); // ????
} else {
ResponseCmndNumber(Shutter.max_pwm_frequency);
}
}
void CmndShutterSetClose(void)
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {

View File

@ -1,407 +1,3 @@
# decode-config.py
_decode-config.py_ is able to backup and restore Tasmota configuration.
A tool to backup and restore the configuration of [Tasmota](http://tasmota.com/)-devices.
In comparison with the Tasmota build-in "Backup/Restore Configuration" function _decode-config.py_
* uses human readable and editable [JSON](http://www.json.org/)-format for backup/restore,
* can restore previously backup and changed [JSON](http://www.json.org/)-format files,
* is able to create Tasmota compatible command list with related config parameter
Comparing backup files created by *decode-config.py* and *.dmp files created by Tasmota "Backup/Restore Configuration":
| &nbsp; | decode-config.py<br />*.json file | Tasmota<br />*.dmp file |
|-------------------------|:-------------------------------:|:-----------------------------------:|
| Encrypted | No | Yes |
| Readable | Yes | No |
| Simply editable | Yes | No |
| Simply batch processing | Yes | No |
_decode-config.py_ is compatible with Tasmota version from v5.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-format)
* [.json File Format](decode-config.md#-json-format)
* [.bin File Format](decode-config.md#-bin-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)
* [Output to screen](decode-config.md#output-to-screen)
* [JSON output](decode-config.md#json-output)
* [Tasmota command output](decode-config.md#tasmota-command-output)
* [Filter data](decode-config.md#filter-data)
* [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)
* [Notes](decode-config.md#notes)
## Prerequisite
* This program is written in [Python](https://en.wikipedia.org/wiki/Python_(programming_language)) so you need to install a working python environment for your operating system.
### Linux
```
sudo apt-get install python python-pip libcurl4-openssl-dev libssl-dev
```
```
pip install pycurl configargparse
```
### Windows 10
Install [Python 2.7](https://www.python.org/download/releases/2.7/) then install dependencies. For PyCurl you need to [download pycurl7.43.0.3cp27cp27mwin_amd64.whl](https://www.lfd.uci.edu/~gohlke/pythonlibs/#pycurl) for Windows 10 64bit.
```
pip install pycurl-7.43.0.3-cp27-cp27m-win_amd64.whl
// run the command from the folder where you downloaded the file
pip install configargparse
```
* [Tasmota](https://github.com/arendst/Tasmota) [Firmware](https://github.com/arendst/Tasmota/releases) with Web-Server enabled:
* To backup or restore configurations from or to a Tasmota device you need a firmare with enabled web-server in admin mode (command [WebServer 2](https://tasmota.github.io/docs/#/Commands#wifi)). This is the Tasmota default.
* If using your own compiled firmware be aware to enable the web-server (`#define USE_WEBSERVER` and `#define WEB_SERVER 2`).
## 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` parameter.
This file will be created by _decode-config.py_ using the `--backup-file` with `--backup-type json` parameter, this is the 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:
The .bin file contains the same information as the original .dmp file from Tasmota "Backup/Restore Configuration" but it is decrpted and 4 byte longer than an original (it is a prefix header at the beginning). .bin file data starting at address 4 contains the same as the **struct SYSCFG** from Tasmota [settings.h](https://github.com/arendst/Tasmota/blob/master/tasmota/settings.h) in decrypted format.
#### File extensions
You don't need to append exensions for your file name as _decode-config.py_ uses auto extension as default. The extension will be choose based on file contents and `--backup-type` parameter.
If you do not want using auto extensions use the `--no-extension` parameter.
## Usage
After download don't forget to set the executable 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 using the `-d <host>` parameter
* a Tasmota `*.dmp` configuration file using `-f <filename>` parameter
Example:
decode-config.py -d tasmota-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 use `--backup-file <filename>`, you can use placeholder for Version, Friendlyname and Hostname:
decode-config.py -d tasmota-4281 --backup-file Config_@f_@v
If you have setup a WebPassword within Tasmota, use
decode-config.py -d tasmota-4281 -p <yourpassword> --backup-file Config_@f_@v
will create a file like `Config_Tasmota_6.4.0.json` (the part `Tasmota` and `6.4.0` will choosen related to your device configuration). Because the default backup file format is JSON, you can read and change it with any raw text editor.
### Restore backup file
Reading back a saved (and possible changed) backup file use the `--restore-file <filename>` parameter. 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_Tasmota_6.2.1.json` to device `tasmota-4281` use:
decode-config.py -d tasmota-4281 --restore-file Config_Tasmota_6.2.1.json
with password set by WebPassword:
decode-config.py -d tasmota-4281 -p <yourpassword> --restore-file Config_Tasmota_6.2.1.json
### Output to screen
To force screen output use the `--output` parameter.
Output to screen is default enabled when calling the program with a source parameter (-f or -d) but without any backup or restore parameter.
#### JSON output
The default output format is [JSON](decode-config.md#-json-format). You can force JSON output using the `--output-format json` parameter.
Example:
decode-config.py -d tasmota-4281 -c my.conf -x Wifi --output-format json
{
...
"hostname": "%s-%04d",
"ip_address": [
"0.0.0.0",
"192.168.12.1",
"255.255.255.0",
"192.168.12.1"
],
"ntp_server": [
"ntp.localnet.home",
"ntp2.localnet.home",
"192.168.12.1"
],
"sta_active": 0,
"sta_config": 5,
"sta_pwd": [
"myWlAnPaszxwo!z",
"myWlAnPaszxwo!z2"
],
"sta_ssid": [
"wlan.1",
"my-wlan"
],
"web_password": "myPaszxwo!z",
"webserver": 2
...
}
Note: JSON output always contains all configuration data like the backup file except you are using `--group` arg.
#### Tasmota command output
_decode-config.py_ is able to translate the configuration data to (most all) Tasmota commands. To output your configuration as Tasmota commands use `--output-format cmnd` or `--output-format command`.
Example:
decode-config.py -d tasmota-4281 -c my.conf -g Wifi --output-format cmnd
# Wifi:
AP 0
Hostname %s-%04d
IPAddress1 0.0.0.0
IPAddress2 192.168.12.1
IPAddress3 255.255.255.0
IPAddress4 192.168.12.1
NtpServer1 ntp.localnet.home
NtpServer2 ntp2.localnet.home
NtpServer3 192.168.12.1
Password1 myWlAnPaszxwo!z
Password2 myWlAnPaszxwo!z2
SSId1 wlan.1
SSId2 wlan.1
WebPassword myPaszxwo!z
WebServer 2
WifiConfig 5
Note: A few very specific module commands like MPC230xx, KNX and some Display commands are not supported. These are still available by JSON output.
### Filter data
The huge number of Tasmota configuration data can be overstrained and confusing, so the most of the configuration data are grouped into categories.
With _decode-config.py_ the following categories are available: `Display`, `Domoticz`, `Internal`, `KNX`, `Led`, `Logging`, `MCP230xx`, `MQTT`, `Main`, `Management`, `Pow`, `Sensor`, `Serial`, `SetOption`, `RF`, `System`, `Timers`, `Wifi`
These are similary to the categories on [https://tasmota.github.io/docs/#/Commands](Tasmota Command Wiki).
To filter outputs to a subset of groups use the `-g` or `--group` arg concatenating the grooup you want, e. g.
decode-config.py -d tasmota-4281 -c my.conf --output-format cmnd --group Main MQTT Management Wifi
### 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 tasmota-4281 -c my.conf --backup-file Config_@f_@v
### More program arguments
For better reading each short written arg (minus sign `-`) has a corresponding 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>] [-t json|bin|dmp] [-E] [-e] [-F]
[--json-indent <indent>] [--json-compact]
[--json-hide-pw] [--json-show-pw]
[--cmnd-indent <indent>] [--cmnd-groups]
[--cmnd-nogroups] [--cmnd-sort] [--cmnd-unsort]
[-c <filename>] [-S] [-T json|cmnd|command]
[-g {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rf,Rules,Sensor,Serial,Setoption,Shutter,System,Timer,Wifi} [{Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rf,Rules,Sensor,Serial,Setoption,Shutter,System,Timer,Wifi} ...]]
[--ignore-warnings] [-h] [-H] [-v] [-V]
Backup/Restore 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.
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 specification
-i, --restore-file <filename>
file to restore configuration from (default: None).
Replacements: @v=firmware version from config,
@f=device friendly name from config, @h=device
hostname from config, @H=device hostname from device
(-d arg only)
-o, --backup-file <filename>
file to backup configuration to (default: None).
Replacements: @v=firmware version from config,
@f=device friendly name from config, @h=device
hostname from config, @H=device hostname from device
(-d arg only)
-t, --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
-F, --force-restore force restore even configuration is identical
JSON output:
JSON 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
--json-show-pw, --json-unhide-pw
unhide passwords (default)
Tasmota command output:
Tasmota command output format specification
--cmnd-indent <indent>
Tasmota command grouping indent level (default: '2').
0 disables indent
--cmnd-groups group Tasmota commands (default)
--cmnd-nogroups leave Tasmota commands ungrouped
--cmnd-sort sort Tasmota commands (default)
--cmnd-unsort leave Tasmota commands unsorted
Common:
Optional arguments
-c, --config <filename>
program config file - can be used to set default
command args (default: None)
-S, --output display output regardsless of backup/restore usage
(default do not output on backup or restore usage)
-T, --output-format json|cmnd|command
display output format (default: 'json')
-g, --group {Control,Devices,Display,Domoticz,Internal,Knx,Light,Management,Mqtt,Power,Rf,Rules,Sensor,Serial,Setoption,Shutter,System,Timer,Wifi}
limit data processing to command groups (default no
filter)
--ignore-warnings do not exit on warnings. Not recommended, used by your
own responsibility!
Info:
Extra 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.
### Program parameter notes
_decode-config.py_
### 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 tasmota --restore-file Config_Tasmota_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 tasmota --backup-file Config_@f_@v.dmp`
b) use args to choice the file format
`decode-config.py -c my.conf -d tasmota --backup-type dmp --backup-file Config_@f_@v`
#### Use batch processing
for device in tasmota1 tasmota2 tasmota3; do ./decode-config.py -c my.conf -d $device -o Config_@f_@v
or under windows
for device in (tasmota1 tasmota2 tasmota3) do python decode-config.py -c my.conf -d %device -o Config_@f_@v
will produce JSON configuration files for host tasmota1, tasmota2 and tasmota3 using friendly name and Tasmota firmware version for backup filenames.
## Notes
Some general notes:
* Filename replacement macros **@h** and **@H**:
* **@h**
The **@h** replacement macro uses the hostname configured with the Tasomta Wifi `Hostname <host>` command (defaults to `%s-%04d`). It will not use the network hostname of your device because this is not available when working with files only (e.g. `--file <filename>` as source).
To prevent having a useless % in your filename, **@h** will not replaced by configuration data hostname if this contains '%' characters.
* **@H**
If you want to use the network hostname within your filename, use the **@H** replacement macro instead - but be aware this will only replaced if you are using a network device as source (`-d`, `--device`, `--host`); it will not work when using a file as source (`-f`, `--file`)
## decode-config has moved to [https://github.com/tasmota/decode-config](https://github.com/tasmota/decode-config)

File diff suppressed because it is too large Load Diff

View File

@ -1,491 +0,0 @@
:020000040000FA
:100000000210D8A2029290A2029280AD40AC3F7F33
:100010000A7E0012002E12001DA202B322E59120DA
:10002000E2FB220210487597A5222202141B8E4182
:100030008F428C438D4412163112188EE54424BF32
:100040009000E8F0E54334FF9000E7F09000E3E52E
:1000500041F0A3E542F043910422220211671219F4
:100060002253D87853DAFE1218F3E4900087F02276
:10007000D2DE2202146E1217C0C290C296C280E471
:10008000FBFD7F101218DA12053174A4F0D2AF1202
:10009000170AD2969000ECE004F070069000EBE0B6
:1000A00004F09000EBE0B427E9A3E0B410E4C296BA
:1000B0001200263003091216B18E228F2380067596
:1000C0002201752300E5237004E522640170469047
:1000D00000DEE0700612170B0202959000EBE4754B
:1000E000F001120807FED3E5F09410EE94274002C9
:1000F000D296D39000ECE094309000EBE0947550F1
:1001000003020295E4F0A3F09000DEF0900099F075
:10011000C29602029512170A9000DEE014602A14BB
:1001200070030202591470030202171470030202D2
:100130003024046003020295E52364AA60030202EE
:10014000959000DE04F0020295E523900099F0906E
:1001500000DE7402F0E52312092F0201A0017FA145
:10016000018BA501A9A601BDA701C6A801DDA901B2
:10017000CCB001D5B1019DC00295FF0000020C1268
:10018000051EE490008AF07FA1806512054E900064
:10019000EA7408F0E4F52575240902029512054E6B
:1001A000E4F52575240202029590008A7401F07F1F
:1001B000A61215A690007974A6F0020295120531D8
:1001C00074A4F00202959000EA7408F09000DE74C6
:1001D00003F00202957FB112056202029512051E1C
:1001E00090008AE09000E9F090008A7401F07FA905
:1001F0001205627D307C757F017E00121797020226
:100200009512056B900079EFF0E48005E490009979
:10021000F09000DEF0807EE4F525E523F524E5246A
:10022000D39400402C12005E9000DE7404F08065D0
:1002300074032525F582E43400F583E523F00525D4
:10024000E525B52402800AE525C39470404775244E
:10025000709000DE7402F0803CE5236455703690A7
:1002600000DEF0C203900099E02460601B24FC6073
:100270001224FE600E14600B24F760101460042436
:100280001070127FA0121875D2038009900004E04C
:10029000049000EAF0900099E012092F02BEA10339
:1002A00033A40377A50333A60447A802BEA9047CA0
:1002B000B004E5B1041EC00442FF000000B090008D
:1002C00086E030E73F7DC87C0012053F900099E052
:1002D0002457600E2408701F12056B7FA31215ECC3
:1002E00080159000E9E090008AF0900079E0FF121C
:1002F00015A67FAB12057CE4900086F043DA01D2AC
:10030000030200B01218EB50207DE87C0312053F79
:10031000900099E02457600C240860030200B07F2D
:10032000A20204D77FAA0204D71205744003020078
:10033000B0802E900086E030E71F900099E0245AAC
:10034000600F240260030204F17FA41215EC020482
:10035000F17FA612057C0204F1120574400302002D
:10036000B01216E7C006C0071216F69200D007D0EA
:10037000061209810200B09000DEE060030200B0C6
:100380001217127003020411240560030200B01258
:100390000558900005E0FFA3E090008BCFF0A3EF9D
:1003A000F0900007E0FFA3E090008DCFF0A3EFF006
:1003B000900003E0FFA3E090008FCFF0A3EFF07B6D
:1003C000017A00798B901A0EE493FC740193FD90EE
:1003D0001A10E493F52E1217028E2FF530901A138F
:1003E000E493F5311217028E32F533901A16E49326
:1003F000F5341217028E35F536901A19E493F53755
:10040000A3E493F538753900753A09120EBC020061
:10041000B09000EAE07063C2807FA00204D7900031
:10042000DEE060030200B0900003E0FCA3E0FD7F8B
:10043000017E00121797D29612001DC2967FA0026D
:1004400004D77F030204D79000DEE060030200B00F
:100450001217126019240560030200B012055890AB
:100460000003E0FF7C007D041213570200B09000EF
:10047000EAE07006C2807FA0805D80619000DEE0CF
:1004800060030200B01217126043240560030200EB
:10049000B09000EAE014F012005E7E007F05C00616
:1004A000C007900003E0FB25E0FFE433FE74052F56
:1004B000F58274003EAD82FCEB25E0FFE52424FECE
:1004C000C39FFBD007D006120FA70200B09000EA2E
:1004D000E0700AC2807FA01218680200B0E49000A9
:1004E00087F00200B0900086E030E7107FB1121173
:1004F000ECE4900086F043DA010200B07E007FED6C
:1005000012151040030200B01216E7C006C0071211
:1005100016F69200D007D006120D160200B07D32FA
:100520007C007F017E00121797D29612001DC296A2
:1005300022E490008AF07FA41215A6900079227F11
:10054000017E00121797D29612001DC29622120049
:100550005E9000DE7404F0229000EAE014F01200D5
:100560005E221215A6900079EFF022900079E0FF4C
:100570001215A6227E007FED12151022900086E053
:10058000547FFD12155B228F29E4F536EF25E02517
:10059000E02468F8E6701EEF25E025E02469F8768F
:1005A000087E007F707D007B017A00790312095577
:1005B000E490007AF0AB2CAA2DA92EC001120B6793
:1005C0002466F9E7540F120CA3120B86D001121403
:1005D000C1503D120B672466F9E7540FFF120CA3BC
:1005E000120C90300101B34031EF700A900077E5B2
:1005F0002AF0A3E52BF0120B67120CAF2401FFEFDA
:10060000FEEC54F04EFEEDFF120B67120C9A800ABE
:10061000120B672466F874F056F6AB2CAA2DA92E9F
:10062000C001120B67120CBB120BD1120CC7120BBC
:1006300086D0011214C15052120B67120CBB120B60
:10064000D1FF120CC75408FE120C92300101B340C6
:1006500043EF700A900088E52AF0A3E52BF0120B17
:1006600067120BC22401FFE433FEEFC4F8540FC835
:1006700068FFEEC454F048FEED540FFDEC4EFEED65
:100680004FFF120B67120C9A800A120B672467F84F
:10069000740F56F6120B67120CAFFB700F120BCAD9
:1006A000700A120B4D2469F8E4F6C322120B67247A
:1006B00068F8E53514667003753601C3E531953683
:1006C0006B7020D290120B672466F874F056F674A3
:1006D0000F0856120B662468F806120B672469F897
:1006E00016804C120B67120BC2FFC3E53495366FB0
:1006F000703DD290120B672466F8EC54F0FEED5476
:100700000FA60608120B662468F806120B67246908
:10071000F816120B67120BD8E0FF120B672469F86A
:10072000E6FE7401A806088002C333D8FC4FF0121D
:100730000B672469F8E67017120B67120BD8120CBE
:100740004CFF12182DEFF0120B672469F87608128F
:100750000B672468F8E6C3953540311218E350055D
:10076000E4900085F0120C4960181218F37D207C8B
:10077000037F017E0012176E120CD3A3E529F0440B
:1007800080F0120B4D2469F8E4F6D322C322BB019A
:100790000689828A83F0225002F722BBFE01F322EF
:1007A000EF8DF0A4A8F0CF8CF0A428CE8DF0A42E6D
:1007B000FE22BC000BBE0029EF8DF084FFADF022BD
:1007C000E4CCF875F008EF2FFFEE33FEEC33FCEECF
:1007D0009DEC984005FCEE9DFE0FD5F0E9E4CEFDC2
:1007E00022EDF8F5F0EE8420D21CFEADF075F00895
:1007F000EF2FFFED33FD4007985006D5F0F222C3EE
:1008000098FD0FD5F0EA22C5F0F8A3E028F0C5F076
:10081000F8E582158270021583E038F022BB0110E2
:10082000E58229F582E5833AF583E0F5F0A3E0223D
:100830005009E92582F886F008E622BBFE0AE92580
:1008400082F8E2F5F008E222E5832AF583E993F5E0
:10085000F0A3E9932275F008758200EF2FFFEE33C5
:10086000FECD33CDCC33CCC58233C5829BED9AEC23
:1008700099E58298400CF582EE9BFEED9AFDEC998D
:10088000FC0FD5F0D6E4CEFBE4CDFAE4CCF9A88297
:1008900022B800C1B90059BA002DEC8BF084CFCE3C
:1008A000CDFCE5F0CBF97818EF2FFFEE33FEED33FA
:1008B000FDEC33FCEB33FB10D703994004EB99FBC1
:1008C0000FD8E5E4F9FA227818EF2FFFEE33FEEDAA
:1008D00033FDEC33FCC933C910D7059BE99A4007B7
:1008E000EC9BFCE99AF90FD8E0E4C9FAE4CCFB22CE
:1008F00075F010EF2FFFEE33FEED33FDCC33CCC897
:1009000033C810D7079BEC9AE899400AED9BFDECA1
:100910009AFCE899F80FD5F0DAE4CDFBE4CCFAE4E0
:10092000C8F922A42582F582E5F03583F58322D02B
:1009300083D082F8E4937012740193700DA3A39393
:10094000F8740193F5828883E4737402936860EF0E
:10095000A3A3A380DFEF4E6012EF60010EEDBB0199
:100960000B89828A83F0A3DFFCDEFA2289F050072C
:10097000F709DFFCA9F022BBFEFCF309DFFCA9F0BC
:10098000228E268F27E4F528C3E5279464E5269474
:10099000005017E4F528E528120B922469F8E4F6D4
:1009A0000528E528B40FEFC2902290008AE0147069
:1009B00003020A6F046003020B4C7866E6C4540F0E
:1009C000F97065D3E5279494E52694115003020B42
:1009D0004C300003020B4CE9120C32E6540FFC08B9
:1009E000E6FDEC4E18F6ED08F618120C29EC540F43
:1009F0004E18F6ED08F6900001E526F0A3E527F085
:100A0000AE26FF7C007D1F1207B290008BEEF0A394
:100A1000EFF07C007D031207A0A3EEF0A3EFF0A39C
:100A2000E526F0A3E527F0227866E6C4540F6402B9
:100A30006003020B4C120CEB752C01752D00752E0A
:100A40008B901BD793FE7401938E2FF530901BD99A
:100A5000E493F531A3120BBB8E32F533901BDCE42B
:100A600093F534901BE0E493F535E4FF020587E449
:100A7000F528120BA8120D0CFFE528120C54F9EF03
:100A8000C399506EE528120C16F5828C832FF582DF
:100A9000E43583F583E493FF120C90300001B350EA
:100AA00003020B40E528C454F024D1F582E4341B42
:100AB000120C20F5828C83EF540775F00212092383
:100AC000120C22FDAF27AE261214CBE528501925B3
:100AD000E025E02466F8120C29EC540F4EFEEDFFE1
:100AE000120BA8120C9A8058120B922469F8E4F6A3
:100AF000804E120BA8120D0C697045120CEBE52804
:100B0000120BAFAA06752CFF8A2DF52EE528120CC4
:100B1000F6120BB98E2FF530E528120C63F531E58E
:100B200028120D01120BB98E32F533E528120C7222
:100B3000F534E528120C81F535AF28120587400CF5
:100B40000528E528C3940F5003020A7222C290E5DB
:100B50002925E025E02466F8E4F608F6E52925E0F5
:100B600025E02468F8E4F6E52925E025E022F58370
:100B7000E493FF5408FE131313541F24FF9202AB97
:100B800029AA2AA92BEF540775F002A4F58285F053
:100B9000832225E025E02466F8E4F608F6E528251A
:100BA000E025E02468F8E4F6E52825E025E022C405
:100BB00054F024D1F582E4341BF583E493FE7401F0
:100BC00093222466F8E6FC08E6FDECC4F854F0C86D
:100BD000EDC4540F48540F222468F8E6141313137D
:100BE000541F2403F582E43400F58322E529252BE4
:100BF000F582E43528F583E022A200E433C43333E0
:100C00003354804526FFE527900074CFF0A3EFF022
:100C1000E490007BF022C454F024D4F582E4341B29
:100C2000F583E493FC74019322E6FC08E6FDECC432
:100C3000540F2401FFEFC454F0FE22E52E25E024DA
:100C40008BF582E43400F58322900085E0FF90006C
:100C50007AE06F22C454F024D6F582E4341BF58385
:100C6000E49322C454F024D9F582E4341BF583E4E0
:100C70009322C454F024DCF582E4341BF583E4931E
:100C800022C454F024E0F582E4341BF583E493227B
:100C90005408131313541F24FF222466F8A60608D1
:100CA000A607222530F582E4352FF583E49322242C
:100CB00066F8E6FC08E6FDEC540F222466F9E7C46A
:100CC000F854F0C809E7222533F582E43532F5837C
:100CD000E4932290007AE0900085F053DAFE22251A
:100CE000E0247DF582E43400F58322A200920185A0
:100CF000262A85272B22C454F024D7F582E4341BFE
:100D000022C454F024DAF582E4341B222466F8E687
:100D1000FEEEC4540F228E268F27C3E5279464E588
:100D20002694005003020EAA900087E024FE60255E
:100D3000147003020DB724036003020EAFC290AF1C
:100D400027AE2612185A4003020EAF120BF990007C
:100D5000877402F022120EB0503090007BE09404B1
:100D60004021D290E4900000F0900073F0C2049013
:100D7000007CF090007AF0900003F09000877403FC
:100D8000F08025E4900087F0801E900074E0547F8E
:100D9000FEA3E0FFD3E5279FE5269E4005120BF951
:100DA000800690007BE004F090007BE0C394E0506C
:100DB00003020EAF020EAA90007CE004F090007BCC
:100DC000E0FFA3E0D39F4003020E587B007A007936
:100DD00028AF27AE261212DF4022900000E0FF125B
:100DE0000C3DE526F0A3E527F08F28900000E004F5
:100DF000F0E0D394074005E4900087F030041DA292
:100E000000E433C43333335480FFE528C454F04F37
:100E1000FF900073E0120BE2EFF08039900073E076
:100E2000FF120BE2E0FEA200E43333333354F84503
:100E300028FDEE4DF074032F120BE4120C4CFF1240
:100E4000182DEFF0900073E004F0E0D394704005AB
:100E5000E4900087F0B20422120EB0504D1218E355
:100E60005005E4900085F0120C49603A1218F37DA9
:100E7000207C037F017E0012176E120CD3900003BA
:100E8000E0FD900074E05480FF900000E0C454F056
:100E90004FFFED4F900003F0900074E0547FF0900E
:100EA0000086E04480F0C2908000E4900087F02249
:100EB000A2009201AF27AE26121744228B298A2A5C
:100EC000892B8C2C8D2DE4F53D753E80F53BE53B63
:100ED000C3952E5010E52D253BF582E4352C120FDD
:100EE0006C053B80E9E4F53BE53BC395385057E59D
:100EF0003A253DF582E43539F583E0553E7019F524
:100F00003CE53CC39531502DE530253CF582E43578
:100F10002F120F6C053C80E9E4F53CE53CC39534A9
:100F20005013E533253CF582E43532120B6E120F77
:100F30009B053C80E6E53EC313F53E7005053D7517
:100F40003E80053B80A2E4F53BE53BC3953750135B
:100F5000E536253BF582E43535120B6E120F9B0505
:100F60003B80E6C2909000877405F022F583E493FD
:100F7000FF5408FE131313541F24FF9202AB29AA37
:100F80002AA92BEF540775F002A4F58285F083128D
:100F9000081DF54085F03F1200032212081DF540A0
:100FA00085F03F120003228E268F278C288D298BF7
:100FB0002AD200C201852982852883E05488D394EF
:100FC000004003D38001C39201E4F52BE52BC395C8
:100FD0002A505930010D120BECC413131354012481
:100FE000FF8002A2009202852782852683C083C0EB
:100FF00082120BECFFC45407D082D083121035301C
:10100000010C120BECFF131313541F138002A200E8
:101010009202852782852683C083C082120BEC54FE
:1010200007D082D083121035052B80A0C29090008B
:10103000877405F02275F002120923E0F53FA3E062
:10104000F540120003920022C0E0C0F0C083C082CD
:10105000C0D075D000C000C001C002C003C004C031
:1010600005C006C007E5985403F545F45298E545D8
:1010700030E01712192B9000DD121739EFF09000B5
:10108000DDE004F0E0B44002E4F0E54530E12E900C
:1010900000E0E0D39400401A9000DCE02446F8E63B
:1010A000FF1219289000DCE004F09000E0E014F05A
:1010B0008002D2059000DCE0B42002E4F0D007D03A
:1010C00006D005D004D003D002D001D000D0D0D0BB
:1010D00082D083D0F0D0E03212005A787FE4F6D884
:1010E000FD7581A1021122020076E493A3F8E49336
:1010F000A34003F68001F208DFF48029E493A3F80B
:101100005407240CC8C333C4540F4420C88340047C
:10111000F456800146F6DFE4800B0102040810203B
:101120004080901266E47E019360BCA3FF543F3080
:10113000E509541FFEE493A360010ECF54C025E0DF
:1011400060A840B8E493A3FAE493A3F8E493A3C897
:10115000C582C8CAC583CAF0A3C8C582C8CAC58328
:10116000CADFE9DEE780BEC0E0C0F0C083C082C055
:10117000D075D000C000C001C002C003C004C005CB
:10118000C006C007E5D85487F521F452D8E5F730FA
:10119000E508E5F730E60312193253F7DFE52130B1
:1011A000E708E5D930E003121931E52130E008E520
:1011B000DA30E003121675E52130E108E5DB30E0B6
:1011C00003121933E52130E208E5DC30E00312199F
:1011D00034D007D006D005D004D003D002D001D03F
:1011E00000D0D0D082D083D0F0D0E032AE07E4F58A
:1011F0002612180A900000E004FF12181112125F64
:10120000900000E0FFE526C39F501412172BE05416
:101210007FFF12181112172B121725052680E19057
:101220000074E0547FFF12181190007412172512F9
:10123000125FE4F526900073E0FFE526C39F501788
:10124000740325261217190526E526541F70E61289
:10125000192512191E80DE7F551218110219251248
:10126000192512191E224200E500004200E100008B
:101270004200E700004200E30000C1834100860015
:101280004100870041008A004100790042000100CE
:101290000042008800004200770000C10441007352
:1012A000004100850041007A004100000048007DB7
:1012B0000000000000000000410076004100DD0059
:1012C0004100DF004100DB004100DC004100E000A4
:1012D0004100DA00C1054100DE0041009900008EA6
:1012E000298F2A8B2B8A2C892DE4F52E900000E083
:1012F000FFE52EC39F505EE52AAE297803CEC313C7
:10130000CE13D8F9FDAC06E52AAE297802CEC31378
:10131000CE13D8F92DFFEE3CAB07FA120C3BE0FEE2
:10132000A3E0FFC39BEE9A50028004AE02AF03AA73
:1013300006AB07120C3BE0FCA3E0FDAF2AAE29127E
:1013400017E7500DAB2BAA2CA92DE52E12078ED333
:1013500022052E8097C3228F268C278D28EF120B13
:10136000AFAA06F97BFFEF120C16FDEF120C54F535
:101370002EEF120CF6120BB98E2FF530EF120C6314
:10138000F531EF120D01120BB98E32F533EF120C5D
:1013900072F534EFC454F024DDF582E4341B120BF3
:1013A000B98E35F536EFC454F024DFF582E4341BF2
:1013B000F583E493F537EF120C81F53885273985ED
:1013C000283A020EBC900076E0FDC4540F2401FBC5
:1013D000E433FAED540FF96B7001EA603DE97010E7
:1013E000E0C4540F2401FDE433FCED64044C602A96
:1013F000900076E0C4540FFD540F120CDFEEF0A302
:10140000EFF0ED04C454F049900076F0E0FFC454CE
:101410000FC394044004EF540FF022C0E0C083C017
:1014200082C0D075D000C004C005C006C00753C834
:101430007F9000E5E0FEA3E0FF4E700353C8FB90F1
:1014400000E112166A50099000E5E4F0A3F0800D67
:10145000C39000E6E09DF09000E5E09CF0D007D05E
:1014600006D005D004D0D0D082D083D0E032C0E006
:10147000C083C082C0D075D000C004C005C006C003
:101480000753917F9000E7E0FEA3E0FF4E70035307
:1014900091FB9000E312166A50099000E7E4F0A374
:1014A000F0800DC39000E8E09DF09000E7E09CF034
:1014B000D007D006D005D004D0D0D082D083D0E0E1
:1014C0003212081DFDACF0AF2BAE2A8F828E83AF97
:1014D00005AE041218A6AB07AA06D3EB94F4EA945F
:1014E0000140067E017FF48004AE02AF03AA06AB82
:1014F00007C3EB9464EA940050067E007F64800486
:10150000AE02AF03AA06AB07AF82AE831217E72283
:10151000AD07AC06ABDA900076E0FEC4540FFFEEE8
:10152000540FFEB50702C32253DAFE900076E0FAAC
:10153000EE120CDFE0FFA3E08D828C83CFF0A3EFEF
:10154000F0EA54F0FF900076E0044FF0540FC3949B
:10155000044004E054F0F08BDAD322AE05AD07E48A
:10156000FCFB7FAA121811AF05121811EEC454F03B
:1015700024A6F582E4341DF583E493FFECC39F5069
:101580000774082CFC0B80F4EB04FF12180CE4FC2D
:10159000ECC39B500974032C1217190C80F27F5571
:1015A0001218110219258F26900079E0F5277E0088
:1015B0007F3C7D007B007A0079661209557F0B1213
:1015C000192E43DA011200707D0A7C007F017E0033
:1015D00012179712001DE4900087F0900086F0909B
:1015E0000099E526F0900079F0AF2722AE07E4FDE0
:1015F000F52612180A900001E0FF12181190000160
:10160000121725900077E0FF12181190007712173B
:1016100025900088E0FF1218119000881217257499
:10162000032D1217190DBD03F67F5512181102195B
:1016300025AB07AA06E4F9F87F407E427D0FFC1235
:101640000891A804A905AA06AB077F207ED77D755F
:101650007C01120891C3E49FFFE49EFE22AB07AA1F
:1016600006E4F9F87FE87E03FD22E0FCA3E0FDC379
:10167000EF9DEE9C22AFFBAEFC7C007D0A1207A022
:10168000AD07AC06AFD953D9BFE4F5FAF5F98FD958
:10169000C3EC948050157F002093027F01EFC43388
:1016A000333354804CFEEDFF0213C5E4900076F016
:1016B000229000DDE0FF9000DBE0B507057E017FB2
:1016C00000229000DB121739E0FD7C009000DBE087
:1016D00004F0E0B44002E4F09000DAE0FEEE4204F0
:1016E000E4F0AE04AF05229000EDE0FCA3E0FDECD9
:1016F000547FFEAF0522EC5480C41313135401240D
:10170000FF22A3E493FE74019322E49000EBF0A384
:10171000F022900087E024FB22F582E43400F58378
:10172000E0FF021811A3E0FF021811E52625E024CE
:101730008BF582E43400F58322E0249AF582E434C8
:1017400000F58322AD07AC06900074E0FAA3E0FB3D
:10175000EA5480C413131354017005300102C322EC
:10176000AF05AE04EA547FFCAD031214CB228E37D2
:101770008F388C398D3A12165D12163E12188290EF
:1017800000E5E539F0A3E53AF09000E1E537F0A394
:10179000E538F043C804228E288F298C2A8D2B121D
:1017A000165D12163E12188E9000E7E52AF0A3E5AA
:1017B0002BF09000E3E528F0A3E529F04391042203
:1017C00012002A1218FA1219011218B2121916125E
:1017D00018441218D01218BC1218C612189A1219EE
:1017E0000812191A02190FC3ED9BF582EC9AF583C2
:1017F000C3E5829FE5839E500FED2BFDEC3AFCC3C1
:10180000EF9DEE9C50028001C3227FAA121811AFF7
:1018100006C2059000DFE0B42002E4F09000DFE0B3
:101820002446F8A607E004F0A3E004F0227E1DE4BD
:10183000FDEF30E70625E06EFF8004EF25E0FF0DA9
:10184000BD08EE22AF885388AF758CA0758DCBEFA5
:101850005440FEEF54104E428822C3EF942CEE9475
:10186000014003D38001C322121875D2039000797E
:10187000E0FF0215A6AE0712180A7F5512181102D2
:101880001925AD07AC06ECF5CBAF058FCA22AD0725
:10189000AC06ECF593AF058F9222C2DE75D90575C3
:1018A000F9FF75960122EF7802CEC313CE13D8F953
:1018B000FF2275E34075E10175E20122E5915404D0
:1018C0005391FB429122758E547589224388502290
:1018D000E5C8540453C8FB42C82253984FEB4F4D00
:1018E000F59822E5C8C320E201D322E591C320E2A6
:1018F00001D32253C8FB53C87F2275A41175D4CFDE
:101900002275A54175D5772253F77F75DA30227598
:10191000E69075A8B022E4F5A9224398102230057C
:10192000FD22C2DE22D299228F9922AF99228F8C7A
:101930002222222222015E041A2A620802080109D8
:1019400000019004B00BB81C520A03080109000101
:10195000C20384286E020800090108014A02762A9F
:101960004E020800090108028A1E82071C0F8C081B
:101970000108020803016802D012C005DC0A03084E
:10198000010900024E05DC01AE348A0A0308010990
:1019900000012C0A00008C047E27F60801080308C9
:1019A0000208020803080401040A9A051428A00882
:1019B000010800080208020800080301720438192F
:1019C00082020801080009029407D00FA02328080A
:1019D00003080108020801061802D000D208010A13
:1019E0000109020A0101D603FC0BFE0208010800EE
:1019F00009019002D0132E010A00090108023007E4
:101A0000760F322274030801080208193503193BC6
:101A100002193D02193F020000001819410419493A
:101A200002194B02194D0200000018194F031955F5
:101A30000219570219590200000018195B031961B5
:101A4000021963021965020000000C196704196F7E
:101A50000219710219730200000028197504197D1A
:101A600002197F0219810200000028198304198BD2
:101A700002198D02198F0200000018199105199B97
:101A800002199D0419A10419A5022019A70419AF70
:101A90000219B10419B50419B9022019BB0319C1FF
:101AA0000219C30219C5020000001119C70419CF99
:101AB0000219D10219D30219D5022419D70319DD4D
:101AC0000219DF0219E10219E3022819E50319EBF3
:101AD0000219ED0219EF020000001419F10319F7C1
:101AE0000219F90219FB020000002719FD041A056A
:101AF000021A07021A090200000024015E041A2AD1
:101B000062080208010900019004B00BB81C520AD7
:101B1000030801090001C20384286E0208000901BC
:101B200008014A02762A4E020800090108028A1EAC
:101B300082071C0F8C080108020803016802D012FA
:101B4000C005DC0A0308010900024E05DC01AE34C1
:101B50008A0A0308010900012C0A00008C047E2770
:101B6000F608010803080208020803080401040A31
:101B70009A051428A00801080008020802080008B5
:101B8000030172043819820208010800090294074F
:101B9000D00FA02328080308010802080106180234
:101BA000D000D208010A0109020A0101D603FC0B88
:101BB000FE020801080009019002D0132E010A005C
:101BC000090108023007760F322274030801080267
:101BD000081AFB031B01021B03021B050200000085
:101BE000181B07041B0F021B11021B13020000002D
:101BF000181B15031B1B021B1D021B1F02000000EC
:101C0000181B21031B27021B29021B2B02000000AB
:101C10000C1B2D041B35021B37021B390200000070
:101C2000281B3B041B43021B45021B47020000000C
:101C3000281B49041B51021B53021B5502000000C4
:101C4000181B57051B61021B63041B67041B6B02F7
:101C5000201B6D041B75021B77041B7B041B7F027A
:101C6000201B81031B87021B89021B8B02000000C3
:101C7000111B8D041B95021B97021B99021B9B02D3
:101C8000241B9D031BA3021BA5021BA7021BA90269
:101C9000281BAB031BB1021BB3021BB502000000E3
:101CA000141BB7031BBD021BBF021BC102000000B7
:101CB000271BC3041BCB021BCD021BCF020000005D
:101CC00024015E041A2A6208020801090001900436
:101CD000B00BB81C520A030801090001C203842892
:101CE0006E020800090108014A02762A4E02080025
:101CF000090108028A1E82071C0F8C0801080208CD
:101D000003016802D012C005DC0A030801090002C1
:101D10004E05DC01AE348A0A0308010900012C0AD1
:101D200000008C047E27F608010803080208020858
:101D300003080401040A9A051428A00801080008F1
:101D4000020802080008030172043819820208011F
:101D5000080009029407D00FA023280803080108EF
:101D6000020801061802D000D208010A0109020A7D
:101D70000101D603FC0BFE020801080009019002D4
:101D8000D0132E010A00090108023007760F322213
:101D9000740308010802081CC1031CC7021CC90205
:101DA0001CCB02000000181CCD041CD5021CD7025D
:101DB0001CD902000000181CDB031CE1021CE3021A
:101DC0001CE502000000181CE7031CED021CEF02DA
:101DD0001CF1020000000C1CF3041CFB021CFD02A1
:101DE0001CFF02000000281D01041D09021D0B023A
:101DF0001D0D02000000281D0F041D17021D1902F1
:101E00001D1B02000000181D1D051D27021D2904B1
:101E10001D2D041D3102201D33041D3B021D3D04F8
:101E20001D41041D4502201D47031D4D021D4F028B
:101E30001D5102000000111D53041D5B021D5D02B7
:101E40001D5F021D6102241D63031D69021D6B02DB
:101E50001D6D021D6F02281D71031D77021D790281
:101E60001D7B02000000141D7D031D83021D8502E1
:101E70001D8702000000271D89041D91021D930289
:071E80001D95020000002483
:00000001FF