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

This commit is contained in:
Gennaro Tortone 2018-06-05 18:59:05 +02:00
commit 4b2670f13f
57 changed files with 3976 additions and 957 deletions

View File

@ -13,16 +13,16 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute!
### Development ### Development
[![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota) [![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota)
Current version is **5.14.0a** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. Current version is **6.0.0a** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
### Quick install ### Quick Install
Download one of the released binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki. Download one of the released binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki.
### Important User Compilation Information ### Important User Compilation Information
If you want to compile Sonoff-Tasmota yourself keep in mind the following: If you want to compile Sonoff-Tasmota yourself keep in mind the following:
- Only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device. See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips) for background information. - Only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device. See [Wiki](https://github.com/arendst/Sonoff-Tasmota/wiki/Theo's-Tasmota-Tips) for background information.
- Sonoff-Tasmota uses a 1M linker script WITHOUT spiffs for optimal code space. If you compile using ESP/Arduino library 2.3.0 then download the provided new linker script to your Arduino IDE or Platformio base folder. Later version of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite). - Sonoff-Tasmota uses a 1M linker script WITHOUT spiffs **1M (no SPIFFS)** for optimal code space. If you compile using ESP/Arduino library 2.3.0 then download the provided new linker script to your Arduino IDE or Platformio base folder. Later version of ESP/Arduino library already contain the correct linker script. See [Wiki > Prerequisite](https://github.com/arendst/Sonoff-Tasmota/wiki/Prerequisite).
- To make compile time changes to Sonoff-Tasmota it can use the ``user_config_override.h`` file. It assures keeping your settings when you download and compile a new version. To use ``user_config.override.h`` you will have to make a copy of the provided ``user_config.override_sample.h`` file and add your setting overrides. To enable the override file you will need to use a compile define as documented in the ``user_config_override_sample.h`` file. - To make compile time changes to Sonoff-Tasmota it can use the ``user_config_override.h`` file. It assures keeping your settings when you download and compile a new version. To use ``user_config.override.h`` you will have to make a copy of the provided ``user_config.override_sample.h`` file and add your setting overrides. To enable the override file you will need to use a compile define as documented in the ``user_config_override_sample.h`` file.
### Version Information ### Version Information
@ -68,7 +68,7 @@ The following devices are supported:
- [Luani HVIO board](https://luani.de/projekte/esp8266-hvio/) - [Luani HVIO board](https://luani.de/projekte/esp8266-hvio/)
- Wemos D1 mini, NodeMcu and Ledunia - Wemos D1 mini, NodeMcu and Ledunia
### Firmware release information ### Firmware Release Information
Different firmware images are released based on Features and Sensors selection guided by code and memory usage. Different firmware images are released based on Features and Sensors selection guided by code and memory usage.
- The Minimal version allows intermediate OTA uploads to support larger versions and does NOT change any persistent parameter. - The Minimal version allows intermediate OTA uploads to support larger versions and does NOT change any persistent parameter.
@ -129,7 +129,7 @@ Different firmware images are released based on Features and Sensors selection g
| USE_ARILUX_RF | x | x | - | x | x | | USE_ARILUX_RF | x | x | - | x | x |
| USE_SR04 | x | - | - | x | x | | USE_SR04 | x | - | - | x | x |
#### Typical file size #### Typical File Size
| ESP/Arduino library version | sonoff | classic | minimal | knx | allsensors | | ESP/Arduino library version | sonoff | classic | minimal | knx | allsensors |
|-----------------------------|--------|---------|---------|------|------------| |-----------------------------|--------|---------|---------|------|------------|
@ -147,7 +147,7 @@ You can contribute to Sonoff-Tasmota by
### Credits ### Credits
#### Libraries used #### Libraries Used
Libraries used with Sonoff-Tasmota are: Libraries used with Sonoff-Tasmota are:
- [ESP8266 core for Arduino](https://github.com/esp8266/Arduino) - [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)
- [Adafruit BME680](https://github.com/adafruit/Adafruit_BME680) - [Adafruit BME680](https://github.com/adafruit/Adafruit_BME680)

View File

@ -0,0 +1,10 @@
# c2_prog_wifi
WiFi-enabled programmer for Silicon Labs microcontrollers using the C2 programmer protocol, and to act as a serial-wifi bridge.
Designed to run in the Arduino environment for ESP8266 module: https://github.com/esp8266/Arduino
New programs can be loaded sending .hex files through the web-interface.
Everything is still alpha. Currently tested with EFM8BB10F2G-A-QFN20 and ESP-01 module: http://app.cear.ufpb.br/~lucas.hartmann/tag/efm8bb1/
LICENSE: GPLv3 or newer.

View File

@ -0,0 +1,19 @@
#######################################
# Syntax Coloring Map for C2Programmer
# (esp8266)
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
#######################################
# Methods and Functions (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,15 @@
{
"name": "C2Programmer",
"version": "1.0.0",
"keywords": [
"C2", "io", "Programmer"
],
"description": "Implementation of C2 programmer allowing update of Sonoff Bridge RF chip.",
"repository":
{
"type": "git",
"url": "https://github.com/lhartmann/c2_prog_wifi"
},
"frameworks": "arduino",
"platforms": "espressif8266"
}

View File

@ -0,0 +1,9 @@
name=C2Programmer
version=1.0.0
author=Lucas Hartmann
maintainer=Theo Arends <theo@arends.com>
sentence=Implementation of C2 programmer allowing update of Sonoff Bridge RF chip.
paragraph=
category=Signal Input/Output
url=
architectures=esp8266

View File

@ -0,0 +1,649 @@
#include "c2.h"
/////////////////////////////////////////////
// Nothing should need change on this file //
/////////////////////////////////////////////
// Times in microseconds
#define T_RD (20+5)
#define T_SD ( 2+5)
// Layer 0: Bit shifter
static bool c2_bit(bool b) {
C2D(b);
// C2_DELAY_US(1);
C2CK(0);
// C2_DELAY_US(1);
b = C2D();
C2CK(1);
return b;
}
// Layer 1: C2D Register read/write
void c2_address_write(uint8_t address) {
#ifdef C2_DEBUG
Serial.print("AW");
Serial.println(address, HEX);
#endif
// start
c2_bit(true);
C2D_enable(true);
// instruction
c2_bit(1);
c2_bit(1);
// Address
for (int i = 0; i < 8; ++i) {
c2_bit(address & 1);
address >>= 1;
}
// Stop
C2D_enable(false);
c2_bit(1);
}
uint8_t c2_address_read() {
// start
c2_bit(true);
C2D_enable(true);
// instruction
c2_bit(0);
c2_bit(1);
// Change C2D direction
C2D_enable(false);
c2_bit(0);
// Address
uint8_t a = 0, m = 1;
for (int i = 0; i < 8; ++i) {
if (c2_bit(a & 1)) {
a |= m;
}
m <<= 1;
}
// Stop is implied
#ifdef C2_DEBUG
Serial.print("AR");
Serial.println(a, HEX);
#endif
return a;
}
uint8_t c2_data_write(uint32_t d, uint8_t bytes) {
#ifdef C2_DEBUG
Serial.print("DW");
Serial.println(d, HEX);
#endif
// start
c2_bit(true);
C2D_enable(true);
// instruction
c2_bit(1);
c2_bit(0);
// Length
bytes--;
c2_bit(bytes & 1);
c2_bit(bytes & 2);
bytes++;
// Data
for (int i = 0; i < 8 * bytes; ++i) {
c2_bit(d & 1);
d >>= 1;
}
// Reverse C2D direction
C2D_enable(false);
c2_bit(0);
// Wait
uint8_t to = 128;
while (!c2_bit(0)) if (!--to) return C2_SHIFT_TIMEOUT;
// Stop
//c2_bit(0); implied
return C2_SUCCESS;
}
uint8_t c2_data_read(uint32_t &d, uint8_t bytes) {
// start
c2_bit(true);
C2D_enable(true);
// instruction
c2_bit(0);
c2_bit(0);
// Length
bytes--;
c2_bit(bytes & 1);
c2_bit(bytes & 2);
bytes++;
// Reverse C2D direction
C2D_enable(false);
c2_bit(0);
// Wait
uint8_t to = 128;
while (!c2_bit(0)) if (!--to) return C2_SHIFT_TIMEOUT;
// Data
d = 0;
uint32_t m = 1;
for (int i = 0; i < 8 * bytes; ++i) {
if (c2_bit(d & 1)) {
d |= m;
}
m <<= 1;
}
// Stop is implied
#ifdef C2D_DEBUG
Serial.print("DR");
Serial.println(d, HEX);
#endif
return C2_SUCCESS;
}
// Layer 2: Operations
#define C2_POLL_INBUSY() { \
uint16_t to = 1000; \
uint8_t a; \
while (1) { \
a = c2_address_read(); \
if (a == 0xFF) return C2_BROKEN_LINK; \
if (~a & C2_INBUSY) break; \
if (--to == 0) return C2_POLL_TIMEOUT; \
C2_DELAY_MS(1); \
}; \
}
#define C2_POLL_OUTREADY() { \
uint16_t to = 10000; \
uint8_t a; \
while (1) { \
a = c2_address_read(); \
if (a == 0xFF) return C2_BROKEN_LINK; \
if (a & C2_OUTREADY) break; \
if (--to == 0) return C2_POLL_TIMEOUT; \
C2_DELAY_MS(1); \
}; \
}
#define C2_DATA_WRITE_AND_CHECK(v, s) { \
uint8_t r = c2_data_write(v, s); \
if (r != C2_SUCCESS) return r; \
}
#define C2_DATA_READ_AND_CHECK(v, s) { \
uint8_t r = c2_data_read(v, s); \
if (r != C2_SUCCESS) return r; \
}
#define C2_EXPECT_DATA(value) { \
uint8_t d; \
C2_DATA_READ_AND_CHECK(d, 1); \
if (d != (value)) return C2_CMD_ERROR; \
}
uint8_t c2_reset() {
C2CK(false);
C2_DELAY_US(T_RD);
C2CK(true);
C2_DELAY_US(T_SD);
return C2_SUCCESS;
}
uint8_t c2_programming_init() {
c2_reset();
c2_address_write(C2FPCTL);
C2_DATA_WRITE_AND_CHECK(C2FPCTL_ENABLE0, 1);
C2_DATA_WRITE_AND_CHECK(C2FPCTL_CORE_HALT, 1);
C2_DATA_WRITE_AND_CHECK(C2FPCTL_ENABLE1, 1)
C2_DELAY_MS(21);
return C2_SUCCESS;
}
uint8_t c2_block_write(uint32_t address, uint8_t *data, uint8_t len) {
// 1. Perform an Address Write with a value of FPDAT
c2_address_write(C2FPDAT);
// 2. Perform a Data Write with the Block Write command.
C2_DATA_WRITE_AND_CHECK(C2FPDAT_BLOCK_WRITE, 1);
// 3. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 4. Poll on OutReady using Address Read until the bit set.
C2_POLL_OUTREADY();
// 5. Perform a Data Read instruction. A value of 0x0D is okay.
C2_EXPECT_DATA(0x0D);
// 6. Perform a Data Write with the high byte of the address.
C2_DATA_WRITE_AND_CHECK(address >> 8, 1);
// 7. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 8. Perform a Data Write with the low byte of the address.
C2_DATA_WRITE_AND_CHECK(address & 255, 1);
// 9. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 10. Perform a Data Write with the length.
C2_DATA_WRITE_AND_CHECK(len, 1);
// 12a. Repeat steps 11 and 12 for each byte specified by the length field.
uint8_t i = 0;
do {
// 11. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 12. Perform a Data Write with the data. This will write the data to the flash.
C2_DATA_WRITE_AND_CHECK(data[i], 1);
} while (++i != len);
// 13. Poll on OutReady using Address Read until the bit set.
C2_POLL_OUTREADY();
// 14. Perform a Data Read instruction. A value of 0x0D is okay. write to an EPROM block:
C2_EXPECT_DATA(0x0D);
return C2_SUCCESS;
}
uint8_t c2_eeprom_write(uint32_t address, uint8_t *data, uint8_t len) {
// 1. Write 0x04 to the FPCTL register.
c2_address_write(C2FPCTL);
C2_DATA_WRITE_AND_CHECK(0x04, 1);
// 2. Write 0x40 to EPCTL.
c2_address_write(C2EPCTL);
C2_DATA_WRITE_AND_CHECK(0x40, 1);
// 3. Write 0x58 to EPCTL.
C2_DATA_WRITE_AND_CHECK(0x58, 1);
// 4. Write the high byte of the address to EPADDRH.
c2_address_write(C2EPADDRH);
C2_DATA_WRITE_AND_CHECK(address >> 8, 1);
// 5. Write the low byte of the address to address EPADDRL.
c2_address_write(C2EPADDRL);
C2_DATA_WRITE_AND_CHECK(address, 1);
// 6. Perform an Address Write with a value of EPDAT.
c2_address_write(C2EPDAT);
// 7. Turn on VPP.
// 8. Wait for the VPP settling time.
// 10a. Repeat steps 9 and 10 until all bytes are written.
uint8_t i = 0;
do {
// 9. Write the data to the device using a Data Write.
C2_DATA_WRITE_AND_CHECK(data[i], 1);
// 10. Perform Address Read instructions until the value returned is not 0x80 and the EPROM is no longer busy.
C2_POLL_INBUSY();
} while (++i != len);
// 12. Turn off VPP. Note that VPP can only be applied for a maximum lifetime amount, and this value is specified in the device data sheet.
// 13. Write 0x40 to EPCTL.
c2_address_write(C2EPCTL);
C2_DATA_WRITE_AND_CHECK(0x40, 1);
// 14. Write 0x00 to EPCTL.
C2_DATA_WRITE_AND_CHECK(0x00, 1);
// 15. Write 0x02 to FPCTL.
c2_address_write(C2FPCTL);
C2_DATA_WRITE_AND_CHECK(0x02, 1);
// 16. Write 0x04 to FPCTL.
C2_DATA_WRITE_AND_CHECK(0x04, 1);
// 17. Write 0x01 to FPCTL.
C2_DATA_WRITE_AND_CHECK(0x01, 1);
return C2_SUCCESS;
}
uint8_t c2_block_read(uint32_t address, uint8_t *data, uint8_t len) {
// 1. Perform an Address Write with a value of FPDAT.
c2_address_write(C2FPDAT);
// 2. Perform a Data Write with the Block Read command.
C2_DATA_WRITE_AND_CHECK(C2FPDAT_BLOCK_READ, 1);
// 3. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 4. Poll on OutReady using Address Read until the bit set.
C2_POLL_OUTREADY();
// 5. Perform a Data Read instruction. A value of 0x0D is okay.
C2_EXPECT_DATA(0x0D);
// 6. Perform a Data Write with the high byte of the address.
C2_DATA_WRITE_AND_CHECK(address >> 8, 1);
// 7. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 8. Perform a Data Write with the low byte of the address.
C2_DATA_WRITE_AND_CHECK(address, 1);
// 9. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 10. Perform a Data Write with the length.
C2_DATA_WRITE_AND_CHECK(len, 1);
// 11. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 12. Poll on OutReady using Address Read until the bit set.
C2_POLL_OUTREADY();
// 13. Read FPI Command Status. Abort if Status != 0x0D.
C2_EXPECT_DATA(0x0D);
// 15a. Repeat step 14 and 15 for each byte specified by the length field.
uint8_t i = 0;
do {
// 14. Poll on OutReady using Address Read until the bit set.
C2_POLL_OUTREADY();
// 15. Perform a Data Read instruction. This will read the data from the flash.
C2_DATA_READ_AND_CHECK(data[i], 1);
} while (++i != len);
return C2_SUCCESS;
}
uint8_t c2_eeprom_read(uint32_t address, uint8_t *data, uint8_t len) {
// 1. Write 0x04 to the FPCTL register.
c2_address_write(C2FPCTL);
C2_DATA_WRITE_AND_CHECK(0x04, 1);
// 2. Write 0x00 to EPCTL.
c2_address_write(C2EPCTL);
C2_DATA_WRITE_AND_CHECK(0x00, 1);
// 3. Write 0x58 to EPCTL.
C2_DATA_WRITE_AND_CHECK(0x58, 1);
// 4. Write the high byte of the address to EPADDRH.
c2_address_write(C2EPADDRH);
C2_DATA_WRITE_AND_CHECK(address >> 8, 1);
// 5. Write the low byte of the address to address EPADDRL.
c2_address_write(C2EPADDRL);
C2_DATA_WRITE_AND_CHECK(address, 1);
// 6. Perform an Address Write with a value of EPDAT.
c2_address_write(C2EPDAT);
// 9. Repeat steps 7 and 8 until all bytes are read.
uint8_t i = 0;
do {
// 7.1. Perform an Address Write operation with a value of EPSTAT.
c2_address_write(C2EPSTAT);
// 7.2. Perform a Data Read operation and check the bits of the EPSTAT register.
uint8_t err;
C2_DATA_READ_AND_CHECK(err, 1);
if (err & C2EPSTAT_ERROR) return C2_CMD_ERROR;
// 7.3. Perform an Address Write operation with a value of EPDAT.
c2_address_write(C2EPDAT);
// 7. Perform Address Read instructions until the value returned is not 0x80 and the EPROM is no longer busy.
C2_POLL_INBUSY();
// 8.1. Perform an Address Write operation with a value of EPSTAT.
c2_address_write(C2EPSTAT);
// 8.2. Perform a Data Read operation and check the ERROR bit in the EPSTAT register.
C2_DATA_READ_AND_CHECK(err, 1);
if (err & C2EPSTAT_ERROR) return C2_CMD_ERROR;
// 8.3. Perform an Address Write operation with a value of EPDAT.
C2_DATA_WRITE_AND_CHECK(C2EPDAT, 1);
// 8. Read the byte using the Data Read instruction.
C2_DATA_READ_AND_CHECK(data[i], 1);
} while (++i != len);
// 10. Write 0x40 to EPCTL.
c2_address_write(C2EPCTL);
C2_DATA_WRITE_AND_CHECK(0x40, 1);
// 11. Write 0x00 to EPCTL.
C2_DATA_WRITE_AND_CHECK(0x00, 1);
// 12. Write 0x02 to FPCTL.
c2_address_write(C2FPCTL);
C2_DATA_WRITE_AND_CHECK(0x02, 1);
// 13. Write 0x04 to FPCTL.
C2_DATA_WRITE_AND_CHECK(0x04, 1);
// 14. Write 0x01 to FPCTL.
C2_DATA_WRITE_AND_CHECK(0x01, 1);
return C2_SUCCESS;
}
uint8_t c2_page_erase(uint8_t page) {
// 1. Perform an Address Write with a value of FPDAT.
c2_address_write(C2FPDAT);
// 2. Perform a Data Write with the Page Erase command.
c2_data_write(C2FPDAT_FLASH_PAGE_ERASE, 1);
// 3. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 4. Poll on OutReady using Address Read until the bit set.
C2_POLL_OUTREADY();
// 5. Perform a Data Read instruction. A value of 0x0D is okay.
C2_EXPECT_DATA(0x0D);
// 6. Perform a Data Write with the page number.
c2_data_write(page, 1);
// 7. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 8. Poll on OutReady using Address Read until the bit clears.
C2_POLL_OUTREADY();
// 9. Perform a Data Read instruction. A value of 0x0D is okay.
C2_EXPECT_DATA(0x0D);
// 10. Perform a Data Write with the a value of 0x00.
c2_data_write(0x00, 1);
// 11. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 12. Poll on OutReady using Address Read until the bit set.
C2_POLL_OUTREADY();
// 13. Perform a Data Read instruction. A value of 0x0D is okay.
C2_EXPECT_DATA(0x0D);
return C2_SUCCESS;
}
uint8_t c2_device_erase() {
// 1. Perform an Address Write with a value of FPDAT.
c2_address_write(C2FPDAT);
// 2. Perform a Data Write with the Device Erase command.
C2_DATA_WRITE_AND_CHECK(C2FPDAT_DEVICE_ERASE, 1);
// 3. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 4. Poll on OutReady using Address Read until the bit set.
C2_POLL_OUTREADY();
// 5. Perform a Data Read instruction. A value of 0x0D is okay.
C2_EXPECT_DATA(0x0D);
// 6. Perform a Data Write with a value of 0xDE.
C2_DATA_WRITE_AND_CHECK(0xDE, 1);
// 7. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 8. Perform a Data Write with a value of 0xAD.
C2_DATA_WRITE_AND_CHECK(0xAD, 1);
// 9. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 10. Perform a Data Write with a value of 0xA5.
C2_DATA_WRITE_AND_CHECK(0xA5, 1);
// 11. Poll on InBusy using Address Read until the bit clears.
C2_POLL_INBUSY();
// 12. Poll on OutReady using Address Read until the bit set.
C2_POLL_OUTREADY();
// 13. Perform a Data Read instruction. A value of 0x0D is okay.
C2_EXPECT_DATA(0x0D);
return C2_SUCCESS;
}
uint8_t c2_sfr_write_non_paged(uint8_t address, uint8_t data) {
// 1. Write the SFR address to the device using the Address Write instruction.
c2_address_write(address);
// 2. Write the SFR value to the device using the Data Write instruction.
C2_DATA_WRITE_AND_CHECK(data, 1);
return C2_SUCCESS;
}
uint8_t c2_sfr_write_paged(uint8_t address, uint8_t data) {
// 1. Perform an Address Write with a value of FPDAT.
c2_address_write(C2FPDAT);
// 2. Write the Direct Write command (0x0A) using a Data Write
C2_DATA_WRITE_AND_CHECK(C2FPDAT_DIRECT_WRITE, 1);
// 3. Poll InBusy until the data is processed by the PI.
C2_POLL_INBUSY();
// 4. Poll OutReady it sets to 1.
C2_POLL_OUTREADY();
// 5. Perform a Data Read to ensure a return value of 0x0D (no errors).
C2_EXPECT_DATA(0x0D);
// 6. Perform a Data Write with a value of the SFR address.
C2_DATA_WRITE_AND_CHECK(address, 1);
// 7. Poll InBusy until the data is processed by the PI.
C2_POLL_INBUSY();
// 8. Perform a Data Write with a value of 0x01.
C2_DATA_WRITE_AND_CHECK(0x01, 1);
// 9. Poll InBusy until the data is processed by the PI.
C2_POLL_INBUSY();
// 10. Perform a Data Write with the new SFR value.
C2_DATA_WRITE_AND_CHECK(data, 1);
// 11. Poll InBusy until the data is processed by the PI.
C2_POLL_INBUSY();
return C2_SUCCESS;
}
// 4.6. Reading from an SFR
// To read from an SFR on a device that does not have SFR paging:
uint8_t c2_sfr_read_non_paged(uint8_t address, uint8_t &v) {
// 1. Write the SFR address to the device using the Address Write instruction.
c2_address_write(address);
// 2. Read the SFR value from the device using the Data Read instruction.
C2_DATA_READ_AND_CHECK(v, 1);
return C2_SUCCESS;
}
// For devices with SFR paging, direct reads through the PI using the Direct Read command are recommended to ensure the SFR Page is managed properly.
// To read an SFR from a device with SFR paging:
uint8_t c2_sfr_read_paged(uint8_t address, uint8_t &v) {
// 1. Perform an Address Write with a value of FPDAT.
c2_address_write(C2FPDAT);
// 2. Write the Direct Read command (0x09) using a Data Write.
C2_DATA_WRITE_AND_CHECK(C2FPDAT_DIRECT_READ, 1);
// 3. Poll InBusy until the data is processed by the PI.
C2_POLL_INBUSY();
// 4. Poll OutReady until it sets to 1.
C2_POLL_OUTREADY();
// 5. Perform a Data Read to ensure a return value of 0x0D (no errors).
C2_EXPECT_DATA(0x0D);
// 6. Perform a Data Write with a value of the SFR address.
C2_DATA_WRITE_AND_CHECK(address, 1);
// 7. Poll InBusy until the data is processed by the PI.
C2_POLL_INBUSY();
// 8. Perform a Data Write with a value of 0x01.
C2_DATA_WRITE_AND_CHECK(0x01, 1);
// 9. Poll InBusy until the data is processed by the PI.
C2_POLL_INBUSY();
// 10. Poll OutReady until it sets to 0.
C2_POLL_OUTREADY();
// 11. Read the SFR value from the device using the Data Read instruction.
C2_DATA_READ_AND_CHECK(v, 1);
return C2_SUCCESS;
}
const char *c2_print_status_by_name(uint8_t ch) {
switch (ch) {
case C2_SUCCESS: return "Success";
case C2_SHIFT_TIMEOUT: return "Shift wait timeout error";
case C2_POLL_TIMEOUT: return "Register poll timeout error";
case C2_CMD_ERROR: return "In-command error";
case C2_BROKEN_LINK: return "Broken link, address read failed";
default: return "unknownl error";
}
}
// This is to enforce arduino-like formatting in kate
// kate: space-indent on; indent-width 2; mixed-indent off; indent-mode cstyle;

View File

@ -0,0 +1,141 @@
#ifndef C2_H
#define C2_H
#include <stdint.h>
#include <Arduino.h>
////////////////////////////////
// Hardware Abstraction Layer //
////////////////////////////////
// Rewrite these for your hardware
#define PIN_C2CK 4
#define PIN_C2D 5
// Set C2CK state
inline void C2CK(bool ck) {
digitalWrite(PIN_C2CK, ck);
}
// get C2CK state
inline bool C2CK() {
return digitalRead(PIN_C2CK);
}
// Set C2D state
inline void C2D(bool d) {
digitalWrite(PIN_C2D, d);
}
// Get C2D state
inline bool C2D() {
return digitalRead(PIN_C2D);
}
// Enable/disable C2D output butter
inline void C2D_enable(bool oe) {
if (oe) pinMode(PIN_C2D, OUTPUT);
else pinMode(PIN_C2D, INPUT);
}
// Delay functions
#define C2_DELAY_US(n) delayMicroseconds(n)
#define C2_DELAY_MS(n) delay(n)
////////////////////////////////////////////
// Nothing should need change from now on //
////////////////////////////////////////////
// Exceptions:
#define C2_SUCCESS 0x00 // Compare for success
#define C2_ERROR 0xFF // Mask for all errors
#define C2_TIMEOUT 0x03 // Mask for timeouts
#define C2_SHIFT_TIMEOUT 0x01 // Shift wait
#define C2_POLL_TIMEOUT 0x02 // Register poll
#define C2_CMD_ERROR 0x04 // In-command Error
#define C2_BROKEN_LINK 0x08 // Address read returned 0xFF, comms disabled
// Register Addresses
#define C2DEVID 0x00
#define C2REVID 0x01
#define C2FPCTL 0x02
#define C2FPDAT 0xB4
#define C2EPCTL 0x00
#define C2EPDAT 0x00
#define C2EPDAT 0x00
#define C2EPADDRH 0x00
#define C2EPADDRL 0x00
#define C2EPSTAT 0x00
// Commands for FPCTL register
#define C2FPCTL_ENABLE0 0x02
#define C2FPCTL_CORE_HALT 0x04
#define C2FPCTL_ENABLE1 0x01
// Commands for FPDAT register
#define C2FPDAT_DEVICE_ERASE 0x03
#define C2FPDAT_FLASH_BLOCK_READ 0x06
#define C2FPDAT_BLOCK_WRITE 0x07
#define C2FPDAT_FLASH_PAGE_ERASE 0x08
#define C2FPDAT_BLOCK_READ 0x06
#define C2FPDAT_GET_VERSION 0x01
#define C2FPDAT_GET_DERIVATIVE 0x02
#define C2FPDAT_DIRECT_READ 0x09
#define C2FPDAT_DIRECT_WRITE 0x0A
#define C2FPDAT_INDIRECT_READ 0x0B
#define C2FPDAT_INDIRECT_WRITE 0x0C
// Commands for EPCTL register
#define C2EPCTL_ENABLE0 0x40
#define C2EPCTL_ENABLE1 0x58
// EPSTAT status bits
#define C2EPSTAT_WLOCK 0x80
#define C2EPSTAT_RLOCK 0x40
#define C2EPSTAT_ERROR 0x01
// 'Address read' status bits
#define C2_FLBUSY 0x08
#define C2_EEBUSY C2_FLBUSY
#define C2_EEERROR 0x04
#define C2_INBUSY 0x02
#define C2_OUTREADY 0x01
// Layer 1: C2 Programmig Interface (PI) Register access
void c2_address_write(uint8_t address);
uint8_t c2_address_read();
uint8_t c2_data_write(uint32_t d, uint8_t bytes);
uint8_t c2_data_read(uint32_t &d, uint8_t bytes=4);
// Shorcuts for smaller words
inline uint8_t c2_data_read(uint16_t &d, uint8_t bytes=2) {
uint32_t dd;
uint8_t r = c2_data_read(dd, 2);
d = dd;
return r;
}
inline uint8_t c2_data_read(uint8_t &d, uint8_t bytes=1) {
uint32_t dd;
uint8_t r = c2_data_read(dd, 1);
d = dd;
return r;
}
// Layer 2: Operations
uint8_t c2_reset();
uint8_t c2_programming_init();
uint8_t c2_block_write(uint32_t address, uint8_t *data, uint8_t len);
uint8_t c2_block_read(uint32_t address, uint8_t *data, uint8_t len);
uint8_t c2_eeprom_read(uint32_t address, uint8_t *data, uint8_t len);
uint8_t c2_page_erase(uint8_t page);
uint8_t c2_device_erase();
uint8_t c2_sfr_write_non_paged(uint8_t address, uint8_t data);
uint8_t c2_sfr_write_paged(uint8_t address, uint8_t data);
uint8_t c2_sfr_read_non_paged(uint8_t address, uint8_t &data);
uint8_t c2_sfr_read_paged(uint8_t address, uint8_t &data);
const char *c2_print_status_by_name(uint8_t ch);
#endif // C2_H

View File

@ -0,0 +1,71 @@
#include "ihx.h"
#include <Arduino.h>
static const char *conv = "0123456789ABCDEFabcdef";
static uint8_t value_of_hex(uint8_t ch) {
uint8_t i = 0;
//Loop through list
while (conv[i] && ch != conv[i]) i++;
if (!conv[i]) return 0;
//Convert to upper case
if (i >= 16) return i - 6; // lowercase
return i;
}
uint8_t ihx_decode(uint8_t *buff, uint16_t slen) {
// Make sure the line looks like intel
if (buff[0] != ':') {
#ifdef IHX_DEBUG
Serial.println("IHX: Bad start:" + buff[0]);
#endif
return IHX_ERROR;
}
// Remove strayline terminators at the end of the file
while (buff[slen - 1] == '\n' || buff[slen - 1] == '\r') slen--;
// Length must be odd: start followed by hex pairs
if (slen < 11) {
#ifdef IHX_DEBUG
Serial.printf("IHX: Short read: %u\n", slen);
#endif
return IHX_ERROR;
}
if (slen % 2 != 1) {
#ifdef IHX_DEBUG
Serial.printf("IHX: Length not odd (%u)\n", slen);
#endif
return IHX_ERROR;
}
// Decode
uint8_t cs = 0;
for (int i = 0; i < (slen - 1) / 2; ++i) {
buff[i] = (value_of_hex(buff[2 * i + 1]) << 4) | value_of_hex(buff[2 * i + 2]);
cs += buff[i];
}
// Validate checksum
if (cs) {
#ifdef IHX_DEBUG
Serial.print("IHX: Bad checksum: ");
Serial.println(cs, HEX);
#endif
return IHX_ERROR;
}
// Check if lengths match
if (buff[0] * 2 + 11 != slen) {
#ifdef IHX_DEBUG
Serial.println("IHX: Length mismatch");
#endif
return IHX_ERROR;
}
return IHX_SUCCESS;
}

View File

@ -0,0 +1,39 @@
#ifndef IHX_H
#define IHX_H
#include <stdint.h>
// Decoded
// Intel HEX file format:
// 1B - Start ':'
// 2B - data bytes
// 4B - address
// 2B - record type
// ?B - data
// 2B - checksum
// 01234567890123
// :NNAAAATTDDSS
struct ihx_t {
uint8_t len;
uint8_t address_high;
uint8_t address_low;
uint8_t record_type; // See IHX_RT_* below
uint8_t data[];
};
#define IHX_RT_DATA 0x00
#define IHX_RT_END_OF_FILE 0x01
#define IHX_RT_EXTENDED_SEGMENT_ADDRESS 0x02
#define IHX_RT_START_SEGMENT_ADDRESS 0x03
#define IHX_RT_EXTENDED_LINEAR_ADDRESS 0x04
#define IHX_RT_START_LINEAR_ADDRESS 0x05
#define IHX_SUCCESS 0x00
#define IHX_ERROR 0xFF
extern uint8_t ihx_decode(uint8_t *buff, uint16_t slen);
#endif // IHX_H
// This is to enforce arduino-like formatting in kate
// kate: space-indent on; indent-width 2; mixed-indent off; indent-mode cstyle;

View File

@ -30,6 +30,7 @@ env_default = sonoff
;env_default = sonoff-PL ;env_default = sonoff-PL
;env_default = sonoff-PT ;env_default = sonoff-PT
;env_default = sonoff-RU ;env_default = sonoff-RU
;env_default = sonoff-UK
;env_default = sonoff-TW ;env_default = sonoff-TW
[common] ; ************************************************************ [common] ; ************************************************************
@ -46,7 +47,7 @@ platform = espressif8266@1.5.0
framework = arduino framework = arduino
board = esp01_1m board = esp01_1m
board_flash_mode = dout board_build.flash_mode = dout
; *** Fix espressif8266@1.7.0 induced undesired all warnings ; *** Fix espressif8266@1.7.0 induced undesired all warnings
build_unflags = -Wall build_unflags = -Wall
@ -57,9 +58,6 @@ build_flags =
-DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
; -DUSE_CONFIG_OVERRIDE ; -DUSE_CONFIG_OVERRIDE
; *** Fix Esp/Arduino core 2.4.x induced Tasmota unused floating point includes
extra_scripts = pio/strip-floats.py
; *** Serial Monitor options ; *** Serial Monitor options
monitor_speed = 115200 monitor_speed = 115200
@ -68,6 +66,8 @@ monitor_speed = 115200
upload_speed = 512000 upload_speed = 512000
upload_resetmethod = nodemcu upload_resetmethod = nodemcu
upload_port = COM5 upload_port = COM5
; *** Fix Esp/Arduino core 2.4.x induced Tasmota unused floating point includes
extra_scripts = pio/strip-floats.py
; *** Upload file to OTA server using SCP ; *** Upload file to OTA server using SCP
;upload_port = user@host:/path ;upload_port = user@host:/path
@ -83,7 +83,7 @@ upload_port = COM5
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} build_flags = ${common.build_flags}
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -96,7 +96,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DBE_MINIMAL build_flags = ${common.build_flags} -DBE_MINIMAL
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -108,7 +108,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DUSE_CLASSIC build_flags = ${common.build_flags} -DUSE_CLASSIC
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -120,7 +120,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DUSE_KNX_NO_EMULATION build_flags = ${common.build_flags} -DUSE_KNX_NO_EMULATION
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -132,7 +132,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DUSE_ALL_SENSORS build_flags = ${common.build_flags} -DUSE_ALL_SENSORS
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -144,7 +144,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=bg-BG build_flags = ${common.build_flags} -DMY_LANGUAGE=bg-BG
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -156,7 +156,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=pt-BR build_flags = ${common.build_flags} -DMY_LANGUAGE=pt-BR
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -168,7 +168,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=zh-CN build_flags = ${common.build_flags} -DMY_LANGUAGE=zh-CN
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -180,7 +180,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=cs-CZ build_flags = ${common.build_flags} -DMY_LANGUAGE=cs-CZ
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -192,7 +192,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=de-DE build_flags = ${common.build_flags} -DMY_LANGUAGE=de-DE
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -204,7 +204,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=es-AR build_flags = ${common.build_flags} -DMY_LANGUAGE=es-AR
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -216,7 +216,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=fr-FR build_flags = ${common.build_flags} -DMY_LANGUAGE=fr-FR
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -228,7 +228,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=el-GR build_flags = ${common.build_flags} -DMY_LANGUAGE=el-GR
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -240,7 +240,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=hu-HU build_flags = ${common.build_flags} -DMY_LANGUAGE=hu-HU
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -252,7 +252,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=it-IT build_flags = ${common.build_flags} -DMY_LANGUAGE=it-IT
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -264,7 +264,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=nl-NL build_flags = ${common.build_flags} -DMY_LANGUAGE=nl-NL
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -276,7 +276,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=pl-PL build_flags = ${common.build_flags} -DMY_LANGUAGE=pl-PL
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -288,7 +288,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=pt-PT build_flags = ${common.build_flags} -DMY_LANGUAGE=pt-PT
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -300,7 +300,7 @@ extra_scripts = ${common.extra_scripts}
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=ru-RU build_flags = ${common.build_flags} -DMY_LANGUAGE=ru-RU
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}
@ -308,11 +308,23 @@ upload_speed = ${common.upload_speed}
upload_port = ${common.upload_port} upload_port = ${common.upload_port}
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
[env:sonoff-UK]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board}
board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=uk-UK
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
upload_port = ${common.upload_port}
extra_scripts = ${common.extra_scripts}
[env:sonoff-TW] [env:sonoff-TW]
platform = ${common.platform} platform = ${common.platform}
framework = ${common.framework} framework = ${common.framework}
board = ${common.board} board = ${common.board}
board_flash_mode = ${common.board_flash_mode} board_build.flash_mode = ${common.board_build.flash_mode}
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -DMY_LANGUAGE=zh-TW build_flags = ${common.build_flags} -DMY_LANGUAGE=zh-TW
monitor_speed = ${common.monitor_speed} monitor_speed = ${common.monitor_speed}

View File

@ -1,4 +1,40 @@
/* 5.14.0a /* 6.0.0a
* Add CRC to Settings making future upgrades more fail-safe
* Add support for uploading Sonoff Bridge firmware found in tools/fw_efm8bb1 folder build by Portisch using Web Gui File Upload (#2886)
* Add support for I2C temperature sensor LM75AD (#2909)
* Add command RfRaw to control Portisch firmware features
* Remove version 3, 4 and pre 5.2 settings auto-upgrade. See https://github.com/arendst/Sonoff-Tasmota/wiki/Upgrade#migration-path
* Change default CFG_HOLDER from 0x20161209 to 4617 (=0x1209) - no impact on default upgrades
* Fix Pzem004T checksum error
*
* 5.14.0b
* Add Console Commands to send KNX Commands
usage: KnxTx_Cmnd[slot] command
where [slot] is any of the 5 slots on the KNX Menu and command is 0 or 1
example: KnxTx_Cmnd1 0
* Add Console Commands to send KNX Values
usage: KnxTx_Val[slot] value
where [slot] is any of the 5 slots on the KNX Menu and value is a number
example: KnxTx_Val1 35
* Add Slots on the KNX Web Menu to select Group Addess to send data from console commands
* Add Events to trigger rules when received data from KNX
usage on rules as: event#KnxRx_Val[slot]
where [slot] is any of the 5 slots on the KNX Menu
example: rule on event#KnxRx_Val1 do VAR1 %value% endon
* Add Events to trigger rules when received read requests from KNX
usage on rules as: event#KnxRx_Req[slot]
where [slot] is any of the 5 slots on the KNX Menu
example: rule on event#KnxRx_Req1 do KnxTx_Val1 35 endon
* Add Slots on the KNX Web Menu to select Group Addess to receive data to trigger rules
* Add two rule sets of 511 characters using commands rule1, rule2 and rule3
* Add Ukranian language file
* Add rule support for IrReceive and RfReceive (#2758)
* Add command WebSend [<host>(:<port>,<user>:<password>)] <command> (#2821)
* Add source information to command execution to be shown with logging option 3 (#2843)
* Fix some Pow R2 and S31 checksum errors (#1907)
* Fix Hardware Watchdog restart when using event command (#2853)
*
* 5.14.0a
* Add feature information to Status 4 * Add feature information to Status 4
* Add tools folder with python script decode-status.py for decoding some status fields like SetOption and Features * Add tools folder with python script decode-status.py for decoding some status fields like SetOption and Features
* Add Eastron SDM630 energy meter by Gennaro Tortone (#2735) * Add Eastron SDM630 energy meter by Gennaro Tortone (#2735)
@ -7,7 +43,7 @@
* Add python script fw-server.py in tools folder to create a simple OTA server by Gennaro Tortone (#2759) * Add python script fw-server.py in tools folder to create a simple OTA server by Gennaro Tortone (#2759)
* Add rules %mem1% to %mem5% variable names storing data in flash (#2780) * Add rules %mem1% to %mem5% variable names storing data in flash (#2780)
* Add rules test on %varx% or %memx% (#2780) * Add rules test on %varx% or %memx% (#2780)
* Add optional token %id% substituting the unique MAC address for topic names by Michael Graf (#2794) * Add optional token %id% substituting the unique MAC address to fulltopic by Michael Graf (#2794)
* Fix display selection of un-available GPIO options in Module Configuration webpage (#2718) * Fix display selection of un-available GPIO options in Module Configuration webpage (#2718)
* Fix timer re-trigger within one minute after restart (#2744) * Fix timer re-trigger within one minute after restart (#2744)
* Fix IRSend not accepting data value of 0 by David Conran (#2751) * Fix IRSend not accepting data value of 0 by David Conran (#2751)

View File

@ -42,6 +42,7 @@
#define D_JSON_BUILDDATETIME "BuildDateTime" #define D_JSON_BUILDDATETIME "BuildDateTime"
#define D_JSON_CO2 "CarbonDioxide" #define D_JSON_CO2 "CarbonDioxide"
#define D_JSON_COMMAND "Command" #define D_JSON_COMMAND "Command"
#define D_JSON_CONNECT_FAILED "Connect failed"
#define D_JSON_COREVERSION "Core" #define D_JSON_COREVERSION "Core"
#define D_JSON_COUNTER "Counter" #define D_JSON_COUNTER "Counter"
#define D_JSON_CURRENT "Current" // As in Voltage and Current #define D_JSON_CURRENT "Current" // As in Voltage and Current
@ -67,6 +68,7 @@
#define D_JSON_GATEWAY "Gateway" #define D_JSON_GATEWAY "Gateway"
#define D_JSON_HEAPSIZE "Heap" #define D_JSON_HEAPSIZE "Heap"
#define D_JSON_HIGH "High" #define D_JSON_HIGH "High"
#define D_JSON_HOST_NOT_FOUND "Host not found"
#define D_JSON_HSBCOLOR "HSBColor" #define D_JSON_HSBCOLOR "HSBColor"
#define D_JSON_HUMIDITY "Humidity" #define D_JSON_HUMIDITY "Humidity"
#define D_JSON_I2CSCAN_DEVICES_FOUND_AT "Device(s) found at" #define D_JSON_I2CSCAN_DEVICES_FOUND_AT "Device(s) found at"
@ -133,6 +135,7 @@
#define D_JSON_VOLTAGE "Voltage" #define D_JSON_VOLTAGE "Voltage"
#define D_JSON_WIFI "Wifi" #define D_JSON_WIFI "Wifi"
#define D_JSON_WRONG "Wrong" #define D_JSON_WRONG "Wrong"
#define D_JSON_WRONG_PARAMETERS "Wrong parameters"
#define D_JSON_YESTERDAY "Yesterday" #define D_JSON_YESTERDAY "Yesterday"
#define D_JSON_ZERO_POINT_CALIBRATION "Zero Point Calibration" #define D_JSON_ZERO_POINT_CALIBRATION "Zero Point Calibration"
@ -213,14 +216,6 @@
#define D_WCFG_5_WAIT "Wait" #define D_WCFG_5_WAIT "Wait"
#define D_CMND_FRIENDLYNAME "FriendlyName" #define D_CMND_FRIENDLYNAME "FriendlyName"
#define D_CMND_SWITCHMODE "SwitchMode" #define D_CMND_SWITCHMODE "SwitchMode"
#define D_CMND_WEBSERVER "Webserver"
#define D_JSON_WEBSERVER_MODE "WebServerMode"
#define D_JSON_ACTIVE_FOR "Active for"
#define D_JSON_ON_DEVICE "on"
#define D_JSON_WITH_IP_ADDRESS "with IP address"
#define D_CMND_WEBPASSWORD "WebPassword"
#define D_CMND_WEBLOG "WebLog"
#define D_CMND_EMULATION "Emulation"
#define D_CMND_TELEPERIOD "TelePeriod" #define D_CMND_TELEPERIOD "TelePeriod"
#define D_CMND_RESTART "Restart" #define D_CMND_RESTART "Restart"
#define D_JSON_ONE_TO_RESTART "1 to restart" #define D_JSON_ONE_TO_RESTART "1 to restart"
@ -238,7 +233,7 @@
#define D_CMND_SERIALDELIMITER "SerialDelimiter" #define D_CMND_SERIALDELIMITER "SerialDelimiter"
#define D_CMND_BAUDRATE "Baudrate" #define D_CMND_BAUDRATE "Baudrate"
// Commands xdrv_00_mqtt.ino // Commands xdrv_01_mqtt.ino
#define D_CMND_MQTTHOST "MqttHost" #define D_CMND_MQTTHOST "MqttHost"
#define D_CMND_MQTTPORT "MqttPort" #define D_CMND_MQTTPORT "MqttPort"
#define D_CMND_MQTTRETRY "MqttRetry" #define D_CMND_MQTTRETRY "MqttRetry"
@ -263,37 +258,16 @@
#define D_CMND_SENSORRETAIN "SensorRetain" #define D_CMND_SENSORRETAIN "SensorRetain"
#define D_CMND_PUBLISH "Publish" #define D_CMND_PUBLISH "Publish"
// Commands xdrv_01_light.ino // Commands xdrv_02_webserver.ino
#define D_CMND_CHANNEL "Channel" #define D_CMND_WEBSERVER "Webserver"
#define D_CMND_COLOR "Color" #define D_JSON_WEBSERVER_MODE "WebServerMode"
#define D_CMND_COLORTEMPERATURE "CT" #define D_JSON_ACTIVE_FOR "Active for"
#define D_CMND_DIMMER "Dimmer" #define D_JSON_ON_DEVICE "on"
#define D_CMND_HSBCOLOR "HSBColor" #define D_JSON_WITH_IP_ADDRESS "with IP address"
#define D_CMND_LED "Led" #define D_CMND_WEBPASSWORD "WebPassword"
#define D_CMND_LEDTABLE "LedTable" #define D_CMND_WEBLOG "WebLog"
#define D_CMND_FADE "Fade" #define D_CMND_WEBSEND "WebSend"
#define D_CMND_PIXELS "Pixels" #define D_CMND_EMULATION "Emulation"
#define D_CMND_ROTATION "Rotation"
#define D_CMND_SCHEME "Scheme"
#define D_CMND_SPEED "Speed"
#define D_CMND_WAKEUP "Wakeup"
#define D_CMND_WAKEUPDURATION "WakeUpDuration"
#define D_CMND_WIDTH "Width"
// Commands xdrv_02_irremote.ino
#define D_CMND_IRSEND "IRSend"
#define D_JSON_INVALID_JSON "Invalid JSON"
#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocol not supported"
#define D_JSON_IR_PROTOCOL "Protocol"
#define D_JSON_IR_BITS "Bits"
#define D_JSON_IR_DATA "Data"
#define D_CMND_IRHVAC "IRHVAC"
#define D_JSON_IRHVAC_VENDOR "VENDOR"
#define D_JSON_IRHVAC_POWER "POWER"
#define D_JSON_IRHVAC_MODE "MODE"
#define D_JSON_IRHVAC_FANSPEED "FANSPEED"
#define D_JSON_IRHVAC_TEMP "TEMP"
#define D_JSON_IRRECEIVED "IrReceived"
// Commands xdrv_03_energy.ino // Commands xdrv_03_energy.ino
#define D_CMND_POWERLOW "PowerLow" #define D_CMND_POWERLOW "PowerLow"
@ -324,7 +298,39 @@
#define D_JSON_ENERGYMONITOR "EnergyMonitor" #define D_JSON_ENERGYMONITOR "EnergyMonitor"
#define D_JSON_MAXENERGYREACHED "MaxEnergyReached" #define D_JSON_MAXENERGYREACHED "MaxEnergyReached"
// Commands xdrv_04_snfbridge.ino // Commands xdrv_04_light.ino
#define D_CMND_CHANNEL "Channel"
#define D_CMND_COLOR "Color"
#define D_CMND_COLORTEMPERATURE "CT"
#define D_CMND_DIMMER "Dimmer"
#define D_CMND_HSBCOLOR "HSBColor"
#define D_CMND_LED "Led"
#define D_CMND_LEDTABLE "LedTable"
#define D_CMND_FADE "Fade"
#define D_CMND_PIXELS "Pixels"
#define D_CMND_ROTATION "Rotation"
#define D_CMND_SCHEME "Scheme"
#define D_CMND_SPEED "Speed"
#define D_CMND_WAKEUP "Wakeup"
#define D_CMND_WAKEUPDURATION "WakeUpDuration"
#define D_CMND_WIDTH "Width"
// Commands xdrv_05_irremote.ino
#define D_CMND_IRSEND "IRSend"
#define D_JSON_INVALID_JSON "Invalid JSON"
#define D_JSON_PROTOCOL_NOT_SUPPORTED "Protocol not supported"
#define D_JSON_IR_PROTOCOL "Protocol"
#define D_JSON_IR_BITS "Bits"
#define D_JSON_IR_DATA "Data"
#define D_CMND_IRHVAC "IRHVAC"
#define D_JSON_IRHVAC_VENDOR "VENDOR"
#define D_JSON_IRHVAC_POWER "POWER"
#define D_JSON_IRHVAC_MODE "MODE"
#define D_JSON_IRHVAC_FANSPEED "FANSPEED"
#define D_JSON_IRHVAC_TEMP "TEMP"
#define D_JSON_IRRECEIVED "IrReceived"
// Commands xdrv_06_snfbridge.ino
#define D_CMND_RFCODE "RfCode" #define D_CMND_RFCODE "RfCode"
#define D_CMND_RFHIGH "RfHigh" #define D_CMND_RFHIGH "RfHigh"
#define D_CMND_RFHOST "RfHost" #define D_CMND_RFHOST "RfHost"
@ -339,8 +345,9 @@
#define D_CMND_RFLOW "RfLow" #define D_CMND_RFLOW "RfLow"
#define D_CMND_RFSYNC "RfSync" #define D_CMND_RFSYNC "RfSync"
#define D_JSON_RFRECEIVED "RfReceived" #define D_JSON_RFRECEIVED "RfReceived"
#define D_CMND_RFRAW "RfRaw"
// Commands xdrv_05_domoticz.ino // Commands xdrv_07_domoticz.ino
#define D_CMND_DOMOTICZ "Domoticz" #define D_CMND_DOMOTICZ "Domoticz"
#define D_CMND_IDX "Idx" #define D_CMND_IDX "Idx"
#define D_CMND_KEYIDX "KeyIdx" #define D_CMND_KEYIDX "KeyIdx"
@ -348,18 +355,6 @@
#define D_CMND_SENSORIDX "SensorIdx" #define D_CMND_SENSORIDX "SensorIdx"
#define D_CMND_UPDATETIMER "UpdateTimer" #define D_CMND_UPDATETIMER "UpdateTimer"
// Commands xdrv_06_display.ino
#define D_CMND_DISPLAY "Display"
#define D_CMND_DISP_ADDRESS "Address"
#define D_CMND_DISP_COLS "Cols"
#define D_CMND_DISP_DIMMER "Dimmer"
#define D_CMND_DISP_MODE "Mode"
#define D_CMND_DISP_MODEL "Model"
#define D_CMND_DISP_REFRESH "Refresh"
#define D_CMND_DISP_ROWS "Rows"
#define D_CMND_DISP_SIZE "Size"
#define D_CMND_DISP_TEXT "Text"
// Commands xdrv_08_serial_bridge.ino // Commands xdrv_08_serial_bridge.ino
#define D_CMND_SSERIALSEND "SSerialSend" #define D_CMND_SSERIALSEND "SSerialSend"
#define D_CMND_SBAUDRATE "SBaudrate" #define D_CMND_SBAUDRATE "SBaudrate"
@ -380,6 +375,18 @@
#define D_CMND_LATITUDE "Latitude" #define D_CMND_LATITUDE "Latitude"
#define D_CMND_LONGITUDE "Longitude" #define D_CMND_LONGITUDE "Longitude"
// Commands xdrv_98_display.ino
#define D_CMND_DISPLAY "Display"
#define D_CMND_DISP_ADDRESS "Address"
#define D_CMND_DISP_COLS "Cols"
#define D_CMND_DISP_DIMMER "Dimmer"
#define D_CMND_DISP_MODE "Mode"
#define D_CMND_DISP_MODEL "Model"
#define D_CMND_DISP_REFRESH "Refresh"
#define D_CMND_DISP_ROWS "Rows"
#define D_CMND_DISP_SIZE "Size"
#define D_CMND_DISP_TEXT "Text"
/********************************************************************************************/ /********************************************************************************************/
#define D_ASTERIX "********" #define D_ASTERIX "********"
@ -505,7 +512,7 @@ const char kOptionToggle[] PROGMEM = "TOGGLE|" D_TOGGLE "|" D_ADMIN ;
const char kOptionBlink[] PROGMEM = "BLINK|" D_BLINK ; const char kOptionBlink[] PROGMEM = "BLINK|" D_BLINK ;
const char kOptionBlinkOff[] PROGMEM = "BLINKOFF|" D_BLINKOFF ; const char kOptionBlinkOff[] PROGMEM = "BLINKOFF|" D_BLINKOFF ;
// webserver.ino // xdrv_02_webserver.ino
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
const char HTTP_SNS_TEMP[] PROGMEM = "%s{s}%s " D_TEMPERATURE "{m}%s&deg;%c{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr> const char HTTP_SNS_TEMP[] PROGMEM = "%s{s}%s " D_TEMPERATURE "{m}%s&deg;%c{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HTTP_SNS_HUM[] PROGMEM = "%s{s}%s " D_HUMIDITY "{m}%s%%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr> const char HTTP_SNS_HUM[] PROGMEM = "%s{s}%s " D_HUMIDITY "{m}%s%%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>

View File

@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele. * Use online command Prefix to translate cmnd, stat and tele.
* *
* Updated until v5.14.0a * Updated until v6.0.0a
\*********************************************************************/ \*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -205,8 +205,8 @@
#define D_USE_DEFAULTS "Използване на параметри по подразбиране" #define D_USE_DEFAULTS "Използване на параметри по подразбиране"
#define D_ERASED_SECTOR "Изтрит сектор" #define D_ERASED_SECTOR "Изтрит сектор"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Минимаен фърмуеър - моля надградете го" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Минимален фърмуеър - моля надградете го"
#define D_WEBSERVER_ACTIVE_ON "Уеб сървърът е активен на" #define D_WEBSERVER_ACTIVE_ON "Уеб сървърът е активен на"
#define D_WITH_IP_ADDRESS "с IP адрес" #define D_WITH_IP_ADDRESS "с IP адрес"
#define D_WEBSERVER_STOPPED "Уеб сървърът е спрян" #define D_WEBSERVER_STOPPED "Уеб сървърът е спрян"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Зареждането е прекъснато" #define D_UPLOAD_ERR_7 "Зареждането е прекъснато"
#define D_UPLOAD_ERR_8 "Файлът е невалиден" #define D_UPLOAD_ERR_8 "Файлът е невалиден"
#define D_UPLOAD_ERR_9 "Файлът е прекалено голям" #define D_UPLOAD_ERR_9 "Файлът е прекалено голям"
#define D_UPLOAD_ERR_10 "Грешка при инициализация на RF чипа"
#define D_UPLOAD_ERR_11 "Грешка при изтриване на RF чипа"
#define D_UPLOAD_ERR_12 "Грешка при записване в RF чипа"
#define D_UPLOAD_ERR_13 "Грешка при декодиране на RF фирмуера"
#define D_UPLOAD_ERROR_CODE "Код на грешка при зареждането" #define D_UPLOAD_ERROR_CODE "Код на грешка при зареждането"
#define D_ENTER_COMMAND "Въвеждане на команда" #define D_ENTER_COMMAND "Въвеждане на команда"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Включете ниво 2 на лога, ако очаквате отговор" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Включете ниво 2 на лога, ако очаквате отговор"
#define D_NEED_USER_AND_PASSWORD "Очаква user=<username>&password=<password>" #define D_NEED_USER_AND_PASSWORD "Очаква user=<username>&password=<password>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Проверка на TLS отпечатък..." #define D_FINGERPRINT "Проверка на TLS отпечатък..."
#define D_TLS_CONNECT_FAILED_TO "Неуспешно TLS свързване към" #define D_TLS_CONNECT_FAILED_TO "Неуспешно TLS свързване към"
#define D_RETRY_IN "Повторно след" #define D_RETRY_IN "Повторно след"
@ -335,7 +339,7 @@
#define D_INSECURE "Нешифрована връзка, недействителен отпечатък" #define D_INSECURE "Нешифрована връзка, недействителен отпечатък"
#define D_CONNECT_FAILED_TO "Грешка при свързването към" #define D_CONNECT_FAILED_TO "Грешка при свързването към"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast е изключен" #define D_MULTICAST_DISABLED "Multicast е изключен"
#define D_MULTICAST_REJOINED "Multicast е повторно съединен" #define D_MULTICAST_REJOINED "Multicast е повторно съединен"
#define D_MULTICAST_JOIN_FAILED "Multicast грешка при присъединяването" #define D_MULTICAST_JOIN_FAILED "Multicast грешка при присъединяването"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST аргументи" #define D_HUE_POST_ARGS "Hue POST аргументи"
#define D_3_RESPONSE_PACKETS_SENT "Изпратени са 3 пакета за отговор" #define D_3_RESPONSE_PACKETS_SENT "Изпратени са 3 пакета за отговор"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz параметри" #define D_DOMOTICZ_PARAMETERS "Domoticz параметри"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "изпратен до" #define D_SENT_TO "изпратен до"
#define D_KNX_WARNING "Груповият адрес ( 0 / 0 / 0 ) е резервиран и не може да бъде използван." #define D_KNX_WARNING "Груповият адрес ( 0 / 0 / 0 ) е резервиран и не може да бъде използван."
#define D_KNX_ENHANCEMENT "Подобрена комуникация" #define D_KNX_ENHANCEMENT "Подобрена комуникация"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Използвана енергия днес" #define D_ENERGY_TODAY "Използвана енергия днес"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Použij defaultní hodnoty" #define D_USE_DEFAULTS "Použij defaultní hodnoty"
#define D_ERASED_SECTOR "Smazaný sektor" #define D_ERASED_SECTOR "Smazaný sektor"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware MINIMÁLNÍ - prosím zaktualizujte" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware MINIMÁLNÍ - prosím zaktualizujte"
#define D_WEBSERVER_ACTIVE_ON "Aktivní Web server" #define D_WEBSERVER_ACTIVE_ON "Aktivní Web server"
#define D_WITH_IP_ADDRESS "na IP adrese" #define D_WITH_IP_ADDRESS "na IP adrese"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Nahrávání přerušeno" #define D_UPLOAD_ERR_7 "Nahrávání přerušeno"
#define D_UPLOAD_ERR_8 "Špatný soubor" #define D_UPLOAD_ERR_8 "Špatný soubor"
#define D_UPLOAD_ERR_9 "Soubor je příliš velký" #define D_UPLOAD_ERR_9 "Soubor je příliš velký"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Chyba nahrávání" #define D_UPLOAD_ERROR_CODE "Chyba nahrávání"
#define D_ENTER_COMMAND "Vlož příkaz" #define D_ENTER_COMMAND "Vlož příkaz"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Zapni úroveň 2 zápisu Weblog, pokud je očekávána odpověď" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Zapni úroveň 2 zápisu Weblog, pokud je očekávána odpověď"
#define D_NEED_USER_AND_PASSWORD "Vyžadován uživatel=<username>&heslo=<password>" #define D_NEED_USER_AND_PASSWORD "Vyžadován uživatel=<username>&heslo=<password>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Verifikuj otisk TLS..." #define D_FINGERPRINT "Verifikuj otisk TLS..."
#define D_TLS_CONNECT_FAILED_TO "Nepřipojeno TLS do" #define D_TLS_CONNECT_FAILED_TO "Nepřipojeno TLS do"
#define D_RETRY_IN "Zopakuji za" #define D_RETRY_IN "Zopakuji za"
@ -335,7 +339,7 @@
#define D_INSECURE "Nesprávné připojení z důvodu chybného otisku TLS" #define D_INSECURE "Nesprávné připojení z důvodu chybného otisku TLS"
#define D_CONNECT_FAILED_TO "Spojení se nepodařilo navázat" #define D_CONNECT_FAILED_TO "Spojení se nepodařilo navázat"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast je vypnutý" #define D_MULTICAST_DISABLED "Multicast je vypnutý"
#define D_MULTICAST_REJOINED "Multicast opět připojený" #define D_MULTICAST_REJOINED "Multicast opět připojený"
#define D_MULTICAST_JOIN_FAILED "Multicast neúspěšný" #define D_MULTICAST_JOIN_FAILED "Multicast neúspěšný"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 pakety odpovědi odeslány" #define D_3_RESPONSE_PACKETS_SENT "3 pakety odpovědi odeslány"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Nastavení Domoticz" #define D_DOMOTICZ_PARAMETERS "Nastavení Domoticz"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "pošli" #define D_SENT_TO "pošli"
#define D_KNX_WARNING "Skupinová adresa ( 0 / 0 / 0 ) je rezervována a nemůže být použita." #define D_KNX_WARNING "Skupinová adresa ( 0 / 0 / 0 ) je rezervována a nemůže být použita."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Spotřeba Dnes" #define D_ENERGY_TODAY "Spotřeba Dnes"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Standard verwenden" #define D_USE_DEFAULTS "Standard verwenden"
#define D_ERASED_SECTOR "gelöschter Sektor" #define D_ERASED_SECTOR "gelöschter Sektor"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMUM-Firmware - bitte upgraden" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMUM-Firmware - bitte upgraden"
#define D_WEBSERVER_ACTIVE_ON "Web-Server aktiv bei" #define D_WEBSERVER_ACTIVE_ON "Web-Server aktiv bei"
#define D_WITH_IP_ADDRESS "mit IP-Adresse" #define D_WITH_IP_ADDRESS "mit IP-Adresse"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Upload abgebrochen" #define D_UPLOAD_ERR_7 "Upload abgebrochen"
#define D_UPLOAD_ERR_8 "Datei ungültig" #define D_UPLOAD_ERR_8 "Datei ungültig"
#define D_UPLOAD_ERR_9 "Datei zu groß" #define D_UPLOAD_ERR_9 "Datei zu groß"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Upload Fehler Nummer" #define D_UPLOAD_ERROR_CODE "Upload Fehler Nummer"
#define D_ENTER_COMMAND "Befehl eingeben" #define D_ENTER_COMMAND "Befehl eingeben"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Aktivere Web Log Level 2 falls Reaktion erwartet" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Aktivere Web Log Level 2 falls Reaktion erwartet"
#define D_NEED_USER_AND_PASSWORD "Benötige user=<Benutzername>&password=<Passwort>" #define D_NEED_USER_AND_PASSWORD "Benötige user=<Benutzername>&password=<Passwort>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "TLS-Fingerabdruck wird verifiziert..." #define D_FINGERPRINT "TLS-Fingerabdruck wird verifiziert..."
#define D_TLS_CONNECT_FAILED_TO "TLS-Verbindung fehlgeschlagen an" #define D_TLS_CONNECT_FAILED_TO "TLS-Verbindung fehlgeschlagen an"
#define D_RETRY_IN "Wiederversuch in" #define D_RETRY_IN "Wiederversuch in"
@ -335,7 +339,7 @@
#define D_INSECURE "unsichere Verbindung aufgrund ungültigen Fingerabdrucks" #define D_INSECURE "unsichere Verbindung aufgrund ungültigen Fingerabdrucks"
#define D_CONNECT_FAILED_TO "Verbindung fehlgeschlagen aufgrund von" #define D_CONNECT_FAILED_TO "Verbindung fehlgeschlagen aufgrund von"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast deaktiviert" #define D_MULTICAST_DISABLED "Multicast deaktiviert"
#define D_MULTICAST_REJOINED "Multicast (wieder-)verbunden" #define D_MULTICAST_REJOINED "Multicast (wieder-)verbunden"
#define D_MULTICAST_JOIN_FAILED "Multicast Verbindung fehlgeschlagen" #define D_MULTICAST_JOIN_FAILED "Multicast Verbindung fehlgeschlagen"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST-Argumente" #define D_HUE_POST_ARGS "Hue POST-Argumente"
#define D_3_RESPONSE_PACKETS_SENT "3 Antwortpakete gesendet" #define D_3_RESPONSE_PACKETS_SENT "3 Antwortpakete gesendet"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz-Parameter" #define D_DOMOTICZ_PARAMETERS "Domoticz-Parameter"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "sent to" #define D_SENT_TO "sent to"
#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." #define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energie heute" #define D_ENERGY_TODAY "Energie heute"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Χρήση προεπιλογών" #define D_USE_DEFAULTS "Χρήση προεπιλογών"
#define D_ERASED_SECTOR "Διαγραμμένος τομέας" #define D_ERASED_SECTOR "Διαγραμμένος τομέας"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - παρακαλώ αναβαθμήστε" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - παρακαλώ αναβαθμήστε"
#define D_WEBSERVER_ACTIVE_ON "Web διακομιστής ενεργός" #define D_WEBSERVER_ACTIVE_ON "Web διακομιστής ενεργός"
#define D_WITH_IP_ADDRESS "με διεύθυνση IP" #define D_WITH_IP_ADDRESS "με διεύθυνση IP"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Το ανεβάσμα διακόπηκε" #define D_UPLOAD_ERR_7 "Το ανεβάσμα διακόπηκε"
#define D_UPLOAD_ERR_8 "Μη έγκυρο αρχείο" #define D_UPLOAD_ERR_8 "Μη έγκυρο αρχείο"
#define D_UPLOAD_ERR_9 "Το αρχείο είναι πολύ μεγάλο" #define D_UPLOAD_ERR_9 "Το αρχείο είναι πολύ μεγάλο"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Κωδικός λάθους ανεβάσματος" #define D_UPLOAD_ERROR_CODE "Κωδικός λάθους ανεβάσματος"
#define D_ENTER_COMMAND "Εισαγωγή εντολής" #define D_ENTER_COMMAND "Εισαγωγή εντολής"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Ενεργοποιήστε το weblog 2 αν περιμένετε απάντηση" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Ενεργοποιήστε το weblog 2 αν περιμένετε απάντηση"
#define D_NEED_USER_AND_PASSWORD "Χρειάζεστε user=<όνομα χρήστη>&password=<κωδικό χρήστη>" #define D_NEED_USER_AND_PASSWORD "Χρειάζεστε user=<όνομα χρήστη>&password=<κωδικό χρήστη>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Επαλήθευση TLS fingerprint..." #define D_FINGERPRINT "Επαλήθευση TLS fingerprint..."
#define D_TLS_CONNECT_FAILED_TO "Αποτυχία TLS σύνδεσης" #define D_TLS_CONNECT_FAILED_TO "Αποτυχία TLS σύνδεσης"
#define D_RETRY_IN "Επανάληψη σε" #define D_RETRY_IN "Επανάληψη σε"
@ -335,7 +339,7 @@
#define D_INSECURE "Μη ασφαλής σύνδεση λόγο ακατάλληλου Fingerprint" #define D_INSECURE "Μη ασφαλής σύνδεση λόγο ακατάλληλου Fingerprint"
#define D_CONNECT_FAILED_TO "Αποτυχία σύνδεσης στο" #define D_CONNECT_FAILED_TO "Αποτυχία σύνδεσης στο"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast απενεργοποιημένο" #define D_MULTICAST_DISABLED "Multicast απενεργοποιημένο"
#define D_MULTICAST_REJOINED "Multicast επανασύνδεση" #define D_MULTICAST_REJOINED "Multicast επανασύνδεση"
#define D_MULTICAST_JOIN_FAILED "Αποτυχία σύνδεσης Multicast" #define D_MULTICAST_JOIN_FAILED "Αποτυχία σύνδεσης Multicast"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3πλο πακέτο απάντησεης στάλθηκε" #define D_3_RESPONSE_PACKETS_SENT "3πλο πακέτο απάντησεης στάλθηκε"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz παράμετροι" #define D_DOMOTICZ_PARAMETERS "Domoticz παράμετροι"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "αποστολή σε" #define D_SENT_TO "αποστολή σε"
#define D_KNX_WARNING "Η Ομάδα Διευθύνσεων ( 0 / 0 / 0 ) είναι δεσμευμένη και δεν μπορεί να χρησιμοποιηθεί." #define D_KNX_WARNING "Η Ομάδα Διευθύνσεων ( 0 / 0 / 0 ) είναι δεσμευμένη και δεν μπορεί να χρησιμοποιηθεί."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Σήμερα" #define D_ENERGY_TODAY "Energy Σήμερα"

View File

@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele. * Use online command Prefix to translate cmnd, stat and tele.
* *
* Updated until v5.14.0a * Updated until v5.14.0b
\*********************************************************************/ \*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Use defaults" #define D_USE_DEFAULTS "Use defaults"
#define D_ERASED_SECTOR "Erased sector" #define D_ERASED_SECTOR "Erased sector"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - please upgrade" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - please upgrade"
#define D_WEBSERVER_ACTIVE_ON "Web server active on" #define D_WEBSERVER_ACTIVE_ON "Web server active on"
#define D_WITH_IP_ADDRESS "with IP address" #define D_WITH_IP_ADDRESS "with IP address"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Upload aborted" #define D_UPLOAD_ERR_7 "Upload aborted"
#define D_UPLOAD_ERR_8 "File invalid" #define D_UPLOAD_ERR_8 "File invalid"
#define D_UPLOAD_ERR_9 "File too large" #define D_UPLOAD_ERR_9 "File too large"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Upload error code" #define D_UPLOAD_ERROR_CODE "Upload error code"
#define D_ENTER_COMMAND "Enter command" #define D_ENTER_COMMAND "Enter command"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Enable weblog 2 if response expected" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Enable weblog 2 if response expected"
#define D_NEED_USER_AND_PASSWORD "Need user=<username>&password=<password>" #define D_NEED_USER_AND_PASSWORD "Need user=<username>&password=<password>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Verify TLS fingerprint..." #define D_FINGERPRINT "Verify TLS fingerprint..."
#define D_TLS_CONNECT_FAILED_TO "TLS Connect failed to" #define D_TLS_CONNECT_FAILED_TO "TLS Connect failed to"
#define D_RETRY_IN "Retry in" #define D_RETRY_IN "Retry in"
@ -335,7 +339,7 @@
#define D_INSECURE "Insecure connection due to invalid Fingerprint" #define D_INSECURE "Insecure connection due to invalid Fingerprint"
#define D_CONNECT_FAILED_TO "Connect failed to" #define D_CONNECT_FAILED_TO "Connect failed to"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast disabled" #define D_MULTICAST_DISABLED "Multicast disabled"
#define D_MULTICAST_REJOINED "Multicast (re)joined" #define D_MULTICAST_REJOINED "Multicast (re)joined"
#define D_MULTICAST_JOIN_FAILED "Multicast join failed" #define D_MULTICAST_JOIN_FAILED "Multicast join failed"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 response packets sent" #define D_3_RESPONSE_PACKETS_SENT "3 response packets sent"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz parameters" #define D_DOMOTICZ_PARAMETERS "Domoticz parameters"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "sent to" #define D_SENT_TO "sent to"
#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." #define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today" #define D_ENERGY_TODAY "Energy Today"

View File

@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele. * Use online command Prefix to translate cmnd, stat and tele.
* *
* Updated until v5.14.0a * Updated until v6.0.0a
\*********************************************************************/ \*********************************************************************/
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Usar valores por defecto" #define D_USE_DEFAULTS "Usar valores por defecto"
#define D_ERASED_SECTOR "Sector borrado" #define D_ERASED_SECTOR "Sector borrado"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware MÍNIMO - actualice por favor" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware MÍNIMO - actualice por favor"
#define D_WEBSERVER_ACTIVE_ON "Servidor web activo en" #define D_WEBSERVER_ACTIVE_ON "Servidor web activo en"
#define D_WITH_IP_ADDRESS "con dirección IP" #define D_WITH_IP_ADDRESS "con dirección IP"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Carga cancelada" #define D_UPLOAD_ERR_7 "Carga cancelada"
#define D_UPLOAD_ERR_8 "Archivo no válido" #define D_UPLOAD_ERR_8 "Archivo no válido"
#define D_UPLOAD_ERR_9 "Archivo muy grande" #define D_UPLOAD_ERR_9 "Archivo muy grande"
#define D_UPLOAD_ERR_10 "No inició chip RF"
#define D_UPLOAD_ERR_11 "No se pudo borrar en el chip RF"
#define D_UPLOAD_ERR_12 "No se puedo escribir en el chip RF"
#define D_UPLOAD_ERR_13 "No se pudo decodificar firmware RF"
#define D_UPLOAD_ERROR_CODE "Código de error de carga" #define D_UPLOAD_ERROR_CODE "Código de error de carga"
#define D_ENTER_COMMAND "Ingresar comando" #define D_ENTER_COMMAND "Ingresar comando"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 si desea respuesta" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 si desea respuesta"
#define D_NEED_USER_AND_PASSWORD "Se necesita user=<username>&password=<password>" #define D_NEED_USER_AND_PASSWORD "Se necesita user=<username>&password=<password>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Verificar TLS fingerprint..." #define D_FINGERPRINT "Verificar TLS fingerprint..."
#define D_TLS_CONNECT_FAILED_TO "Falló Conección TLS a" #define D_TLS_CONNECT_FAILED_TO "Falló Conección TLS a"
#define D_RETRY_IN "Reintentando" #define D_RETRY_IN "Reintentando"
@ -335,7 +339,7 @@
#define D_INSECURE "Conección insegura por Fingerprint no válido" #define D_INSECURE "Conección insegura por Fingerprint no válido"
#define D_CONNECT_FAILED_TO "Falló Conección a" #define D_CONNECT_FAILED_TO "Falló Conección a"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast deshabilitado" #define D_MULTICAST_DISABLED "Multicast deshabilitado"
#define D_MULTICAST_REJOINED "Multicast (re)conectado" #define D_MULTICAST_REJOINED "Multicast (re)conectado"
#define D_MULTICAST_JOIN_FAILED "Conección Multicast fallida" #define D_MULTICAST_JOIN_FAILED "Conección Multicast fallida"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 paquetes de respuesta enviados" #define D_3_RESPONSE_PACKETS_SENT "3 paquetes de respuesta enviados"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Parámetros Domoticz" #define D_DOMOTICZ_PARAMETERS "Parámetros Domoticz"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "enviada a" #define D_SENT_TO "enviada a"
#define D_KNX_WARNING "La dirección de grupo ( 0 / 0 / 0 ) está reservada y no puede ser utilizada." #define D_KNX_WARNING "La dirección de grupo ( 0 / 0 / 0 ) está reservada y no puede ser utilizada."
#define D_KNX_ENHANCEMENT "Mejora de Comunicación" #define D_KNX_ENHANCEMENT "Mejora de Comunicación"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energía Hoy" #define D_ENERGY_TODAY "Energía Hoy"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Utiliser par défaut" #define D_USE_DEFAULTS "Utiliser par défaut"
#define D_ERASED_SECTOR "Secteur effacé" #define D_ERASED_SECTOR "Secteur effacé"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware MINIMAL - merci de mettre à jour" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware MINIMAL - merci de mettre à jour"
#define D_WEBSERVER_ACTIVE_ON "Serveur web actif sur" #define D_WEBSERVER_ACTIVE_ON "Serveur web actif sur"
#define D_WITH_IP_ADDRESS "avec l'adresse IP" #define D_WITH_IP_ADDRESS "avec l'adresse IP"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Téléchargement annulé" #define D_UPLOAD_ERR_7 "Téléchargement annulé"
#define D_UPLOAD_ERR_8 "Fichier invalide" #define D_UPLOAD_ERR_8 "Fichier invalide"
#define D_UPLOAD_ERR_9 "Fichier trop grand" #define D_UPLOAD_ERR_9 "Fichier trop grand"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Code d'erreur téléchargement" #define D_UPLOAD_ERROR_CODE "Code d'erreur téléchargement"
#define D_ENTER_COMMAND "Saisir une commande" #define D_ENTER_COMMAND "Saisir une commande"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Activer Weblog 2 si une réponse est attendue" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Activer Weblog 2 si une réponse est attendue"
#define D_NEED_USER_AND_PASSWORD "Nécessite utilisateur=<username>&password=<password>" #define D_NEED_USER_AND_PASSWORD "Nécessite utilisateur=<username>&password=<password>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Vérification d'empreinte TLS ..." #define D_FINGERPRINT "Vérification d'empreinte TLS ..."
#define D_TLS_CONNECT_FAILED_TO "Échec de connexion TLS à" #define D_TLS_CONNECT_FAILED_TO "Échec de connexion TLS à"
#define D_RETRY_IN "Nouvelle tentative dans" #define D_RETRY_IN "Nouvelle tentative dans"
@ -335,7 +339,7 @@
#define D_INSECURE "Connexion non sécurisée car empreinte non vérifiée" #define D_INSECURE "Connexion non sécurisée car empreinte non vérifiée"
#define D_CONNECT_FAILED_TO "Échec de connexion à" #define D_CONNECT_FAILED_TO "Échec de connexion à"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast désactivé" #define D_MULTICAST_DISABLED "Multicast désactivé"
#define D_MULTICAST_REJOINED "Multicast (re)joint" #define D_MULTICAST_REJOINED "Multicast (re)joint"
#define D_MULTICAST_JOIN_FAILED "Multicast échec abonnement" #define D_MULTICAST_JOIN_FAILED "Multicast échec abonnement"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 paquets de réponse envoyés" #define D_3_RESPONSE_PACKETS_SENT "3 paquets de réponse envoyés"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Paramètres Domoticz" #define D_DOMOTICZ_PARAMETERS "Paramètres Domoticz"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "envoyé à" #define D_SENT_TO "envoyé à"
#define D_KNX_WARNING "L'Adresse de Groupe ( 0 / 0 / 0 ) est réservée et ne peut être utilisée." #define D_KNX_WARNING "L'Adresse de Groupe ( 0 / 0 / 0 ) est réservée et ne peut être utilisée."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xsns_03_energy.ino // xsns_03_energy.ino
#define D_ENERGY_TODAY "Énergie aujourd'hui" #define D_ENERGY_TODAY "Énergie aujourd'hui"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Alapértelmezett beáll. használata" #define D_USE_DEFAULTS "Alapértelmezett beáll. használata"
#define D_ERASED_SECTOR "Szektor törlése" #define D_ERASED_SECTOR "Szektor törlése"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - frissítsd!" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - frissítsd!"
#define D_WEBSERVER_ACTIVE_ON "Web szerver aktív a" #define D_WEBSERVER_ACTIVE_ON "Web szerver aktív a"
#define D_WITH_IP_ADDRESS "IP címe:" #define D_WITH_IP_ADDRESS "IP címe:"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Feltöltés megszakítva" #define D_UPLOAD_ERR_7 "Feltöltés megszakítva"
#define D_UPLOAD_ERR_8 "Érvénytelen file" #define D_UPLOAD_ERR_8 "Érvénytelen file"
#define D_UPLOAD_ERR_9 "File túl nagy" #define D_UPLOAD_ERR_9 "File túl nagy"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Feltöltés hiba kód" #define D_UPLOAD_ERROR_CODE "Feltöltés hiba kód"
#define D_ENTER_COMMAND "Parancsolj" #define D_ENTER_COMMAND "Parancsolj"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Engedélyezz 2-es weblogolást több információért" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Engedélyezz 2-es weblogolást több információért"
#define D_NEED_USER_AND_PASSWORD "Kell felhasználó=<felhasználónév>&jelszó=<jelszó>" #define D_NEED_USER_AND_PASSWORD "Kell felhasználó=<felhasználónév>&jelszó=<jelszó>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "TLS fingerprint hitelesítése..." #define D_FINGERPRINT "TLS fingerprint hitelesítése..."
#define D_TLS_CONNECT_FAILED_TO "TLS Csatlakozás sikertelen a" #define D_TLS_CONNECT_FAILED_TO "TLS Csatlakozás sikertelen a"
#define D_RETRY_IN "Újrapróbálás" #define D_RETRY_IN "Újrapróbálás"
@ -335,7 +339,7 @@
#define D_INSECURE "Nem biztonságos kapcsolat érvénytelen Fingerprint miatt" #define D_INSECURE "Nem biztonságos kapcsolat érvénytelen Fingerprint miatt"
#define D_CONNECT_FAILED_TO "Sikertelen csatlakozás a" #define D_CONNECT_FAILED_TO "Sikertelen csatlakozás a"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast kikapcsolva" #define D_MULTICAST_DISABLED "Multicast kikapcsolva"
#define D_MULTICAST_REJOINED "Multicast (újra)csatlakozás" #define D_MULTICAST_REJOINED "Multicast (újra)csatlakozás"
#define D_MULTICAST_JOIN_FAILED "Multicast csatlakozás sikertelen" #define D_MULTICAST_JOIN_FAILED "Multicast csatlakozás sikertelen"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 válaszcsomagok elküldve" #define D_3_RESPONSE_PACKETS_SENT "3 válaszcsomagok elküldve"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz paraméterek" #define D_DOMOTICZ_PARAMETERS "Domoticz paraméterek"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "sent to" #define D_SENT_TO "sent to"
#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." #define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Mai Energia" #define D_ENERGY_TODAY "Mai Energia"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Utilizzo valori default" #define D_USE_DEFAULTS "Utilizzo valori default"
#define D_ERASED_SECTOR "Settore cancellato" #define D_ERASED_SECTOR "Settore cancellato"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - effettuare aggiornamento" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - effettuare aggiornamento"
#define D_WEBSERVER_ACTIVE_ON "Web server attivo su" #define D_WEBSERVER_ACTIVE_ON "Web server attivo su"
#define D_WITH_IP_ADDRESS "con indirizzo IP" #define D_WITH_IP_ADDRESS "con indirizzo IP"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Invio annullato" #define D_UPLOAD_ERR_7 "Invio annullato"
#define D_UPLOAD_ERR_8 "File non valido" #define D_UPLOAD_ERR_8 "File non valido"
#define D_UPLOAD_ERR_9 "File troppo grande" #define D_UPLOAD_ERR_9 "File troppo grande"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Codice errore invio" #define D_UPLOAD_ERROR_CODE "Codice errore invio"
#define D_ENTER_COMMAND "Inserire comando" #define D_ENTER_COMMAND "Inserire comando"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Abilitare weblog 2 se è attesa una risposta" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Abilitare weblog 2 se è attesa una risposta"
#define D_NEED_USER_AND_PASSWORD "Richiesto user=<username>&password=<password>" #define D_NEED_USER_AND_PASSWORD "Richiesto user=<username>&password=<password>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Verifica TLS fingerprint..." #define D_FINGERPRINT "Verifica TLS fingerprint..."
#define D_TLS_CONNECT_FAILED_TO "Connessione TLS fallita a" #define D_TLS_CONNECT_FAILED_TO "Connessione TLS fallita a"
#define D_RETRY_IN "Nuovo tentativo in" #define D_RETRY_IN "Nuovo tentativo in"
@ -335,7 +339,7 @@
#define D_INSECURE "Connessione insicura a causa di Fingerprint non valido" #define D_INSECURE "Connessione insicura a causa di Fingerprint non valido"
#define D_CONNECT_FAILED_TO "Connessione Fallita a" #define D_CONNECT_FAILED_TO "Connessione Fallita a"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast disabilitato" #define D_MULTICAST_DISABLED "Multicast disabilitato"
#define D_MULTICAST_REJOINED "Multicast (ri)associato" #define D_MULTICAST_REJOINED "Multicast (ri)associato"
#define D_MULTICAST_JOIN_FAILED "Associazione Multicast fallita" #define D_MULTICAST_JOIN_FAILED "Associazione Multicast fallita"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST argomenti" #define D_HUE_POST_ARGS "Hue POST argomenti"
#define D_3_RESPONSE_PACKETS_SENT "3 pacchetti di risposta inviati" #define D_3_RESPONSE_PACKETS_SENT "3 pacchetti di risposta inviati"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Parametri Domoticz" #define D_DOMOTICZ_PARAMETERS "Parametri Domoticz"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "invia a" #define D_SENT_TO "invia a"
#define D_KNX_WARNING "L'indirizzo del gruppo ( 0 / 0 / 0 ) è riservato e non può essere usato." #define D_KNX_WARNING "L'indirizzo del gruppo ( 0 / 0 / 0 ) è riservato e non può essere usato."
#define D_KNX_ENHANCEMENT "Miglioramento Comunicazione" #define D_KNX_ENHANCEMENT "Miglioramento Comunicazione"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia Oggi" #define D_ENERGY_TODAY "Energia Oggi"

View File

@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele. * Use online command Prefix to translate cmnd, stat and tele.
* *
* Updated until v5.14.0a * Updated until v6.0.0a
\*********************************************************************/ \*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Gebruik standaardwaarden" #define D_USE_DEFAULTS "Gebruik standaardwaarden"
#define D_ERASED_SECTOR "Wis sector" #define D_ERASED_SECTOR "Wis sector"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - opwaarderen" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - opwaarderen"
#define D_WEBSERVER_ACTIVE_ON "Webserver actief op" #define D_WEBSERVER_ACTIVE_ON "Webserver actief op"
#define D_WITH_IP_ADDRESS "met IP adres" #define D_WITH_IP_ADDRESS "met IP adres"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Opwaarderen afgebroken" #define D_UPLOAD_ERR_7 "Opwaarderen afgebroken"
#define D_UPLOAD_ERR_8 "Ongeldig bestand" #define D_UPLOAD_ERR_8 "Ongeldig bestand"
#define D_UPLOAD_ERR_9 "Bestand is te groot" #define D_UPLOAD_ERR_9 "Bestand is te groot"
#define D_UPLOAD_ERR_10 "Init RF chip mislukt"
#define D_UPLOAD_ERR_11 "Wissen RF chip mislukt"
#define D_UPLOAD_ERR_12 "Opwaarderen RF chip mislukt"
#define D_UPLOAD_ERR_13 "Decoderen RF bestand mislukt"
#define D_UPLOAD_ERROR_CODE "Opwaardeer foutcode" #define D_UPLOAD_ERROR_CODE "Opwaardeer foutcode"
#define D_ENTER_COMMAND "Geef opdracht" #define D_ENTER_COMMAND "Geef opdracht"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Schakel weblog 2 in indien antwoord verwacht" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Schakel weblog 2 in indien antwoord verwacht"
#define D_NEED_USER_AND_PASSWORD "Benodig user=<gebruiker>&password=<webwachtwoord>" #define D_NEED_USER_AND_PASSWORD "Benodig user=<gebruiker>&password=<webwachtwoord>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Controleer TLS vingerafdruk..." #define D_FINGERPRINT "Controleer TLS vingerafdruk..."
#define D_TLS_CONNECT_FAILED_TO "TLS Verbinding mislukt naar" #define D_TLS_CONNECT_FAILED_TO "TLS Verbinding mislukt naar"
#define D_RETRY_IN "Opnieuw proberen over" #define D_RETRY_IN "Opnieuw proberen over"
@ -335,7 +339,7 @@
#define D_INSECURE "Door ongeldige vingerafdruk een onveilige verbinding" #define D_INSECURE "Door ongeldige vingerafdruk een onveilige verbinding"
#define D_CONNECT_FAILED_TO "Verbinding mislukt naar" #define D_CONNECT_FAILED_TO "Verbinding mislukt naar"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast uitgeschakeld" #define D_MULTICAST_DISABLED "Multicast uitgeschakeld"
#define D_MULTICAST_REJOINED "Multicast verbonden" #define D_MULTICAST_REJOINED "Multicast verbonden"
#define D_MULTICAST_JOIN_FAILED "Multicast verbinding mislukt" #define D_MULTICAST_JOIN_FAILED "Multicast verbinding mislukt"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST argumenten" #define D_HUE_POST_ARGS "Hue POST argumenten"
#define D_3_RESPONSE_PACKETS_SENT "3 antwoord paketten verstuurd" #define D_3_RESPONSE_PACKETS_SENT "3 antwoord paketten verstuurd"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz parameters" #define D_DOMOTICZ_PARAMETERS "Domoticz parameters"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Toets idx" #define D_DOMOTICZ_KEY_IDX "Toets idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "verzend naar" #define D_SENT_TO "verzend naar"
#define D_KNX_WARNING "Groep adres (0/0/0) is gereserveerd en mag niet worden gebruikt." #define D_KNX_WARNING "Groep adres (0/0/0) is gereserveerd en mag niet worden gebruikt."
#define D_KNX_ENHANCEMENT "Verbeter verbinding" #define D_KNX_ENHANCEMENT "Verbeter verbinding"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Verbruik vandaag" #define D_ENERGY_TODAY "Verbruik vandaag"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Użyj domyślnych" #define D_USE_DEFAULTS "Użyj domyślnych"
#define D_ERASED_SECTOR "Wymazany sektor" #define D_ERASED_SECTOR "Wymazany sektor"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Oprogramowanie MINIMAL - proszę uaktualnić" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Oprogramowanie MINIMAL - proszę uaktualnić"
#define D_WEBSERVER_ACTIVE_ON "Aktywny serwer Web" #define D_WEBSERVER_ACTIVE_ON "Aktywny serwer Web"
#define D_WITH_IP_ADDRESS "z adresem IP" #define D_WITH_IP_ADDRESS "z adresem IP"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Wgrywanie przerwane" #define D_UPLOAD_ERR_7 "Wgrywanie przerwane"
#define D_UPLOAD_ERR_8 "Błędny plik" #define D_UPLOAD_ERR_8 "Błędny plik"
#define D_UPLOAD_ERR_9 "Plik jest za duży" #define D_UPLOAD_ERR_9 "Plik jest za duży"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Błąd wgrywania" #define D_UPLOAD_ERROR_CODE "Błąd wgrywania"
#define D_ENTER_COMMAND "Wprowadź polecenie" #define D_ENTER_COMMAND "Wprowadź polecenie"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Włącz poziom 2 zapisu Weblog, jeśli oczekiwana jest odpowiedź" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Włącz poziom 2 zapisu Weblog, jeśli oczekiwana jest odpowiedź"
#define D_NEED_USER_AND_PASSWORD "Wymagany użytkownik=<username>&hasło=<password>" #define D_NEED_USER_AND_PASSWORD "Wymagany użytkownik=<username>&hasło=<password>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Weryfikuj odcisk TLS..." #define D_FINGERPRINT "Weryfikuj odcisk TLS..."
#define D_TLS_CONNECT_FAILED_TO "Nieudane połączenie TLS do" #define D_TLS_CONNECT_FAILED_TO "Nieudane połączenie TLS do"
#define D_RETRY_IN "Spróbuj ponownie" #define D_RETRY_IN "Spróbuj ponownie"
@ -335,7 +339,7 @@
#define D_INSECURE "Nieprawidłowe połączenie z powodu błędnego odcisku TLS" #define D_INSECURE "Nieprawidłowe połączenie z powodu błędnego odcisku TLS"
#define D_CONNECT_FAILED_TO "Nie udało się nawiązać połączenia" #define D_CONNECT_FAILED_TO "Nie udało się nawiązać połączenia"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast jest wyłączony" #define D_MULTICAST_DISABLED "Multicast jest wyłączony"
#define D_MULTICAST_REJOINED "Multicast (re)dołączony" #define D_MULTICAST_REJOINED "Multicast (re)dołączony"
#define D_MULTICAST_JOIN_FAILED "Multicast nie powiodło się" #define D_MULTICAST_JOIN_FAILED "Multicast nie powiodło się"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 pakiety odpowiedzi wysyłane" #define D_3_RESPONSE_PACKETS_SENT "3 pakiety odpowiedzi wysyłane"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Parametry Domoticz" #define D_DOMOTICZ_PARAMETERS "Parametry Domoticz"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "sent to" #define D_SENT_TO "sent to"
#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." #define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia Dzisiaj" #define D_ENERGY_TODAY "Energia Dzisiaj"

View File

@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele. * Use online command Prefix to translate cmnd, stat and tele.
* *
* Updated until v5.13.0 * Updated until v5.14.0b
\*********************************************************************/ \*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -52,8 +52,8 @@
// Common // Common
#define D_ADMIN "Admin" #define D_ADMIN "Admin"
#define D_AIR_QUALITY "Qualidade do Ar" #define D_AIR_QUALITY "Qualidade do ar"
#define D_AP "Pondo de acesso" // Ponto de Acesso #define D_AP "Ponto de acesso" // Ponto de Acesso
#define D_AS "como" #define D_AS "como"
#define D_AUTO "Auto" #define D_AUTO "Auto"
#define D_BLINK "Pulsar" #define D_BLINK "Pulsar"
@ -64,16 +64,16 @@
#define D_BY "por" // Write by me #define D_BY "por" // Write by me
#define D_BYTES "Bytes" #define D_BYTES "Bytes"
#define D_CELSIUS "Celsius" #define D_CELSIUS "Celsius"
#define D_CO2 "Dióxido de Carbono" #define D_CO2 "Dióxido de carbono"
#define D_CODE "Código" // Button code #define D_CODE "Código" // Button code
#define D_COLDLIGHT "Luz Fria" #define D_COLDLIGHT "Luz fria"
#define D_COMMAND "Comando" #define D_COMMAND "Comando"
#define D_CONNECTED "Ligado" #define D_CONNECTED "Ligado"
#define D_COUNT "Contagem" #define D_COUNT "Contagem"
#define D_COUNTER "Contador" #define D_COUNTER "Contador"
#define D_CURRENT "Corrente" // As in Voltage and Current #define D_CURRENT "Corrente" // As in Voltage and Current
#define D_DATA "Dados" #define D_DATA "Dados"
#define D_DARKLIGHT "Luz Escura" #define D_DARKLIGHT "Luz escura"
#define D_DEBUG "Depurar" #define D_DEBUG "Depurar"
#define D_DISABLED "Desabilitado" #define D_DISABLED "Desabilitado"
#define D_DISTANCE "Distância" #define D_DISTANCE "Distância"
@ -91,8 +91,8 @@
#define D_FALLBACK_TOPIC "Tópico para retornar" #define D_FALLBACK_TOPIC "Tópico para retornar"
#define D_FALSE "Falso" #define D_FALSE "Falso"
#define D_FILE "Arquivo" #define D_FILE "Arquivo"
#define D_FREE_MEMORY "Memória Livre" #define D_FREE_MEMORY "Memória livre"
#define D_FREQUENCY "Frequency" #define D_FREQUENCY "Frequência"
#define D_GAS "Gás" #define D_GAS "Gás"
#define D_GATEWAY "Gateway" #define D_GATEWAY "Gateway"
#define D_GROUP "Grupo" #define D_GROUP "Grupo"
@ -103,7 +103,7 @@
#define D_IMMEDIATE "Imediato" // Button immediate #define D_IMMEDIATE "Imediato" // Button immediate
#define D_INDEX "Índice" #define D_INDEX "Índice"
#define D_INFO "Informação" #define D_INFO "Informação"
#define D_INFRARED "Infrared" #define D_INFRARED "Infravermelho"
#define D_INITIALIZED "Inicializado" #define D_INITIALIZED "Inicializado"
#define D_IP_ADDRESS "Endereço IP" #define D_IP_ADDRESS "Endereço IP"
#define D_LIGHT "Luz" #define D_LIGHT "Luz"
@ -122,9 +122,9 @@
#define D_PORT "Porta" #define D_PORT "Porta"
#define D_POWER_FACTOR "Fator de potência" #define D_POWER_FACTOR "Fator de potência"
#define D_POWERUSAGE "Potência" #define D_POWERUSAGE "Potência"
#define D_POWERUSAGE_ACTIVE "Active Power" #define D_POWERUSAGE_ACTIVE "Potência ativa"
#define D_POWERUSAGE_APPARENT "Apparent Power" #define D_POWERUSAGE_APPARENT "Potência aparente"
#define D_POWERUSAGE_REACTIVE "Reactive Power" #define D_POWERUSAGE_REACTIVE "Potência reativa"
#define D_PRESSURE "Pressão" #define D_PRESSURE "Pressão"
#define D_PRESSUREATSEALEVEL "Pressão ao nível do mar" #define D_PRESSUREATSEALEVEL "Pressão ao nível do mar"
#define D_PROGRAM_FLASH_SIZE "Tamanho do programa na memória" #define D_PROGRAM_FLASH_SIZE "Tamanho do programa na memória"
@ -168,10 +168,10 @@
#define D_WEB_SERVER "Servidor WEB" #define D_WEB_SERVER "Servidor WEB"
// sonoff.ino // sonoff.ino
#define D_WARNING_MINIMAL_VERSION "AVISO esta versão não supporta configurações persistentes" #define D_WARNING_MINIMAL_VERSION "AVISO: esta versão não supporta configurações persistentes"
#define D_LEVEL_10 "nível 1-0" #define D_LEVEL_10 "nível 1-0"
#define D_LEVEL_01 "nível 0-1" #define D_LEVEL_01 "nível 0-1"
#define D_SERIAL_LOGGING_DISABLED "Registro em serie desabilitado" #define D_SERIAL_LOGGING_DISABLED "Registro em série desabilitado"
#define D_SYSLOG_LOGGING_REENABLED "Registro do Syslog reativado" #define D_SYSLOG_LOGGING_REENABLED "Registro do Syslog reativado"
#define D_SET_BAUDRATE_TO "Ajuste da velocidade para" #define D_SET_BAUDRATE_TO "Ajuste da velocidade para"
@ -205,15 +205,15 @@
#define D_USE_DEFAULTS "Usar predefinições" #define D_USE_DEFAULTS "Usar predefinições"
#define D_ERASED_SECTOR "Apagar setores" #define D_ERASED_SECTOR "Apagar setores"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware mínimo - Atualizar por favor" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware mínimo - Atualizar por favor"
#define D_WEBSERVER_ACTIVE_ON "Servidor WEB ativo em" #define D_WEBSERVER_ACTIVE_ON "Servidor WEB ativo em"
#define D_WITH_IP_ADDRESS "com o endereço IP" #define D_WITH_IP_ADDRESS "com o endereço IP"
#define D_WEBSERVER_STOPPED "Servidor WEB parou" #define D_WEBSERVER_STOPPED "Servidor WEB parou"
#define D_FILE_NOT_FOUND "Arquivo não encontrado" #define D_FILE_NOT_FOUND "Arquivo não encontrado"
#define D_REDIRECTED "Redirecionado para o portal ativo" #define D_REDIRECTED "Redirecionado para o portal ativo"
#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager configura o Ponto de Acesso e mantém a estação" #define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager: configura o Ponto de Acesso e a Estação"
#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager configura o Ponto de Acesso" #define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager: configura o Ponto de Acesso"
#define D_TRYING_TO_CONNECT "Conectar o dispositivo à rede" #define D_TRYING_TO_CONNECT "Conectar o dispositivo à rede"
#define D_RESTART_IN "Reinicia em" #define D_RESTART_IN "Reinicia em"
@ -238,7 +238,7 @@
#define D_RESTORE_CONFIGURATION "Repor configuração" #define D_RESTORE_CONFIGURATION "Repor configuração"
#define D_MAIN_MENU "Menu principal" #define D_MAIN_MENU "Menu principal"
#define D_MODULE_PARAMETERS "Parametros do módulo" #define D_MODULE_PARAMETERS "Parâmetros do módulo"
#define D_MODULE_TYPE "Tipo de módulo" #define D_MODULE_TYPE "Tipo de módulo"
#define D_GPIO "GPIO" #define D_GPIO "GPIO"
#define D_SERIAL_IN "Entrada serial" #define D_SERIAL_IN "Entrada serial"
@ -282,12 +282,12 @@
#define D_SINGLE_DEVICE "Dispositivo único" #define D_SINGLE_DEVICE "Dispositivo único"
#define D_MULTI_DEVICE "Múltiplos dispositivos" #define D_MULTI_DEVICE "Múltiplos dispositivos"
#define D_SAVE_CONFIGURATION "Salvar configuração" #define D_SAVE_CONFIGURATION "Gravar configuração"
#define D_CONFIGURATION_SAVED "Configuração salva" #define D_CONFIGURATION_SAVED "Configuração gravada"
#define D_CONFIGURATION_RESET "Reinicialização da configuração" #define D_CONFIGURATION_RESET "Reinicialização da configuração"
#define D_PROGRAM_VERSION "Versão do programa" #define D_PROGRAM_VERSION "Versão do programa"
#define D_BUILD_DATE_AND_TIME "Data e Hora da construção" #define D_BUILD_DATE_AND_TIME "Data e Hora da compilação"
#define D_CORE_AND_SDK_VERSION "Versão Core/SDK" #define D_CORE_AND_SDK_VERSION "Versão Core/SDK"
#define D_FLASH_WRITE_COUNT "Contagem de gravação flash" #define D_FLASH_WRITE_COUNT "Contagem de gravação flash"
#define D_MAC_ADDRESS "Endereço MAC" #define D_MAC_ADDRESS "Endereço MAC"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Envio cancelado" #define D_UPLOAD_ERR_7 "Envio cancelado"
#define D_UPLOAD_ERR_8 "Arquivo inválido" #define D_UPLOAD_ERR_8 "Arquivo inválido"
#define D_UPLOAD_ERR_9 "Arquivo muito grande" #define D_UPLOAD_ERR_9 "Arquivo muito grande"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Código de erro do envio" #define D_UPLOAD_ERROR_CODE "Código de erro do envio"
#define D_ENTER_COMMAND "Inserir comando" #define D_ENTER_COMMAND "Inserir comando"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 se resposta esperada" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 se resposta esperada"
#define D_NEED_USER_AND_PASSWORD "Necessário user=<nome usuário>&password=<senha>" #define D_NEED_USER_AND_PASSWORD "Necessário user=<nome usuário>&password=<senha>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Verifique a impressão digital TLS..." #define D_FINGERPRINT "Verifique a impressão digital TLS..."
#define D_TLS_CONNECT_FAILED_TO "TLS não conseguiu ligar" #define D_TLS_CONNECT_FAILED_TO "TLS não conseguiu ligar"
#define D_RETRY_IN "Tentativa em" #define D_RETRY_IN "Tentativa em"
@ -335,7 +339,7 @@
#define D_INSECURE "Ligação insegura devido à impressão digital inválida" #define D_INSECURE "Ligação insegura devido à impressão digital inválida"
#define D_CONNECT_FAILED_TO "A ligação falhou ao" #define D_CONNECT_FAILED_TO "A ligação falhou ao"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast desabilitado" #define D_MULTICAST_DISABLED "Multicast desabilitado"
#define D_MULTICAST_REJOINED "Multicast (re)ingressou" #define D_MULTICAST_REJOINED "Multicast (re)ingressou"
#define D_MULTICAST_JOIN_FAILED "Multicast falha no reingresso" #define D_MULTICAST_JOIN_FAILED "Multicast falha no reingresso"
@ -355,15 +359,15 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 pacotes de resposta enviados" #define D_3_RESPONSE_PACKETS_SENT "3 pacotes de resposta enviados"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Parâmetros Domoticz" #define D_DOMOTICZ_PARAMETERS "Parâmetros Domoticz"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Chave idx" #define D_DOMOTICZ_KEY_IDX "Chave idx"
#define D_DOMOTICZ_SWITCH_IDX "Interruptor idx" #define D_DOMOTICZ_SWITCH_IDX "Interruptor idx"
#define D_DOMOTICZ_SENSOR_IDX "Sensor idx" #define D_DOMOTICZ_SENSOR_IDX "Sensor idx"
#define D_DOMOTICZ_TEMP "Temp" #define D_DOMOTICZ_TEMP "Temp"
#define D_DOMOTICZ_TEMP_HUM "Temp,Hum" #define D_DOMOTICZ_TEMP_HUM "Temp,Umi"
#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro" #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Umi,Pres"
#define D_DOMOTICZ_POWER_ENERGY "Potência,Energia" #define D_DOMOTICZ_POWER_ENERGY "Potência,Energia"
#define D_DOMOTICZ_ILLUMINANCE "Luminância" #define D_DOMOTICZ_ILLUMINANCE "Luminância"
#define D_DOMOTICZ_COUNT "Contagem/PM1" #define D_DOMOTICZ_COUNT "Contagem/PM1"
@ -401,7 +405,9 @@
#define D_KNX_COMMAND_OTHER "Outros" #define D_KNX_COMMAND_OTHER "Outros"
#define D_SENT_TO "Enviar para" #define D_SENT_TO "Enviar para"
#define D_KNX_WARNING "O endereço ( 0 / 0 / 0 ) é reservado e não pode ser usado." #define D_KNX_WARNING "O endereço ( 0 / 0 / 0 ) é reservado e não pode ser usado."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Melhoria da comunicação"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje" #define D_ENERGY_TODAY "Consumo energético de hoje"
@ -439,19 +445,19 @@
#define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_IRSEND "IRsend" #define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Interruptor" // Suffix "1" #define D_SENSOR_SWITCH "Interruptor" // Suffix "1"
#define D_SENSOR_BUTTON "Botão" // Suffix "1" #define D_SENSOR_BUTTON "Botão" // Suffix "1"
#define D_SENSOR_RELAY "Relé" // Suffix "1i" #define D_SENSOR_RELAY "Relé" // Suffix "1i"
#define D_SENSOR_LED "Led" // Suffix "1i" #define D_SENSOR_LED "Led" // Suffix "1i"
#define D_SENSOR_PWM "PWM" // Suffix "1" #define D_SENSOR_PWM "PWM" // Suffix "1"
#define D_SENSOR_COUNTER "Contador" // Suffix "1" #define D_SENSOR_COUNTER "Contador" // Suffix "1"
#define D_SENSOR_IRRECV "IRrecv" #define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_RX "MHz Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx" #define D_SENSOR_MHZ_TX "MHz Tx"
#define D_SENSOR_PZEM_RX "PZEM Rx" #define D_SENSOR_PZEM_RX "PZEM Rx"
#define D_SENSOR_PZEM_TX "PZEM Tx" #define D_SENSOR_PZEM_TX "PZEM Tx"
#define D_SENSOR_SAIR_RX "SAir Rx" #define D_SENSOR_SAIR_RX "SAIR Rx"
#define D_SENSOR_SAIR_TX "SAir Tx" #define D_SENSOR_SAIR_TX "SAIR Tx"
#define D_SENSOR_SPI_CS "SPI CS" #define D_SENSOR_SPI_CS "SPI CS"
#define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "Luz de fundo" #define D_SENSOR_BACKLIGHT "Luz de fundo"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Usar predefinições" #define D_USE_DEFAULTS "Usar predefinições"
#define D_ERASED_SECTOR "Apagar setores" #define D_ERASED_SECTOR "Apagar setores"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMO firmware - Atualizar Por favor" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMO firmware - Atualizar Por favor"
#define D_WEBSERVER_ACTIVE_ON "Servidor WEB ativo em" #define D_WEBSERVER_ACTIVE_ON "Servidor WEB ativo em"
#define D_WITH_IP_ADDRESS "com o endereço IP" #define D_WITH_IP_ADDRESS "com o endereço IP"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Envio cancelado" #define D_UPLOAD_ERR_7 "Envio cancelado"
#define D_UPLOAD_ERR_8 "Ficheiro inválido" #define D_UPLOAD_ERR_8 "Ficheiro inválido"
#define D_UPLOAD_ERR_9 "Ficheiro demasiado grande" #define D_UPLOAD_ERR_9 "Ficheiro demasiado grande"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Código de erro do envio" #define D_UPLOAD_ERROR_CODE "Código de erro do envio"
#define D_ENTER_COMMAND "Inserir comando" #define D_ENTER_COMMAND "Inserir comando"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 se resposta esperada" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 se resposta esperada"
#define D_NEED_USER_AND_PASSWORD "Necessário user=<nome utilizador>&password=<palavra chave>" #define D_NEED_USER_AND_PASSWORD "Necessário user=<nome utilizador>&password=<palavra chave>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Verifique a impressão digital TLS..." #define D_FINGERPRINT "Verifique a impressão digital TLS..."
#define D_TLS_CONNECT_FAILED_TO "TLS não conseguiu ligar" #define D_TLS_CONNECT_FAILED_TO "TLS não conseguiu ligar"
#define D_RETRY_IN "Tentativa em" #define D_RETRY_IN "Tentativa em"
@ -335,7 +339,7 @@
#define D_INSECURE "Ligação insegura devido à impressão digital inválida" #define D_INSECURE "Ligação insegura devido à impressão digital inválida"
#define D_CONNECT_FAILED_TO "A ligação falhou ao" #define D_CONNECT_FAILED_TO "A ligação falhou ao"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast desabilitado" #define D_MULTICAST_DISABLED "Multicast desabilitado"
#define D_MULTICAST_REJOINED "Multicast (re)ingressou" #define D_MULTICAST_REJOINED "Multicast (re)ingressou"
#define D_MULTICAST_JOIN_FAILED "Multicast falha no reingresso" #define D_MULTICAST_JOIN_FAILED "Multicast falha no reingresso"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 pacotes de resposta enviados" #define D_3_RESPONSE_PACKETS_SENT "3 pacotes de resposta enviados"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Parametros Domoticz" #define D_DOMOTICZ_PARAMETERS "Parametros Domoticz"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Chave idx" #define D_DOMOTICZ_KEY_IDX "Chave idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "sent to" #define D_SENT_TO "sent to"
#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." #define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje" #define D_ENERGY_TODAY "Consumo energético de hoje"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "Использовать значение по умолчанию" #define D_USE_DEFAULTS "Использовать значение по умолчанию"
#define D_ERASED_SECTOR "Стереть сектор" #define D_ERASED_SECTOR "Стереть сектор"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Прошивка MINIMAL - пожалуйста обновите" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Прошивка MINIMAL - пожалуйста обновите"
#define D_WEBSERVER_ACTIVE_ON "Веб-сервер активен" #define D_WEBSERVER_ACTIVE_ON "Веб-сервер активен"
#define D_WITH_IP_ADDRESS "с IP-адресом" #define D_WITH_IP_ADDRESS "с IP-адресом"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "Загрузка прервана" #define D_UPLOAD_ERR_7 "Загрузка прервана"
#define D_UPLOAD_ERR_8 "Файл неверный" #define D_UPLOAD_ERR_8 "Файл неверный"
#define D_UPLOAD_ERR_9 "Слишком большой файл" #define D_UPLOAD_ERR_9 "Слишком большой файл"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Код ошибки загрузки" #define D_UPLOAD_ERROR_CODE "Код ошибки загрузки"
#define D_ENTER_COMMAND "Введите команду" #define D_ENTER_COMMAND "Введите команду"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Включить Веб лог уровня 2 если ожидается ответ" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Включить Веб лог уровня 2 если ожидается ответ"
#define D_NEED_USER_AND_PASSWORD "Ожидается user=<username>&password=<password>" #define D_NEED_USER_AND_PASSWORD "Ожидается user=<username>&password=<password>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "Проверка TLS Fingerprint..." #define D_FINGERPRINT "Проверка TLS Fingerprint..."
#define D_TLS_CONNECT_FAILED_TO "Сбой подключения TLS к" #define D_TLS_CONNECT_FAILED_TO "Сбой подключения TLS к"
#define D_RETRY_IN "Повторить" #define D_RETRY_IN "Повторить"
@ -335,7 +339,7 @@
#define D_INSECURE "Небезопасное соединение, недействительный Fingerprint" #define D_INSECURE "Небезопасное соединение, недействительный Fingerprint"
#define D_CONNECT_FAILED_TO "Ошибка подключения к" #define D_CONNECT_FAILED_TO "Ошибка подключения к"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast отключен" #define D_MULTICAST_DISABLED "Multicast отключен"
#define D_MULTICAST_REJOINED "Multicast (ре)соединился" #define D_MULTICAST_REJOINED "Multicast (ре)соединился"
#define D_MULTICAST_JOIN_FAILED "Multicast ошибка соединения" #define D_MULTICAST_JOIN_FAILED "Multicast ошибка соединения"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST args" #define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 ответных пакета получено" #define D_3_RESPONSE_PACKETS_SENT "3 ответных пакета получено"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz parameters" #define D_DOMOTICZ_PARAMETERS "Domoticz parameters"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "sent to" #define D_SENT_TO "sent to"
#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." #define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "Энергия Сегодня" #define D_ENERGY_TODAY "Энергия Сегодня"

526
sonoff/language/uk-UK.h Normal file
View File

@ -0,0 +1,526 @@
/*
uk-UK.h - localization for Ukrainian - Ukrain for Sonoff-Tasmota
Copyright (C) 2018 Theo Arends / vadym-adik
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LANGUAGE_UK_UK_H_
#define _LANGUAGE_UK_UK_H_
/*************************** ATTENTION *******************************\
*
* Due to memory constraints only UTF-8 is supported.
* To save code space keep text as short as possible.
* Time and Date provided by SDK can not be localized (yet).
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele.
*
* Updated until v5.14.0a
\*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
#define LANGUAGE_LCID 1058
// HTML (ISO 639-1) Language Code
#define D_HTML_LANGUAGE "uk"
// "2017-03-07T11:08:02" - ISO8601:2004
#define D_YEAR_MONTH_SEPARATOR "-"
#define D_MONTH_DAY_SEPARATOR "-"
#define D_DATE_TIME_SEPARATOR "T"
#define D_HOUR_MINUTE_SEPARATOR ":"
#define D_MINUTE_SECOND_SEPARATOR ":"
#define D_DAY3LIST "НедПонВівСерЧетПятСуб"
#define D_MONTH3LIST "СічЛютБерКвіТраЧерЛипВерЖовЛисГру"
// Non JSON decimal separator
#define D_DECIMAL_SEPARATOR ","
// Common
#define D_ADMIN "Admin"
#define D_AIR_QUALITY "Якість повітря"
#define D_AP "AP" // Access Point
#define D_AS "як"
#define D_AUTO "АВТО"
#define D_BLINK "Блимати"
#define D_BLINKOFF "Не блимати"
#define D_BOOT_COUNT "Кіл-сть завант."
#define D_BRIGHTLIGHT "Яскравість"
#define D_BUTTON "Кнопка"
#define D_BY "by" // Written by me
#define D_BYTES "Байт"
#define D_CELSIUS "Цельсія"
#define D_CO2 "Вуглек. газ"
#define D_CODE "код" // Button code
#define D_COLDLIGHT "Холодний"
#define D_COMMAND "Команда"
#define D_CONNECTED "Під'єднано"
#define D_COUNT "Підрахунок"
#define D_COUNTER "Лічильник"
#define D_CURRENT "Струм" // As in Voltage and Current
#define D_DATA "Дані"
#define D_DARKLIGHT "Темний"
#define D_DEBUG "Налагодження"
#define D_DISABLED "Заблоковано"
#define D_DISTANCE "Дистанція"
#define D_DNS_SERVER "DNS Сервер"
#define D_DONE "Виконано"
#define D_DST_TIME "Літній час"
#define D_ECO2 "eCO2"
#define D_EMULATION "Емуляція"
#define D_ENABLED "Активно"
#define D_ERASE "Стирати"
#define D_ERROR "Помилка"
#define D_FAHRENHEIT "Фаренгейт"
#define D_FAILED "Невдало"
#define D_FALLBACK "Зворотній зв'язок"
#define D_FALLBACK_TOPIC "Топік зворотнього зв'язку"
#define D_FALSE "Помилково"
#define D_FILE "Файл"
#define D_FREE_MEMORY "Вільна память"
#define D_FREQUENCY "Частота"
#define D_GAS "Газ"
#define D_GATEWAY "Шлюз"
#define D_GROUP "Група"
#define D_HOST "Хост"
#define D_HOSTNAME "Ім'я Хосту"
#define D_HUMIDITY "Вологість"
#define D_ILLUMINANCE "Освітленність"
#define D_IMMEDIATE "негайно" // Button immediate
#define D_INDEX "Індекс"
#define D_INFO "Інфо"
#define D_INFRARED "Інфрачервоний"
#define D_INITIALIZED "Ініціалізовано"
#define D_IP_ADDRESS "IP Адрес"
#define D_LIGHT "Світло"
#define D_LWT "LWT"
#define D_MODULE "Модуль"
#define D_MQTT "MQTT"
#define D_MULTI_PRESS "багаторазове натискання"
#define D_NOISE "Шум"
#define D_NONE "Ні"
#define D_OFF "Вимк."
#define D_OFFLINE "Офф-лайн"
#define D_OK "Ок"
#define D_ON "Увімк."
#define D_ONLINE "Он-лайн"
#define D_PASSWORD "Гасло"
#define D_PORT "Порт"
#define D_POWER_FACTOR "Коефіцієнт потужності"
#define D_POWERUSAGE "Потужність"
#define D_POWERUSAGE_ACTIVE "Активна потужність"
#define D_POWERUSAGE_APPARENT "Дійсна потужність"
#define D_POWERUSAGE_REACTIVE "Реактивна потужність"
#define D_PRESSURE "Тиск"
#define D_PRESSUREATSEALEVEL "Тиск на рівні моря"
#define D_PROGRAM_FLASH_SIZE "Розмір Flash для програм"
#define D_PROGRAM_SIZE "Розмір програм "
#define D_PROJECT "Проект"
#define D_RECEIVED "Отримано"
#define D_RESTART "Перезавантаження"
#define D_RESTARTING "Перезавантаження"
#define D_RESTART_REASON "Причина перезавантаження"
#define D_RESTORE "відновлення"
#define D_RETAINED "нерозподілений"
#define D_RULE "Правило"
#define D_SAVE "Зберегти"
#define D_SENSOR "Датчик"
#define D_SSID "SSID"
#define D_START "Старт"
#define D_STD_TIME "STD"
#define D_STOP "Стоп"
#define D_SUBNET_MASK "Маска Підмережі"
#define D_SUBSCRIBE_TO "Підписатись на"
#define D_SUCCESSFUL "Успішно"
#define D_SUNRISE "Схід сонця"
#define D_SUNSET "Захід сонця"
#define D_TEMPERATURE "Температура"
#define D_TO "до"
#define D_TOGGLE "Перекл."
#define D_TOPIC "Топік"
#define D_TRANSMIT "Передати"
#define D_TRUE "Істина"
#define D_TVOC "TVOC"
#define D_UPGRADE "оновлення"
#define D_UPLOAD "Завантажити"
#define D_UPTIME "Час роботи"
#define D_USER "Користувач"
#define D_UTC_TIME "UTC"
#define D_UV_INDEX "УФ індекс"
#define D_UV_LEVEL "УФ рівень"
#define D_VERSION "Версія"
#define D_VOLTAGE "Напруга"
#define D_WARMLIGHT "Тепло"
#define D_WEB_SERVER "Web сервер"
// sonoff.ino
#define D_WARNING_MINIMAL_VERSION "ПОПЕРЕДЖЕННЯ! Ця версія не підтримує персистентні налаштування"
#define D_LEVEL_10 "рівень 1-0"
#define D_LEVEL_01 "рівень 0-1"
#define D_SERIAL_LOGGING_DISABLED "Serial logging вимкнений"
#define D_SYSLOG_LOGGING_REENABLED "Syslog logging увімкнений"
#define D_SET_BAUDRATE_TO "Встановити швидкість передачі (Baudrate)"
#define D_RECEIVED_TOPIC "Отриманий Топік"
#define D_DATA_SIZE "Розмір даних"
#define D_ANALOG_INPUT "Аналоговий вхід"
// support.ino
#define D_OSWATCH "osWatch"
#define D_BLOCKED_LOOP "Блокуючий цикл"
#define D_WPS_FAILED_WITH_STATUS "WPS конфігурація з статусом НЕВДАЛА"
#define D_ACTIVE_FOR_3_MINUTES "активний протягом 3 хвилин"
#define D_FAILED_TO_START "не вдалось запустити"
#define D_PATCH_ISSUE_2186 "Проблема з виправленням 2186"
#define D_CONNECTING_TO_AP "Підключення до AP"
#define D_IN_MODE "в режимі"
#define D_CONNECT_FAILED_NO_IP_ADDRESS "Помилка підключення, IP-адрес не отриманий"
#define D_CONNECT_FAILED_AP_NOT_REACHED "Помилка з'єднання, AP не запущений"
#define D_CONNECT_FAILED_WRONG_PASSWORD "Помилка з'єднання, невірне гасло до AP"
#define D_CONNECT_FAILED_AP_TIMEOUT "Помилка з'єднання з AP по тайм-ауту"
#define D_ATTEMPTING_CONNECTION "Спроба підключення..."
#define D_CHECKING_CONNECTION "Перевірка з'єднання..."
#define D_QUERY_DONE "Запит виконаний. Виявлено служби MQTT"
#define D_MQTT_SERVICE_FOUND "MQTT сервіс знайдено"
#define D_FOUND_AT "знайдено в"
#define D_SYSLOG_HOST_NOT_FOUND "System лог хост не знайдено"
// settings.ino
#define D_SAVED_TO_FLASH_AT "Збережено в флэш-пам'ять"
#define D_LOADED_FROM_FLASH_AT "Завантажено з флэш-пам'яті"
#define D_USE_DEFAULTS "Використовувати значення за замовчуванням"
#define D_ERASED_SECTOR "Стерти сектор"
// xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Прошивка MINIMAL - будь-ласка оновіть"
#define D_WEBSERVER_ACTIVE_ON "Веб-сервер активний"
#define D_WITH_IP_ADDRESS "з IP-адресом"
#define D_WEBSERVER_STOPPED "Веб-сервер зупинений"
#define D_FILE_NOT_FOUND "Файл не знайдений"
#define D_REDIRECTED "Перенаправлено на адаптивний портал"
#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifi менеджер встановлює Точку Доступу і зберігає параметри"
#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifi менеджер встановив Точку Доступу"
#define D_TRYING_TO_CONNECT "Спроба підключення пристрою до мережі"
#define D_RESTART_IN "Перезавантаження"
#define D_SECONDS "секунд"
#define D_DEVICE_WILL_RESTART "Пристрій буде перезавантажено через декілька секунд"
#define D_BUTTON_TOGGLE "Переключити"
#define D_CONFIGURATION "Конфігурація"
#define D_INFORMATION "Інформація"
#define D_FIRMWARE_UPGRADE "Оновлення прошивки"
#define D_CONSOLE "Консоль"
#define D_CONFIRM_RESTART "Підтвердити перезавантаження"
#define D_CONFIGURE_MODULE "Конфігурація модуля"
#define D_CONFIGURE_WIFI "Конфігурація WiFi"
#define D_CONFIGURE_MQTT "Конфігурація MQTT"
#define D_CONFIGURE_DOMOTICZ "Конфігурація Domoticz"
#define D_CONFIGURE_LOGGING "Конфігурація Логів"
#define D_CONFIGURE_OTHER "Конфігурація інше"
#define D_CONFIRM_RESET_CONFIGURATION "Підтвердити скидання конфігурації"
#define D_RESET_CONFIGURATION "Скидання конфігурації"
#define D_BACKUP_CONFIGURATION "Резервне копіювання конфігурації"
#define D_RESTORE_CONFIGURATION "Відновлення конфігурації"
#define D_MAIN_MENU "Головне меню"
#define D_MODULE_PARAMETERS "Параметри модулю"
#define D_MODULE_TYPE "Тип модулю"
#define D_GPIO "GPIO"
#define D_SERIAL_IN "Serial вхід"
#define D_SERIAL_OUT "Serial вихід"
#define D_WIFI_PARAMETERS "Параметри Wifi"
#define D_SCAN_FOR_WIFI_NETWORKS "Сканування беспроводових мереж Wifi"
#define D_SCAN_DONE "Сканування завершене"
#define D_NO_NETWORKS_FOUND "Не знайдено мереж"
#define D_REFRESH_TO_SCAN_AGAIN "Оновити для повторного сканування"
#define D_DUPLICATE_ACCESSPOINT "Дублювати Точку Доступу (AP)"
#define D_SKIPPING_LOW_QUALITY "Пропущено через низьку якість"
#define D_RSSI "RSSI"
#define D_WEP "WEP"
#define D_WPA_PSK "WPA PSK"
#define D_WPA2_PSK "WPA2 PSK"
#define D_AP1_SSID "AP1 SSID"
#define D_AP1_PASSWORD "AP1 Гасло"
#define D_AP2_SSID "AP2 SSID"
#define D_AP2_PASSWORD "AP2 Гасло"
#define D_MQTT_PARAMETERS "Параметри MQTT"
#define D_CLIENT "Клієнт"
#define D_FULL_TOPIC "Повний Топік"
#define D_LOGGING_PARAMETERS "Параметри логів"
#define D_SERIAL_LOG_LEVEL "Serial лог рівень"
#define D_WEB_LOG_LEVEL "Web лог рівень"
#define D_SYS_LOG_LEVEL "System лог рівень"
#define D_MORE_DEBUG "Додаткова інформація для налагодження"
#define D_SYSLOG_HOST "System лог хост"
#define D_SYSLOG_PORT "System лог порт"
#define D_TELEMETRY_PERIOD "Період телеметрії"
#define D_OTHER_PARAMETERS "Параметри Інше"
#define D_WEB_ADMIN_PASSWORD "Гасло Web адміністратора"
#define D_MQTT_ENABLE "MQTT активний"
#define D_FRIENDLY_NAME "Дружнє Ім'я"
#define D_BELKIN_WEMO "Belkin WeMo"
#define D_HUE_BRIDGE "Hue Bridge"
#define D_SINGLE_DEVICE "одиночне"
#define D_MULTI_DEVICE "мульти"
#define D_SAVE_CONFIGURATION "Зберегти конфігурацію"
#define D_CONFIGURATION_SAVED "Конфігурація збережена "
#define D_CONFIGURATION_RESET "Конфігурація скинута"
#define D_PROGRAM_VERSION "Версія програми"
#define D_BUILD_DATE_AND_TIME "Дата & Час збірки"
#define D_CORE_AND_SDK_VERSION "Версія Core/SDK"
#define D_FLASH_WRITE_COUNT "Кіл-ть записів Flash"
#define D_MAC_ADDRESS "MAC Адрес"
#define D_MQTT_HOST "MQTT Хост"
#define D_MQTT_PORT "MQTT Порт"
#define D_MQTT_CLIENT "MQTT Клієнт ID"
#define D_MQTT_USER "MQTT Користувач"
#define D_MQTT_TOPIC "MQTT Топік"
#define D_MQTT_GROUP_TOPIC "MQTT Топік групи"
#define D_MQTT_FULL_TOPIC "MQTT Топік повний"
#define D_MDNS_DISCOVERY "mDNS Виявлення"
#define D_MDNS_ADVERTISE "mDNS Транcляція"
#define D_ESP_CHIP_ID "ID чипу ESP"
#define D_FLASH_CHIP_ID "ID чипу Flash пам'яті"
#define D_FLASH_CHIP_SIZE "Розмір Flash пам'яті"
#define D_FREE_PROGRAM_SPACE "Вільний простір програм"
#define D_UPGRADE_BY_WEBSERVER "Оновлення через Веб-сервер"
#define D_OTA_URL "OTA Url"
#define D_START_UPGRADE "Почати оновлення"
#define D_UPGRADE_BY_FILE_UPLOAD "Оновлення шляхом завантаження файлів"
#define D_UPLOAD_STARTED "Завантаження почалось"
#define D_UPGRADE_STARTED "Оновлення почалось"
#define D_UPLOAD_DONE "Завантаження завершено"
#define D_UPLOAD_ERR_1 "Файл не вибраний"
#define D_UPLOAD_ERR_2 "Недостатньо місця"
#define D_UPLOAD_ERR_3 "Magic байт не 0xE9"
#define D_UPLOAD_ERR_4 "Размір прошивки більше, чим реальний размір флеш пам'яті"
#define D_UPLOAD_ERR_5 "Помилка завантаження буферу"
#define D_UPLOAD_ERR_6 "Помилка завантаження. Увімкнено лог рівень 3"
#define D_UPLOAD_ERR_7 "Завантаження перервано"
#define D_UPLOAD_ERR_8 "Файл невірний"
#define D_UPLOAD_ERR_9 "Занадто великий файл"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "Код помилки завантаження"
#define D_ENTER_COMMAND "Уведіть команду"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Увімкніть Веб лог рівня 2 якщо очікуєте відповідь"
#define D_NEED_USER_AND_PASSWORD "Очікується user=<username>&password=<password>"
// xdrv_01_mqtt.ino
#define D_FINGERPRINT "Перевірка TLS відбитка..."
#define D_TLS_CONNECT_FAILED_TO "Збій підключення TLS до"
#define D_RETRY_IN "Повторити"
#define D_VERIFIED "Перевірено відбиток"
#define D_INSECURE "Небезпечне з'єднання, недійсний відбиток "
#define D_CONNECT_FAILED_TO "Помилка підключення до"
// xplg_wemohue.ino
#define D_MULTICAST_DISABLED "Multicast вимкнений"
#define D_MULTICAST_REJOINED "Multicast (пере)під'єднався"
#define D_MULTICAST_JOIN_FAILED "Multicast помилка з'єднання"
#define D_FAILED_TO_SEND_RESPONSE "Не вдалось відправити відповідь"
#define D_WEMO "WeMo"
#define D_WEMO_BASIC_EVENT "WeMo основна подія"
#define D_WEMO_EVENT_SERVICE "WeMo служба подій"
#define D_WEMO_META_SERVICE "WeMo мета-сервіс"
#define D_WEMO_SETUP "WeMo налаштування"
#define D_RESPONSE_SENT "Відповідь відправлена"
#define D_HUE "Hue"
#define D_HUE_BRIDGE_SETUP "Hue налаштування"
#define D_HUE_API_NOT_IMPLEMENTED "Hue API не реалізовано"
#define D_HUE_API "Hue API"
#define D_HUE_POST_ARGS "Hue POST args"
#define D_3_RESPONSE_PACKETS_SENT "3 пакету відповіді отримано"
// xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz налаштування"
#define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Ключ idx"
#define D_DOMOTICZ_SWITCH_IDX "Перемикач idx"
#define D_DOMOTICZ_SENSOR_IDX "Датчик idx"
#define D_DOMOTICZ_TEMP "Температура"
#define D_DOMOTICZ_TEMP_HUM "Темп,Волог"
#define D_DOMOTICZ_TEMP_HUM_BARO "Темп,Волог,Тиск"
#define D_DOMOTICZ_POWER_ENERGY "Потуж,Енергія"
#define D_DOMOTICZ_ILLUMINANCE "Освітлення"
#define D_DOMOTICZ_COUNT "Лічильник/PM1"
#define D_DOMOTICZ_VOLTAGE "Напруга/PM2,5"
#define D_DOMOTICZ_CURRENT "Струм/PM10"
#define D_DOMOTICZ_AIRQUALITY "Якість повітря"
#define D_DOMOTICZ_UPDATE_TIMER "Оновлення таймерів"
// xdrv_09_timers.ino
#define D_CONFIGURE_TIMER "Конфігурація таймеру"
#define D_TIMER_PARAMETERS "Налаштування таймеру"
#define D_TIMER_ARM "Увімкнений"
#define D_TIMER_TIME "Час"
#define D_TIMER_DAYS "Дні"
#define D_TIMER_REPEAT "Повтор"
#define D_TIMER_OUTPUT "Вихід"
#define D_TIMER_ACTION "Дія"
// xdrv_10_knx.ino
#define D_CONFIGURE_KNX "Конфігурація KNX"
#define D_KNX_PARAMETERS "Налаштування KNX"
#define D_KNX_GENERAL_CONFIG "Основні"
#define D_KNX_PHYSICAL_ADDRESS "Фізична адреса"
#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Має бути унікальним у мережі KNX)"
#define D_KNX_ENABLE "Увімкнений KNX"
#define D_KNX_GROUP_ADDRESS_TO_WRITE "Дані для запису групових адрес"
#define D_ADD "Додати"
#define D_DELETE "Видалити"
#define D_REPLY "Повторити"
#define D_KNX_GROUP_ADDRESS_TO_READ "Дані для читання групових адрес"
#define D_LOG_KNX "KNX: "
#define D_RECEIVED_FROM "Отримати з"
#define D_KNX_COMMAND_WRITE "Записати"
#define D_KNX_COMMAND_READ "Читати"
#define D_KNX_COMMAND_OTHER "Інше"
#define D_SENT_TO "надіслати до"
#define D_KNX_WARNING "Адреса групи (0/0/0) зарезервована і не може бути використана."
#define D_KNX_ENHANCEMENT "Підвищення зв'язку"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Енергія Сьогодні"
#define D_ENERGY_YESTERDAY "Енергія Вчора"
#define D_ENERGY_TOTAL "Енергія Всього"
// xsns_05_ds18b20.ino
#define D_SENSOR_BUSY "Датчик DS18x20 занятий"
#define D_SENSOR_CRC_ERROR "Датчик DS18x20 - помилка CRC"
#define D_SENSORS_FOUND "Датчик DS18x20 знайдено"
// xsns_06_dht.ino
#define D_TIMEOUT_WAITING_FOR "Тайм-аут, в очікуванні"
#define D_START_SIGNAL_LOW "стартовий сигнал низький"
#define D_START_SIGNAL_HIGH "стартовий сигнал високий"
#define D_PULSE "імпульс"
#define D_CHECKSUM_FAILURE "Помилка контрольної суми"
// xsns_07_sht1x.ino
#define D_SENSOR_DID_NOT_ACK_COMMAND "Датчик не отримав команду ACK"
#define D_SHT1X_FOUND "SHT1X знайдено"
// xsns_18_pms5003.ino
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
#define D_PARTICALS_BEYOND "Через Частини"
// sonoff_template.h
#define D_SENSOR_NONE "-відсутньо-"
#define D_SENSOR_DHT11 "DHT11"
#define D_SENSOR_AM2301 "AM2301"
#define D_SENSOR_SI7021 "SI7021"
#define D_SENSOR_DS18X20 "DS18x20"
#define D_SENSOR_I2C_SCL "I2C SCL"
#define D_SENSOR_I2C_SDA "I2C SDA"
#define D_SENSOR_WS2812 "WS2812"
#define D_SENSOR_IRSEND "IRsend"
#define D_SENSOR_SWITCH "Перемикач" // Suffix "1"
#define D_SENSOR_BUTTON "Кнопка" // Suffix "1"
#define D_SENSOR_RELAY "Реле" // Suffix "1i"
#define D_SENSOR_LED "Led" // Suffix "1i"
#define D_SENSOR_PWM "PWM" // Suffix "1"
#define D_SENSOR_COUNTER "Лічильник" // Suffix "1"
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_PZEM_RX "PZEM Rx"
#define D_SENSOR_PZEM_TX "PZEM Tx"
#define D_SENSOR_SAIR_RX "SAir Rx"
#define D_SENSOR_SAIR_TX "SAir Tx"
#define D_SENSOR_SPI_CS "SPI CS"
#define D_SENSOR_SPI_DC "SPI DC"
#define D_SENSOR_BACKLIGHT "BkLight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_SDS0X1 "SDS0X1"
#define D_SENSOR_SBR_RX "SerBr Rx"
#define D_SENSOR_SBR_TX "SerBr Tx"
#define D_SENSOR_SR04_TRIG "SR04 Tri"
#define D_SENSOR_SR04_ECHO "SR04 Ech"
#define D_SENSOR_SDM120_TX "SDM120 Tx"
#define D_SENSOR_SDM120_RX "SDM120 Rx"
#define D_SENSOR_SDM630_TX "SDM630 Tx"
#define D_SENSOR_SDM630_RX "SDM630 Rx"
// Units
#define D_UNIT_AMPERE "А"
#define D_UNIT_CENTIMETER "cм"
#define D_UNIT_HERTZ "Гц"
#define D_UNIT_HOUR "Г"
#define D_UNIT_KILOOHM "кОм"
#define D_UNIT_KILOWATTHOUR "кВт"
#define D_UNIT_LUX "лк"
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "мкг/м3"
#define D_UNIT_MICROMETER "мкм"
#define D_UNIT_MICROSECOND "мкс"
#define D_UNIT_MILLIAMPERE "мА"
#define D_UNIT_MILLISECOND "мс"
#define D_UNIT_MINUTE "хв"
#define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_PRESSURE "гПа"
#define D_UNIT_SECOND "сек"
#define D_UNIT_SECTORS "секторів"
#define D_UNIT_VA "ВA"
#define D_UNIT_VAR "VAr"
#define D_UNIT_VOLT "В"
#define D_UNIT_WATT "Вт"
#define D_UNIT_WATTHOUR "ВтГод"
// Log message prefix
#define D_LOG_APPLICATION "APP: " // Application
#define D_LOG_BRIDGE "BRG: " // Bridge
#define D_LOG_CONFIG "CFG: " // Settings
#define D_LOG_COMMAND "CMD: " // Command
#define D_LOG_DEBUG "DBG: " // Debug
#define D_LOG_DHT "DHT: " // DHT sensor
#define D_LOG_DOMOTICZ "DOM: " // Domoticz
#define D_LOG_DSB "DSB: " // DS18xB20 sensor
#define D_LOG_HTTP "HTP: " // HTTP webserver
#define D_LOG_I2C "I2C: " // I2C
#define D_LOG_IRR "IRR: " // Infra Red Received
#define D_LOG_LOG "LOG: " // Logging
#define D_LOG_MODULE "MOD: " // Module
#define D_LOG_MDNS "DNS: " // mDNS
#define D_LOG_MQTT "MQT: " // MQTT
#define D_LOG_OTHER "OTH: " // Other
#define D_LOG_RESULT "RSL: " // Result
#define D_LOG_RFR "RFR: " // RF Received
#define D_LOG_SERIAL "SER: " // Serial
#define D_LOG_SHT1 "SHT: " // SHT1x sensor
#define D_LOG_UPLOAD "UPL: " // Upload
#define D_LOG_UPNP "UPP: " // UPnP
#define D_LOG_WIFI "WIF: " // Wifi
#endif // _LANGUAGE_UK_UK_H_

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "使用默认设置" #define D_USE_DEFAULTS "使用默认设置"
#define D_ERASED_SECTOR "擦除删除" #define D_ERASED_SECTOR "擦除删除"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "固件版本过低 - 请升级" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "固件版本过低 - 请升级"
#define D_WEBSERVER_ACTIVE_ON "Web服务器:" #define D_WEBSERVER_ACTIVE_ON "Web服务器:"
#define D_WITH_IP_ADDRESS "IP地址:" #define D_WITH_IP_ADDRESS "IP地址:"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "上传取消" #define D_UPLOAD_ERR_7 "上传取消"
#define D_UPLOAD_ERR_8 "错误的固件" #define D_UPLOAD_ERR_8 "错误的固件"
#define D_UPLOAD_ERR_9 "固件太大" #define D_UPLOAD_ERR_9 "固件太大"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "上传错误代码" #define D_UPLOAD_ERROR_CODE "上传错误代码"
#define D_ENTER_COMMAND "输入命令" #define D_ENTER_COMMAND "输入命令"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "如果预期响应则启用Weblog 2" #define D_ENABLE_WEBLOG_FOR_RESPONSE "如果预期响应则启用Weblog 2"
#define D_NEED_USER_AND_PASSWORD "需要 user=<用户名>&password=<密码>" #define D_NEED_USER_AND_PASSWORD "需要 user=<用户名>&password=<密码>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "验证 TLS 指纹..." #define D_FINGERPRINT "验证 TLS 指纹..."
#define D_TLS_CONNECT_FAILED_TO "TLS 连接失败" #define D_TLS_CONNECT_FAILED_TO "TLS 连接失败"
#define D_RETRY_IN "重试倒计时:" #define D_RETRY_IN "重试倒计时:"
@ -335,7 +339,7 @@
#define D_INSECURE "指纹无效导致连接不安全" #define D_INSECURE "指纹无效导致连接不安全"
#define D_CONNECT_FAILED_TO "连接失败:" #define D_CONNECT_FAILED_TO "连接失败:"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "组播已禁用" #define D_MULTICAST_DISABLED "组播已禁用"
#define D_MULTICAST_REJOINED "组播已(重新)加入" #define D_MULTICAST_REJOINED "组播已(重新)加入"
#define D_MULTICAST_JOIN_FAILED "组播加入失败" #define D_MULTICAST_JOIN_FAILED "组播加入失败"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST 参数" #define D_HUE_POST_ARGS "Hue POST 参数"
#define D_3_RESPONSE_PACKETS_SENT "3 请求包发送" #define D_3_RESPONSE_PACKETS_SENT "3 请求包发送"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz 设置" #define D_DOMOTICZ_PARAMETERS "Domoticz 设置"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "sent to" #define D_SENT_TO "sent to"
#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." #define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用电量" #define D_ENERGY_TODAY "今日用电量"

View File

@ -205,7 +205,7 @@
#define D_USE_DEFAULTS "使用默認設置" #define D_USE_DEFAULTS "使用默認設置"
#define D_ERASED_SECTOR "擦除刪除" #define D_ERASED_SECTOR "擦除刪除"
// webserver.ino // xdrv_02_webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "固件版本過低 - 請升級" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "固件版本過低 - 請升級"
#define D_WEBSERVER_ACTIVE_ON "Web服務器:" #define D_WEBSERVER_ACTIVE_ON "Web服務器:"
#define D_WITH_IP_ADDRESS "IP地址:" #define D_WITH_IP_ADDRESS "IP地址:"
@ -321,13 +321,17 @@
#define D_UPLOAD_ERR_7 "上傳取消" #define D_UPLOAD_ERR_7 "上傳取消"
#define D_UPLOAD_ERR_8 "錯誤的固件" #define D_UPLOAD_ERR_8 "錯誤的固件"
#define D_UPLOAD_ERR_9 "固件太大" #define D_UPLOAD_ERR_9 "固件太大"
#define D_UPLOAD_ERR_10 "Failed to init RF chip"
#define D_UPLOAD_ERR_11 "Failed to erase RF chip"
#define D_UPLOAD_ERR_12 "Failed to write to RF chip"
#define D_UPLOAD_ERR_13 "Failed to decode RF firmware"
#define D_UPLOAD_ERROR_CODE "上傳錯誤代碼" #define D_UPLOAD_ERROR_CODE "上傳錯誤代碼"
#define D_ENTER_COMMAND "輸入命令" #define D_ENTER_COMMAND "輸入命令"
#define D_ENABLE_WEBLOG_FOR_RESPONSE "如果預期響應則啟用Weblog 2" #define D_ENABLE_WEBLOG_FOR_RESPONSE "如果預期響應則啟用Weblog 2"
#define D_NEED_USER_AND_PASSWORD "需要 user=<用戶名>&password=<密碼>" #define D_NEED_USER_AND_PASSWORD "需要 user=<用戶名>&password=<密碼>"
// xdrv_00_mqtt.ino // xdrv_01_mqtt.ino
#define D_FINGERPRINT "驗證 TLS 指紋..." #define D_FINGERPRINT "驗證 TLS 指紋..."
#define D_TLS_CONNECT_FAILED_TO "TLS 連接失敗" #define D_TLS_CONNECT_FAILED_TO "TLS 連接失敗"
#define D_RETRY_IN "重試倒計時:" #define D_RETRY_IN "重試倒計時:"
@ -335,7 +339,7 @@
#define D_INSECURE "指紋無效導致連接不安全" #define D_INSECURE "指紋無效導致連接不安全"
#define D_CONNECT_FAILED_TO "連接失敗:" #define D_CONNECT_FAILED_TO "連接失敗:"
// xdrv_wemohue.ino // xplg_wemohue.ino
#define D_MULTICAST_DISABLED "組播已禁用" #define D_MULTICAST_DISABLED "組播已禁用"
#define D_MULTICAST_REJOINED "組播已(重新)加入" #define D_MULTICAST_REJOINED "組播已(重新)加入"
#define D_MULTICAST_JOIN_FAILED "組播加入失敗" #define D_MULTICAST_JOIN_FAILED "組播加入失敗"
@ -355,7 +359,7 @@
#define D_HUE_POST_ARGS "Hue POST 參數" #define D_HUE_POST_ARGS "Hue POST 參數"
#define D_3_RESPONSE_PACKETS_SENT "3 請求包發送" #define D_3_RESPONSE_PACKETS_SENT "3 請求包發送"
// xdrv_05_domoticz.ino // xdrv_07_domoticz.ino
#define D_DOMOTICZ_PARAMETERS "Domoticz 設置" #define D_DOMOTICZ_PARAMETERS "Domoticz 設置"
#define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_IDX "Idx"
#define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_KEY_IDX "Key idx"
@ -402,6 +406,8 @@
#define D_SENT_TO "sent to" #define D_SENT_TO "sent to"
#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." #define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used."
#define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_ENHANCEMENT "Communication Enhancement"
#define D_KNX_TX_SLOT "KNX TX"
#define D_KNX_RX_SLOT "KNX RX"
// xdrv_03_energy.ino // xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用電量" #define D_ENERGY_TODAY "今日用電量"

View File

@ -48,8 +48,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t not_power_linked : 1; // bit 20 (v5.11.1f) uint32_t not_power_linked : 1; // bit 20 (v5.11.1f)
uint32_t no_power_on_check : 1; // bit 21 (v5.11.1i) uint32_t no_power_on_check : 1; // bit 21 (v5.11.1i)
uint32_t mqtt_serial : 1; // bit 22 (v5.12.0f) uint32_t mqtt_serial : 1; // bit 22 (v5.12.0f)
uint32_t rules_enabled : 1; // bit 23 (v5.12.0j) uint32_t rules_enabled : 1; // bit 23 (v5.12.0j) - free since v5.14.0b
uint32_t rules_once : 1; // bit 24 (v5.12.0k) uint32_t rules_once : 1; // bit 24 (v5.12.0k) - free since v5.14.0b
uint32_t knx_enabled : 1; // bit 25 (v5.12.0l) KNX uint32_t knx_enabled : 1; // bit 25 (v5.12.0l) KNX
uint32_t device_index_enable : 1; // bit 26 (v5.13.1a) uint32_t device_index_enable : 1; // bit 26 (v5.13.1a)
uint32_t knx_enable_enhancement : 1; // bit 27 (v5.14.0a) KNX uint32_t knx_enable_enhancement : 1; // bit 27 (v5.14.0a) KNX
@ -114,12 +114,21 @@ typedef union {
}; };
} Timer; } Timer;
/*
struct SYSCFG { struct SYSCFG {
unsigned long cfg_holder; // 000 unsigned long cfg_holder; // 000 Pre v6 header
unsigned long save_flag; // 004 unsigned long save_flag; // 004
unsigned long version; // 008 unsigned long version; // 008
unsigned long bootcount; // 00C unsigned long bootcount; // 00C
SysBitfield flag; // 010 Add flag since 5.0.2 */
struct SYSCFG {
uint16_t cfg_holder; // 000 v6 header
uint16_t cfg_size; // 002
unsigned long save_flag; // 004
unsigned long version; // 008
uint16_t bootcount; // 00C
uint16_t cfg_crc; // 00E
SysBitfield flag; // 010
int16_t save_data; // 014 int16_t save_data; // 014
int8_t timezone; // 016 int8_t timezone; // 016
char ota_url[101]; // 017 char ota_url[101]; // 017
@ -163,11 +172,13 @@ struct SYSCFG {
uint16_t pwm_frequency; // 2E6 uint16_t pwm_frequency; // 2E6
power_t power; // 2E8 power_t power; // 2E8
uint16_t pwm_value[MAX_PWMS]; // 2EC uint16_t pwm_value[MAX_PWMS]; // 2EC
int16_t altitude; // 2F6 Add since 5.8.0i int16_t altitude; // 2F6
uint16_t tele_period; // 2F8 uint16_t tele_period; // 2F8
uint8_t ex_power; // 2FA Not used since 5.8.0j
byte free_2fa[1]; // 2FA
uint8_t ledstate; // 2FB uint8_t ledstate; // 2FB
uint8_t param[PARAM8_SIZE]; // 2FC was domoticz_in_topic until 5.1.6 uint8_t param[PARAM8_SIZE]; // 2FC
int16_t toffset[2]; // 30E int16_t toffset[2]; // 30E
byte free_312[1]; // 312 byte free_312[1]; // 312
@ -204,19 +215,9 @@ struct SYSCFG {
uint16_t blinktime; // 39A uint16_t blinktime; // 39A
uint16_t blinkcount; // 39C uint16_t blinkcount; // 39C
uint16_t light_rotation; // 39E uint16_t light_rotation; // 39E
uint8_t ws_red; // 3A0 Not used since 5.8.0
uint8_t ws_green; // 3A1 Not used since 5.8.0
uint8_t ws_blue; // 3A2 Not used since 5.8.0
uint8_t ws_ledtable; // 3A3 Not used since 5.8.0
uint8_t ws_dimmer; // 3A4 Not used since 5.8.0
uint8_t ws_fade; // 3A5 Not used since 5.8.0
uint8_t ws_speed; // 3A6 Not used since 5.8.0
uint8_t ws_scheme; // 3A7 Not used since 5.8.0
uint8_t ex_ws_width; // 3A8 Not used since 5.8.0
byte free_3A9[1]; // 3A9 byte free_3A0[12]; // 3A9
uint16_t ws_wakeup; // 3AA Not used since 5.8.0
char friendlyname[MAX_FRIENDLYNAMES][33]; // 3AC char friendlyname[MAX_FRIENDLYNAMES][33]; // 3AC
char switch_topic[33]; // 430 char switch_topic[33]; // 430
char serial_delimiter; // 451 char serial_delimiter; // 451
@ -232,9 +233,8 @@ struct SYSCFG {
uint8_t light_color[5]; // 498 uint8_t light_color[5]; // 498
uint8_t light_correction; // 49D uint8_t light_correction; // 49D
uint8_t light_dimmer; // 49E uint8_t light_dimmer; // 49E
uint8_t rule_enabled; // 49F
byte free_49F[2]; // 49F uint8_t rule_once; // 4A0
uint8_t light_fade; // 4A1 uint8_t light_fade; // 4A1
uint8_t light_speed; // 4A2 uint8_t light_speed; // 4A2
uint8_t light_scheme; // 4A3 uint8_t light_scheme; // 4A3
@ -251,9 +251,9 @@ struct SYSCFG {
byte free_542[2]; // 542 byte free_542[2]; // 542
uint32_t ip_address[4]; // 544 uint32_t ip_address[4]; // 544
unsigned long energy_kWhtotal; // 554 unsigned long energy_kWhtotal; // 554
char mqtt_fulltopic[100]; // 558 char mqtt_fulltopic[100]; // 558
SysBitfield2 flag2; // 5BC Add flag2 since 5.9.2 SysBitfield2 flag2; // 5BC
unsigned long pulse_counter[MAX_COUNTERS]; // 5C0 unsigned long pulse_counter[MAX_COUNTERS]; // 5C0
uint16_t pulse_counter_type; // 5D0 uint16_t pulse_counter_type; // 5D0
uint16_t pulse_counter_debounce; // 5D2 uint16_t pulse_counter_debounce; // 5D2
@ -274,9 +274,11 @@ struct SYSCFG {
byte free_6f6[216]; // 6F6 byte free_6f6[216]; // 6F6
char mems[RULES_MAX_MEMS][10]; // 7CE char mems[RULES_MAX_MEMS][10]; // 7CE
char rules[MAX_RULE_SIZE]; // 800 uses 512 bytes in v5.12.0m // 800 Full - no more free locations
// A00 - FFF free locations char rules[MAX_RULE_SETS][MAX_RULE_SIZE]; // 800 uses 512 bytes in v5.12.0m, 3 x 512 bytes in v5.14.0b
// E00 - FFF free locations
} Settings; } Settings;
struct RTCMEM { struct RTCMEM {

View File

@ -67,25 +67,25 @@
#define RTC_MEM_VALID 0xA55A #define RTC_MEM_VALID 0xA55A
uint32_t rtc_settings_hash = 0; uint32_t rtc_settings_crc = 0;
uint32_t GetRtcSettingsHash() uint32_t GetRtcSettingsCrc()
{ {
uint32_t hash = 0; uint32_t crc = 0;
uint8_t *bytes = (uint8_t*)&RtcSettings; uint8_t *bytes = (uint8_t*)&RtcSettings;
for (uint16_t i = 0; i < sizeof(RTCMEM); i++) { for (uint16_t i = 0; i < sizeof(RTCMEM); i++) {
hash += bytes[i]*(i+1); crc += bytes[i]*(i+1);
} }
return hash; return crc;
} }
void RtcSettingsSave() void RtcSettingsSave()
{ {
if (GetRtcSettingsHash() != rtc_settings_hash) { if (GetRtcSettingsCrc() != rtc_settings_crc) {
RtcSettings.valid = RTC_MEM_VALID; RtcSettings.valid = RTC_MEM_VALID;
ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
rtc_settings_hash = GetRtcSettingsHash(); rtc_settings_crc = GetRtcSettingsCrc();
#ifdef DEBUG_THEO #ifdef DEBUG_THEO
AddLog_P(LOG_LEVEL_DEBUG, PSTR("Dump: Save")); AddLog_P(LOG_LEVEL_DEBUG, PSTR("Dump: Save"));
RtcSettingsDump(); RtcSettingsDump();
@ -111,7 +111,7 @@ void RtcSettingsLoad()
RtcSettings.power = Settings.power; RtcSettings.power = Settings.power;
RtcSettingsSave(); RtcSettingsSave();
} }
rtc_settings_hash = GetRtcSettingsHash(); rtc_settings_crc = GetRtcSettingsCrc();
} }
boolean RtcSettingsValid() boolean RtcSettingsValid()
@ -133,16 +133,14 @@ extern "C" uint32_t _SPIFFS_end;
// From libraries/EEPROM/EEPROM.cpp EEPROMClass // From libraries/EEPROM/EEPROM.cpp EEPROMClass
#define SPIFFS_END ((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE #define SPIFFS_END ((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE
// Version 3.x config
#define SETTINGS_LOCATION_3 SPIFFS_END - 4
// Version 4.2 config = eeprom area // Version 4.2 config = eeprom area
#define SETTINGS_LOCATION SPIFFS_END // No need for SPIFFS as it uses EEPROM area #define SETTINGS_LOCATION SPIFFS_END // No need for SPIFFS as it uses EEPROM area
// Version 5.2 allow for more flash space // Version 5.2 allow for more flash space
#define CFG_ROTATES 8 // Number of flash sectors used (handles uploads) #define CFG_ROTATES 8 // Number of flash sectors used (handles uploads)
uint32_t settings_hash = 0; uint16_t settings_crc = 0;
uint32_t settings_location = SETTINGS_LOCATION; uint32_t settings_location = SETTINGS_LOCATION;
uint8_t *settings_buffer = NULL;
/********************************************************************************************/ /********************************************************************************************/
/* /*
@ -167,15 +165,33 @@ void SetFlashModeDout()
delete[] _buffer; delete[] _buffer;
} }
uint32_t GetSettingsHash() void SettingsBufferFree()
{ {
uint32_t hash = 0; if (settings_buffer != NULL) {
free(settings_buffer);
settings_buffer = NULL;
}
}
bool SettingsBufferAlloc()
{
SettingsBufferFree();
if (!(settings_buffer = (uint8_t *)malloc(sizeof(Settings)))) {
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_UPLOAD_ERR_2)); // Not enough (memory) space
return false;
}
return true;
}
uint16_t GetSettingsCrc()
{
uint16_t crc = 0;
uint8_t *bytes = (uint8_t*)&Settings; uint8_t *bytes = (uint8_t*)&Settings;
for (uint16_t i = 0; i < sizeof(SYSCFG); i++) { for (uint16_t i = 0; i < sizeof(SYSCFG); i++) {
hash += bytes[i]*(i+1); if ((i < 14) || (i > 15)) { crc += bytes[i]*(i+1); } // Skip crc
} }
return hash; return crc;
} }
void SettingsSaveAll() void SettingsSaveAll()
@ -209,7 +225,7 @@ void SettingsSave(byte rotate)
* stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1) * stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1)
*/ */
#ifndef BE_MINIMAL #ifndef BE_MINIMAL
if ((GetSettingsHash() != settings_hash) || rotate) { if ((GetSettingsCrc() != settings_crc) || rotate) {
if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade) if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade)
stop_flash_rotate = 1; stop_flash_rotate = 1;
} }
@ -225,6 +241,8 @@ void SettingsSave(byte rotate)
} }
} }
Settings.save_flag++; Settings.save_flag++;
Settings.cfg_size = sizeof(SYSCFG);
Settings.cfg_crc = GetSettingsCrc();
ESP.flashEraseSector(settings_location); ESP.flashEraseSector(settings_location);
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
if (!stop_flash_rotate && rotate) { if (!stop_flash_rotate && rotate) {
@ -236,7 +254,8 @@ void SettingsSave(byte rotate)
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"),
settings_location, Settings.save_flag, sizeof(SYSCFG)); settings_location, Settings.save_flag, sizeof(SYSCFG));
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
settings_hash = GetSettingsHash();
settings_crc = Settings.cfg_crc;
} }
#endif // BE_MINIMAL #endif // BE_MINIMAL
RtcSettingsSave(); RtcSettingsSave();
@ -247,36 +266,28 @@ void SettingsLoad()
/* Load configuration from eeprom or one of 7 slots below if first load does not stop_flash_rotate /* Load configuration from eeprom or one of 7 slots below if first load does not stop_flash_rotate
*/ */
struct SYSCFGH { struct SYSCFGH {
unsigned long cfg_holder; uint16_t cfg_holder; // 000
unsigned long save_flag; uint16_t cfg_size; // 002
unsigned long save_flag; // 004
} _SettingsH; } _SettingsH;
bool bad_crc = false;
settings_location = SETTINGS_LOCATION +1; settings_location = SETTINGS_LOCATION +1;
for (byte i = 0; i < CFG_ROTATES; i++) { for (byte i = 0; i < CFG_ROTATES; i++) {
settings_location--; settings_location--;
ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
ESP.flashRead((settings_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH)); ESP.flashRead((settings_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
if (Settings.version > 0x06000000) { bad_crc = (Settings.cfg_crc != GetSettingsCrc()); }
// snprintf_P(log_data, sizeof(log_data), PSTR("Cnfg: Check at %X with count %d and holder %X"), settings_location -1, _SettingsH.save_flag, _SettingsH.cfg_holder); if (Settings.flag.stop_flash_rotate || bad_crc || (Settings.cfg_holder != _SettingsH.cfg_holder) || (Settings.save_flag > _SettingsH.save_flag)) {
// AddLog(LOG_LEVEL_DEBUG);
if (((Settings.version > 0x05000200) && Settings.flag.stop_flash_rotate) || (Settings.cfg_holder != _SettingsH.cfg_holder) || (Settings.save_flag > _SettingsH.save_flag)) {
break; break;
} }
delay(1); delay(1);
} }
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %d"), snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %d"), settings_location, Settings.save_flag);
settings_location, Settings.save_flag);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
if (Settings.cfg_holder != CFG_HOLDER) {
// Auto upgrade
ESP.flashRead((SETTINGS_LOCATION_3) * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
ESP.flashRead((SETTINGS_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
if (Settings.save_flag < _SettingsH.save_flag) ESP.flashRead((SETTINGS_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
if ((Settings.cfg_holder != CFG_HOLDER) || (Settings.version >= 0x04020000)) SettingsDefault();
}
settings_hash = GetSettingsHash(); if (bad_crc || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { SettingsDefault(); }
settings_crc = GetSettingsCrc();
RtcSettingsLoad(); RtcSettingsLoad();
} }
@ -353,50 +364,110 @@ void SettingsDefaultSet1()
{ {
memset(&Settings, 0x00, sizeof(SYSCFG)); memset(&Settings, 0x00, sizeof(SYSCFG));
Settings.cfg_holder = CFG_HOLDER; Settings.cfg_holder = (uint16_t)CFG_HOLDER;
Settings.cfg_size = sizeof(SYSCFG);
// Settings.save_flag = 0; // Settings.save_flag = 0;
Settings.version = VERSION; Settings.version = VERSION;
// Settings.bootcount = 0; // Settings.bootcount = 0;
// Settings.cfg_crc = 0;
} }
void SettingsDefaultSet2() void SettingsDefaultSet2()
{ {
memset((char*)&Settings +16, 0x00, sizeof(SYSCFG) -16); memset((char*)&Settings +16, 0x00, sizeof(SYSCFG) -16);
Settings.flag.save_state = SAVE_STATE; // Settings.flag.value_units = 0;
//Settings.flag.button_restrict = 0; // Settings.flag.stop_flash_rotate = 0;
//Settings.flag.value_units = 0;
Settings.flag.mqtt_enabled = MQTT_USE;
//Settings.flag.mqtt_response = 0;
Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN;
Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
Settings.flag.pwm_control = 1;
Settings.flag.hass_discovery = HOME_ASSISTANT_DISCOVERY_ENABLE;
Settings.flag2.emulation = EMULATION;
Settings.save_data = SAVE_DATA; Settings.save_data = SAVE_DATA;
Settings.timezone = APP_TIMEZONE; Settings.sleep = APP_SLEEP;
// Module
// Settings.flag.interlock = 0;
Settings.module = MODULE;
// for (byte i = 0; i < MAX_GPIO_PIN; i++) { Settings.my_gp.io[i] = 0; }
strlcpy(Settings.friendlyname[0], FRIENDLY_NAME, sizeof(Settings.friendlyname[0]));
strlcpy(Settings.friendlyname[1], FRIENDLY_NAME"2", sizeof(Settings.friendlyname[1]));
strlcpy(Settings.friendlyname[2], FRIENDLY_NAME"3", sizeof(Settings.friendlyname[2]));
strlcpy(Settings.friendlyname[3], FRIENDLY_NAME"4", sizeof(Settings.friendlyname[3]));
strlcpy(Settings.ota_url, OTA_URL, sizeof(Settings.ota_url)); strlcpy(Settings.ota_url, OTA_URL, sizeof(Settings.ota_url));
// Power
Settings.flag.save_state = SAVE_STATE;
Settings.power = APP_POWER;
Settings.poweronstate = APP_POWERON_STATE;
Settings.blinktime = APP_BLINKTIME;
Settings.blinkcount = APP_BLINKCOUNT;
Settings.ledstate = APP_LEDSTATE;
Settings.pulse_timer[0] = APP_PULSETIME;
// for (byte i = 1; i < MAX_PULSETIMERS; i++) { Settings.pulse_timer[i] = 0; }
// Serial
Settings.baudrate = APP_BAUDRATE / 1200; Settings.baudrate = APP_BAUDRATE / 1200;
Settings.sbaudrate = SOFT_BAUDRATE / 1200; Settings.sbaudrate = SOFT_BAUDRATE / 1200;
Settings.serial_delimiter = 0xff; Settings.serial_delimiter = 0xff;
Settings.seriallog_level = SERIAL_LOG_LEVEL; Settings.seriallog_level = SERIAL_LOG_LEVEL;
// Wifi
ParseIp(&Settings.ip_address[0], WIFI_IP_ADDRESS);
ParseIp(&Settings.ip_address[1], WIFI_GATEWAY);
ParseIp(&Settings.ip_address[2], WIFI_SUBNETMASK);
ParseIp(&Settings.ip_address[3], WIFI_DNS);
Settings.sta_config = WIFI_CONFIG_TOOL;
// Settings.sta_active = 0; // Settings.sta_active = 0;
strlcpy(Settings.sta_ssid[0], STA_SSID1, sizeof(Settings.sta_ssid[0])); strlcpy(Settings.sta_ssid[0], STA_SSID1, sizeof(Settings.sta_ssid[0]));
strlcpy(Settings.sta_pwd[0], STA_PASS1, sizeof(Settings.sta_pwd[0])); strlcpy(Settings.sta_pwd[0], STA_PASS1, sizeof(Settings.sta_pwd[0]));
strlcpy(Settings.sta_ssid[1], STA_SSID2, sizeof(Settings.sta_ssid[1])); strlcpy(Settings.sta_ssid[1], STA_SSID2, sizeof(Settings.sta_ssid[1]));
strlcpy(Settings.sta_pwd[1], STA_PASS2, sizeof(Settings.sta_pwd[1])); strlcpy(Settings.sta_pwd[1], STA_PASS2, sizeof(Settings.sta_pwd[1]));
strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname)); strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname));
Settings.sta_config = WIFI_CONFIG_TOOL;
// Syslog
strlcpy(Settings.syslog_host, SYS_LOG_HOST, sizeof(Settings.syslog_host)); strlcpy(Settings.syslog_host, SYS_LOG_HOST, sizeof(Settings.syslog_host));
Settings.syslog_port = SYS_LOG_PORT; Settings.syslog_port = SYS_LOG_PORT;
Settings.syslog_level = SYS_LOG_LEVEL; Settings.syslog_level = SYS_LOG_LEVEL;
// Webserver
Settings.flag2.emulation = EMULATION;
Settings.webserver = WEB_SERVER; Settings.webserver = WEB_SERVER;
Settings.weblog_level = WEB_LOG_LEVEL; Settings.weblog_level = WEB_LOG_LEVEL;
strlcpy(Settings.web_password, WEB_PASSWORD, sizeof(Settings.web_password));
// Button
// Settings.flag.button_restrict = 0;
// Settings.flag.button_swap = 0;
// Settings.flag.button_single = 0;
Settings.param[P_HOLD_TIME] = KEY_HOLD_TIME; // Default 4 seconds hold time
// Switch
for (byte i = 0; i < MAX_SWITCHES; i++) { Settings.switchmode[i] = SWITCH_MODE; }
// MQTT
Settings.flag.mqtt_enabled = MQTT_USE;
// Settings.flag.mqtt_response = 0;
Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN;
Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
// Settings.flag.mqtt_sensor_retain = 0;
// Settings.flag.mqtt_offline = 0;
// Settings.flag.mqtt_serial = 0;
// Settings.flag.device_index_enable = 0;
strlcpy(Settings.mqtt_host, MQTT_HOST, sizeof(Settings.mqtt_host));
Settings.mqtt_port = MQTT_PORT;
strlcpy(Settings.mqtt_client, MQTT_CLIENT_ID, sizeof(Settings.mqtt_client));
strlcpy(Settings.mqtt_user, MQTT_USER, sizeof(Settings.mqtt_user));
strlcpy(Settings.mqtt_pwd, MQTT_PASS, sizeof(Settings.mqtt_pwd));
strlcpy(Settings.mqtt_topic, MQTT_TOPIC, sizeof(Settings.mqtt_topic));
strlcpy(Settings.button_topic, "0", sizeof(Settings.button_topic));
strlcpy(Settings.switch_topic, "0", sizeof(Settings.switch_topic));
strlcpy(Settings.mqtt_grptopic, MQTT_GRPTOPIC, sizeof(Settings.mqtt_grptopic));
strlcpy(Settings.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(Settings.mqtt_fulltopic));
Settings.mqtt_retry = MQTT_RETRY_SECS;
strlcpy(Settings.mqtt_prefix[0], SUB_PREFIX, sizeof(Settings.mqtt_prefix[0]));
strlcpy(Settings.mqtt_prefix[1], PUB_PREFIX, sizeof(Settings.mqtt_prefix[1]));
strlcpy(Settings.mqtt_prefix[2], PUB_PREFIX2, sizeof(Settings.mqtt_prefix[2]));
strlcpy(Settings.state_text[0], MQTT_STATUS_OFF, sizeof(Settings.state_text[0]));
strlcpy(Settings.state_text[1], MQTT_STATUS_ON, sizeof(Settings.state_text[1]));
strlcpy(Settings.state_text[2], MQTT_CMND_TOGGLE, sizeof(Settings.state_text[2]));
strlcpy(Settings.state_text[3], MQTT_CMND_HOLD, sizeof(Settings.state_text[3]));
char fingerprint[60]; char fingerprint[60];
strlcpy(fingerprint, MQTT_FINGERPRINT1, sizeof(fingerprint)); strlcpy(fingerprint, MQTT_FINGERPRINT1, sizeof(fingerprint));
char *p = fingerprint; char *p = fingerprint;
@ -408,32 +479,14 @@ void SettingsDefaultSet2()
for (byte i = 0; i < 20; i++) { for (byte i = 0; i < 20; i++) {
Settings.mqtt_fingerprint[1][i] = strtol(p, &p, 16); Settings.mqtt_fingerprint[1][i] = strtol(p, &p, 16);
} }
strlcpy(Settings.mqtt_host, MQTT_HOST, sizeof(Settings.mqtt_host));
Settings.mqtt_port = MQTT_PORT;
strlcpy(Settings.mqtt_client, MQTT_CLIENT_ID, sizeof(Settings.mqtt_client));
strlcpy(Settings.mqtt_user, MQTT_USER, sizeof(Settings.mqtt_user));
strlcpy(Settings.mqtt_pwd, MQTT_PASS, sizeof(Settings.mqtt_pwd));
strlcpy(Settings.mqtt_topic, MQTT_TOPIC, sizeof(Settings.mqtt_topic));
strlcpy(Settings.button_topic, "0", sizeof(Settings.button_topic));
strlcpy(Settings.mqtt_grptopic, MQTT_GRPTOPIC, sizeof(Settings.mqtt_grptopic));
Settings.tele_period = TELE_PERIOD; Settings.tele_period = TELE_PERIOD;
Settings.power = APP_POWER; // Energy
Settings.poweronstate = APP_POWERON_STATE; Settings.flag2.current_resolution = 3;
Settings.ledstate = APP_LEDSTATE; // Settings.flag2.voltage_resolution = 0;
Settings.blinktime = APP_BLINKTIME; // Settings.flag2.wattage_resolution = 0;
Settings.blinkcount = APP_BLINKCOUNT; Settings.flag2.energy_resolution = ENERGY_RESOLUTION;
Settings.sleep = APP_SLEEP; Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY;
Settings.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER;
for (byte i = 0; i < MAX_SWITCHES; i++) {
Settings.switchmode[i] = SWITCH_MODE;
// Settings.domoticz_relay_idx[i] = 0;
// Settings.domoticz_key_idx[i] = 0;
// Settings.domoticz_switch_idx[i] = 0;
}
Settings.energy_power_delta = DEFAULT_POWER_DELTA; Settings.energy_power_delta = DEFAULT_POWER_DELTA;
Settings.energy_power_calibration = HLW_PREF_PULSE; Settings.energy_power_calibration = HLW_PREF_PULSE;
Settings.energy_voltage_calibration = HLW_UREF_PULSE; Settings.energy_voltage_calibration = HLW_UREF_PULSE;
@ -455,122 +508,71 @@ void SettingsDefaultSet2()
Settings.energy_max_power_safe_limit_window = SAFE_POWER_WINDOW; Settings.energy_max_power_safe_limit_window = SAFE_POWER_WINDOW;
// Settings.energy_max_energy = 0; // MaxEnergy // Settings.energy_max_energy = 0; // MaxEnergy
// Settings.energy_max_energy_start = 0; // MaxEnergyStart // Settings.energy_max_energy_start = 0; // MaxEnergyStart
SettingsDefaultSet_3_2_4();
strlcpy(Settings.friendlyname[0], FRIENDLY_NAME, sizeof(Settings.friendlyname[0]));
strlcpy(Settings.friendlyname[1], FRIENDLY_NAME"2", sizeof(Settings.friendlyname[1]));
strlcpy(Settings.friendlyname[2], FRIENDLY_NAME"3", sizeof(Settings.friendlyname[2]));
strlcpy(Settings.friendlyname[3], FRIENDLY_NAME"4", sizeof(Settings.friendlyname[3]));
SettingsDefaultSet_3_9_3();
strlcpy(Settings.switch_topic, "0", sizeof(Settings.switch_topic));
strlcpy(Settings.web_password, WEB_PASSWORD, sizeof(Settings.web_password));
SettingsDefaultSet_4_0_4();
Settings.pulse_timer[0] = APP_PULSETIME;
// 4.0.7
// for (byte i = 0; i < MAX_PWMS; i++) Settings.pwm_value[i] = 0;
// 4.0.9
SettingsDefaultSet_4_0_9();
// 4.1.1 + 5.1.6
SettingsDefaultSet_4_1_1();
// 5.0.2
SettingsDefaultSet_5_0_2();
// 5.0.4
// Settings.energy_kWhtotal = 0; // Settings.energy_kWhtotal = 0;
RtcSettings.energy_kWhtotal = 0; RtcSettings.energy_kWhtotal = 0;
// 5.0.5 // RF Bridge
strlcpy(Settings.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(Settings.mqtt_fulltopic)); // for (byte i = 0; i < 17; i++) { Settings.rf_code[i][0] = 0; }
// 5.0.6
Settings.mqtt_retry = MQTT_RETRY_SECS;
// 5.1.7
Settings.param[P_HOLD_TIME] = KEY_HOLD_TIME; // Default 4 seconds hold time
// 5.2.0
Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY;
// 5.4.1
memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9); memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9);
// 5.8.0 // Domoticz
Settings.light_pixels = WS2812_LEDS; Settings.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER;
// Settings.light_rotation = 0; // for (byte i = 0; i < MAX_DOMOTICZ_IDX; i++) {
// Settings.domoticz_relay_idx[i] = 0;
// Settings.domoticz_key_idx[i] = 0;
// Settings.domoticz_switch_idx[i] = 0;
// }
// for (byte i = 0; i < MAX_DOMOTICZ_SNS_IDX; i++) {
// Settings.domoticz_sensor_idx[i] = 0;
// }
// 5.8.1 // Sensor
Settings.flag.temperature_conversion = TEMP_CONVERSION;
Settings.flag2.pressure_resolution = PRESSURE_RESOLUTION;
Settings.flag2.humidity_resolution = HUMIDITY_RESOLUTION;
Settings.flag2.temperature_resolution = TEMP_RESOLUTION;
// Settings.altitude = 0; // Settings.altitude = 0;
// Rules
// Settings.flag.rules_enabled = 0;
// Settings.flag.rules_once = 0;
// for (byte i = 1; i < MAX_RULE_SETS; i++) { Settings.rules[i][0] = '\0'; }
// Home Assistant
Settings.flag.hass_discovery = HOME_ASSISTANT_DISCOVERY_ENABLE;
// Knx
// Settings.flag.knx_enabled = 0;
// Settings.flag.knx_enable_enhancement = 0;
// Light
Settings.flag.pwm_control = 1;
//Settings.flag.ws_clock_reverse = 0;
//Settings.flag.light_signal = 0;
//Settings.flag.not_power_linked = 0;
//Settings.flag.decimal_text = 0;
Settings.pwm_frequency = PWM_FREQ; Settings.pwm_frequency = PWM_FREQ;
Settings.pwm_range = PWM_RANGE; Settings.pwm_range = PWM_RANGE;
SettingsDefaultSet_5_8_1();
// 5.9.2
Settings.flag2.current_resolution = 3;
// 5.10.1
SettingsDefaultSet_5_10_1();
Settings.latitude = (int)((double)LATITUDE * 1000000);
Settings.longitude = (int)((double)LONGITUDE * 1000000);
SettingsDefaultSet_5_13_1c();
}
/********************************************************************************************/
void SettingsDefaultSet_3_2_4()
{
Settings.ws_red = 255;
Settings.ws_green = 0;
Settings.ws_blue = 0;
Settings.ws_ledtable = 0;
Settings.ws_dimmer = 8;
Settings.ws_fade = 0;
Settings.ws_speed = 1;
Settings.ws_scheme = 0;
Settings.ex_ws_width = 1;
Settings.ws_wakeup = 0;
}
void SettingsDefaultSet_3_9_3()
{
for (byte i = 0; i < MAX_DOMOTICZ_IDX; i++) {
Settings.domoticz_switch_idx[i] = 0;
}
for (byte i = 0; i < 12; i++) {
Settings.domoticz_sensor_idx[i] = 0;
}
Settings.module = MODULE;
for (byte i = 0; i < MAX_GPIO_PIN; i++){
Settings.my_gp.io[i] = 0;
}
Settings.light_pixels = WS2812_LEDS;
Settings.light_rotation = 0;
for (byte i = 0; i < MAX_PWMS; i++) { for (byte i = 0; i < MAX_PWMS; i++) {
Settings.light_color[i] = 255; Settings.light_color[i] = 255;
// Settings.pwm_value[i] = 0;
} }
Settings.light_correction = 0; // Settings.light_correction = 0;
Settings.light_dimmer = 10; Settings.light_dimmer = 10;
Settings.light_fade = 0; // Settings.light_fade = 0;
Settings.light_speed = 1; Settings.light_speed = 1;
Settings.light_scheme = 0; // Settings.light_scheme = 0;
Settings.light_width = 1; Settings.light_width = 1;
Settings.light_wakeup = 0; // Settings.light_wakeup = 0;
} Settings.light_pixels = WS2812_LEDS;
// Settings.light_rotation = 0;
SettingsDefaultSet_5_8_1(); // Clock color
void SettingsDefaultSet_4_0_4() // Display
{ SettingsDefaultSet_5_10_1(); // Display settings
// Time
Settings.timezone = APP_TIMEZONE;
strlcpy(Settings.ntp_server[0], NTP_SERVER1, sizeof(Settings.ntp_server[0])); strlcpy(Settings.ntp_server[0], NTP_SERVER1, sizeof(Settings.ntp_server[0]));
strlcpy(Settings.ntp_server[1], NTP_SERVER2, sizeof(Settings.ntp_server[1])); strlcpy(Settings.ntp_server[1], NTP_SERVER2, sizeof(Settings.ntp_server[1]));
strlcpy(Settings.ntp_server[2], NTP_SERVER3, sizeof(Settings.ntp_server[2])); strlcpy(Settings.ntp_server[2], NTP_SERVER3, sizeof(Settings.ntp_server[2]));
@ -581,39 +583,12 @@ void SettingsDefaultSet_4_0_4()
} }
} }
} }
Settings.pulse_timer[0] = APP_PULSETIME; Settings.latitude = (int)((double)LATITUDE * 1000000);
for (byte i = 1; i < MAX_PULSETIMERS; i++) { Settings.longitude = (int)((double)LONGITUDE * 1000000);
Settings.pulse_timer[i] = 0; SettingsDefaultSet_5_13_1c(); // Time STD/DST settings
}
} }
void SettingsDefaultSet_4_0_9() /********************************************************************************************/
{
strlcpy(Settings.mqtt_prefix[0], SUB_PREFIX, sizeof(Settings.mqtt_prefix[0]));
strlcpy(Settings.mqtt_prefix[1], PUB_PREFIX, sizeof(Settings.mqtt_prefix[1]));
strlcpy(Settings.mqtt_prefix[2], PUB_PREFIX2, sizeof(Settings.mqtt_prefix[2]));
ParseIp(&Settings.ip_address[0], WIFI_IP_ADDRESS);
ParseIp(&Settings.ip_address[1], WIFI_GATEWAY);
ParseIp(&Settings.ip_address[2], WIFI_SUBNETMASK);
ParseIp(&Settings.ip_address[3], WIFI_DNS);
}
void SettingsDefaultSet_4_1_1()
{
strlcpy(Settings.state_text[0], MQTT_STATUS_OFF, sizeof(Settings.state_text[0]));
strlcpy(Settings.state_text[1], MQTT_STATUS_ON, sizeof(Settings.state_text[1]));
strlcpy(Settings.state_text[2], MQTT_CMND_TOGGLE, sizeof(Settings.state_text[2]));
strlcpy(Settings.state_text[3], MQTT_CMND_HOLD, sizeof(Settings.state_text[3])); // v5.1.6
}
void SettingsDefaultSet_5_0_2()
{
Settings.flag.temperature_conversion = TEMP_CONVERSION;
Settings.flag2.temperature_resolution = TEMP_RESOLUTION;
Settings.flag2.humidity_resolution = HUMIDITY_RESOLUTION;
Settings.flag2.pressure_resolution = PRESSURE_RESOLUTION;
Settings.flag2.energy_resolution = ENERGY_RESOLUTION;
}
void SettingsDefaultSet_5_8_1() void SettingsDefaultSet_5_8_1()
{ {
@ -685,132 +660,27 @@ void SettingsDefaultSet_5_13_1c()
void SettingsDelta() void SettingsDelta()
{ {
if (Settings.version != VERSION) { // Fix version dependent changes if (Settings.version != VERSION) { // Fix version dependent changes
if (Settings.version < 0x03010200) { // 3.1.2 - Add parameter
Settings.poweronstate = APP_POWERON_STATE;
}
if (Settings.version < 0x03010600) { // 3.1.6 - Add parameter
Settings.blinktime = APP_BLINKTIME;
Settings.blinkcount = APP_BLINKCOUNT;
}
if (Settings.version < 0x03020400) { // 3.2.4 - Add parameter
SettingsDefaultSet_3_2_4();
}
if (Settings.version < 0x03020500) { // 3.2.5 - Add parameter
Format(Settings.friendlyname[0], Settings.mqtt_client, sizeof(Settings.friendlyname[0]));
strlcpy(Settings.friendlyname[1], FRIENDLY_NAME"2", sizeof(Settings.friendlyname[1]));
strlcpy(Settings.friendlyname[2], FRIENDLY_NAME"3", sizeof(Settings.friendlyname[2]));
strlcpy(Settings.friendlyname[3], FRIENDLY_NAME"4", sizeof(Settings.friendlyname[3]));
}
if (Settings.version < 0x03020800) { // 3.2.8 - Add parameter
strlcpy(Settings.switch_topic, Settings.button_topic, sizeof(Settings.switch_topic));
}
if (Settings.version < 0x03020C00) { // 3.2.12 - Add parameter
Settings.sleep = APP_SLEEP;
}
if (Settings.version < 0x03090300) { // 3.9.2d - Add parameter
SettingsDefaultSet_3_9_3();
}
if (Settings.version < 0x03091400) {
strlcpy(Settings.web_password, WEB_PASSWORD, sizeof(Settings.web_password));
}
if (Settings.version < 0x03091500) {
for (byte i = 0; i < MAX_SWITCHES; i++) {
Settings.switchmode[i] = SWITCH_MODE;
}
}
if (Settings.version < 0x04000400) {
SettingsDefaultSet_4_0_4();
}
if (Settings.version < 0x04000500) {
memmove(Settings.my_gp.io, Settings.my_gp.io +1, MAX_GPIO_PIN -1); // move myio 1 byte to front
Settings.my_gp.io[MAX_GPIO_PIN -1] = 0; // Clear ADC0
}
if (Settings.version < 0x04000700) {
for (byte i = 0; i < MAX_PWMS; i++) {
Settings.pwm_value[i] = 0;
}
}
if (Settings.version < 0x04000804) {
SettingsDefaultSet_4_0_9();
}
if (Settings.version < 0x04010100) {
SettingsDefaultSet_4_1_1();
}
if (Settings.version < 0x05000105) {
Settings.flag = { 0 };
Settings.flag.save_state = SAVE_STATE;
// Settings.flag.button_restrict = 0;
// Settings.flag.value_units = 0;
Settings.flag.mqtt_enabled = MQTT_USE;
// Settings.flag.mqtt_response = 0;
// Settings.flag.mqtt_power_retain = 0;
// Settings.flag.mqtt_button_retain = 0;
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
Settings.flag2.emulation = EMULATION;
SettingsDefaultSet_5_0_2();
Settings.save_data = SAVE_DATA;
}
if (Settings.version < 0x05000400) {
Settings.energy_kWhtotal = 0;
RtcSettings.energy_kWhtotal = 0;
}
if (Settings.version < 0x05000500) {
strlcpy(Settings.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(Settings.mqtt_fulltopic));
}
if (Settings.version < 0x05000600) {
Settings.mqtt_retry = MQTT_RETRY_SECS;
}
if (Settings.version < 0x05010100) {
Settings.pulse_counter_type = 0;
Settings.pulse_counter_debounce = 0;
for (byte i = 0; i < MAX_COUNTERS; i++) {
Settings.pulse_counter[i] = 0;
RtcSettings.pulse_counter[i] = 0;
}
}
if (Settings.version < 0x05010600) {
SettingsDefaultSet_4_1_1();
}
if (Settings.version < 0x05010700) {
Settings.param[P_HOLD_TIME] = KEY_HOLD_TIME; // Default 4 seconds hold time
}
if (Settings.version < 0x05020000) {
Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY;
}
if (Settings.version < 0x05050000) { if (Settings.version < 0x05050000) {
for (byte i = 0; i < 17; i++) { for (byte i = 0; i < 17; i++) { Settings.rf_code[i][0] = 0; }
Settings.rf_code[i][0] = 0;
}
memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9); memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9);
} }
if (Settings.version < 0x05080000) { if (Settings.version < 0x05080000) {
uint8_t cfg_wsflg = 0; Settings.light_pixels = WS2812_LEDS;
for (byte i = 0; i < MAX_GPIO_PIN; i++) { Settings.light_width = 1;
if (GPIO_WS2812 == Settings.my_gp.io[i]) { Settings.light_color[0] = 255;
cfg_wsflg = 1; Settings.light_color[1] = 0;
} Settings.light_color[2] = 0;
} Settings.light_dimmer = 10;
if (!Settings.light_pixels && cfg_wsflg) { Settings.light_correction = 0;
Settings.light_pixels = WS2812_LEDS; Settings.light_fade = 0;
Settings.light_color[0] = Settings.ws_red; Settings.light_speed = 1;
Settings.light_color[1] = Settings.ws_green; Settings.light_scheme = 0;
Settings.light_color[2] = Settings.ws_blue; Settings.light_width = 1;
Settings.light_dimmer = Settings.ws_dimmer; Settings.light_wakeup = 0;
Settings.light_correction = Settings.ws_ledtable;
Settings.light_fade = Settings.ws_fade;
Settings.light_speed = Settings.ws_speed;
Settings.light_scheme = Settings.ws_scheme;
Settings.light_width = Settings.ex_ws_width;
Settings.light_wakeup = Settings.ws_wakeup;
} else {
Settings.light_pixels = WS2812_LEDS;
Settings.light_width = 1;
}
} }
if (Settings.version < 0x0508000A) { if (Settings.version < 0x0508000A) {
Settings.power = Settings.ex_power; Settings.power = 0;
Settings.altitude = 0; Settings.altitude = 0;
} }
if (Settings.version < 0x0508000B) { if (Settings.version < 0x0508000B) {
@ -862,15 +732,12 @@ void SettingsDelta()
Settings.sbaudrate = SOFT_BAUDRATE / 1200; Settings.sbaudrate = SOFT_BAUDRATE / 1200;
Settings.serial_delimiter = 0xff; Settings.serial_delimiter = 0xff;
} }
// if (Settings.version < 0x050C0009) {
// memset(&Settings.timer, 0x00, sizeof(Timer) * MAX_TIMERS);
// }
if (Settings.version < 0x050C000A) { if (Settings.version < 0x050C000A) {
Settings.latitude = (int)((double)LATITUDE * 1000000); Settings.latitude = (int)((double)LATITUDE * 1000000);
Settings.longitude = (int)((double)LONGITUDE * 1000000); Settings.longitude = (int)((double)LONGITUDE * 1000000);
} }
if (Settings.version < 0x050C000B) { if (Settings.version < 0x050C000B) {
memset(&Settings.rules, 0x00, sizeof(Settings.rules)); Settings.rules[0][0] = '\0';
} }
if (Settings.version < 0x050C000D) { if (Settings.version < 0x050C000D) {
memmove(Settings.rules, Settings.rules -256, sizeof(Settings.rules)); // move rules up by 256 bytes memmove(Settings.rules, Settings.rules -256, sizeof(Settings.rules)); // move rules up by 256 bytes
@ -887,6 +754,15 @@ void SettingsDelta()
if (Settings.version < 0x050D0103) { if (Settings.version < 0x050D0103) {
SettingsDefaultSet_5_13_1c(); SettingsDefaultSet_5_13_1c();
} }
if (Settings.version < 0x050E0002) {
for (byte i = 1; i < MAX_RULE_SETS; i++) { Settings.rules[i][0] = '\0'; }
Settings.rule_enabled = Settings.flag.rules_enabled;
Settings.rule_once = Settings.flag.rules_once;
}
if (Settings.version < 0x06000000) {
Settings.cfg_size = sizeof(SYSCFG);
Settings.cfg_crc = GetSettingsCrc();
}
Settings.version = VERSION; Settings.version = VERSION;
SettingsSave(1); SettingsSave(1);

View File

@ -51,6 +51,7 @@ typedef unsigned long power_t; // Power (Relay) type
#define MAX_KNX_GA 10 // Max number of KNX Group Addresses to read that can be set #define MAX_KNX_GA 10 // Max number of KNX Group Addresses to read that can be set
#define MAX_KNX_CB 10 // Max number of KNX Group Addresses to write that can be set #define MAX_KNX_CB 10 // Max number of KNX Group Addresses to write that can be set
#define RULES_MAX_MEMS 5 // Max number of saved vars #define RULES_MAX_MEMS 5 // Max number of saved vars
#define MAX_RULE_SETS 3 // Max number of rule sets of size 512 characters
#define MAX_RULE_SIZE 512 // Max number of characters in rules #define MAX_RULE_SIZE 512 // Max number of characters in rules
#define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x] #define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x]
@ -88,7 +89,7 @@ typedef unsigned long power_t; // Power (Relay) type
#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog #define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
#define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware #define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware
#define INPUT_BUFFER_SIZE 512 // Max number of characters in (serial and http) command buffer #define INPUT_BUFFER_SIZE 520 // Max number of characters in (serial and http) command buffer
#define CMDSZ 24 // Max number of characters in command #define CMDSZ 24 // Max number of characters in command
#define TOPSZ 100 // Max number of characters in topic string #define TOPSZ 100 // Max number of characters in topic string
#define LOGSZ 512 // Max number of characters in log #define LOGSZ 512 // Max number of characters in log
@ -136,7 +137,7 @@ typedef unsigned long power_t; // Power (Relay) type
#define DAWN_NAUTIC -12.0 #define DAWN_NAUTIC -12.0
#define DAWN_ASTRONOMIC -18.0 #define DAWN_ASTRONOMIC -18.0
// Sensor definition for KNX Driver // Sensor and Commands definition for KNX Driver
#define KNX_TEMPERATURE 17 #define KNX_TEMPERATURE 17
#define KNX_HUMIDITY 18 #define KNX_HUMIDITY 18
#define KNX_ENERGY_VOLTAGE 19 #define KNX_ENERGY_VOLTAGE 19
@ -146,7 +147,13 @@ typedef unsigned long power_t; // Power (Relay) type
#define KNX_ENERGY_DAILY 23 #define KNX_ENERGY_DAILY 23
#define KNX_ENERGY_START 24 #define KNX_ENERGY_START 24
#define KNX_ENERGY_TOTAL 25 #define KNX_ENERGY_TOTAL 25
#define KNX_MAX_device_param 25 #define KNX_SLOT1 26
#define KNX_SLOT2 27
#define KNX_SLOT3 28
#define KNX_SLOT4 29
#define KNX_SLOT5 30
#define KNX_MAX_device_param 30
#define MAX_KNXTX_CMNDS 5
/*********************************************************************************************\ /*********************************************************************************************\
* Enumeration * Enumeration
@ -186,15 +193,19 @@ enum LightTypes {LT_BASIC, LT_PWM1, LT_PWM2, LT_PWM3, LT_PWM4, LT_PWM5, LT_PWM6,
enum LichtSubtypes {LST_NONE, LST_SINGLE, LST_COLDWARM, LST_RGB, LST_RGBW, LST_RGBWC}; enum LichtSubtypes {LST_NONE, LST_SINGLE, LST_COLDWARM, LST_RGB, LST_RGBW, LST_RGBWC};
enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MAX}; enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MAX};
enum XsnsFunctions {FUNC_INIT, FUNC_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_SECOND, FUNC_PREP_BEFORE_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_APPEND, FUNC_SAVE_BEFORE_RESTART, enum XsnsFunctions {FUNC_PRE_INIT, FUNC_INIT, FUNC_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_SECOND, FUNC_PREP_BEFORE_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_APPEND, FUNC_SAVE_BEFORE_RESTART,
FUNC_COMMAND, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SHOW_SENSOR}; FUNC_COMMAND, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SHOW_SENSOR, FUNC_RULES_PROCESS};
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_MAX };
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|Timer|Rule|MaxPower|MaxEnergy|Light|Knx|Display|Wemo|Hue";
/*********************************************************************************************\ /*********************************************************************************************\
* Extern global variables * Extern global variables
\*********************************************************************************************/ \*********************************************************************************************/
extern uint8_t light_device; // Light device number extern uint8_t light_device; // Light device number
#endif // _SONOFF_H_ #endif // _SONOFF_H_

View File

@ -25,7 +25,7 @@
- Select IDE Tools - Flash Size: "1M (no SPIFFS)" - Select IDE Tools - Flash Size: "1M (no SPIFFS)"
====================================================*/ ====================================================*/
#define VERSION 0x050E0001 // 5.14.0a #define VERSION 0x06000001 // 6.0.0a
// Location specific includes // Location specific includes
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0) #include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
@ -82,7 +82,7 @@ enum TasmotaCommands {
CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE, CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE,
CMND_COUNTERDEBOUNCE, CMND_SLEEP, CMND_UPGRADE, CMND_UPLOAD, CMND_OTAURL, CMND_SERIALLOG, CMND_SYSLOG, CMND_COUNTERDEBOUNCE, CMND_SLEEP, CMND_UPGRADE, CMND_UPLOAD, CMND_OTAURL, CMND_SERIALLOG, CMND_SYSLOG,
CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME, CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME,
CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_WEBSERVER, CMND_WEBPASSWORD, CMND_WEBLOG, CMND_EMULATION, CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE,
CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_TIMESTD, CMND_TIMEDST, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE, CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_TIMESTD, CMND_TIMEDST, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE,
CMND_I2CSCAN, CMND_SERIALSEND, CMND_BAUDRATE, CMND_SERIALDELIMITER }; CMND_I2CSCAN, CMND_SERIALSEND, CMND_BAUDRATE, CMND_SERIALDELIMITER };
const char kTasmotaCommands[] PROGMEM = const char kTasmotaCommands[] PROGMEM =
@ -92,7 +92,7 @@ const char kTasmotaCommands[] PROGMEM =
D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|" D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|"
D_CMND_COUNTERDEBOUNCE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_SYSLOG "|" D_CMND_COUNTERDEBOUNCE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_SYSLOG "|"
D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|"
D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_EMULATION "|" D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|"
D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|"
D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER; D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER;
@ -304,10 +304,12 @@ void SetLatchingRelay(power_t power, uint8_t state)
} }
} }
void SetDevicePower(power_t rpower) void SetDevicePower(power_t rpower, int source)
{ {
uint8_t state; uint8_t state;
ShowSource(source);
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) { // All on and stay on if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) { // All on and stay on
power = (1 << devices_present) -1; power = (1 << devices_present) -1;
rpower = power; rpower = power;
@ -396,6 +398,8 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
memcpy(dataBuf, data +i, sizeof(dataBuf)); memcpy(dataBuf, data +i, sizeof(dataBuf));
dataBuf[sizeof(dataBuf)-1] = 0; dataBuf[sizeof(dataBuf)-1] = 0;
if (topicBuf[0] != '/') { ShowSource(SRC_MQTT); }
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_RESULT D_RECEIVED_TOPIC " %s, " D_DATA_SIZE " %d, " D_DATA " %s"), snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_RESULT D_RECEIVED_TOPIC " %s, " D_DATA_SIZE " %d, " D_DATA " %s"),
topicBuf, data_len, dataBuf); topicBuf, data_len, dataBuf);
AddLog(LOG_LEVEL_DEBUG_MORE); AddLog(LOG_LEVEL_DEBUG_MORE);
@ -490,7 +494,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
else if ((CMND_POWER == command_code) && (index > 0) && (index <= devices_present)) { else if ((CMND_POWER == command_code) && (index > 0) && (index <= devices_present)) {
if ((payload < 0) || (payload > 4)) payload = 9; if ((payload < 0) || (payload > 4)) payload = 9;
// Settings.flag.device_index_enable = user_append_index; // Settings.flag.device_index_enable = user_append_index;
ExecuteCommandPower(index, payload); ExecuteCommandPower(index, payload, SRC_IGNORE);
fallback_topic_flag = 0; fallback_topic_flag = 0;
return; return;
} }
@ -516,7 +520,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
Settings.poweronstate = payload; Settings.poweronstate = payload;
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) { if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) {
for (byte i = 1; i <= devices_present; i++) { for (byte i = 1; i <= devices_present; i++) {
ExecuteCommandPower(i, POWER_ON); ExecuteCommandPower(i, POWER_ON, SRC_IGNORE);
} }
} }
} }
@ -736,6 +740,8 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
} }
} }
else if (CMND_GPIOS == command_code) { else if (CMND_GPIOS == command_code) {
mytmplt cmodule;
memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule));
for (byte i = 0; i < GPIO_SENSOR_END; i++) { for (byte i = 0; i < GPIO_SENSOR_END; i++) {
if (!jsflg) { if (!jsflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_GPIOS "%d\":["), lines); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_GPIOS "%d\":["), lines);
@ -743,12 +749,14 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
} }
jsflg = 1; jsflg = 1;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%d (%s)\""), mqtt_data, i, GetTextIndexed(stemp1, sizeof(stemp1), i, kSensorNames)); if (!GetUsedInModule(i, cmodule.gp.io)) {
if ((strlen(mqtt_data) > (LOGSZ - TOPSZ)) || (i == GPIO_SENSOR_END -1)) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%d (%s)\""), mqtt_data, i, GetTextIndexed(stemp1, sizeof(stemp1), i, kSensorNames));
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]}"), mqtt_data); if ((strlen(mqtt_data) > (LOGSZ - TOPSZ)) || (i == GPIO_SENSOR_END -1)) {
MqttPublishPrefixTopic_P(RESULT_OR_STAT, type); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]}"), mqtt_data);
jsflg = 0; MqttPublishPrefixTopic_P(RESULT_OR_STAT, type);
lines++; jsflg = 0;
lines++;
}
} }
} }
mqtt_data[0] = '\0'; mqtt_data[0] = '\0';
@ -980,38 +988,6 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
if ((payload >= 0) && (payload < MAX_SWITCH_OPTION)) Settings.switchmode[index -1] = payload; if ((payload >= 0) && (payload < MAX_SWITCH_OPTION)) Settings.switchmode[index -1] = payload;
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_NVALUE, command, index, Settings.switchmode[index-1]); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_NVALUE, command, index, Settings.switchmode[index-1]);
} }
#ifdef USE_WEBSERVER
else if (CMND_WEBSERVER == command_code) {
if ((payload >= 0) && (payload <= 2)) Settings.webserver = payload;
if (Settings.webserver) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_JSON_ACTIVE_FOR " %s " D_JSON_ON_DEVICE " %s " D_JSON_WITH_IP_ADDRESS " %s\"}"),
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(0));
}
}
else if (CMND_WEBPASSWORD == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.web_password))) {
strlcpy(Settings.web_password, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? WEB_PASSWORD : dataBuf, sizeof(Settings.web_password));
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.web_password);
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_ASTERIX, command);
}
}
else if (CMND_WEBLOG == command_code) {
if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) Settings.weblog_level = payload;
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.weblog_level);
}
#ifdef USE_EMULATION
else if (CMND_EMULATION == command_code) {
if ((payload >= EMUL_NONE) && (payload < EMUL_MAX)) {
Settings.flag2.emulation = payload;
restart_flag = 2;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.emulation);
}
#endif // USE_EMULATION
#endif // USE_WEBSERVER
else if (CMND_TELEPERIOD == command_code) { else if (CMND_TELEPERIOD == command_code) {
if ((payload >= 0) && (payload < 3601)) { if ((payload >= 0) && (payload < 3601)) {
Settings.tele_period = (1 == payload) ? TELE_PERIOD : payload; Settings.tele_period = (1 == payload) ? TELE_PERIOD : payload;
@ -1028,7 +1004,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
break; break;
case 99: case 99:
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING)); AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING));
ESP.restart(); EspRestart();
break; break;
default: default:
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_ONE_TO_RESTART); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_ONE_TO_RESTART);
@ -1177,11 +1153,9 @@ boolean SendKey(byte key, byte device, byte state)
MqttPublishDirect(stopic, (key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain); MqttPublishDirect(stopic, (key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain);
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ
result = true; result = true;
#ifdef USE_RULES
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":{\"State\":%d}}"), (key) ? "Switch" : "Button", device, state); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":{\"State\":%d}}"), (key) ? "Switch" : "Button", device, state);
result = RulesProcess(); result = XdrvRulesProcess();
#endif // USE_RULES
} }
#ifdef USE_KNX #ifdef USE_KNX
KnxSendButtonPower(key, device, state); KnxSendButtonPower(key, device, state);
@ -1189,7 +1163,7 @@ boolean SendKey(byte key, byte device, byte state)
return result; return result;
} }
void ExecuteCommandPower(byte device, byte state) void ExecuteCommandPower(byte device, byte state, int source)
{ {
// device = Relay number 1 and up // device = Relay number 1 and up
// state 0 = Relay Off // state 0 = Relay Off
@ -1201,6 +1175,8 @@ void ExecuteCommandPower(byte device, byte state)
// state 7 = Relay On and no publishPowerState // state 7 = Relay On and no publishPowerState
// state 9 = Show power state // state 9 = Show power state
// ShowSource(source);
uint8_t publish_power = 1; uint8_t publish_power = 1;
if ((POWER_OFF_NO_STATE == state) || (POWER_ON_NO_STATE == state)) { if ((POWER_OFF_NO_STATE == state) || (POWER_ON_NO_STATE == state)) {
state &= 1; state &= 1;
@ -1218,7 +1194,7 @@ void ExecuteCommandPower(byte device, byte state)
interlock_mutex = 1; interlock_mutex = 1;
for (byte i = 0; i < devices_present; i++) { for (byte i = 0; i < devices_present; i++) {
power_t imask = 1 << i; power_t imask = 1 << i;
if ((power & imask) && (mask != imask)) ExecuteCommandPower(i +1, POWER_OFF); if ((power & imask) && (mask != imask)) ExecuteCommandPower(i +1, POWER_OFF, SRC_IGNORE);
} }
interlock_mutex = 0; interlock_mutex = 0;
} }
@ -1232,7 +1208,7 @@ void ExecuteCommandPower(byte device, byte state)
case POWER_TOGGLE: case POWER_TOGGLE:
power ^= mask; power ^= mask;
} }
SetDevicePower(power); SetDevicePower(power, source);
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
DomoticzUpdatePowerState(device); DomoticzUpdatePowerState(device);
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ
@ -1259,7 +1235,7 @@ void ExecuteCommandPower(byte device, byte state)
byte flag = (blink_mask & mask); byte flag = (blink_mask & mask);
blink_mask &= (POWER_MASK ^ mask); // Clear device mask blink_mask &= (POWER_MASK ^ mask); // Clear device mask
MqttPublishPowerBlinkState(device); MqttPublishPowerBlinkState(device);
if (flag) ExecuteCommandPower(device, (blink_powersave >> (device -1))&1); // Restore state if (flag) ExecuteCommandPower(device, (blink_powersave >> (device -1))&1, SRC_IGNORE); // Restore state
return; return;
} }
if (publish_power) MqttPublishPowerState(device); if (publish_power) MqttPublishPowerState(device);
@ -1274,18 +1250,20 @@ void StopAllPowerBlink()
if (blink_mask & mask) { if (blink_mask & mask) {
blink_mask &= (POWER_MASK ^ mask); // Clear device mask blink_mask &= (POWER_MASK ^ mask); // Clear device mask
MqttPublishPowerBlinkState(i); MqttPublishPowerBlinkState(i);
ExecuteCommandPower(i, (blink_powersave >> (i -1))&1); // Restore state ExecuteCommandPower(i, (blink_powersave >> (i -1))&1, SRC_IGNORE); // Restore state
} }
} }
} }
void ExecuteCommand(char *cmnd) void ExecuteCommand(char *cmnd, int source)
{ {
char stopic[CMDSZ]; char stopic[CMDSZ];
char svalue[INPUT_BUFFER_SIZE]; char svalue[INPUT_BUFFER_SIZE];
char *start; char *start;
char *token; char *token;
ShowSource(source);
token = strtok(cmnd, " "); token = strtok(cmnd, " ");
if (token != NULL) { if (token != NULL) {
start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble
@ -1300,11 +1278,11 @@ void ExecuteCommand(char *cmnd)
void PublishStatus(uint8_t payload) void PublishStatus(uint8_t payload)
{ {
uint8_t option = 1; uint8_t option = STAT;
char stemp[MAX_FRIENDLYNAMES * (sizeof(Settings.friendlyname[0]) +4)]; char stemp[MAX_FRIENDLYNAMES * (sizeof(Settings.friendlyname[0]) +4)];
// Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX // Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX
if (!strcmp(Settings.mqtt_prefix[0],Settings.mqtt_prefix[1]) && (!payload)) option++; if (!strcmp(Settings.mqtt_prefix[0],Settings.mqtt_prefix[1]) && (!payload)) option++; // TELE
if ((!Settings.flag.mqtt_enabled) && (6 == payload)) payload = 99; if ((!Settings.flag.mqtt_enabled) && (6 == payload)) payload = 99;
if (!energy_flg && (9 == payload)) payload = 99; if (!energy_flg && (9 == payload)) payload = 99;
@ -1584,7 +1562,7 @@ void ButtonHandler()
} }
if (button_pressed) { if (button_pressed) {
if (!SendKey(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set if (!SendKey(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
ExecuteCommandPower(button_index +1, POWER_TOGGLE); // Execute Toggle command internally ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
} }
} }
} else { } else {
@ -1593,7 +1571,7 @@ void ButtonHandler()
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_IMMEDIATE), button_index +1); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_IMMEDIATE), button_index +1);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
if (!SendKey(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set if (!SendKey(0, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set
ExecuteCommandPower(button_index +1, POWER_TOGGLE); // Execute Toggle command internally ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
} }
} else { } else {
multipress[button_index] = (multiwindow[button_index]) ? multipress[button_index] +1 : 1; multipress[button_index] = (multiwindow[button_index]) ? multipress[button_index] +1 : 1;
@ -1612,7 +1590,7 @@ void ButtonHandler()
if (holdbutton[button_index] == Settings.param[P_HOLD_TIME] * (STATES / 10) * hold_time_extent) { // Button held for factor times longer if (holdbutton[button_index] == Settings.param[P_HOLD_TIME] * (STATES / 10) * hold_time_extent) { // Button held for factor times longer
// Settings.flag.button_single = 0; // Settings.flag.button_single = 0;
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_SETOPTION "13 0")); // Disable single press only snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_SETOPTION "13 0")); // Disable single press only
ExecuteCommand(scmnd); ExecuteCommand(scmnd, SRC_BUTTON);
} }
} else { } else {
if (Settings.flag.button_restrict) { // Button restriction if (Settings.flag.button_restrict) { // Button restriction
@ -1624,7 +1602,7 @@ void ButtonHandler()
if (holdbutton[button_index] == (Settings.param[P_HOLD_TIME] * (STATES / 10)) * hold_time_extent) { // Button held for factor times longer if (holdbutton[button_index] == (Settings.param[P_HOLD_TIME] * (STATES / 10)) * hold_time_extent) { // Button held for factor times longer
multipress[button_index] = 0; multipress[button_index] = 0;
snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1")); snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1"));
ExecuteCommand(scmnd); ExecuteCommand(scmnd, SRC_BUTTON);
} }
} }
} }
@ -1651,12 +1629,12 @@ void ButtonHandler()
if (WifiState()) { // WPSconfig, Smartconfig or Wifimanager active if (WifiState()) { // WPSconfig, Smartconfig or Wifimanager active
restart_flag = 1; restart_flag = 1;
} else { } else {
ExecuteCommandPower(button_index + multipress[button_index], POWER_TOGGLE); // Execute Toggle command internally ExecuteCommandPower(button_index + multipress[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
} }
} else { // 3 - 7 press } else { // 3 - 7 press
if (!Settings.flag.button_restrict) { if (!Settings.flag.button_restrict) {
snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[button_index] -3]); snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[button_index] -3]);
ExecuteCommand(scmnd); ExecuteCommand(scmnd, SRC_BUTTON);
} }
} }
} }
@ -1739,7 +1717,7 @@ void SwitchHandler()
if (switchflag < 3) { if (switchflag < 3) {
if (!SendKey(1, i +1, switchflag)) { // Execute command via MQTT if (!SendKey(1, i +1, switchflag)) { // Execute command via MQTT
ExecuteCommandPower(i +1, switchflag); // Execute command internally (if i < devices_present) ExecuteCommandPower(i +1, switchflag, SRC_SWITCH); // Execute command internally (if i < devices_present)
} }
} }
@ -1786,8 +1764,8 @@ void StateLoop()
if ((pulse_timer[i] > 0) && (pulse_timer[i] < 112)) { if ((pulse_timer[i] > 0) && (pulse_timer[i] < 112)) {
pulse_timer[i]--; pulse_timer[i]--;
if (!pulse_timer[i]) { if (!pulse_timer[i]) {
// ExecuteCommandPower(i +1, POWER_OFF); // ExecuteCommandPower(i +1, POWER_OFF, SRC_PULSETIMER);
ExecuteCommandPower(i +1, (POWER_ALL_OFF_PULSETIME_ON == Settings.poweronstate) ? POWER_ON : POWER_OFF); ExecuteCommandPower(i +1, (POWER_ALL_OFF_PULSETIME_ON == Settings.poweronstate) ? POWER_ON : POWER_OFF, SRC_PULSETIMER);
} }
} }
} }
@ -1802,7 +1780,7 @@ void StateLoop()
} else { } else {
blink_power ^= 1; blink_power ^= 1;
power_now = (power & (POWER_MASK ^ blink_mask)) | ((blink_power) ? blink_mask : 0); power_now = (power & (POWER_MASK ^ blink_mask)) | ((blink_power) ? blink_mask : 0);
SetDevicePower(power_now); SetDevicePower(power_now, SRC_IGNORE);
} }
} }
} }
@ -1811,7 +1789,7 @@ void StateLoop()
if (backlog_delay) backlog_delay--; if (backlog_delay) backlog_delay--;
if ((backlog_pointer != backlog_index) && !backlog_delay && !backlog_mutex) { if ((backlog_pointer != backlog_index) && !backlog_delay && !backlog_mutex) {
backlog_mutex = 1; backlog_mutex = 1;
ExecuteCommand((char*)backlog[backlog_pointer].c_str()); ExecuteCommand((char*)backlog[backlog_pointer].c_str(), SRC_BACKLOG);
backlog_mutex = 0; backlog_mutex = 0;
backlog_pointer++; backlog_pointer++;
if (backlog_pointer >= MAX_BACKLOG) backlog_pointer = 0; if (backlog_pointer >= MAX_BACKLOG) backlog_pointer = 0;
@ -1963,7 +1941,7 @@ void StateLoop()
restart_flag--; restart_flag--;
if (restart_flag <= 0) { if (restart_flag <= 0) {
AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING)); AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING));
ESP.restart(); EspRestart();
} }
} }
break; break;
@ -2038,8 +2016,7 @@ void ArduinoOTAInit()
} }
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Arduino OTA %s. " D_RESTARTING), error_str); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Arduino OTA %s. " D_RESTARTING), error_str);
AddLog(LOG_LEVEL_INFO); AddLog(LOG_LEVEL_INFO);
delay(100); // Allow time for message xfer EspRestart();
ESP.restart();
}); });
ArduinoOTA.onEnd([]() ArduinoOTA.onEnd([]()
@ -2047,8 +2024,7 @@ void ArduinoOTAInit()
if ((LOG_LEVEL_DEBUG <= seriallog_level)) Serial.println(); if ((LOG_LEVEL_DEBUG <= seriallog_level)) Serial.println();
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Arduino OTA " D_SUCCESSFUL ". " D_RESTARTING)); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Arduino OTA " D_SUCCESSFUL ". " D_RESTARTING));
AddLog(LOG_LEVEL_INFO); AddLog(LOG_LEVEL_INFO);
delay(100); // Allow time for message xfer EspRestart();
ESP.restart();
}); });
ArduinoOTA.begin(); ArduinoOTA.begin();
@ -2156,7 +2132,7 @@ void SerialInput()
seriallog_level = (Settings.seriallog_level < LOG_LEVEL_INFO) ? (byte)LOG_LEVEL_INFO : Settings.seriallog_level; seriallog_level = (Settings.seriallog_level < LOG_LEVEL_INFO) ? (byte)LOG_LEVEL_INFO : Settings.seriallog_level;
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), serial_in_buffer); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), serial_in_buffer);
AddLog(LOG_LEVEL_INFO); AddLog(LOG_LEVEL_INFO);
ExecuteCommand(serial_in_buffer); ExecuteCommand(serial_in_buffer, SRC_SERIAL);
serial_in_byte_counter = 0; serial_in_byte_counter = 0;
serial_polling_window = 0; serial_polling_window = 0;
Serial.flush(); Serial.flush();
@ -2168,6 +2144,7 @@ void SerialInput()
serial_in_buffer[serial_in_byte_counter] = 0; // serial data completed serial_in_buffer[serial_in_byte_counter] = 0; // serial data completed
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SERIALRECEIVED "\":\"%s\"}"), serial_in_buffer); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SERIALRECEIVED "\":\"%s\"}"), serial_in_buffer);
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED)); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED));
// XdrvRulesProcess();
serial_in_byte_counter = 0; serial_in_byte_counter = 0;
} }
} }
@ -2347,7 +2324,7 @@ void GpioInit()
} }
SetLedPower(Settings.ledstate &8); SetLedPower(Settings.ledstate &8);
XdrvCall(FUNC_INIT); XdrvCall(FUNC_PRE_INIT);
} }
extern "C" { extern "C" {
@ -2412,36 +2389,36 @@ void setup()
if (MOTOR == Settings.module) Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo! if (MOTOR == Settings.module) Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo!
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) { if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) {
SetDevicePower(1); SetDevicePower(1, SRC_RESTART);
} else { } else {
if ((resetInfo.reason == REASON_DEFAULT_RST) || (resetInfo.reason == REASON_EXT_SYS_RST)) { if ((resetInfo.reason == REASON_DEFAULT_RST) || (resetInfo.reason == REASON_EXT_SYS_RST)) {
switch (Settings.poweronstate) { switch (Settings.poweronstate) {
case POWER_ALL_OFF: case POWER_ALL_OFF:
case POWER_ALL_OFF_PULSETIME_ON: case POWER_ALL_OFF_PULSETIME_ON:
power = 0; power = 0;
SetDevicePower(power); SetDevicePower(power, SRC_RESTART);
break; break;
case POWER_ALL_ON: // All on case POWER_ALL_ON: // All on
power = (1 << devices_present) -1; power = (1 << devices_present) -1;
SetDevicePower(power); SetDevicePower(power, SRC_RESTART);
break; break;
case POWER_ALL_SAVED_TOGGLE: case POWER_ALL_SAVED_TOGGLE:
power = (Settings.power & ((1 << devices_present) -1)) ^ POWER_MASK; power = (Settings.power & ((1 << devices_present) -1)) ^ POWER_MASK;
if (Settings.flag.save_state) { if (Settings.flag.save_state) {
SetDevicePower(power); SetDevicePower(power, SRC_RESTART);
} }
break; break;
case POWER_ALL_SAVED: case POWER_ALL_SAVED:
power = Settings.power & ((1 << devices_present) -1); power = Settings.power & ((1 << devices_present) -1);
if (Settings.flag.save_state) { if (Settings.flag.save_state) {
SetDevicePower(power); SetDevicePower(power, SRC_RESTART);
} }
break; break;
} }
} else { } else {
power = Settings.power & ((1 << devices_present) -1); power = Settings.power & ((1 << devices_present) -1);
if (Settings.flag.save_state) { if (Settings.flag.save_state) {
SetDevicePower(power); SetDevicePower(power, SRC_RESTART);
} }
} }
} }
@ -2472,6 +2449,7 @@ void setup()
ArduinoOTAInit(); ArduinoOTAInit();
#endif // USE_ARDUINO_OTA #endif // USE_ARDUINO_OTA
XdrvCall(FUNC_INIT);
XsnsCall(FUNC_INIT); XsnsCall(FUNC_INIT);
} }
@ -2481,13 +2459,6 @@ void loop()
OsWatchLoop(); OsWatchLoop();
#ifdef USE_WEBSERVER
PollDnsWebserver();
#ifdef USE_EMULATION
if (Settings.flag2.emulation) PollUdp();
#endif // USE_EMULATION
#endif // USE_WEBSERVER
if (millis() >= state_loop_timer) StateLoop(); if (millis() >= state_loop_timer) StateLoop();
if (!serial_local) SerialInput(); if (!serial_local) SerialInput();

View File

@ -244,6 +244,29 @@ char* LTrim(char* p)
return p; return p;
} }
char* RTrim(char* p)
{
char* q = p + strlen(p) -1;
while ((q >= p) && (isblank(*q))) {
q--; // Trim trailing spaces
}
q++;
*q = '\0';
return p;
}
char* Trim(char* p)
{
if (*p == '\0') { return p; }
while (isspace(*p)) { p++; } // Trim leading spaces
if (*p == '\0') { return p; }
char* q = p + strlen(p) -1;
while (isspace(*q) && q >= p) { q--; } // Trim trailing spaces
q++;
*q = '\0';
return p;
}
char* NoAlNumToUnderscore(char* dest, const char* source) char* NoAlNumToUnderscore(char* dest, const char* source)
{ {
char* write = dest; char* write = dest;
@ -482,6 +505,96 @@ int GetStateNumber(char *state_text)
return state_number; return state_number;
} }
boolean GetUsedInModule(byte val, uint8_t *arr)
{
int offset = 0;
if (!val) { return false; } // None
#ifndef USE_I2C
if (GPIO_I2C_SCL == val) { return true; }
if (GPIO_I2C_SDA == val) { return true; }
#endif
#ifndef USE_SR04
if (GPIO_SR04_TRIG == val) { return true; }
if (GPIO_SR04_ECHO == val) { return true; }
#endif
#ifndef USE_WS2812
if (GPIO_WS2812 == val) { return true; }
#endif
#ifndef USE_IR_REMOTE
if (GPIO_IRSEND == val) { return true; }
#ifndef USE_IR_RECEIVE
if (GPIO_IRRECV == val) { return true; }
#endif
#endif
#ifndef USE_MHZ19
if (GPIO_MHZ_TXD == val) { return true; }
if (GPIO_MHZ_RXD == val) { return true; }
#endif
#ifndef USE_PZEM004T
if (GPIO_PZEM_TX == val) { return true; }
if (GPIO_PZEM_RX == val) { return true; }
#endif
#ifndef USE_SENSEAIR
if (GPIO_SAIR_TX == val) { return true; }
if (GPIO_SAIR_RX == val) { return true; }
#endif
#ifndef USE_SPI
if (GPIO_SPI_CS == val) { return true; }
if (GPIO_SPI_DC == val) { return true; }
#endif
#ifndef USE_DISPLAY
if (GPIO_BACKLIGHT == val) { return true; }
#endif
#ifndef USE_PMS5003
if (GPIO_PMS5003 == val) { return true; }
#endif
#ifndef USE_NOVA_SDS
if (GPIO_SDS0X1 == val) { return true; }
#endif
#ifndef USE_SERIAL_BRIDGE
if (GPIO_SBR_TX == val) { return true; }
if (GPIO_SBR_RX == val) { return true; }
#endif
#ifndef USE_SR04
if (GPIO_SR04_TRIG == val) { return true; }
if (GPIO_SR04_ECHO == val) { return true; }
#endif
#ifndef USE_SDM120
if (GPIO_SDM120_TX == val) { return true; }
if (GPIO_SDM120_RX == val) { return true; }
#endif
#ifndef USE_SDM630
if (GPIO_SDM630_TX == val) { return true; }
if (GPIO_SDM630_RX == val) { return true; }
#endif
if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) {
offset = (GPIO_REL1_INV - GPIO_REL1);
}
if ((val >= GPIO_REL1_INV) && (val < GPIO_REL1_INV + MAX_RELAYS)) {
offset = -(GPIO_REL1_INV - GPIO_REL1);
}
if ((val >= GPIO_LED1) && (val < GPIO_LED1 + MAX_LEDS)) {
offset = (GPIO_LED1_INV - GPIO_LED1);
}
if ((val >= GPIO_LED1_INV) && (val < GPIO_LED1_INV + MAX_LEDS)) {
offset = -(GPIO_LED1_INV - GPIO_LED1);
}
if ((val >= GPIO_PWM1) && (val < GPIO_PWM1 + MAX_PWMS)) {
offset = (GPIO_PWM1_INV - GPIO_PWM1);
}
if ((val >= GPIO_PWM1_INV) && (val < GPIO_PWM1_INV + MAX_PWMS)) {
offset = -(GPIO_PWM1_INV - GPIO_PWM1);
}
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
if (arr[i] == val) { return true; }
if (arr[i] == val + offset) { return true; }
}
return false;
}
void SetSerialBaudrate(int baudrate) void SetSerialBaudrate(int baudrate)
{ {
Settings.baudrate = baudrate / 1200; Settings.baudrate = baudrate / 1200;
@ -516,13 +629,22 @@ uint32_t GetHash(const char *buffer, size_t size)
return hash; return hash;
} }
void ShowSource(int source)
{
if ((source > 0) && (source < SRC_MAX)) {
char stemp1[20];
snprintf_P(log_data, sizeof(log_data), PSTR("SRC: %s"), GetTextIndexed(stemp1, sizeof(stemp1), source, kCommandSource));
AddLog(LOG_LEVEL_DEBUG);
}
}
/*********************************************************************************************\ /*********************************************************************************************\
* Fill feature list * Fill feature list
\*********************************************************************************************/ \*********************************************************************************************/
void GetFeatures() void GetFeatures()
{ {
feature_drv1 = 0x00000000; // xdrv_00_mqtt.ino, xdrv_01_light.ino, xdrv_04_snfbridge.ino feature_drv1 = 0x00000000; // xdrv_01_mqtt.ino, xdrv_01_light.ino, xdrv_04_snfbridge.ino
// feature_drv1 |= 0x00000001; // feature_drv1 |= 0x00000001;
// feature_drv1 |= 0x00000002; // feature_drv1 |= 0x00000002;
@ -543,52 +665,52 @@ void GetFeatures()
feature_drv1 |= 0x00000040; // sonoff.ino feature_drv1 |= 0x00000040; // sonoff.ino
#endif #endif
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
feature_drv1 |= 0x00000080; // webserver.ino feature_drv1 |= 0x00000080; // xdrv_02_webserver.ino
#endif #endif
#ifdef WEBSERVER_ADVERTISE #ifdef WEBSERVER_ADVERTISE
feature_drv1 |= 0x00000100; // webserver.ino feature_drv1 |= 0x00000100; // xdrv_02_webserver.ino
#endif #endif
#ifdef USE_EMULATION #ifdef USE_EMULATION
feature_drv1 |= 0x00000200; // xplg_wemohue.ino feature_drv1 |= 0x00000200; // xplg_wemohue.ino
#endif #endif
#if (MQTT_LIBRARY_TYPE == MQTT_PUBSUBCLIENT) #if (MQTT_LIBRARY_TYPE == MQTT_PUBSUBCLIENT)
feature_drv1 |= 0x00000400; // xdrv_00_mqtt.ino feature_drv1 |= 0x00000400; // xdrv_01_mqtt.ino
#endif #endif
#if (MQTT_LIBRARY_TYPE == MQTT_TASMOTAMQTT) #if (MQTT_LIBRARY_TYPE == MQTT_TASMOTAMQTT)
feature_drv1 |= 0x00000800; // xdrv_00_mqtt.ino feature_drv1 |= 0x00000800; // xdrv_01_mqtt.ino
#endif #endif
#if (MQTT_LIBRARY_TYPE == MQTT_ESPMQTTARDUINO) #if (MQTT_LIBRARY_TYPE == MQTT_ESPMQTTARDUINO)
feature_drv1 |= 0x00001000; // xdrv_00_mqtt.ino feature_drv1 |= 0x00001000; // xdrv_01_mqtt.ino
#endif #endif
#ifdef MQTT_HOST_DISCOVERY #ifdef MQTT_HOST_DISCOVERY
feature_drv1 |= 0x00002000; // xdrv_00_mqtt.ino feature_drv1 |= 0x00002000; // xdrv_01_mqtt.ino
#endif #endif
#ifdef USE_ARILUX_RF #ifdef USE_ARILUX_RF
feature_drv1 |= 0x00004000; // xdrv_01_light.ino feature_drv1 |= 0x00004000; // xdrv_04_light.ino
#endif #endif
#ifdef USE_WS2812 #ifdef USE_WS2812
feature_drv1 |= 0x00008000; // xdrv_01_light.ino feature_drv1 |= 0x00008000; // xdrv_04_light.ino
#endif #endif
#ifdef USE_WS2812_DMA #ifdef USE_WS2812_DMA
feature_drv1 |= 0x00010000; // xdrv_01_light.ino feature_drv1 |= 0x00010000; // xdrv_04_light.ino
#endif #endif
#ifdef USE_IR_REMOTE #ifdef USE_IR_REMOTE
feature_drv1 |= 0x00020000; // xdrv_02_irremote.ino feature_drv1 |= 0x00020000; // xdrv_05_irremote.ino
#endif #endif
#ifdef USE_IR_HVAC #ifdef USE_IR_HVAC
feature_drv1 |= 0x00040000; // xdrv_02_irremote.ino feature_drv1 |= 0x00040000; // xdrv_05_irremote.ino
#endif #endif
#ifdef USE_IR_RECEIVE #ifdef USE_IR_RECEIVE
feature_drv1 |= 0x00080000; // xdrv_02_irremote.ino feature_drv1 |= 0x00080000; // xdrv_05_irremote.ino
#endif #endif
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
feature_drv1 |= 0x00100000; // xdrv_05_domoticz.ino feature_drv1 |= 0x00100000; // xdrv_07_domoticz.ino
#endif #endif
#ifdef USE_DISPLAY #ifdef USE_DISPLAY
feature_drv1 |= 0x00200000; // xdrv_06_display.ino feature_drv1 |= 0x00200000; // xdrv_98_display.ino
#endif #endif
#ifdef USE_HOME_ASSISTANT #ifdef USE_HOME_ASSISTANT
feature_drv1 |= 0x00400000; // xdrv_07_home_assistant.ino feature_drv1 |= 0x00400000; // xdrv_12_home_assistant.ino
#endif #endif
#ifdef USE_SERIAL_BRIDGE #ifdef USE_SERIAL_BRIDGE
feature_drv1 |= 0x00800000; // xdrv_08_serial_bridge.ino feature_drv1 |= 0x00800000; // xdrv_08_serial_bridge.ino
@ -884,6 +1006,7 @@ void WifiBegin(uint8_t flag)
WiFi.mode(WIFI_OFF); // See https://github.com/esp8266/Arduino/issues/2186 WiFi.mode(WIFI_OFF); // See https://github.com/esp8266/Arduino/issues/2186
#endif #endif
WiFi.persistent(false); // Solve possible wifi init errors
WiFi.disconnect(true); // Delete SDK wifi config WiFi.disconnect(true); // Delete SDK wifi config
delay(200); delay(200);
WiFi.mode(WIFI_STA); // Disable AP mode WiFi.mode(WIFI_STA); // Disable AP mode
@ -1051,7 +1174,7 @@ void WifiCheck(uint8_t param)
StartWebserver(Settings.webserver, WiFi.localIP()); StartWebserver(Settings.webserver, WiFi.localIP());
#ifdef USE_DISCOVERY #ifdef USE_DISCOVERY
#ifdef WEBSERVER_ADVERTISE #ifdef WEBSERVER_ADVERTISE
MDNS.addService("http", "tcp", 80); MDNS.addService("http", "tcp", WEB_PORT);
#endif // WEBSERVER_ADVERTISE #endif // WEBSERVER_ADVERTISE
#endif // USE_DISCOVERY #endif // USE_DISCOVERY
} else { } else {
@ -1097,13 +1220,30 @@ int WifiState()
void WifiConnect() void WifiConnect()
{ {
WiFi.persistent(false); // Solve possible wifi init errors WiFi.persistent(false); // Solve possible wifi init errors
wifi_status = 0; wifi_status = 0;
wifi_retry_init = WIFI_RETRY_OFFSET_SEC + ((ESP.getChipId() & 0xF) * 2); wifi_retry_init = WIFI_RETRY_OFFSET_SEC + ((ESP.getChipId() & 0xF) * 2);
wifi_retry = wifi_retry_init; wifi_retry = wifi_retry_init;
wifi_counter = 1; wifi_counter = 1;
} }
void WifiDisconnect()
{
// Courtesy of EspEasy
WiFi.persistent(true); // use SDK storage of SSID/WPA parameters
ETS_UART_INTR_DISABLE();
wifi_station_disconnect(); // this will store empty ssid/wpa into sdk storage
ETS_UART_INTR_ENABLE();
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
}
void EspRestart()
{
delay(100); // Allow time for message xfer
WifiDisconnect();
ESP.restart();
}
#ifdef USE_DISCOVERY #ifdef USE_DISCOVERY
/*********************************************************************************************\ /*********************************************************************************************\
* mDNS * mDNS
@ -1610,14 +1750,12 @@ void RtcSecond()
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"), snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "(" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"),
GetTime(0).c_str(), GetTime(2).c_str(), GetTime(3).c_str()); GetTime(0).c_str(), GetTime(2).c_str(), GetTime(3).c_str());
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
#ifdef USE_RULES
if (local_time < 1451602800) { // 2016-01-01 if (local_time < 1451602800) { // 2016-01-01
strncpy_P(mqtt_data, PSTR("{\"Time\":{\"Initialized\":1}}"), sizeof(mqtt_data)); strncpy_P(mqtt_data, PSTR("{\"Time\":{\"Initialized\":1}}"), sizeof(mqtt_data));
} else { } else {
strncpy_P(mqtt_data, PSTR("{\"Time\":{\"Set\":1}}"), sizeof(mqtt_data)); strncpy_P(mqtt_data, PSTR("{\"Time\":{\"Set\":1}}"), sizeof(mqtt_data));
} }
RulesProcess(); XdrvRulesProcess();
#endif // USE_RULES
} else { } else {
ntp_sync_minute++; // Try again in next minute ntp_sync_minute++; // Try again in next minute
} }
@ -1698,7 +1836,7 @@ void AdcEvery50ms()
adc_last_value = new_value; adc_last_value = new_value;
uint16_t value = adc_last_value / 10; uint16_t value = adc_last_value / 10;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"ANALOG\":{\"A0div10\":%d}}"), (value > 99) ? 100 : value); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"ANALOG\":{\"A0div10\":%d}}"), (value > 99) ? 100 : value);
RulesProcess(); XdrvRulesProcess();
} }
} }
} }

View File

@ -44,7 +44,7 @@
\*********************************************************************************************/ \*********************************************************************************************/
// -- Master parameter control -------------------- // -- Master parameter control --------------------
#define CFG_HOLDER 0x20161209 // [Reset 1] Change this value to load SECTION1 configuration parameters to flash #define CFG_HOLDER 4617 // [Reset 1] Change this value to load SECTION1 configuration parameters to flash
// -- Project ------------------------------------- // -- Project -------------------------------------
#define PROJECT "sonoff" // PROJECT is used as the default topic delimiter #define PROJECT "sonoff" // PROJECT is used as the default topic delimiter
@ -178,7 +178,7 @@
* - Disable a feature by preceding it with // * - Disable a feature by preceding it with //
\*********************************************************************************************/ \*********************************************************************************************/
//#define USE_ARDUINO_OTA // Add optional support for Arduino OTA (+4k5 code) //#define USE_ARDUINO_OTA // Add optional support for Arduino OTA (+13k code)
// -- Localization -------------------------------- // -- Localization --------------------------------
// If non selected the default en-GB will be used // If non selected the default en-GB will be used
@ -196,6 +196,7 @@
//#define MY_LANGUAGE pt-BR // Portuguese in Brazil //#define MY_LANGUAGE pt-BR // Portuguese in Brazil
//#define MY_LANGUAGE pt-PT // Portuguese in Portugal //#define MY_LANGUAGE pt-PT // Portuguese in Portugal
//#define MY_LANGUAGE ru-RU // Russian in Russia //#define MY_LANGUAGE ru-RU // Russian in Russia
//#define MY_LANGUAGE uk-UK // Ukrainian in Ukrain
//#define MY_LANGUAGE zh-CN // Chinese (Simplified) in China //#define MY_LANGUAGE zh-CN // Chinese (Simplified) in China
//#define MY_LANGUAGE zh-TW // Chinese (Traditional) in Taiwan //#define MY_LANGUAGE zh-TW // Chinese (Traditional) in Taiwan
@ -262,6 +263,7 @@
#define USE_SHT // Add I2C emulating code for SHT1X sensor (+1k4 code) #define USE_SHT // Add I2C emulating code for SHT1X sensor (+1k4 code)
#define USE_SHT3X // Add I2C code for SHT3x or SHTC3 sensor (+0k7 code) #define USE_SHT3X // Add I2C code for SHT3x or SHTC3 sensor (+0k7 code)
#define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor (+1k5 code) #define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor (+1k5 code)
#define USE_LM75AD // Add I2C code for LM75AD sensor (+0k5 code)
#define USE_BMP // Add I2C code for BMP085/BMP180/BMP280/BME280 sensor (+4k code) #define USE_BMP // Add I2C code for BMP085/BMP180/BMP280/BME280 sensor (+4k code)
// #define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code) // #define USE_BME680 // Add additional support for BME680 sensor using Adafruit Sensor and BME680 libraries (+6k code)
#define USE_SGP30 // Add I2C code for SGP30 sensor (+1k1 code) #define USE_SGP30 // Add I2C code for SGP30 sensor (+1k1 code)
@ -309,6 +311,8 @@
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code) #define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k 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
/*********************************************************************************************\ /*********************************************************************************************\
* Select features and sensors enabled in previous version saving space * Select features and sensors enabled in previous version saving space
\*********************************************************************************************/ \*********************************************************************************************/

View File

@ -47,7 +47,7 @@ Examples :
// -- Master parameter control -------------------- // -- Master parameter control --------------------
#undef CFG_HOLDER #undef CFG_HOLDER
#define CFG_HOLDER 0x20161209 // [Reset 1] Change this value to load SECTION1 configuration parameters to flash #define CFG_HOLDER 4617 // [Reset 1] Change this value to load SECTION1 configuration parameters to flash
// -- Setup your own Wifi settings --------------- // -- Setup your own Wifi settings ---------------
#undef STA_SSID1 #undef STA_SSID1

View File

@ -1,5 +1,5 @@
/* /*
xdrv_00_mqtt.ino - mqtt support for Sonoff-Tasmota xdrv_01_mqtt.ino - mqtt support for Sonoff-Tasmota
Copyright (C) 2018 Theo Arends Copyright (C) 2018 Theo Arends
@ -315,10 +315,8 @@ void MqttDisconnected(int state)
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d, rc %d. " D_RETRY_IN " %d " D_UNIT_SECOND), snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d, rc %d. " D_RETRY_IN " %d " D_UNIT_SECOND),
Settings.mqtt_host, Settings.mqtt_port, state, mqtt_retry_counter); Settings.mqtt_host, Settings.mqtt_port, state, mqtt_retry_counter);
AddLog(LOG_LEVEL_INFO); AddLog(LOG_LEVEL_INFO);
#ifdef USE_RULES
strncpy_P(mqtt_data, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(mqtt_data)); strncpy_P(mqtt_data, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(mqtt_data));
RulesProcess(); XdrvRulesProcess();
#endif // USE_RULES
} }
void MqttConnected() void MqttConnected()
@ -370,17 +368,13 @@ void MqttConnected()
tele_period = Settings.tele_period -9; tele_period = Settings.tele_period -9;
} }
status_update_timer = 2; status_update_timer = 2;
#ifdef USE_RULES
strncpy_P(mqtt_data, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(mqtt_data)); strncpy_P(mqtt_data, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(mqtt_data));
RulesProcess(); XdrvRulesProcess();
#endif // USE_RULES
XdrvCall(FUNC_MQTT_INIT); XdrvCall(FUNC_MQTT_INIT);
} }
mqtt_initial_connection_state = 0; mqtt_initial_connection_state = 0;
#ifdef USE_RULES
strncpy_P(mqtt_data, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(mqtt_data)); strncpy_P(mqtt_data, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(mqtt_data));
RulesProcess(); XdrvRulesProcess();
#endif // USE_RULES
} }
#ifdef USE_MQTT_TLS #ifdef USE_MQTT_TLS
@ -751,9 +745,9 @@ bool MqttCommand()
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
#define XDRV_00 #define XDRV_01
boolean Xdrv00(byte function) boolean Xdrv01(byte function)
{ {
boolean result = false; boolean result = false;

View File

@ -1,5 +1,5 @@
/* /*
webserver.ino - webserver for Sonoff-Tasmota xdrv_02_webserver.ino - webserver for Sonoff-Tasmota
Copyright (C) 2018 Theo Arends Copyright (C) 2018 Theo Arends
@ -25,6 +25,12 @@
* Based on source by AlexT (https://github.com/tzapu) * Based on source by AlexT (https://github.com/tzapu)
\*********************************************************************************************/ \*********************************************************************************************/
#ifdef USE_RF_FLASH
uint8_t *efm8bb1_update = NULL;
#endif // USE_RF_FLASH
enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1 };
const char HTTP_HEAD[] PROGMEM = const char HTTP_HEAD[] PROGMEM =
"<!DOCTYPE html><html lang=\"" D_HTML_LANGUAGE "\" class=\"\">" "<!DOCTYPE html><html lang=\"" D_HTML_LANGUAGE "\" class=\"\">"
"<head>" "<head>"
@ -328,7 +334,6 @@ uint8_t upload_progress_dot_count;
uint8_t config_block_count = 0; uint8_t config_block_count = 0;
uint8_t config_xor_on = 0; uint8_t config_xor_on = 0;
uint8_t config_xor_on_set = CONFIG_FILE_XOR; uint8_t config_xor_on_set = CONFIG_FILE_XOR;
uint8_t *settings_new = NULL;
// Helper function to avoid code duplication (saves 4k Flash) // Helper function to avoid code duplication (saves 4k Flash)
static void WebGetArg(const char* arg, char* out, size_t max) static void WebGetArg(const char* arg, char* out, size_t max)
@ -338,6 +343,21 @@ static void WebGetArg(const char* arg, char* out, size_t max)
out[max-1] = '\0'; // Ensure terminating NUL out[max-1] = '\0'; // Ensure terminating NUL
} }
void ShowWebSource(int source)
{
if ((source > 0) && (source < SRC_MAX)) {
char stemp1[20];
snprintf_P(log_data, sizeof(log_data), PSTR("SRC: %s from %s"), GetTextIndexed(stemp1, sizeof(stemp1), source, kCommandSource), WebServer->client().remoteIP().toString().c_str());
AddLog(LOG_LEVEL_DEBUG);
}
}
void ExecuteWebCommand(char* svalue, int source)
{
ShowWebSource(source);
ExecuteCommand(svalue, SRC_IGNORE);
}
void StartWebserver(int type, IPAddress ipweb) void StartWebserver(int type, IPAddress ipweb)
{ {
if (!webserver_state) { if (!webserver_state) {
@ -568,22 +588,23 @@ void HandleAjaxStatusRefresh()
WebGetArg("o", tmp, sizeof(tmp)); WebGetArg("o", tmp, sizeof(tmp));
if (strlen(tmp)) { if (strlen(tmp)) {
ExecuteCommandPower(atoi(tmp), POWER_TOGGLE); ShowWebSource(SRC_WEBGUI);
ExecuteCommandPower(atoi(tmp), POWER_TOGGLE, SRC_IGNORE);
} }
WebGetArg("d", tmp, sizeof(tmp)); WebGetArg("d", tmp, sizeof(tmp));
if (strlen(tmp)) { if (strlen(tmp)) {
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_DIMMER " %s"), tmp); snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_DIMMER " %s"), tmp);
ExecuteCommand(svalue); ExecuteWebCommand(svalue, SRC_WEBGUI);
} }
WebGetArg("t", tmp, sizeof(tmp)); WebGetArg("t", tmp, sizeof(tmp));
if (strlen(tmp)) { if (strlen(tmp)) {
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_COLORTEMPERATURE " %s"), tmp); snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_COLORTEMPERATURE " %s"), tmp);
ExecuteCommand(svalue); ExecuteWebCommand(svalue, SRC_WEBGUI);
} }
WebGetArg("k", tmp, sizeof(tmp)); WebGetArg("k", tmp, sizeof(tmp));
if (strlen(tmp)) { if (strlen(tmp)) {
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RFKEY "%s"), tmp); snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RFKEY "%s"), tmp);
ExecuteCommand(svalue); ExecuteWebCommand(svalue, SRC_WEBGUI);
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{t}")); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{t}"));
@ -639,96 +660,6 @@ void HandleConfiguration()
ShowPage(page); ShowPage(page);
} }
boolean GetUsedInModule(byte val, uint8_t *arr)
{
int offset = 0;
if (!val) { return false; } // None
#ifndef USE_I2C
if (GPIO_I2C_SCL == val) { return true; }
if (GPIO_I2C_SDA == val) { return true; }
#endif
#ifndef USE_SR04
if (GPIO_SR04_TRIG == val) { return true; }
if (GPIO_SR04_ECHO == val) { return true; }
#endif
#ifndef USE_WS2812
if (GPIO_WS2812 == val) { return true; }
#endif
#ifndef USE_IR_REMOTE
if (GPIO_IRSEND == val) { return true; }
#ifndef USE_IR_RECEIVE
if (GPIO_IRRECV == val) { return true; }
#endif
#endif
#ifndef USE_MHZ19
if (GPIO_MHZ_TXD == val) { return true; }
if (GPIO_MHZ_RXD == val) { return true; }
#endif
#ifndef USE_PZEM004T
if (GPIO_PZEM_TX == val) { return true; }
if (GPIO_PZEM_RX == val) { return true; }
#endif
#ifndef USE_SENSEAIR
if (GPIO_SAIR_TX == val) { return true; }
if (GPIO_SAIR_RX == val) { return true; }
#endif
#ifndef USE_SPI
if (GPIO_SPI_CS == val) { return true; }
if (GPIO_SPI_DC == val) { return true; }
#endif
#ifndef USE_DISPLAY
if (GPIO_BACKLIGHT == val) { return true; }
#endif
#ifndef USE_PMS5003
if (GPIO_PMS5003 == val) { return true; }
#endif
#ifndef USE_NOVA_SDS
if (GPIO_SDS0X1 == val) { return true; }
#endif
#ifndef USE_SERIAL_BRIDGE
if (GPIO_SBR_TX == val) { return true; }
if (GPIO_SBR_RX == val) { return true; }
#endif
#ifndef USE_SR04
if (GPIO_SR04_TRIG == val) { return true; }
if (GPIO_SR04_ECHO == val) { return true; }
#endif
#ifndef USE_SDM120
if (GPIO_SDM120_TX == val) { return true; }
if (GPIO_SDM120_RX == val) { return true; }
#endif
#ifndef USE_SDM630
if (GPIO_SDM630_TX == val) { return true; }
if (GPIO_SDM630_RX == val) { return true; }
#endif
if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) {
offset = (GPIO_REL1_INV - GPIO_REL1);
}
if ((val >= GPIO_REL1_INV) && (val < GPIO_REL1_INV + MAX_RELAYS)) {
offset = -(GPIO_REL1_INV - GPIO_REL1);
}
if ((val >= GPIO_LED1) && (val < GPIO_LED1 + MAX_LEDS)) {
offset = (GPIO_LED1_INV - GPIO_LED1);
}
if ((val >= GPIO_LED1_INV) && (val < GPIO_LED1_INV + MAX_LEDS)) {
offset = -(GPIO_LED1_INV - GPIO_LED1);
}
if ((val >= GPIO_PWM1) && (val < GPIO_PWM1 + MAX_PWMS)) {
offset = (GPIO_PWM1_INV - GPIO_PWM1);
}
if ((val >= GPIO_PWM1_INV) && (val < GPIO_PWM1_INV + MAX_PWMS)) {
offset = -(GPIO_PWM1_INV - GPIO_PWM1);
}
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
if (arr[i] == val) { return true; }
if (arr[i] == val + offset) { return true; }
}
return false;
}
void HandleModuleConfiguration() void HandleModuleConfiguration()
{ {
if (HttpUser()) { return; } if (HttpUser()) { return; }
@ -1005,25 +936,34 @@ void HandleBackupConfiguration()
if (HttpUser()) { return; } if (HttpUser()) { return; }
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_BACKUP_CONFIGURATION)); AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_BACKUP_CONFIGURATION));
uint8_t buffer[sizeof(Settings)]; if (!SettingsBufferAlloc()) { return; }
WiFiClient myClient = WebServer->client(); WiFiClient myClient = WebServer->client();
WebServer->setContentLength(sizeof(buffer)); WebServer->setContentLength(sizeof(Settings));
char attachment[100]; char attachment[100];
char friendlyname[sizeof(Settings.friendlyname[0])]; char friendlyname[sizeof(Settings.friendlyname[0])];
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(friendlyname, Settings.friendlyname[0]), my_version); snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(friendlyname, Settings.friendlyname[0]), my_version);
WebServer->sendHeader(F("Content-Disposition"), attachment); WebServer->sendHeader(F("Content-Disposition"), attachment);
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), ""); WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
memcpy(buffer, &Settings, sizeof(buffer)); memcpy(settings_buffer, &Settings, sizeof(Settings));
buffer[0] = CONFIG_FILE_SIGN; if (config_xor_on_set) {
buffer[1] = (!config_xor_on_set) ? 0 : 1; for (uint16_t i = 2; i < sizeof(Settings); i++) {
if (buffer[1]) { settings_buffer[i] ^= (config_xor_on_set +i);
for (uint16_t i = 2; i < sizeof(buffer); i++) {
buffer[i] ^= (config_xor_on_set +i);
} }
} }
myClient.write((const char*)buffer, sizeof(buffer));
#ifdef ARDUINO_ESP8266_RELEASE_2_3_0
size_t written = myClient.write((const char*)settings_buffer, sizeof(Settings));
if (written < sizeof(Settings)) { // https://github.com/esp8266/Arduino/issues/3218
myClient.write((const char*)settings_buffer +written, sizeof(Settings) -written);
}
#else
myClient.write((const char*)settings_buffer, sizeof(Settings));
#endif
SettingsBufferFree();
} }
void HandleSaveSettings() void HandleSaveSettings()
@ -1186,6 +1126,7 @@ void HandleSaveSettings()
} }
ShowPage(page); ShowPage(page);
ShowWebSource(SRC_WEBGUI);
restart_flag = 2; restart_flag = 2;
} else { } else {
HandleConfiguration(); HandleConfiguration();
@ -1209,7 +1150,7 @@ void HandleResetConfiguration()
ShowPage(page); ShowPage(page);
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RESET " 1")); snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RESET " 1"));
ExecuteCommand(svalue); ExecuteWebCommand(svalue, SRC_WEBGUI);
} }
void HandleRestoreConfiguration() void HandleRestoreConfiguration()
@ -1227,7 +1168,7 @@ void HandleRestoreConfiguration()
ShowPage(page); ShowPage(page);
upload_error = 0; upload_error = 0;
upload_file_type = 1; upload_file_type = UPL_SETTINGS;
} }
void HandleUpgradeFirmware() void HandleUpgradeFirmware()
@ -1246,7 +1187,7 @@ void HandleUpgradeFirmware()
ShowPage(page); ShowPage(page);
upload_error = 0; upload_error = 0;
upload_file_type = 0; upload_file_type = UPL_TASMOTA;
} }
void HandleUpgradeFirmwareStart() void HandleUpgradeFirmwareStart()
@ -1261,7 +1202,7 @@ void HandleUpgradeFirmwareStart()
WebGetArg("o", tmp, sizeof(tmp)); WebGetArg("o", tmp, sizeof(tmp));
if (strlen(tmp)) { if (strlen(tmp)) {
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_OTAURL " %s"), tmp); snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_OTAURL " %s"), tmp);
ExecuteCommand(svalue); ExecuteWebCommand(svalue, SRC_WEBGUI);
} }
String page = FPSTR(HTTP_HEAD); String page = FPSTR(HTTP_HEAD);
@ -1273,15 +1214,7 @@ void HandleUpgradeFirmwareStart()
ShowPage(page); ShowPage(page);
snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_UPGRADE " 1")); snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_UPGRADE " 1"));
ExecuteCommand(svalue); ExecuteWebCommand(svalue, SRC_WEBGUI);
}
void SettingsNewFree()
{
if (settings_new != NULL) {
free(settings_new);
settings_new = NULL;
}
} }
void HandleUploadDone() void HandleUploadDone()
@ -1311,6 +1244,12 @@ void HandleUploadDone()
case 7: strncpy_P(error, PSTR(D_UPLOAD_ERR_7), sizeof(error)); break; case 7: strncpy_P(error, PSTR(D_UPLOAD_ERR_7), sizeof(error)); break;
case 8: strncpy_P(error, PSTR(D_UPLOAD_ERR_8), sizeof(error)); break; case 8: strncpy_P(error, PSTR(D_UPLOAD_ERR_8), sizeof(error)); break;
case 9: strncpy_P(error, PSTR(D_UPLOAD_ERR_9), sizeof(error)); break; case 9: strncpy_P(error, PSTR(D_UPLOAD_ERR_9), sizeof(error)); break;
#ifdef USE_RF_FLASH
case 10: strncpy_P(error, PSTR(D_UPLOAD_ERR_10), sizeof(error)); break;
case 11: strncpy_P(error, PSTR(D_UPLOAD_ERR_11), sizeof(error)); break;
case 12: strncpy_P(error, PSTR(D_UPLOAD_ERR_12), sizeof(error)); break;
case 13: strncpy_P(error, PSTR(D_UPLOAD_ERR_13), sizeof(error)); break;
#endif
default: default:
snprintf_P(error, sizeof(error), PSTR(D_UPLOAD_ERROR_CODE " %d"), upload_error); snprintf_P(error, sizeof(error), PSTR(D_UPLOAD_ERROR_CODE " %d"), upload_error);
} }
@ -1321,9 +1260,10 @@ void HandleUploadDone()
} else { } else {
page += F("green'>" D_SUCCESSFUL "</font></b><br/>"); page += F("green'>" D_SUCCESSFUL "</font></b><br/>");
page += FPSTR(HTTP_MSG_RSTRT); page += FPSTR(HTTP_MSG_RSTRT);
restart_flag = 2; ShowWebSource(SRC_WEBGUI);
restart_flag = 2; // Always restart to re-enable disabled features during update
} }
SettingsNewFree(); SettingsBufferFree();
page += F("</div><br/>"); page += F("</div><br/>");
page += FPSTR(HTTP_BTN_MAIN); page += FPSTR(HTTP_BTN_MAIN);
ShowPage(page); ShowPage(page);
@ -1336,7 +1276,7 @@ void HandleUploadLoop()
if (HTTP_USER == webserver_state) { return; } if (HTTP_USER == webserver_state) { return; }
if (upload_error) { if (upload_error) {
if (!upload_file_type) { Update.end(); } if (UPL_TASMOTA == upload_file_type) { Update.end(); }
return; return;
} }
@ -1345,16 +1285,15 @@ void HandleUploadLoop()
if (UPLOAD_FILE_START == upload.status) { if (UPLOAD_FILE_START == upload.status) {
restart_flag = 60; restart_flag = 60;
if (0 == upload.filename.c_str()[0]) { if (0 == upload.filename.c_str()[0]) {
upload_error = 1; upload_error = 1; // No file selected
return; return;
} }
SettingsSave(1); // Free flash for upload SettingsSave(1); // Free flash for upload
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str()); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str());
AddLog(LOG_LEVEL_INFO); AddLog(LOG_LEVEL_INFO);
if (upload_file_type) { if (UPL_SETTINGS == upload_file_type) {
SettingsNewFree(); if (!SettingsBufferAlloc()) {
if (!(settings_new = (uint8_t *)malloc(sizeof(Settings)))) { upload_error = 2; // Not enough space
upload_error = 2;
return; return;
} }
} else { } else {
@ -1368,45 +1307,93 @@ void HandleUploadLoop()
if (Settings.flag.mqtt_enabled) MqttDisconnect(); if (Settings.flag.mqtt_enabled) MqttDisconnect();
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if (!Update.begin(maxSketchSpace)) { //start with max available size if (!Update.begin(maxSketchSpace)) { //start with max available size
upload_error = 2;
// if (_serialoutput) Update.printError(Serial);
// if (Update.getError() == UPDATE_ERROR_BOOTSTRAP) {
// if (_serialoutput) Serial.println("Device still in UART update mode, perform powercycle");
// }
upload_error = 2; // Not enough space
return; return;
} }
} }
upload_progress_dot_count = 0; upload_progress_dot_count = 0;
} else if (!upload_error && (UPLOAD_FILE_WRITE == upload.status)) { } else if (!upload_error && (UPLOAD_FILE_WRITE == upload.status)) {
if (0 == upload.totalSize) { if (0 == upload.totalSize) {
if (upload_file_type) { if (UPL_SETTINGS == upload_file_type) {
if (upload.buf[0] != CONFIG_FILE_SIGN) {
upload_error = 8;
return;
}
config_xor_on = upload.buf[1];
config_block_count = 0; config_block_count = 0;
} else { }
if (upload.buf[0] != 0xE9) { else {
upload_error = 3; #ifdef USE_RF_FLASH
return; if ((SONOFF_BRIDGE == Settings.module) && (upload.buf[0] == ':')) { // Check if this is a RF bridge FW file
Update.end(); // End esp8266 update session
upload_file_type = UPL_EFM8BB1;
upload_error = SnfBrUpdateInit();
if (upload_error != 0) { return; }
} else
#endif // USE_RF_FLASH
{
if (upload.buf[0] != 0xE9) {
upload_error = 3; // Magic byte is not 0xE9
return;
}
uint32_t bin_flash_size = ESP.magicFlashChipSize((upload.buf[3] & 0xf0) >> 4);
if(bin_flash_size > ESP.getFlashChipRealSize()) {
upload_error = 4; // Program flash size is larger than real flash size
return;
}
upload.buf[2] = 3; // Force DOUT - ESP8285
} }
uint32_t bin_flash_size = ESP.magicFlashChipSize((upload.buf[3] & 0xf0) >> 4);
if(bin_flash_size > ESP.getFlashChipRealSize()) {
upload_error = 4;
return;
}
upload.buf[2] = 3; // Force DOUT - ESP8285
} }
} }
if (upload_file_type) { // config if (UPL_SETTINGS == upload_file_type) {
if (!upload_error) { if (!upload_error) {
if (upload.currentSize > (sizeof(Settings) - (config_block_count * HTTP_UPLOAD_BUFLEN))) { if (upload.currentSize > (sizeof(Settings) - (config_block_count * HTTP_UPLOAD_BUFLEN))) {
upload_error = 9; upload_error = 9; // File too large
return; return;
} }
memcpy(settings_new + (config_block_count * HTTP_UPLOAD_BUFLEN), upload.buf, upload.currentSize); memcpy(settings_buffer + (config_block_count * HTTP_UPLOAD_BUFLEN), upload.buf, upload.currentSize);
config_block_count++; config_block_count++;
} }
} else { // firmware }
#ifdef USE_RF_FLASH
else if (UPL_EFM8BB1 == upload_file_type) {
if (efm8bb1_update != NULL) { // We have carry over data since last write, i. e. a start but not an end
ssize_t result = rf_glue_remnant_with_new_data_and_write(efm8bb1_update, upload.buf, upload.currentSize);
free(efm8bb1_update);
efm8bb1_update = NULL;
if (result != 0) {
upload_error = abs(result); // 2 = Not enough space, 8 = File invalid
return;
}
}
ssize_t result = rf_search_and_write(upload.buf, upload.currentSize);
if (result < 0) {
upload_error = abs(result);
return;
} else if (result > 0) {
if (result > upload.currentSize) {
// Offset is larger than the buffer supplied, this should not happen
upload_error = 9; // File too large - Failed to decode RF firmware
return;
}
// A remnant has been detected, allocate data for it plus a null termination byte
size_t remnant_sz = upload.currentSize - result;
efm8bb1_update = (uint8_t *) malloc(remnant_sz + 1);
if (efm8bb1_update == NULL) {
upload_error = 2; // Not enough space - Unable to allocate memory to store new RF firmware
return;
}
memcpy(efm8bb1_update, upload.buf + result, remnant_sz);
// Add null termination at the end of of remnant buffer
efm8bb1_update[remnant_sz] = '\0';
}
}
#endif // USE_RF_FLASH
else { // firmware
if (!upload_error && (Update.write(upload.buf, upload.currentSize) != upload.currentSize)) { if (!upload_error && (Update.write(upload.buf, upload.currentSize) != upload.currentSize)) {
upload_error = 5; upload_error = 5; // Upload buffer miscompare
return; return;
} }
if (_serialoutput) { if (_serialoutput) {
@ -1419,20 +1406,45 @@ void HandleUploadLoop()
if (_serialoutput && (upload_progress_dot_count % 80)) { if (_serialoutput && (upload_progress_dot_count % 80)) {
Serial.println(); Serial.println();
} }
if (upload_file_type) { if (UPL_SETTINGS == upload_file_type) {
if (config_xor_on) { if (config_xor_on_set) {
for (uint16_t i = 2; i < sizeof(Settings); i++) { for (uint16_t i = 2; i < sizeof(Settings); i++) {
settings_new[i] ^= (config_xor_on_set +i); settings_buffer[i] ^= (config_xor_on_set +i);
} }
} }
SettingsDefaultSet2(); bool valid_settings = false;
memcpy((char*)&Settings +16, settings_new +16, sizeof(Settings) -16); unsigned long buffer_version = settings_buffer[11] << 24 | settings_buffer[10] << 16 | settings_buffer[9] << 8 | settings_buffer[8];
memcpy((char*)&Settings +8, settings_new +8, 4); // Restore version and auto upgrade if (buffer_version > 0x06000000) {
SettingsNewFree(); uint16_t buffer_size = settings_buffer[3] << 8 | settings_buffer[2];
} else { uint16_t buffer_crc = settings_buffer[15] << 8 | settings_buffer[14];
uint16_t crc = 0;
for (uint16_t i = 0; i < buffer_size; i++) {
if ((i < 14) || (i > 15)) { crc += settings_buffer[i]*(i+1); } // Skip crc
}
valid_settings = (buffer_crc == crc);
} else {
valid_settings = (settings_buffer[0] == CONFIG_FILE_SIGN);
}
if (valid_settings) {
SettingsDefaultSet2();
memcpy((char*)&Settings +16, settings_buffer +16, sizeof(Settings) -16);
Settings.version = buffer_version; // Restore version and auto upgrade after restart
SettingsBufferFree();
} else {
upload_error = 8; // File invalid
return;
}
}
#ifdef USE_RF_FLASH
else if (UPL_EFM8BB1 == upload_file_type) {
// RF FW flash done
upload_file_type = UPL_TASMOTA;
}
#endif // USE_RF_FLASH
else {
if (!Update.end(true)) { // true to set the size to the current progress if (!Update.end(true)) { // true to set the size to the current progress
if (_serialoutput) { Update.printError(Serial); } if (_serialoutput) { Update.printError(Serial); }
upload_error = 6; upload_error = 6; // Upload failed. Enable logging 3
return; return;
} }
} }
@ -1443,8 +1455,8 @@ void HandleUploadLoop()
} else if (UPLOAD_FILE_ABORTED == upload.status) { } else if (UPLOAD_FILE_ABORTED == upload.status) {
restart_flag = 0; restart_flag = 0;
MqttRetryCounter(0); MqttRetryCounter(0);
upload_error = 7; upload_error = 7; // Upload aborted
if (!upload_file_type) { Update.end(); } if (UPL_TASMOTA == upload_file_type) { Update.end(); }
} }
delay(0); delay(0);
} }
@ -1470,16 +1482,16 @@ void HandleHttpCommand()
WebGetArg("user", tmp1, sizeof(tmp1)); WebGetArg("user", tmp1, sizeof(tmp1));
char tmp2[100]; char tmp2[100];
WebGetArg("password", tmp2, sizeof(tmp2)); WebGetArg("password", tmp2, sizeof(tmp2));
if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, Settings.web_password))) { if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, Settings.web_password))) { valid = 0; }
valid = 0;
}
} }
String message = F("{\"" D_RSLT_WARNING "\":\""); String message = F("{\"" D_RSLT_WARNING "\":\"");
if (valid) { if (valid) {
byte curridx = web_log_index; byte curridx = web_log_index;
WebGetArg("cmnd", svalue, sizeof(svalue)); WebGetArg("cmnd", svalue, sizeof(svalue));
if (strlen(svalue)) { ExecuteCommand(svalue); } if (strlen(svalue)) {
ExecuteWebCommand(svalue, SRC_WEBCOMMAND);
}
if (web_log_index != curridx) { if (web_log_index != curridx) {
byte counter = curridx; byte counter = curridx;
@ -1538,7 +1550,7 @@ void HandleAjaxConsoleRefresh()
if (strlen(svalue)) { if (strlen(svalue)) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue);
AddLog(LOG_LEVEL_INFO); AddLog(LOG_LEVEL_INFO);
ExecuteCommand(svalue); ExecuteWebCommand(svalue, SRC_WEBCONSOLE);
} }
WebGetArg("c2", svalue, sizeof(svalue)); WebGetArg("c2", svalue, sizeof(svalue));
@ -1713,6 +1725,7 @@ void HandleRestart()
} }
ShowPage(page); ShowPage(page);
ShowWebSource(SRC_WEBGUI);
restart_flag = 2; restart_flag = 2;
} }
@ -1765,4 +1778,202 @@ boolean ValidIpAddress(String str)
} }
return true; return true;
} }
/*********************************************************************************************/
String UrlEncode(const String& text)
{
const char hex[] = "0123456789ABCDEF";
String encoded = "";
int len = text.length();
int i = 0;
while (i < len) {
char decodedChar = text.charAt(i++);
/*
if (('a' <= decodedChar && decodedChar <= 'z') ||
('A' <= decodedChar && decodedChar <= 'Z') ||
('0' <= decodedChar && decodedChar <= '9') ||
('=' == decodedChar)) {
encoded += decodedChar;
} else {
encoded += '%';
encoded += hex[decodedChar >> 4];
encoded += hex[decodedChar & 0xF];
}
*/
if (' ' == decodedChar) {
encoded += '%';
encoded += hex[decodedChar >> 4];
encoded += hex[decodedChar & 0xF];
} else {
encoded += decodedChar;
}
}
return encoded;
}
int WebSend(char *buffer)
{
// http://192.168.178.86:80/cm?user=admin&password=joker&cmnd=POWER1 ON
// http://192.168.178.86:80/cm?cmnd=POWER1 ON
// [192.168.178.86:80,admin:joker] POWER1 ON
char *host;
char *port;
char *user;
char *password;
char *command;
uint16_t nport = 80;
int status = 1; // Wrong parameters
host = strtok_r(buffer, "]", &command); // buffer = [192.168.178.86:80,admin:joker] POWER1 ON
if (host && command) {
host = LTrim(host);
host++; // Skip [
host = strtok_r(host, ",", &user); // host = 192.168.178.86:80,admin:joker > 192.168.178.86:80
host = strtok_r(host, ":", &port); // host = 192.168.178.86:80 > 192.168.178.86
if (user) {
user = strtok_r(user, ":", &password); // user = admin:joker > admin
}
//snprintf_P(log_data, sizeof(log_data), PSTR("DBG: Buffer |%X|, Host |%X|, Port |%X|, User |%X|, Password |%X|, Command |%X|"), buffer, host, port, user, password, command);
//AddLog(LOG_LEVEL_DEBUG);
if (port) { nport = atoi(port); }
String nuri = "";
if (user && password) {
nuri += F("user=");
nuri += user;
nuri += F("&password=");
nuri += password;
nuri += F("&");
}
nuri += F("cmnd=");
nuri += LTrim(command);
String uri = UrlEncode(nuri);
IPAddress host_ip;
if (WiFi.hostByName(host, host_ip)) {
WiFiClient client;
bool connected = false;
byte retry = 2;
while ((retry > 0) && !connected) {
--retry;
connected = client.connect(host_ip, nport);
if (connected) break;
}
if (connected) {
String url = F("GET /cm?");
url += uri;
url += F(" HTTP/1.1\r\n Host: ");
url += IPAddress(host_ip).toString();
if (port) {
url += F(" \r\n Port: ");
url += port;
}
url += F(" \r\n Connection: close\r\n\r\n");
//snprintf_P(log_data, sizeof(log_data), PSTR("DBG: Url |%s|"), url.c_str());
//AddLog(LOG_LEVEL_DEBUG);
client.print(url.c_str());
client.flush();
client.stop();
status = 0; // No error - Done
} else {
status = 2; // Connection failed
}
} else {
status = 3; // Host not found
}
}
return status;
}
/*********************************************************************************************/
enum WebCommands { CMND_WEBSERVER, CMND_WEBPASSWORD, CMND_WEBLOG, CMND_WEBSEND, CMND_EMULATION };
const char kWebCommands[] PROGMEM = D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_WEBSEND "|" D_CMND_EMULATION ;
const char kWebSendStatus[] PROGMEM = D_JSON_DONE "|" D_JSON_WRONG_PARAMETERS "|" D_JSON_CONNECT_FAILED "|" D_JSON_HOST_NOT_FOUND ;
bool WebCommand()
{
char command[CMDSZ];
bool serviced = true;
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kWebCommands);
if (-1 == command_code) {
serviced = false; // Unknown command
}
if (CMND_WEBSERVER == command_code) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { Settings.webserver = XdrvMailbox.payload; }
if (Settings.webserver) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_JSON_ACTIVE_FOR " %s " D_JSON_ON_DEVICE " %s " D_JSON_WITH_IP_ADDRESS " %s\"}"),
(2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str());
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(0));
}
}
else if (CMND_WEBPASSWORD == command_code) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.web_password))) {
strlcpy(Settings.web_password, (!strcmp(XdrvMailbox.data,"0")) ? "" : (1 == XdrvMailbox.payload) ? WEB_PASSWORD : XdrvMailbox.data, sizeof(Settings.web_password));
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, Settings.web_password);
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_ASTERIX, command);
}
}
else if (CMND_WEBLOG == command_code) {
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_ALL)) { Settings.weblog_level = XdrvMailbox.payload; }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.weblog_level);
}
else if (CMND_WEBSEND == command_code) {
if (XdrvMailbox.data_len > 0) {
uint8_t result = WebSend(XdrvMailbox.data);
char stemp1[20];
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetTextIndexed(stemp1, sizeof(stemp1), result, kWebSendStatus));
}
}
#ifdef USE_EMULATION
else if (CMND_EMULATION == command_code) {
if ((XdrvMailbox.payload >= EMUL_NONE) && (XdrvMailbox.payload < EMUL_MAX)) {
Settings.flag2.emulation = XdrvMailbox.payload;
restart_flag = 2;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.flag2.emulation);
}
#endif // USE_EMULATION
else serviced = false; // Unknown command
return serviced;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XDRV_02
boolean Xdrv02(byte function)
{
boolean result = false;
switch (function) {
case FUNC_LOOP:
PollDnsWebserver();
#ifdef USE_EMULATION
if (Settings.flag2.emulation) PollUdp();
#endif // USE_EMULATION
break;
case FUNC_COMMAND:
result = WebCommand();
break;
}
return result;
}
#endif // USE_WEBSERVER #endif // USE_WEBSERVER

View File

@ -281,6 +281,9 @@ long cf_pulses_last_time = CSE_PULSES_NOT_INITIALIZED;
void CseReceived() void CseReceived()
{ {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// 55 5A 02 F7 60 00 03 AB 00 40 10 02 60 5D 51 A6 58 03 E9 EF 71 0B 7A 36
// Hd Id VCal---- Voltage- ICal---- Current- PCal---- Power--- Ad CF--- Ck
AddLogSerial(LOG_LEVEL_DEBUG_MORE); AddLogSerial(LOG_LEVEL_DEBUG_MORE);
uint8_t header = serial_in_buffer[0]; uint8_t header = serial_in_buffer[0];
@ -371,7 +374,12 @@ bool CseSerialInput()
return 1; return 1;
} }
} else { } else {
if (0x5A == serial_in_byte) { // 0x5A - Packet header 2 if ((0x5A == serial_in_byte) && (serial_in_byte_counter)) { // 0x5A - Packet header 2
if (serial_in_byte_counter > 1) { // Sync buffer with data (issue #1907)
serial_in_buffer[0] = serial_in_buffer[--serial_in_byte_counter];
serial_in_byte_counter = 1;
AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: Fixed out-of-sync"));
}
cse_receive_flag = 1; cse_receive_flag = 1;
} else { } else {
serial_in_byte_counter = 0; serial_in_byte_counter = 0;
@ -476,7 +484,17 @@ bool PzemReceiveReady()
bool PzemRecieve(uint8_t resp, float *data) bool PzemRecieve(uint8_t resp, float *data)
{ {
uint8_t buffer[sizeof(PZEMCommand)]; // 0 1 2 3 4 5 6
// A4 00 00 00 00 00 A4 - Set address
// A0 00 D4 07 00 00 7B - Voltage (212.7V)
// A1 00 00 0A 00 00 AB - Current (0.1A)
// A1 00 00 00 00 00 A1 - No current
// A2 00 16 00 00 00 B8 - Power (22W)
// A2 00 00 00 00 00 A2 - No power
// A3 00 08 A4 00 00 4F - Energy (2.212kWh)
// A3 01 86 9F 00 00 C9 - Energy (99.999kWh)
uint8_t buffer[sizeof(PZEMCommand)] = { 0 };
unsigned long start = millis(); unsigned long start = millis();
uint8_t len = 0; uint8_t len = 0;
@ -486,6 +504,10 @@ bool PzemRecieve(uint8_t resp, float *data)
if (!c && !len) { if (!c && !len) {
continue; // skip 0 at startup continue; // skip 0 at startup
} }
if ((1 == len) && (buffer[0] == c)) {
len--;
continue; // fix skewed data
}
buffer[len++] = c; buffer[len++] = c;
} }
} }
@ -721,7 +743,7 @@ void EnergyMarginCheck()
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXPOWERREACHED "\":\"%d%s\"}"), energy_power_u, (Settings.flag.value_units) ? " " D_UNIT_WATT : ""); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXPOWERREACHED "\":\"%d%s\"}"), energy_power_u, (Settings.flag.value_units) ? " " D_UNIT_WATT : "");
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING); MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
EnergyMqttShow(); EnergyMqttShow();
ExecuteCommandPower(1, POWER_OFF); ExecuteCommandPower(1, POWER_OFF, SRC_MAXPOWER);
if (!energy_mplr_counter) { if (!energy_mplr_counter) {
energy_mplr_counter = Settings.param[P_MAX_POWER_RETRY] +1; energy_mplr_counter = Settings.param[P_MAX_POWER_RETRY] +1;
} }
@ -743,7 +765,7 @@ void EnergyMarginCheck()
if (energy_mplr_counter) { if (energy_mplr_counter) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_POWERMONITOR "\":\"%s\"}"), GetStateText(1)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_POWERMONITOR "\":\"%s\"}"), GetStateText(1));
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_POWERMONITOR)); MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_POWERMONITOR));
ExecuteCommandPower(1, POWER_ON); ExecuteCommandPower(1, POWER_ON, SRC_MAXPOWER);
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXPOWERREACHEDRETRY "\":\"%s\"}"), GetStateText(0)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXPOWERREACHEDRETRY "\":\"%s\"}"), GetStateText(0));
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING); MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
@ -761,7 +783,7 @@ void EnergyMarginCheck()
energy_max_energy_state = 1; energy_max_energy_state = 1;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_ENERGYMONITOR "\":\"%s\"}"), GetStateText(1)); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_ENERGYMONITOR "\":\"%s\"}"), GetStateText(1));
MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_ENERGYMONITOR)); MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_ENERGYMONITOR));
ExecuteCommandPower(1, POWER_ON); ExecuteCommandPower(1, POWER_ON, SRC_MAXENERGY);
} }
else if ((1 == energy_max_energy_state) && (energy_daily_u >= Settings.energy_max_energy)) { else if ((1 == energy_max_energy_state) && (energy_daily_u >= Settings.energy_max_energy)) {
energy_max_energy_state = 2; energy_max_energy_state = 2;
@ -769,7 +791,7 @@ void EnergyMarginCheck()
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXENERGYREACHED "\":\"%s%s\"}"), mqtt_data, (Settings.flag.value_units) ? " " D_UNIT_KILOWATTHOUR : ""); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXENERGYREACHED "\":\"%s%s\"}"), mqtt_data, (Settings.flag.value_units) ? " " D_UNIT_KILOWATTHOUR : "");
MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING); MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING);
EnergyMqttShow(); EnergyMqttShow();
ExecuteCommandPower(1, POWER_OFF); ExecuteCommandPower(1, POWER_OFF, SRC_MAXENERGY);
} }
} }
#endif // FEATURE_POWER_LIMIT #endif // FEATURE_POWER_LIMIT
@ -1143,7 +1165,7 @@ boolean Xdrv03(byte function)
if (energy_flg) { if (energy_flg) {
switch (function) { switch (function) {
case FUNC_INIT: case FUNC_PRE_INIT:
EnergyDrvInit(); EnergyDrvInit();
break; break;
case FUNC_COMMAND: case FUNC_COMMAND:

View File

@ -1,5 +1,5 @@
/* /*
xdrv_01_light.ino - PWM, WS2812 and sonoff led support for Sonoff-Tasmota xdrv_04_light.ino - PWM, WS2812 and sonoff led support for Sonoff-Tasmota
Copyright (C) 2018 Theo Arends Copyright (C) 2018 Theo Arends
@ -230,7 +230,7 @@ void AriluxRfHandler()
} }
} }
if (strlen(command)) { if (strlen(command)) {
ExecuteCommand(command); ExecuteCommand(command, SRC_LIGHT);
} }
} }
} }
@ -529,7 +529,7 @@ char* LightGetColor(uint8_t type, char* scolor)
void LightPowerOn() void LightPowerOn()
{ {
if (Settings.light_dimmer && !(light_power)) { if (Settings.light_dimmer && !(light_power)) {
ExecuteCommandPower(light_device, POWER_ON); ExecuteCommandPower(light_device, POWER_ON, SRC_LIGHT);
} }
} }
@ -585,11 +585,11 @@ void LightPreparePower()
{ {
if (Settings.light_dimmer && !(light_power)) { if (Settings.light_dimmer && !(light_power)) {
if (!Settings.flag.not_power_linked) { if (!Settings.flag.not_power_linked) {
ExecuteCommandPower(light_device, POWER_ON_NO_STATE); ExecuteCommandPower(light_device, POWER_ON_NO_STATE, SRC_LIGHT);
} }
} }
else if (!Settings.light_dimmer && light_power) { else if (!Settings.light_dimmer && light_power) {
ExecuteCommandPower(light_device, POWER_OFF_NO_STATE); ExecuteCommandPower(light_device, POWER_OFF_NO_STATE, SRC_LIGHT);
} }
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
DomoticzUpdatePowerState(light_device); DomoticzUpdatePowerState(light_device);
@ -1279,7 +1279,7 @@ boolean LightCommand()
if (coldim) { if (coldim) {
LightPreparePower(); LightPreparePower();
} }
return serviced; return serviced;
} }
@ -1287,15 +1287,15 @@ boolean LightCommand()
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
#define XDRV_01 #define XDRV_04
boolean Xdrv01(byte function) boolean Xdrv04(byte function)
{ {
boolean result = false; boolean result = false;
if (light_type) { if (light_type) {
switch (function) { switch (function) {
case FUNC_INIT: case FUNC_PRE_INIT:
LightInit(); LightInit();
break; break;
case FUNC_EVERY_50_MSECOND: case FUNC_EVERY_50_MSECOND:

View File

@ -1,5 +1,5 @@
/* /*
xdrv_02_irremote.ino - infra red support for Sonoff-Tasmota xdrv_05_irremote.ino - infra red support for Sonoff-Tasmota
Copyright (C) 2018 Heiko Krupp, Lazar Obradovic and Theo Arends Copyright (C) 2018 Heiko Krupp, Lazar Obradovic and Theo Arends
@ -110,6 +110,7 @@ void IrReceiveCheck()
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_IRRECEIVED "\":{\"" D_JSON_IR_PROTOCOL "\":\"%s\",\"" D_JSON_IR_BITS "\":%d,\"" D_JSON_IR_DATA "\":\"%lX\"}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_IRRECEIVED "\":{\"" D_JSON_IR_PROTOCOL "\":\"%s\",\"" D_JSON_IR_BITS "\":%d,\"" D_JSON_IR_DATA "\":\"%lX\"}}"),
GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, (uint32_t)results.value); GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, (uint32_t)results.value);
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED)); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED));
XdrvRulesProcess();
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
unsigned long value = results.value | (iridx << 28); // [Protocol:4, Data:28] unsigned long value = results.value | (iridx << 28); // [Protocol:4, Data:28]
DomoticzSensor(DZ_COUNT, value); // Send data as Domoticz Counter value DomoticzSensor(DZ_COUNT, value); // Send data as Domoticz Counter value
@ -392,15 +393,15 @@ boolean IrSendCommand()
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
#define XDRV_02 #define XDRV_05
boolean Xdrv02(byte function) boolean Xdrv05(byte function)
{ {
boolean result = false; boolean result = false;
if ((pin[GPIO_IRSEND] < 99) || (pin[GPIO_IRRECV] < 99)) { if ((pin[GPIO_IRSEND] < 99) || (pin[GPIO_IRRECV] < 99)) {
switch (function) { switch (function) {
case FUNC_INIT: case FUNC_PRE_INIT:
if (pin[GPIO_IRSEND] < 99) { if (pin[GPIO_IRSEND] < 99) {
IrSendInit(); IrSendInit();
} }

View File

@ -1,7 +1,7 @@
/* /*
xdrv_04_snfbridge.ino - sonoff RF bridge 433 support for Sonoff-Tasmota xdrv_06_snfbridge.ino - sonoff RF bridge 433 support for Sonoff-Tasmota
Copyright (C) 2018 Theo Arends Copyright (C) 2018 Theo Arends and Erik Andrén Zachrisson (fw update)
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -24,11 +24,12 @@
#define SFB_TIME_AVOID_DUPLICATE 2000 // Milliseconds #define SFB_TIME_AVOID_DUPLICATE 2000 // Milliseconds
enum SonoffBridgeCommands { enum SonoffBridgeCommands {
CMND_RFSYNC, CMND_RFLOW, CMND_RFHIGH, CMND_RFHOST, CMND_RFCODE, CMND_RFKEY }; CMND_RFSYNC, CMND_RFLOW, CMND_RFHIGH, CMND_RFHOST, CMND_RFCODE, CMND_RFKEY, CMND_RFRAW };
const char kSonoffBridgeCommands[] PROGMEM = const char kSonoffBridgeCommands[] PROGMEM =
D_CMND_RFSYNC "|" D_CMND_RFLOW "|" D_CMND_RFHIGH "|" D_CMND_RFHOST "|" D_CMND_RFCODE "|" D_CMND_RFKEY ; D_CMND_RFSYNC "|" D_CMND_RFLOW "|" D_CMND_RFHIGH "|" D_CMND_RFHOST "|" D_CMND_RFCODE "|" D_CMND_RFKEY "|" D_CMND_RFRAW;
uint8_t sonoff_bridge_receive_flag = 0; uint8_t sonoff_bridge_receive_flag = 0;
uint8_t sonoff_bridge_receive_raw_flag = 0;
uint8_t sonoff_bridge_learn_key = 1; uint8_t sonoff_bridge_learn_key = 1;
uint8_t sonoff_bridge_learn_active = 0; uint8_t sonoff_bridge_learn_active = 0;
uint8_t sonoff_bridge_expected_bytes = 0; uint8_t sonoff_bridge_expected_bytes = 0;
@ -37,6 +38,206 @@ uint32_t sonoff_bridge_last_send_code = 0;
unsigned long sonoff_bridge_last_time = 0; unsigned long sonoff_bridge_last_time = 0;
unsigned long sonoff_bridge_last_learn_time = 0; unsigned long sonoff_bridge_last_learn_time = 0;
#ifdef USE_RF_FLASH
/*********************************************************************************************\
* EFM8BB1 RF microcontroller in-situ firmware update
*
* Enables upload of EFM8BB1 firmware provided by https://github.com/Portisch/RF-Bridge-EFM8BB1 using the web gui.
* Based on source by Erik Andrén Zachrisson (https://github.com/arendst/Sonoff-Tasmota/pull/2886)
\*********************************************************************************************/
#include "ihx.h"
#include "c2.h"
#define RF_RECORD_NO_START_FOUND -1
#define RF_RECORD_NO_END_FOUND -2
ssize_t rf_find_hex_record_start(uint8_t *buf, size_t size)
{
for (int i = 0; i < size; i++) {
if (buf[i] == ':') {
return i;
}
}
return RF_RECORD_NO_START_FOUND;
}
ssize_t rf_find_hex_record_end(uint8_t *buf, size_t size)
{
for (ssize_t i = 0; i < size; i++) {
if (buf[i] == '\n') {
return i;
}
}
return RF_RECORD_NO_END_FOUND;
}
ssize_t rf_glue_remnant_with_new_data_and_write(const uint8_t *remnant_data, uint8_t *new_data, size_t new_data_len)
{
ssize_t record_start;
ssize_t record_end;
ssize_t glue_record_sz;
uint8_t *glue_buf;
ssize_t result;
if (remnant_data[0] != ':') { return -8; } // File invalid - RF Remnant data did not start with a start token
// Find end token in new data
record_end = rf_find_hex_record_end(new_data, new_data_len);
record_start = rf_find_hex_record_start(new_data, new_data_len);
// Be paranoid and check that there is no start marker before the end record
// If so this implies that there was something wrong with the last start marker saved
// in the last upload part
if ((record_start != RF_RECORD_NO_START_FOUND) && (record_start < record_end)) {
return -8; // File invalid - Unexpected RF start marker found before RF end marker
}
glue_record_sz = strlen((const char *) remnant_data) + record_end;
glue_buf = (uint8_t *) malloc(glue_record_sz);
if (glue_buf == NULL) { return -2; } // Not enough space
// Assemble new glue buffer
memcpy(glue_buf, remnant_data, strlen((const char *) remnant_data));
memcpy(glue_buf + strlen((const char *) remnant_data), new_data, record_end);
result = rf_decode_and_write(glue_buf, glue_record_sz);
free(glue_buf);
return result;
}
ssize_t rf_decode_and_write(uint8_t *record, size_t size)
{
uint8_t err = ihx_decode(record, size);
if (err != IHX_SUCCESS) { return -13; } // Failed to decode RF firmware
ihx_t *h = (ihx_t *) record;
if (h->record_type == IHX_RT_DATA) {
int retries = 5;
uint16_t address = h->address_high * 0x100 + h->address_low;
do {
err = c2_programming_init();
err = c2_block_write(address, h->data, h->len);
} while (err != C2_SUCCESS && retries--);
} else if (h->record_type == IHX_RT_END_OF_FILE) {
// RF firmware upgrade done, restarting RF chip
err = c2_reset();
}
if (err != C2_SUCCESS) { return -12; } // Failed to write to RF chip
return 0;
}
ssize_t rf_search_and_write(uint8_t *buf, size_t size)
{
// Binary contains a set of commands, decode and program each one
ssize_t rec_end;
ssize_t rec_start;
ssize_t err;
for (size_t i = 0; i < size; i++) {
// Find starts and ends of commands
rec_start = rf_find_hex_record_start(buf + i, size - i);
if (rec_start == RF_RECORD_NO_START_FOUND) {
// There is nothing left to save in this buffer
return -8; // File invalid
}
// Translate rec_start from local buffer position to chunk position
rec_start += i;
rec_end = rf_find_hex_record_end(buf + rec_start, size - rec_start);
if (rec_end == RF_RECORD_NO_END_FOUND) {
// We have found a start but not an end, save remnant
return rec_start;
}
// Translate rec_end from local buffer position to chunk position
rec_end += rec_start;
err = rf_decode_and_write(buf + rec_start, rec_end - rec_start);
if (err < 0) { return err; }
i = rec_end;
}
// Buffer was perfectly aligned, start and end found without any remaining trailing characters
return 0;
}
uint8_t rf_erase_flash()
{
uint8_t err;
for (int i = 0; i < 4; i++) { // HACK: Try multiple times as the command sometimes fails (unclear why)
err = c2_programming_init();
if (err != C2_SUCCESS) {
return 10; // Failed to init RF chip
}
err = c2_device_erase();
if (err != C2_SUCCESS) {
if (i < 3) {
c2_reset(); // Reset RF chip and try again
} else {
return 11; // Failed to erase RF chip
}
} else {
break;
}
}
return 0;
}
uint8_t SnfBrUpdateInit()
{
pinMode(PIN_C2CK, OUTPUT);
pinMode(PIN_C2D, INPUT);
return rf_erase_flash(); // 10, 11
}
#endif // USE_RF_FLASH
/********************************************************************************************/
void SonoffBridgeSendRaw(char *codes, int size)
{
char *p;
char stemp[3];
uint8_t code;
while (size > 0) {
snprintf(stemp, sizeof(stemp), codes);
code = strtol(stemp, &p, 16);
Serial.write(code);
size -= 2;
codes += 2;
}
}
void SonoffBridgeReceivedRaw()
{
// Decoding according to https://github.com/Portisch/RF-Bridge-EFM8BB1
uint8_t buckets = 0;
if (0xB1 == serial_in_buffer[1]) { buckets = serial_in_buffer[2] << 1; } // Bucket sniffing
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_RFRAW "\":{\"" D_JSON_DATA "\":\""));
for (int i = 0; i < serial_in_byte_counter; i++) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%02X"), mqtt_data, serial_in_buffer[i]);
if (0xB1 == serial_in_buffer[1]) {
if ((i > 3) && buckets) { buckets--; }
if ((i < 3) || (buckets % 2) || (i == serial_in_byte_counter -2)) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s "), mqtt_data);
}
}
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"}}"), mqtt_data);
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_CMND_RFRAW));
XdrvRulesProcess();
}
/********************************************************************************************/
void SonoffBridgeLearnFailed() void SonoffBridgeLearnFailed()
{ {
sonoff_bridge_learn_active = 0; sonoff_bridge_learn_active = 0;
@ -97,6 +298,7 @@ void SonoffBridgeReceived()
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_SYNC "\":%d,\"" D_JSON_LOW "\":%d,\"" D_JSON_HIGH "\":%d,\"" D_JSON_DATA "\":\"%06X\",\"" D_CMND_RFKEY "\":%s}}"), snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_SYNC "\":%d,\"" D_JSON_LOW "\":%d,\"" D_JSON_HIGH "\":%d,\"" D_JSON_DATA "\":\"%06X\",\"" D_CMND_RFKEY "\":%s}}"),
sync_time, low_time, high_time, received_id, rfkey); sync_time, low_time, high_time, received_id, rfkey);
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED)); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED));
XdrvRulesProcess();
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
DomoticzSensor(DZ_COUNT, received_id); // Send rid as Domoticz Counter value DomoticzSensor(DZ_COUNT, received_id); // Send rid as Domoticz Counter value
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ
@ -109,12 +311,28 @@ boolean SonoffBridgeSerialInput()
{ {
// iTead Rf Universal Transceiver Module Serial Protocol Version 1.0 (20170420) // iTead Rf Universal Transceiver Module Serial Protocol Version 1.0 (20170420)
if (sonoff_bridge_receive_flag) { if (sonoff_bridge_receive_flag) {
if (!((0 == serial_in_byte_counter) && (0 == serial_in_byte))) { // Skip leading 0 if (sonoff_bridge_receive_raw_flag) {
if (!serial_in_byte_counter) {
serial_in_buffer[serial_in_byte_counter++] = 0xAA;
}
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
if (0x55 == serial_in_byte) { // 0x55 - End of text
SonoffBridgeReceivedRaw();
sonoff_bridge_receive_flag = 0;
return 1;
}
}
else if (!((0 == serial_in_byte_counter) && (0 == serial_in_byte))) { // Skip leading 0
if (0 == serial_in_byte_counter) { if (0 == serial_in_byte_counter) {
sonoff_bridge_expected_bytes = 2; // 0xA0, 0xA1, 0xA2 sonoff_bridge_expected_bytes = 2; // 0xA0, 0xA1, 0xA2
if (serial_in_byte >= 0xA3) { if (serial_in_byte >= 0xA3) {
sonoff_bridge_expected_bytes = 11; // 0xA3, 0xA4, 0xA5 sonoff_bridge_expected_bytes = 11; // 0xA3, 0xA4, 0xA5
} }
if (serial_in_byte == 0xA6) {
sonoff_bridge_expected_bytes = 0; // 0xA6 and up supported by Portisch firmware only
serial_in_buffer[serial_in_byte_counter++] = 0xAA;
sonoff_bridge_receive_raw_flag = 1;
}
} }
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte; serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
if ((sonoff_bridge_expected_bytes == serial_in_byte_counter) && (0x55 == serial_in_byte)) { // 0x55 - End of text if ((sonoff_bridge_expected_bytes == serial_in_byte_counter) && (0x55 == serial_in_byte)) { // 0x55 - End of text
@ -133,6 +351,13 @@ boolean SonoffBridgeSerialInput()
return 0; return 0;
} }
void SonoffBridgeSendCommand(byte code)
{
Serial.write(0xAA); // Start of Text
Serial.write(code); // Command or Acknowledge
Serial.write(0x55); // End of Text
}
void SonoffBridgeSendAck() void SonoffBridgeSendAck()
{ {
Serial.write(0xAA); // Start of Text Serial.write(0xAA); // Start of Text
@ -293,23 +518,64 @@ boolean SonoffBridgeCommand()
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, sonoff_bridge_learn_key, D_JSON_LEARNING_ACTIVE); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, sonoff_bridge_learn_key, D_JSON_LEARNING_ACTIVE);
} }
}
else if (CMND_RFRAW == command_code) {
if (XdrvMailbox.data_len) {
if (XdrvMailbox.data_len < 6) { // On, Off
switch (XdrvMailbox.payload) {
case 0: // Receive Raw Off
SonoffBridgeSendCommand(0xA7); // Stop reading RF signals enabling iTead default RF handling
case 1: // Receive Raw On
sonoff_bridge_receive_raw_flag = XdrvMailbox.payload;
break;
case 166: // 0xA6 - Start reading RF signals disabling iTead default RF handling
case 167: // 0xA7 - Stop reading RF signals enabling iTead default RF handling
case 169: // 0xA9 - Start learning predefined protocols
case 176: // 0xB0 - Stop sniffing
case 177: // 0xB1 - Start sniffing
case 255: // 0xFF - Show firmware version
SonoffBridgeSendCommand(XdrvMailbox.payload);
sonoff_bridge_receive_raw_flag = 1;
break;
case 192: // 0xC0 - Beep
char beep[] = "AAC000C055";
SonoffBridgeSendRaw(beep, sizeof(beep));
break;
}
} else {
SonoffBridgeSendRaw(XdrvMailbox.data, XdrvMailbox.data_len);
sonoff_bridge_receive_raw_flag = 1;
}
}
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(sonoff_bridge_receive_raw_flag));
} else serviced = false; // Unknown command } else serviced = false; // Unknown command
return serviced; return serviced;
} }
/*********************************************************************************************/
void SonoffBridgeInit()
{
sonoff_bridge_receive_raw_flag = 0;
SonoffBridgeSendCommand(0xA7); // Stop reading RF signals enabling iTead default RF handling
}
/*********************************************************************************************\ /*********************************************************************************************\
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
#define XDRV_04 #define XDRV_06
boolean Xdrv04(byte function) boolean Xdrv06(byte function)
{ {
boolean result = false; boolean result = false;
if (SONOFF_BRIDGE == Settings.module) { if (SONOFF_BRIDGE == Settings.module) {
switch (function) { switch (function) {
case FUNC_INIT:
SonoffBridgeInit();
break;
case FUNC_COMMAND: case FUNC_COMMAND:
result = SonoffBridgeCommand(); result = SonoffBridgeCommand();
break; break;

View File

@ -1,5 +1,5 @@
/* /*
xdrv_05_domoticz.ino - domoticz support for Sonoff-Tasmota xdrv_07_domoticz.ino - domoticz support for Sonoff-Tasmota
Copyright (C) 2018 Theo Arends Copyright (C) 2018 Theo Arends
@ -265,7 +265,7 @@ boolean DomoticzCommand()
else serviced = false; // Unknown command else serviced = false; // Unknown command
} }
else serviced = false; // Unknown command else serviced = false; // Unknown command
return serviced; return serviced;
} }
@ -437,9 +437,9 @@ void DomoticzSaveSettings()
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
#define XDRV_05 #define XDRV_07
boolean Xdrv05(byte function) boolean Xdrv07(byte function)
{ {
boolean result = false; boolean result = false;

View File

@ -61,6 +61,7 @@ void SerialBridgeInput()
serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // serial data completed serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // serial data completed
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\"%s\"}"), serial_bridge_buffer); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\"%s\"}"), serial_bridge_buffer);
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED));
// XdrvRulesProcess();
serial_bridge_in_byte_counter = 0; serial_bridge_in_byte_counter = 0;
} }
} }
@ -134,7 +135,7 @@ boolean Xdrv08(byte function)
if (serial_bridge_active) { if (serial_bridge_active) {
switch (function) { switch (function) {
case FUNC_INIT: case FUNC_PRE_INIT:
SerialBridgeInit(); SerialBridgeInit();
break; break;
case FUNC_LOOP: case FUNC_LOOP:

View File

@ -287,10 +287,10 @@ void TimerEverySecond()
#ifdef USE_RULES #ifdef USE_RULES
if (3 == xtimer.power) { // Blink becomes Rule disregarding device and allowing use of Backlog commands if (3 == xtimer.power) { // Blink becomes Rule disregarding device and allowing use of Backlog commands
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Clock\":{\"Timer\":%d}}"), i +1); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Clock\":{\"Timer\":%d}}"), i +1);
RulesProcess(); XdrvRulesProcess();
} else } else
#endif // USE_RULES #endif // USE_RULES
if (devices_present) { ExecuteCommandPower(xtimer.device +1, xtimer.power); } if (devices_present) { ExecuteCommandPower(xtimer.device +1, xtimer.power, SRC_TIMER); }
} }
} }
} }
@ -726,7 +726,7 @@ boolean Xdrv09(byte function)
boolean result = false; boolean result = false;
switch (function) { switch (function) {
case FUNC_INIT: case FUNC_PRE_INIT:
TimerSetRandomWindows(); TimerSetRandomWindows();
break; break;
case FUNC_EVERY_SECOND: case FUNC_EVERY_SECOND:

View File

@ -86,10 +86,11 @@ uint8_t rules_quota = 0;
long rules_new_power = -1; long rules_new_power = -1;
long rules_old_power = -1; long rules_old_power = -1;
uint32_t rules_triggers = 0; uint32_t rules_triggers[MAX_RULE_SETS] = { 0 };
uint8_t rules_trigger_count = 0; uint8_t rules_trigger_count[MAX_RULE_SETS] = { 0 };
uint8_t rules_teleperiod = 0; uint8_t rules_teleperiod = 0;
char event_data[100];
char vars[RULES_MAX_VARS][10] = { 0 }; char vars[RULES_MAX_VARS][10] = { 0 };
/*******************************************************************************************/ /*******************************************************************************************/
@ -141,7 +142,7 @@ bool TimeReached(unsigned long timer)
/*******************************************************************************************/ /*******************************************************************************************/
bool RulesRuleMatch(String &event, String &rule) bool RulesRuleMatch(byte rule_set, String &event, String &rule)
{ {
// event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} // event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}}
// event = {"System":{"Boot":1}} // event = {"System":{"Boot":1}}
@ -179,7 +180,7 @@ bool RulesRuleMatch(String &event, String &rule)
} }
} }
char tmp_value[CMDSZ] = { 0 }; char rule_svalue[CMDSZ] = { 0 };
double rule_value = 0; double rule_value = 0;
if (pos > 0) { if (pos > 0) {
String rule_param = rule_name.substring(pos + 1); String rule_param = rule_name.substring(pos + 1);
@ -198,13 +199,13 @@ bool RulesRuleMatch(String &event, String &rule)
} }
} }
rule_param.toUpperCase(); rule_param.toUpperCase();
snprintf(tmp_value, sizeof(tmp_value), rule_param.c_str()); snprintf(rule_svalue, sizeof(rule_svalue), rule_param.c_str());
int temp_value = GetStateNumber(tmp_value); int temp_value = GetStateNumber(rule_svalue);
if (temp_value > -1) { if (temp_value > -1) {
rule_value = temp_value; rule_value = temp_value;
} else { } else {
rule_value = CharToDouble((char*)tmp_value); // 0.1 - This saves 9k code over toFLoat()! rule_value = CharToDouble((char*)rule_svalue); // 0.1 - This saves 9k code over toFLoat()!
} }
rule_name = rule_name.substring(0, pos); // "CURRENT" rule_name = rule_name.substring(0, pos); // "CURRENT"
} }
@ -218,7 +219,7 @@ bool RulesRuleMatch(String &event, String &rule)
const char* str_value = root[rule_task][rule_name]; const char* str_value = root[rule_task][rule_name];
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Task %s, Name %s, Value |%s|, TrigCnt %d, TrigSt %d, Source %s, Json %s"), //snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Task %s, Name %s, Value |%s|, TrigCnt %d, TrigSt %d, Source %s, Json %s"),
// rule_task.c_str(), rule_name.c_str(), tmp_value, rules_trigger_count, bitRead(rules_triggers, rules_trigger_count), event.c_str(), (str_value) ? str_value : "none"); // rule_task.c_str(), rule_name.c_str(), rule_svalue, rules_trigger_count[rule_set], bitRead(rules_triggers[rule_set], rules_trigger_count[rule_set]), event.c_str(), (str_value) ? str_value : "none");
//AddLog(LOG_LEVEL_DEBUG); //AddLog(LOG_LEVEL_DEBUG);
if (!root[rule_task][rule_name].success()) { return false; } if (!root[rule_task][rule_name].success()) { return false; }
@ -231,13 +232,14 @@ bool RulesRuleMatch(String &event, String &rule)
value = CharToDouble((char*)str_value); value = CharToDouble((char*)str_value);
switch (compare) { switch (compare) {
case '>': case '>':
if (value > rule_value) match = true; if (value > rule_value) { match = true; }
break; break;
case '<': case '<':
if (value < rule_value) match = true; if (value < rule_value) { match = true; }
break; break;
case '=': case '=':
if (value == rule_value) match = true; // if (value == rule_value) { match = true; } // Compare values - only decimals or partly hexadecimals
if (!strcasecmp(str_value, rule_svalue)) { match = true; } // Compare strings - this also works for hexadecimals
break; break;
case ' ': case ' ':
match = true; // Json value but not needed match = true; // Json value but not needed
@ -247,13 +249,13 @@ bool RulesRuleMatch(String &event, String &rule)
if (Settings.flag.rules_once) { if (Settings.flag.rules_once) {
if (match) { // Only allow match state changes if (match) { // Only allow match state changes
if (!bitRead(rules_triggers, rules_trigger_count)) { if (!bitRead(rules_triggers[rule_set], rules_trigger_count[rule_set])) {
bitSet(rules_triggers, rules_trigger_count); bitSet(rules_triggers[rule_set], rules_trigger_count[rule_set]);
} else { } else {
match = false; match = false;
} }
} else { } else {
bitClear(rules_triggers, rules_trigger_count); bitClear(rules_triggers[rule_set], rules_trigger_count[rule_set]);
} }
} }
@ -262,24 +264,19 @@ bool RulesRuleMatch(String &event, String &rule)
/*******************************************************************************************/ /*******************************************************************************************/
bool RulesProcess() bool RuleSetProcess(byte rule_set, String &event_saved)
{ {
bool serviced = false; bool serviced = false;
char stemp[10]; char stemp[10];
delay(0); // Prohibit possible loop software watchdog delay(0); // Prohibit possible loop software watchdog
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Event = %s, Rule = %s"), mqtt_data, Settings.rules); //snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Event = %s, Rule = %s"), event_saved.c_str(), Settings.rules[rule_set]);
//AddLog(LOG_LEVEL_DEBUG); //AddLog(LOG_LEVEL_DEBUG);
if (!Settings.flag.rules_enabled) { return serviced; } // Not enabled String rules = Settings.rules[rule_set];
if (!strlen(Settings.rules)) { return serviced; } // No rules
String event_saved = mqtt_data; rules_trigger_count[rule_set] = 0;
event_saved.toUpperCase();
String rules = Settings.rules;
rules_trigger_count = 0;
int plen = 0; int plen = 0;
while (true) { while (true) {
rules = rules.substring(plen); // Select relative to last rule rules = rules.substring(plen); // Select relative to last rule
@ -304,7 +301,7 @@ bool RulesProcess()
//snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Event |%s|, Rule |%s|, Command(s) |%s|"), event.c_str(), event_trigger.c_str(), commands.c_str()); //snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Event |%s|, Rule |%s|, Command(s) |%s|"), event.c_str(), event_trigger.c_str(), commands.c_str());
//AddLog(LOG_LEVEL_DEBUG); //AddLog(LOG_LEVEL_DEBUG);
if (RulesRuleMatch(event, event_trigger)) { if (RulesRuleMatch(rule_set, event, event_trigger)) {
commands.trim(); commands.trim();
String ucommand = commands; String ucommand = commands;
ucommand.toUpperCase(); ucommand.toUpperCase();
@ -328,28 +325,45 @@ bool RulesProcess()
// snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, D_CMND_RULE, D_JSON_INITIATED); // snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, D_CMND_RULE, D_JSON_INITIATED);
// MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RULE)); // MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RULE));
ExecuteCommand(command); ExecuteCommand(command, SRC_RULE);
serviced = true; serviced = true;
} }
rules_trigger_count++; rules_trigger_count[rule_set]++;
} }
return serviced; return serviced;
} }
/*******************************************************************************************/ /*******************************************************************************************/
bool RulesProcess()
{
bool serviced = false;
String event_saved = mqtt_data;
event_saved.toUpperCase();
for (byte i = 0; i < MAX_RULE_SETS; i++) {
if (strlen(Settings.rules[i]) && bitRead(Settings.rule_enabled, i)) {
if (RuleSetProcess(i, event_saved)) { serviced = true; }
}
}
return serviced;
}
void RulesInit() void RulesInit()
{ {
if (Settings.rules[0] == '\0') { for (byte i = 0; i < MAX_RULE_SETS; i++) {
Settings.flag.rules_enabled = 0; if (Settings.rules[i][0] == '\0') {
Settings.flag.rules_once = 0; bitWrite(Settings.rule_enabled, i, 0);
bitWrite(Settings.rule_once, i, 0);
}
} }
rules_teleperiod = 0; rules_teleperiod = 0;
} }
void RulesEvery50ms() void RulesEvery50ms()
{ {
if (Settings.flag.rules_enabled) { if (Settings.rule_enabled) { // Any rule enabled
if (rules_new_power != rules_old_power) { if (rules_new_power != rules_old_power) {
if (rules_old_power != -1) { if (rules_old_power != -1) {
for (byte i = 0; i < devices_present; i++) { for (byte i = 0; i < devices_present; i++) {
@ -361,7 +375,26 @@ void RulesEvery50ms()
} }
} }
rules_old_power = rules_new_power; rules_old_power = rules_new_power;
} else { }
else if(event_data[0]) {
char *event;
char *parameter;
event = strtok_r(event_data, "=", &parameter); // event_data = fanspeed=10
if (event) {
event = Trim(event);
if (parameter) {
parameter = Trim(parameter);
} else {
parameter = event + strlen(event); // '\0'
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Event\":{\"%s\":\"%s\"}}"), event, parameter);
event_data[0] ='\0';
RulesProcess();
} else {
event_data[0] ='\0';
}
}
else {
rules_quota++; rules_quota++;
if (rules_quota &1) { // Every 100 ms if (rules_quota &1) { // Every 100 ms
mqtt_data[0] = '\0'; mqtt_data[0] = '\0';
@ -381,7 +414,7 @@ void RulesEvery50ms()
void RulesEverySecond() void RulesEverySecond()
{ {
if (Settings.flag.rules_enabled) { if (Settings.rule_enabled) { // Any rule enabled
for (byte i = 0; i < MAX_RULE_TIMERS; i++) { for (byte i = 0; i < MAX_RULE_TIMERS; i++) {
if (rules_timer[i] != 0L) { // Timer active? if (rules_timer[i] != 0L) { // Timer active?
if (TimeReached(rules_timer[i])) { // Timer finished? if (TimeReached(rules_timer[i])) { // Timer finished?
@ -416,39 +449,32 @@ boolean RulesCommand()
if (-1 == command_code) { if (-1 == command_code) {
serviced = false; // Unknown command serviced = false; // Unknown command
} }
else if (CMND_RULE == command_code) { else if ((CMND_RULE == command_code) && (index > 0) && (index <= MAX_RULE_SETS)) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules))) { if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules[index -1]))) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) {
switch (XdrvMailbox.payload) { switch (XdrvMailbox.payload) {
case 0: // Off case 0: // Off
case 1: // On case 1: // On
Settings.flag.rules_enabled = XdrvMailbox.payload; bitWrite(Settings.rule_enabled, index -1, XdrvMailbox.payload);
break; break;
case 2: // Toggle case 2: // Toggle
Settings.flag.rules_enabled ^= 1; bitWrite(Settings.rule_enabled, index -1, bitRead(Settings.rule_enabled, index -1) ^1);
break; break;
case 4: // Off case 4: // Off
case 5: // On case 5: // On
Settings.flag.rules_once = XdrvMailbox.payload &1; bitWrite(Settings.rule_once, index -1, XdrvMailbox.payload &1);
break; break;
case 6: // Toggle case 6: // Toggle
Settings.flag.rules_once ^= 1; bitWrite(Settings.rule_once, index -1, bitRead(Settings.rule_once, index -1) ^1);
break; break;
} }
} else { } else {
/* strlcpy(Settings.rules[index -1], ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(Settings.rules[index -1]));
String uc_data = XdrvMailbox.data; // Do not allow Rule to be used within a rule
uc_data.toUpperCase();
String uc_command = command;
uc_command += " "; // Distuingish from RuleTimer
uc_command.toUpperCase();
if (!uc_data.indexOf(uc_command)) { strlcpy(Settings.rules, XdrvMailbox.data, sizeof(Settings.rules)); }
*/
strlcpy(Settings.rules, XdrvMailbox.data, sizeof(Settings.rules));
} }
rules_triggers = 0; // Reset once flag rules_triggers[index -1] = 0; // Reset once flag
} }
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\",\"Once\":\"%s\",\"Rules\":\"%s\"}"), command, GetStateText(Settings.flag.rules_enabled), GetStateText(Settings.flag.rules_once), Settings.rules); snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"Free\":%d,\"Rules\":\"%s\"}"),
command, index, GetStateText(bitRead(Settings.rule_enabled, index -1)), GetStateText(bitRead(Settings.rule_once, index -1)), sizeof(Settings.rules[index -1]) - strlen(Settings.rules[index -1]) -1, Settings.rules[index -1]);
} }
else if ((CMND_RULETIMER == command_code) && (index > 0) && (index <= MAX_RULE_TIMERS)) { else if ((CMND_RULETIMER == command_code) && (index > 0) && (index <= MAX_RULE_TIMERS)) {
if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len > 0) {
@ -458,17 +484,7 @@ boolean RulesCommand()
} }
else if (CMND_EVENT == command_code) { else if (CMND_EVENT == command_code) {
if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len > 0) {
String event = XdrvMailbox.data; strlcpy(event_data, XdrvMailbox.data, sizeof(event_data));
String parameter = "";
int pos = event.indexOf('=');
if (pos > 0) {
parameter = event.substring(pos +1);
parameter.trim();
event = event.substring(0, pos);
}
event.trim();
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Event\":{\"%s\":\"%s\"}}"), event.c_str(), parameter.c_str());
RulesProcess();
} }
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
} }
@ -500,7 +516,7 @@ boolean Xdrv10(byte function)
boolean result = false; boolean result = false;
switch (function) { switch (function) {
case FUNC_INIT: case FUNC_PRE_INIT:
RulesInit(); RulesInit();
break; break;
case FUNC_EVERY_50_MSECOND: case FUNC_EVERY_50_MSECOND:
@ -515,6 +531,9 @@ boolean Xdrv10(byte function)
case FUNC_COMMAND: case FUNC_COMMAND:
result = RulesCommand(); result = RulesCommand();
break; break;
case FUNC_RULES_PROCESS:
result = RulesProcess();
break;
} }
return result; return result;
} }

View File

@ -115,6 +115,11 @@ device_parameters_t device_param[] = {
{ KNX_ENERGY_DAILY , false, false, KNX_Empty }, { KNX_ENERGY_DAILY , false, false, KNX_Empty },
{ KNX_ENERGY_START , false, false, KNX_Empty }, { KNX_ENERGY_START , false, false, KNX_Empty },
{ KNX_ENERGY_TOTAL , false, false, KNX_Empty }, { KNX_ENERGY_TOTAL , false, false, KNX_Empty },
{ KNX_SLOT1 , false, false, KNX_Empty },
{ KNX_SLOT2 , false, false, KNX_Empty },
{ KNX_SLOT3 , false, false, KNX_Empty },
{ KNX_SLOT4 , false, false, KNX_Empty },
{ KNX_SLOT5 , false, false, KNX_Empty },
{ KNX_Empty, false, false, KNX_Empty} { KNX_Empty, false, false, KNX_Empty}
}; };
@ -145,6 +150,11 @@ const char * device_param_ga[] = {
D_ENERGY_TODAY , D_ENERGY_TODAY ,
D_ENERGY_YESTERDAY , D_ENERGY_YESTERDAY ,
D_ENERGY_TOTAL , D_ENERGY_TOTAL ,
D_KNX_TX_SLOT " 1",
D_KNX_TX_SLOT " 2",
D_KNX_TX_SLOT " 3",
D_KNX_TX_SLOT " 4",
D_KNX_TX_SLOT " 5",
nullptr nullptr
}; };
@ -175,9 +185,20 @@ const char *device_param_cb[] = {
D_REPLY " " D_ENERGY_TODAY , D_REPLY " " D_ENERGY_TODAY ,
D_REPLY " " D_ENERGY_YESTERDAY , D_REPLY " " D_ENERGY_YESTERDAY ,
D_REPLY " " D_ENERGY_TOTAL , D_REPLY " " D_ENERGY_TOTAL ,
D_KNX_RX_SLOT " 1",
D_KNX_RX_SLOT " 2",
D_KNX_RX_SLOT " 3",
D_KNX_RX_SLOT " 4",
D_KNX_RX_SLOT " 5",
nullptr nullptr
}; };
// Commands
#define D_CMND_KNXTXCMND "KnxTx_Cmnd"
#define D_CMND_KNXTXVAL "KnxTx_Val"
enum KnxCommands { CMND_KNXTXCMND, CMND_KNXTXVAL };
const char kKnxCommands[] PROGMEM = D_CMND_KNXTXCMND "|" D_CMND_KNXTXVAL ;
byte KNX_GA_Search( byte param, byte start = 0 ) byte KNX_GA_Search( byte param, byte start = 0 )
{ {
@ -377,12 +398,20 @@ bool KNX_CONFIG_NOT_MATCH()
{ {
if ( !device_param[i].show ) { // device has this parameter ? if ( !device_param[i].show ) { // device has this parameter ?
// if not, search for all registered group address to this parameter for deletion // if not, search for all registered group address to this parameter for deletion
// Checks all GA
if ( KNX_GA_Search(i+1) != KNX_Empty ) { return true; } if ( KNX_GA_Search(i+1) != KNX_Empty ) { return true; }
if ( (i < 8) || (i > 15) ) // check relays and sensors (i from 8 to 16 are toggle relays parameters)
// Check all CB
if ( i < 8 ) // check relays (i from 8 to 15 are toggle relays parameters)
{ {
if ( KNX_CB_Search(i+1) != KNX_Empty ) { return true; } if ( KNX_CB_Search(i+1) != KNX_Empty ) { return true; }
if ( KNX_CB_Search(i+9) != KNX_Empty ) { return true; } if ( KNX_CB_Search(i+9) != KNX_Empty ) { return true; }
} }
if ( i > 15 ) // check sensors and others
{
if ( KNX_CB_Search(i+1) != KNX_Empty ) { return true; }
}
} }
} }
return false; return false;
@ -448,6 +477,14 @@ void KNX_INIT()
device_param[KNX_ENERGY_POWERFACTOR-1].show = true; device_param[KNX_ENERGY_POWERFACTOR-1].show = true;
} }
#ifdef USE_RULES
device_param[KNX_SLOT1-1].show = true;
device_param[KNX_SLOT2-1].show = true;
device_param[KNX_SLOT3-1].show = true;
device_param[KNX_SLOT4-1].show = true;
device_param[KNX_SLOT5-1].show = true;
#endif
// Delete from KNX settings all configuration is not anymore related to this device // Delete from KNX settings all configuration is not anymore related to this device
if (KNX_CONFIG_NOT_MATCH()) { if (KNX_CONFIG_NOT_MATCH()) {
Settings.knx_GA_registered = 0; Settings.knx_GA_registered = 0;
@ -494,18 +531,32 @@ void KNX_CB_Action(message_t const &msg, void *arg)
case KNX_CT_WRITE: case KNX_CT_WRITE:
if (chan->type < 9) // Set Relays if (chan->type < 9) // Set Relays
{ {
ExecuteCommandPower(chan->type, msg.data[0]); ExecuteCommandPower(chan->type, msg.data[0], SRC_KNX);
} }
else if (chan->type < 17) // Toggle Relays else if (chan->type < 17) // Toggle Relays
{ {
if (!toggle_inhibit) { if (!toggle_inhibit) {
ExecuteCommandPower((chan->type) -8, 2); ExecuteCommandPower((chan->type) -8, 2, SRC_KNX);
if (Settings.flag.knx_enable_enhancement) { if (Settings.flag.knx_enable_enhancement) {
toggle_inhibit = TOGGLE_INHIBIT_TIME; toggle_inhibit = TOGGLE_INHIBIT_TIME;
} }
} }
} }
#ifdef USE_RULES
else if ((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT5)) // KNX RX SLOTs (write command)
{
if (!toggle_inhibit) {
char command[25];
snprintf_P(command, sizeof(command), PSTR("event KNXRX_VAL%d=%d"), ((chan->type) - KNX_SLOT1 + 1 ), msg.data[0]);
ExecuteCommand(command, SRC_KNX);
if (Settings.flag.knx_enable_enhancement) {
toggle_inhibit = TOGGLE_INHIBIT_TIME;
}
}
}
#endif
break; break;
case KNX_CT_READ: case KNX_CT_READ:
if (chan->type < 9) // reply Relays status if (chan->type < 9) // reply Relays status
{ {
@ -531,6 +582,19 @@ void KNX_CB_Action(message_t const &msg, void *arg)
knx.answer_2byte_float(msg.received_on, last_hum); knx.answer_2byte_float(msg.received_on, last_hum);
} }
} }
#ifdef USE_RULES
else if ((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT5)) // KNX RX SLOTs (read command)
{
if (!toggle_inhibit) {
char command[25];
snprintf_P(command, sizeof(command), PSTR("event KNXRX_REQ%d"), ((chan->type) - KNX_SLOT1 + 1 ) );
ExecuteCommand(command, SRC_KNX);
if (Settings.flag.knx_enable_enhancement) {
toggle_inhibit = TOGGLE_INHIBIT_TIME;
}
}
}
#endif
break; break;
} }
} }
@ -939,6 +1003,71 @@ void KNX_Save_Settings()
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
boolean KnxCommand()
{
char command[CMDSZ];
uint8_t index = XdrvMailbox.index;
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kKnxCommands);
if (!(Settings.flag.knx_enabled)) { return false; }
if (-1 == command_code) { return false; } // Unknown command
else if ((CMND_KNXTXCMND == command_code) && (index > 0) && (index <= MAX_KNXTX_CMNDS) && (XdrvMailbox.data_len > 0)) {
// index <- KNX SLOT to use
// XdrvMailbox.payload <- data to send
// Search all the registered GA that has that output (variable: KNX SLOTx) as parameter
byte i = KNX_GA_Search(index + KNX_SLOT1 -1);
while ( i != KNX_Empty ) {
KNX_addr.value = Settings.knx_GA_addr[i];
knx.write_1bit(KNX_addr, !(XdrvMailbox.payload == 0));
if (Settings.flag.knx_enable_enhancement) {
knx.write_1bit(KNX_addr, !(XdrvMailbox.payload == 0));
knx.write_1bit(KNX_addr, !(XdrvMailbox.payload == 0));
}
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_KNX "%s = %d " D_SENT_TO " %d.%d.%d"),
device_param_ga[index + KNX_SLOT1 -2], !(XdrvMailbox.payload == 0),
KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member);
AddLog(LOG_LEVEL_INFO);
i = KNX_GA_Search(index + KNX_SLOT1 -1, i + 1);
}
}
else if ((CMND_KNXTXVAL == command_code) && (index > 0) && (index <= MAX_KNXTX_CMNDS) && (XdrvMailbox.data_len > 0)) {
// index <- KNX SLOT to use
// XdrvMailbox.payload <- data to send
// Search all the registered GA that has that output (variable: KNX SLOTx) as parameter
byte i = KNX_GA_Search(index + KNX_SLOT1 -1);
while ( i != KNX_Empty ) {
KNX_addr.value = Settings.knx_GA_addr[i];
knx.write_2byte_float(KNX_addr, XdrvMailbox.payload);
if (Settings.flag.knx_enable_enhancement) {
knx.write_2byte_float(KNX_addr, XdrvMailbox.payload);
knx.write_2byte_float(KNX_addr, XdrvMailbox.payload);
}
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_KNX "%s = %d " D_SENT_TO " %d.%d.%d"),
device_param_ga[index + KNX_SLOT1 -2], XdrvMailbox.payload,
KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member);
AddLog(LOG_LEVEL_INFO);
i = KNX_GA_Search(index + KNX_SLOT1 -1, i + 1);
}
}
else { return false; } // Incomplete command
snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":\"%d\"}"),
command, index, XdrvMailbox.payload );
return true;
}
/*********************************************************************************************\ /*********************************************************************************************\
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
@ -949,7 +1078,7 @@ boolean Xdrv11(byte function)
{ {
boolean result = false; boolean result = false;
switch (function) { switch (function) {
case FUNC_INIT: case FUNC_PRE_INIT:
KNX_INIT(); KNX_INIT();
break; break;
case FUNC_LOOP: case FUNC_LOOP:
@ -960,9 +1089,9 @@ boolean Xdrv11(byte function)
toggle_inhibit--; toggle_inhibit--;
} }
break; break;
// case FUNC_COMMAND: case FUNC_COMMAND:
// result = KNXCommand(); result = KnxCommand();
// break; break;
// case FUNC_SET_POWER: // case FUNC_SET_POWER:
// break; // break;
} }

View File

@ -1,5 +1,5 @@
/* /*
xdrv_07_home_assistant.ino - home assistant support for Sonoff-Tasmota xdrv_12_home_assistant.ino - home assistant support for Sonoff-Tasmota
Copyright (C) 2018 Theo Arends Copyright (C) 2018 Theo Arends
@ -208,9 +208,9 @@ void HAssDiscovery(uint8_t mode)
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
#define XDRV_07 #define XDRV_12
boolean Xdrv07(byte function) boolean Xdrv12(byte function)
{ {
boolean result = false; boolean result = false;

View File

@ -18,10 +18,6 @@
*/ */
boolean (* const xdrv_func_ptr[])(byte) PROGMEM = { // Driver Function Pointers boolean (* const xdrv_func_ptr[])(byte) PROGMEM = { // Driver Function Pointers
#ifdef XDRV_00
&Xdrv00,
#endif
#ifdef XDRV_01 #ifdef XDRV_01
&Xdrv01, &Xdrv01,
#endif #endif
@ -175,9 +171,15 @@ boolean XdrvMqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uint16_t
return XdrvCall(FUNC_MQTT_DATA); return XdrvCall(FUNC_MQTT_DATA);
} }
boolean XdrvRulesProcess()
{
return XdrvCall(FUNC_RULES_PROCESS);
}
/*********************************************************************************************\ /*********************************************************************************************\
* Function call to all xdrv * Function call to all xdrv
* *
* FUNC_PRE_INIT
* FUNC_INIT * FUNC_INIT
* FUNC_LOOP * FUNC_LOOP
* FUNC_MQTT_SUBSCRIBE * FUNC_MQTT_SUBSCRIBE
@ -188,6 +190,7 @@ boolean XdrvMqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uint16_t
* FUNC_SHOW_SENSOR * FUNC_SHOW_SENSOR
* FUNC_EVERY_SECOND * FUNC_EVERY_SECOND
* FUNC_EVERY_50_MSECOND * FUNC_EVERY_50_MSECOND
* FUNC_RULES_PROCESS
\*********************************************************************************************/ \*********************************************************************************************/
boolean XdrvCall(byte Function) boolean XdrvCall(byte Function)

View File

@ -387,10 +387,10 @@ void HandleUpnpEvent()
//differentiate get and set state //differentiate get and set state
if (request.indexOf(F("SetBinaryState")) > 0) { if (request.indexOf(F("SetBinaryState")) > 0) {
if (request.indexOf(F("State>1</Binary")) > 0) { if (request.indexOf(F("State>1</Binary")) > 0) {
ExecuteCommandPower(devices_present, POWER_ON); ExecuteCommandPower(devices_present, POWER_ON, SRC_WEMO);
} }
else if (request.indexOf(F("State>0</Binary")) > 0) { else if (request.indexOf(F("State>0</Binary")) > 0) {
ExecuteCommandPower(devices_present, POWER_OFF); ExecuteCommandPower(devices_present, POWER_OFF, SRC_WEMO);
} }
} }
else if(request.indexOf(F("GetBinaryState")) > 0){ else if(request.indexOf(F("GetBinaryState")) > 0){
@ -660,10 +660,10 @@ void HueLights(String *path)
on = hue_json["on"]; on = hue_json["on"];
switch(on) switch(on)
{ {
case false : ExecuteCommandPower(device, POWER_OFF); case false : ExecuteCommandPower(device, POWER_OFF, SRC_HUE);
response.replace("{re", "false"); response.replace("{re", "false");
break; break;
case true : ExecuteCommandPower(device, POWER_ON); case true : ExecuteCommandPower(device, POWER_ON, SRC_HUE);
response.replace("{re", "true"); response.replace("{re", "true");
break; break;
default : response.replace("{re", (power & (1 << (device-1))) ? "true" : "false"); default : response.replace("{re", (power & (1 << (device-1))) ? "true" : "false");

View File

@ -76,8 +76,8 @@ void Sgp30Show(boolean json)
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
if (0 == tele_period) DomoticzSensor(DZ_AIRQUALITY, sgp.eCO2); if (0 == tele_period) DomoticzSensor(DZ_AIRQUALITY, sgp.eCO2);
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ
} else {
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SGP30, mqtt_data, sgp.eCO2, sgp.TVOC); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SGP30, mqtt_data, sgp.eCO2, sgp.TVOC);
#endif #endif
} }

View File

@ -262,8 +262,8 @@ void SDM120Show(boolean json)
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} else { } else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SDM120_DATA, mqtt_data, voltage, current, active_power, apparent_power, reactive_power, power_factor, frequency, energy_total); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SDM120_DATA, mqtt_data, voltage, current, active_power, apparent_power, reactive_power, power_factor, frequency, energy_total);
}
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
}
} }
/*********************************************************************************************\ /*********************************************************************************************\

View File

@ -335,8 +335,8 @@ void Si1145Show(boolean json)
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, visible); if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, visible);
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ
} else {
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SI1145, mqtt_data, visible, infrared, uvindex /100, uvindex %100); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SI1145, mqtt_data, visible, infrared, uvindex /100, uvindex %100);
#endif #endif
} }

View File

@ -317,8 +317,8 @@ void SDM630Show(boolean json)
active_power_l1, active_power_l2, active_power_l3, active_power_l1, active_power_l2, active_power_l3,
reactive_power_l1, reactive_power_l2, reactive_power_l3, reactive_power_l1, reactive_power_l2, reactive_power_l3,
power_factor_l1, power_factor_l2, power_factor_l3, energy_total); power_factor_l1, power_factor_l2, power_factor_l3, energy_total);
}
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
}
} }
/*********************************************************************************************\ /*********************************************************************************************\

128
sonoff/xsns_26_lm75ad.ino Normal file
View File

@ -0,0 +1,128 @@
/*
xsns_26_lm75ad.ino - Support for I2C LM75AD Temperature Sensor
Copyright (C) 2018 Andre Thomas and Theo Arends
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_I2C
#ifdef USE_LM75AD
/*********************************************************************************************\
* LM75AD - Temperature
*
* Docs at https://www.nxp.com/docs/en/data-sheet/LM75A.pdf
*
* I2C Address: 0x48 - 0x4F
\*********************************************************************************************/
#define LM75AD_ADDRESS1 0x48
#define LM75AD_ADDRESS2 0x49
#define LM75AD_ADDRESS3 0x4A
#define LM75AD_ADDRESS4 0x4B
#define LM75AD_ADDRESS5 0x4C
#define LM75AD_ADDRESS6 0x4D
#define LM75AD_ADDRESS7 0x4E
#define LM75AD_ADDRESS8 0x4F
#define LM75_TEMP_REGISTER 0x00
#define LM75_CONF_REGISTER 0x01
#define LM75_THYST_REGISTER 0x02
#define LM75_TOS_REGISTER 0x03
uint8_t lm75ad_type = 0;
uint8_t lm75ad_address;
uint8_t lm75ad_addresses[] = { LM75AD_ADDRESS1, LM75AD_ADDRESS2, LM75AD_ADDRESS3, LM75AD_ADDRESS4, LM75AD_ADDRESS5, LM75AD_ADDRESS6, LM75AD_ADDRESS7, LM75AD_ADDRESS8 };
void LM75ADDetect()
{
uint8_t buffer;
if (lm75ad_type) { return; }
for (byte i = 0; i < sizeof(lm75ad_addresses); i++) {
lm75ad_address = lm75ad_addresses[i];
if (I2cValidRead8(&buffer, lm75ad_address, LM75_CONF_REGISTER)) {
lm75ad_type = 1;
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "LM75AD", lm75ad_address);
AddLog(LOG_LEVEL_DEBUG);
break;
}
}
}
float LM75ADGetTemp() {
int16_t sign = 1;
uint16_t t = I2cRead16(lm75ad_address, LM75_TEMP_REGISTER);
if (t & 0x8000) { // we are getting a negative temperature value
t = (~t) +0x20;
sign = -1;
}
t = t >> 5; // shift value into place (5 LSB not used)
return ConvertTemp(sign * t * 0.125);
}
void LM75ADShow(boolean json)
{
if (lm75ad_type) {
char temperature[10];
float t = LM75ADGetTemp();
dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
if (json) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"LM75AD\":{\"" D_JSON_TEMPERATURE "\":%s}"), mqtt_data, temperature);
#ifdef USE_DOMOTICZ
if (0 == tele_period) DomoticzSensor(DZ_TEMP, temperature);
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "LM75AD", temperature, TempUnit());
#endif // USE_WEBSERVER
}
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_26
boolean Xsns26(byte function)
{
boolean result = false;
if (i2c_flg) {
switch (function) {
case FUNC_PREP_BEFORE_TELEPERIOD:
LM75ADDetect();
break;
case FUNC_JSON_APPEND:
LM75ADShow(1);
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_APPEND:
LM75ADShow(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_LM75AD
#endif // USE_I2C

View File

@ -0,0 +1,406 @@
:020000040000FA
:10000000020FEFED24F8FEEFD39E4015ED2408FD1E
:10001000E433FCC3EF9DEC6480F874809850028058
:1000200001C322020ED0E4F5A922220213637EFF4F
:10003000EFD394004022EF9480501DE4FDED75F065
:100040000EA424A5F582E43418F583E493B50704DF
:10005000AE0580040DBD05E5AF062202110612189B
:100060004E53D87853DBFE12180FE4900085F0222F
:10007000D2DE220213B6D2011215F6C290C296D277
:1000800080E4FBFD7F101217F612064374A4F0D231
:10009000AFE4F52FF530D2960530E5307002052F2C
:1000A000B410F3E52FB427EEC29630010912150DF6
:1000B0008E328F338006753201753300E53370045C
:1000C000E532640170409000CCE07007F52FF53008
:1000D0000202870530E5307002052FD39410E52F1A
:1000E00094274002D296D3E5309430E52F94755092
:1000F00003020287E4F52FF5309000CCF09000CB9E
:10010000F0C296020287E4F52FF5309000CCE0149F
:10011000602A14700302025914700302021E147044
:100120000302023424046003020287E53364AA60F8
:10013000030202879000CC04F0020287E5339000AE
:10014000CBF0A37402F0E5331208B30206A00170ED
:10015000A10182A501A6A601BAA701C3A801DFA932
:1001600001C6B001CFB10197C00287FF00000215A0
:100170001205E69000A87401F0E4900075F07FA1EC
:10018000806E12005E9000CC7404F0753108E4F5C6
:10019000357534090202879000CC7404F0E4F5351B
:1001A000753402020287E49000A8F0900075F07F99
:1001B000A612067474A6F002028712064374A4F015
:1001C0000202877531089000CC7403F00202879018
:1001D00000757401F07FB1120674EFF0020287120D
:1001E00005E69000A8E0F52EE4F0900075F07FA9F8
:1001F0001214D090007CEFF07D307C757F017E0082
:1002000012164902028712065790007CEFF0E49024
:1002100000CCF08072E49000CBF0A3F08069E4F5AC
:1002200035E533F534E534D394009000CC402574A3
:1002300004F0805374042535F582E43400F583E539
:1002400033F00535E53565346007E535C394704016
:10025000369000CC7402F0802EE5336455702890FF
:1002600000CCF0C2019000CBE02460601824FC6058
:100270000F24FE600B14600824F66004241070073D
:100280007FA01217C3D2019000CBE01208B302B0D6
:10029000A102DAA402ECA503C5A603E1A8051FA9E3
:1002A000055CB005CFB1038DC003B3FF000000AA09
:1002B000900084E030E70F7DC87C001206167FA313
:1002C00012140902053912180740030200AA7DE83A
:1002D0007C031206167FA2020554900084E020E7FA
:1002E000030200AA7FA41214090203D99000CCE0F3
:1002F00060030200AA900085E024FC606D24046085
:10030000030200AA1531900008E0FEA3E0FF7C0084
:100310007D641208D9C006C0071215A0D007D00608
:100320001208218F3E900006E0FEA3E0FF8E3FF50D
:10033000407C007D641208D9C006C0071215A0D009
:1003400007D0061208218F41754218900008E0FA84
:10035000A3E0FB900004E0FCA3E0FDA3E0FEA3E02B
:10036000FF12067B7406F00204EBE53160171206FB
:100370002DD39400500302051012062D12066012B0
:1003800018400205101206577FA00205549000CCB9
:10039000E060030200AA900004E0FCA3E0FD7F01FE
:1003A0007E00121649D296121840C2967FA01217EC
:1003B000C3800AE4FF1217C3E49000CCF0D201120C
:1003C000066B0200AA900084E020E7030200AA5412
:1003D0007FF537FD7FA612130CE4900084F0020035
:1003E000AA9000CCE060030200AA900085E024FC03
:1003F00070030204F1240460030200AA1531120004
:100400005E900004E0647F702FA3E0FEA3E0FFA3F2
:10041000E0FCA3E0FDA3E0FAA3E0FBA3E0F53EA32C
:10042000E0F53FA3E0F540A3E0F541A3E0F542127B
:10043000067B740CF00204E2900004E0FF12002E30
:100440008F36E536F470030204DDEF75F00EA42458
:1004500060F582E43418F583E493FE740193FFC0E1
:1004600006C0071215BA2462F582E434181215C1C9
:10047000C004C0051215BA2465F582E43418F5836A
:10048000E493FA740193FB1215BA2469F582E434FB
:1004900018F583E493FF1215BA2467F582E4341843
:1004A0001215C11215BA246AF582E43418F583E4F2
:1004B00093FE1215BA246BF582E43418F583E493A5
:1004C000F5428E418C3F8D408F3ED005D004D00741
:1004D000D0061212929000747401F08005E490002E
:1004E000CBF09000CBE070030200AA121749020083
:1004F000AAE53160231215BA246CF582E43418F5AC
:1005000083E493FFD394004007EF12066012184073
:10051000E4900085F00200AA12066B7FA08035905F
:100520000084E0FF30E71C547FF5377DC87C001263
:1005300005F9AD377FAB12130CE4900084F0D201C3
:100540000200AA12180740030200AA7DE87C0312E9
:1005500005F97FAA1217C3D2010200AA900004E095
:1005600025E0F5379000CCE060030200AA900085FA
:10057000E0700512005E800B900085E0640460036B
:100580000200AAE5376007E534C394045008E490FC
:1005900000CBF00200AA74062537F9E43400753B5D
:1005A00001F53C893DC3E534953724FEF53E9000C6
:1005B00005E0F53F7B017A00790612118B7FA012CE
:1005C00017C390007CE0FF1214D0D2010200AA9061
:1005D0000084E020E7030200AA7FB1121210E49029
:1005E0000084F00200AA7D327C007F017E0012169A
:1005F00049D296121840C296227F017E00121649F7
:10060000D296121840C2969000A8E52EF090007C79
:10061000E0FF1214D0227F017E00121649D29612FA
:100620001840C29690007CE0FF1214D0227F011285
:10063000002EEF75F00EA4246CF582E43418F583D7
:10064000E493229000A87401F0E4900075F07FA478
:100650001214D090007C2290007CE0FF1214D02273
:10066000FD7C007F017E001216492290007CE0FF95
:100670001214D0221214D090007C221212929000F8
:100680007422BB010CE58229F582E5833AF583E00B
:10069000225006E92582F8E622BBFE06E92582F80B
:1006A000E222E58229F582E5833AF583E49322BBD1
:1006B000010689828A83F0225002F722BBFE01F3F1
:1006C00022EF8DF0A4A8F0CF8CF0A428CE8DF0A45A
:1006D0002EFE22BC000BBE0029EF8DF084FFADF092
:1006E00022E4CCF875F008EF2FFFEE33FEEC33FC7C
:1006F000EE9DEC984005FCEE9DFE0FD5F0E9E4CEB2
:10070000FD22EDF8F5F0EE8420D21CFEADF075F080
:1007100008EF2FFFED33FD4007985006D5F0F22289
:10072000C398FD0FD5F0EA22C2D5EC30E709B2D567
:10073000E4C39DFDE49CFCEE30E715B2D5E4C39F15
:10074000FFE49EFE1206D3C3E49DFDE49CFC8003FF
:100750001206D330D507C3E49FFFE49EFE22BB01FF
:1007600010E58229F582E5833AF583E0F5F0A3E010
:10077000225009E92582F886F008E622BBFE0AE944
:100780002582F8E2F5F008E222E5832AF583E99371
:10079000F5F0A3E99322E88FF0A4CC8BF0A42CFC15
:1007A000E98EF0A42CFC8AF0EDA42CFCEA8EF0A4D7
:1007B000CDA8F08BF0A42DCC3825F0FDE98FF0A466
:1007C0002CCD35F0FCEB8EF0A4FEA9F0EB8FF0A45D
:1007D000CFC5F02ECD39FEE43CFCEAA42DCE35F099
:1007E000FDE43CFC2275F008758200EF2FFFEE332C
:1007F000FECD33CDCC33CCC58233C5829BED9AEC94
:1008000099E58298400CF582EE9BFEED9AFDEC99FD
:10081000FC0FD5F0D6E4CEFBE4CDFAE4CCF9A88207
:1008200022B800C1B90059BA002DEC8BF084CFCEAC
:10083000CDFCE5F0CBF97818EF2FFFEE33FEED336A
:10084000FDEC33FCEB33FB10D703994004EB99FB31
:100850000FD8E5E4F9FA227818EF2FFFEE33FEED1A
:1008600033FDEC33FCC933C910D7059BE99A400727
:10087000EC9BFCE99AF90FD8E0E4C9FAE4CCFB223E
:1008800075F010EF2FFFEE33FEED33FDCC33CCC807
:1008900033C810D7079BEC9AE899400AED9BFDEC12
:1008A0009AFCE899F80FD5F0DAE4CDFBE4CCFAE451
:1008B000C8F922D083D082F8E49370127401937047
:1008C0000DA3A393F8740193F5828883E4737402F3
:1008D000936860EFA3A3A380DFEC8EF0A4CCC5F0F7
:1008E000CCCDF8EFA4CEC5F02DFDE43CFCE8A42E61
:1008F000C8C5F03DFDE43CFCEFA4FFE5F028FEE4B4
:100900003DFDE43CFC22EF4E6012EF60010EEDBBBA
:10091000010B89828A83F0A3DFFCDEFA2289F05082
:1009200007F709DFFCA9F022BBFEFCF309DFFCA9F5
:10093000F022AFE9AEEA7C007D0A1206C18E088F74
:1009400009209303020B2185080A85090BC3E509D9
:10095000950DF511E508950CF510900075E01470F3
:1009600003020B1B046003020B42900085E014603D
:1009700065046003020B42900084E06003020B42B6
:100980009000A8E0FFAB11AA10AD0FAC0E120E1331
:100990008F12E51264807003020B4290007F120CEC
:1009A000A3900002E510F0A3E511120C5FE49000A3
:1009B00074F0900077F090007EF0F513F514FE7F50
:1009C00070FD7B017A007904120906E490007DF045
:1009D00090008504F022E51275F00EA424AAF58299
:1009E000E43418F583E493FFD39400400B90007E29
:1009F000E09F5004E004F022900088E014F09000A2
:100A000077E004F0AE10AF11AB07AA06E50F2BFF9D
:100A1000E50E3AFEE433FDE433FCC004A905AA0662
:100A2000AB07AE0EAF0F120CABD0001208218F2215
:100A3000120C231200034029E51275F00EA424B015
:100A4000F582E43418F583E493FDAF2212000340ED
:100A500010120B436F600AE4900084F0C290A3F080
:100A600022120C23AF221200035007120B43C39F24
:100A70004011D3E50F9514E50E9513402B120B434F
:100A80006F7025900086120CA3D290120BF6C083D3
:100A9000C082120C9B7401A806088002C333D8FCE4
:100AA0004FD082D083F0801790007A120CA3C290AE
:100AB000D39514E50E95134006850E13850F1490FB
:100AC0000088E07015120BF6E0FF90007DE06FFFEC
:100AD00012176490007DEF120C5F120B436F70626F
:100AE0001217FF5005E4900083F0900083E0FF9020
:100AF000007DE06F601D12180F7DF47C017F017E88
:100B00000012162090007DE0900083F0A3E512F023
:100B10004480F0C290E4900085F022AF11AE1080C6
:100B20001E85080C85090DC3E509950BF50FE50831
:100B3000950AF50E900075E0147007AF0FAE0E1217
:100B40000CC822E51275F00EA424B1F582E4341825
:100B5000F583E493FF900077E022120821AB07AA07
:100B600006E4F9F87F407E427D0FFC120821E47B09
:100B7000FFFAF9F8120796A804A905AA06AB077FA1
:100B8000207ED77D757C01120821EFF40422AE2669
:100B9000AF277C007D1F1206D38E2A8F2B7C007D11
:100BA000051206D3C3E52B9FFDE52A9EFCD3E52560
:100BB0009DE5249C22E52975F00EA424A8F582E485
:100BC0003418F583E493FE740193FF2438FDEE346A
:100BD000FFFCD3E5279DE5269C22900074E02404C9
:100BE000F582E43400F58322E52525E0248AF582A8
:100BF000E43400F58322900077E024FFFFE434FF23
:100C0000FE7C007D0812072874042FF58274003ED4
:100C1000F58322E52B2FFFE52A3EC3FEE5259FE560
:100C2000249E22E51275F00EA424AFF582E4341858
:100C3000F583E493FD22E52975F00EA424A6F58240
:100C4000E43418F5832253DAFE53F7DF53F7BF225B
:100C5000AB3BAA3CA93D854082758300020682F029
:100C60009000887408F022EF24C8FFE43EFEC3E53C
:100C7000279FE5269E2275F0FFA4FFAEF07C007D45
:100C8000640206D3900078E523F0A3E524F02290D7
:100C90000081E0FF900077E0D39F22E0FF90008882
:100CA000E0FE22E50EF0A3E50FF0227C007D640259
:100CB00008D9540F75F002A4F58285F08322D3E59C
:100CC000279470E5269417228E238F24900085E0C8
:100CD000146035147003020D9D24026003020E049B
:100CE000C290900084E06003020E04AF24AE231291
:100CF00017914003020E04E4900001F0120C84905E
:100D000000857401F0D29022900078E0FCA3E0FD11
:100D1000AE047802CEC313CE13D8F92DFFEC3EFEFD
:100D2000D3E5249FE5239E4009120C84E490000142
:100D3000F022AF24AE23121492501A900001E094D6
:100D4000004012E4900074F09000887404F0900069
:100D5000857402F022C3E5249464E5239400403AAC
:100D6000120E05501C120BE8E0FEA3E02524FFE55F
:100D7000233EC313FEEF13FF120BE8EEF0A3EFF0D8
:100D800022900001E0120BEA120C87900001E004AF
:100D9000F0E0D3941E406DE4805EE48063B290AFD7
:100DA00024AE23121492500D900084E04480F0C2CF
:100DB00090E4A3F022120E055041900088E0B404A4
:100DC00011E525C454F0FF120BDAEFF0E49000882F
:100DD000F022120BDAE0FFE525540FFEEF4EF09003
:100DE0000074E004F09000887404F0900074E0D384
:100DF00094704010E4900001F08005E4900001F050
:100E0000900085F0227B007A007925AF24AE231272
:100E1000107E228F238C248D258A268B277528808F
:100E2000E523707CE4F5297F0112002EEF6529701F
:100E30001B120CBE405FE5279450E52694465055A2
:100E4000120B8E4050120C13504B807E120C36E465
:100E500093FE740193FFD39400EE9400402BEF2493
:100E600038FFEE34FFD3120C1B402A120C367401EB
:100E70009324C8FFE4933400120C1A5018120BB5D7
:100E80004013120C67500E8041120BB54007120C34
:100E900067500280350529E529C394054089802DD6
:100EA000AF2312002E8F297F0112002EEF652970CB
:100EB0001C120CBE4017E5279450E5269446500DB1
:100EC000120B8E4008120C135003852928AF2822DC
:100ED000C0E0C0F0C083C082C0D075D000C000C0E8
:100EE00001C002C003C004C005C006C007E5985495
:100EF00003F547F45298E54730E017121857900071
:100F0000C0121690EFF09000C0E004F0E0B41402BC
:100F1000E4F0E54730E12E9000C2E0D39400401A9F
:100F20009000BFE02448F8E6FF1218549000BFE09C
:100F300004F09000C2E014F08002D2029000BFE002
:100F4000B42002E4F0D007D006D005D004D003D0FE
:100F500002D001D000D0D0D082D083D0F0D0E03207
:100F60004200C700004200C300004200C900004226
:100F700000C500004100CC004100CB0041008400CE
:100F8000410085004100A8004100750041007C003F
:100F900041007656410089AB4100000041008200CB
:100FA00042007F0000420002000042008600004232
:100FB000007A000041008100410088004100770074
:100FC00041007E00410074004100830041007D002B
:100FD000410001004100C0004100C1004100BE00CD
:100FE0004100BF004100C2004100BD00C10200122B
:100FF000002A787FE4F6D8FD758167021039020077
:1010000076E493A3F8E493A34003F68001F208DFAB
:10101000F48029E493A3F85407240CC8C333C454C0
:101020000F4420C8834004F456800146F6DFE48074
:101030000B0102040810204080900F60E47E0193B1
:1010400060BCA3FF543F30E509541FFEE493A36046
:10105000010ECF54C025E060A840B8E493A3FAE4A1
:1010600093A3F8E493A3C8C582C8CAC583CAF0A3F2
:10107000C8C582C8CAC583CADFE9DEE780BE8E263E
:101080008F278B288A29892AC200E4F52B9000013A
:10109000E0FFE52BC39F506BE527AE267803CEC358
:1010A00013CE13D8F9FDAC06E527AE267802CEC3E1
:1010B00013CE13D8F92DF52DEE3CF52CE52B120BA4
:1010C000EAE0FEA3E0FFC3952DFDEE952CFCC3EDF9
:1010D0009527EC95265028E52D2FFFE52C3EFEC3E5
:1010E000E5279FE5269E5017E52A45294528600BF0
:1010F000AB28AA29A92AE52B1206AFD20080040545
:101100002B808AA20022C0E0C0F0C083C082C0D081
:1011100075D000C000C001C002C003C004C005C03B
:1011200006C007E5D85487F521F452D8E5F730E535
:1011300008E5F730E60312154353F7DFE52130E702
:1011400008E5D930E00312185DE52130E008E5DA62
:1011500030E00312169BE52130E108E5DB30E003C7
:10116000120932E52130E208E5DC30E00312185EB6
:10117000D007D006D005D004D003D002D001D000D3
:10118000D0D0D082D083D0F0D0E0328B388A398969
:101190003A53DBFE120C4653E2FDE4F540E540C352
:1011A000953E504FAB38AA39A93AC003C002C001DE
:1011B000120C50C4120CB2D001D002D00312075E40
:1011C000F54285F041D280121202AB38AA39A93A11
:1011D000C003C002C001120C50120CB2D001D002E8
:1011E000D00312075EF54285F041C280121202055B
:1011F0004080AAB290AF3F153FEF709E43E202C21B
:101200009022FDAC417F0A7E001215741218402214
:10121000AE07E4F5381216EA900001E004FF12165A
:10122000F112128B900001E0FFE538C39F501212BB
:101230001684121677121684F58312167E053880EE
:10124000E3900078E0FF1216F190007812167E12FB
:10125000128B900088E07006900074E004F0E4F5D2
:1012600038900074E0FFE538C39F501774042538A8
:101270001216720538E538541F70E612185112180C
:101280004A80DE7F551216F10218511218511218B9
:101290004A228E388F398C3A8D3BAE02AF03120C46
:1012A000ABC007AF3EAB07E4FAF9F8D007120B5A10
:1012B000900000F0AE3FAF40120CABC007AF41ABA7
:1012C00007E4FAF9F8D007120B5A900082F0E53ED5
:1012D000120C76900076EFF0E541120C76900089C2
:1012E000EFF090007FE538F0A3E539F0900002E5DB
:1012F0003AF0A3E53BF0900081E542F043DA015378
:10130000F7DF43F74053DBFE75F9FF22AE07E4FC3D
:10131000FB1216EAED75F00EA424F7F582E43418FA
:10132000F583E493FFECC39F500774082CFC0B80FB
:10133000E3EB04FF1216F1ED75F00EA424EBF58239
:10134000E43418F583E493FF1216F1E4FCECC39B3C
:10135000500974042C1216720C80F27F551216F18B
:10136000021851C0E0C083C082C0D075D000C00454
:10137000C005C006C00753C87F9000C7E0FEA3E0C9
:10138000FF4E700353C8FB9000C31214875009909E
:1013900000C7E4F0A3F0800DC39000C8E09DF0907A
:1013A00000C7E09CF0D007D006D005D004D0D0D044
:1013B00082D083D0E032C0E0C083C082C0D075D07C
:1013C00000C004C005C006C00753917F9000C9E06B
:1013D000FEA3E0FF4E70035391FB9000C5121487EB
:1013E00050099000C9E4F0A3F0800DC39000CAE05A
:1013F0009DF09000C9E09CF0D007D006D005D00445
:10140000D0D0D082D083D0E032AE07E4FDF53812E0
:1014100016EA900002E0FF1216F190000212167E0A
:1014200090007AE0FF1216F190007A12167E90007A
:1014300086E0FF1216F190008612167E74042D12BB
:1014400016720DBD03F67F551216F1021851AB0747
:10145000AA06E4F9F87F407E427D0FFC120821A81D
:1014600004A905AA06AB077F207ED77D757C0112F3
:101470000821C3E49FFFE49EFE22AB07AA06E4F91D
:10148000F87FE87E03FD22E0FCA3E0FDC3EF9DEEC4
:101490009C22AD07AC06900078E0FEA3E07802CE77
:1014A000C313CE13D8F9FFC3900079E09FFB9000DF
:1014B00078E09EFAC3EB9DEA9C5013A3E02FFF90C7
:1014C0000078E03EFEC3ED9FEC9E50028001C322F7
:1014D0008F3890007CE0F5397F0B12185A43DB01FE
:1014E000120C461200707D0A7C007F017E001216ED
:1014F0004912184043E202E4900085F0900084F025
:101500009000CBE538F090007CF0AF39229000C01D
:10151000E0FF9000BEE0B507057E017F002290004D
:10152000BE121690E0FD7C009000BEE004F0E0B436
:101530001402E4F09000BDE0FEEE4204E4F0AE04DC
:10154000AF0522120C8F400302172B120BDA120C7C
:101550009BEFA806088002C313D8FC30E00B900074
:1015600000E0FF12185AD29022900082E0FF121879
:101570005AC290228E438F448C458D4612144E12CF
:1015800017ABE54624BF9000CAF0E54534FF900054
:10159000C9F09000C5E543F0A3E544F0439104226F
:1015A000900006E0FEA3E0FF900009E02FFF90000E
:1015B00008E03EAB07FAE4F9F822E53675F00EA430
:1015C00022F583E493FC740193FD22D29053E2FD53
:1015D000D28090007F1215E6C290C2809000021265
:1015E00015E643E20222E0FCA3E0FD7F0A7E001242
:1015F00015741218402212181612181D12182412EF
:1016000017CE12002612177B1217EC1217D81217DA
:10161000E21217B712182B12183212184602183994
:101620008E238F248C258D2612147A12145B1217A8
:101630009F9000C7E525F0A3E526F09000C3E523C1
:10164000F0A3E524F043C804228E3A8F3B8C3C8DF6
:101650003D12147A12145B1217AB9000C9E53CF0EE
:10166000A3E53DF09000C5E53AF0A3E53BF04391DA
:101670000422F582E43400F583E0FF0216F1A3E0D2
:10168000FF0216F1E53825E0248AF582E4340022D1
:10169000E024A9F582E43400F58322900088E0700C
:1016A00008900074E004120C5F900077E004F09062
:1016B0000088E014F0120C8F50030216C353E2FDB1
:1016C000C28022120BDA120C9BEFA806088002C31C
:1016D00013D8FC30E0059000768003900089E07D0F
:1016E00000FCE4FF12170D22AE077FAA1216F1AF1D
:1016F00006C2029000C1E0B42002E4F09000C1E014
:101700002448F8A607E004F0A3E004F022AB07AFFA
:1017100004EB14600C14600E2402700E8DFB8FFC21
:10172000228DE98FEA228DEB8FEC22E4FDFCFF1283
:10173000170D120C4612184E53D87853E2FDC28092
:10174000C2909000857404F022120C60E014F090B6
:1017500000777401F09000857403F01216C312151F
:10176000CB0200707E1DE4FDEF30E70625E06EFF42
:101770008004EF25E0FF0DBD08EE22AF885388AF4F
:10178000758CA0758DCBEF5440FEEF54104E4288FF
:1017900022C3EF94ACEE940D4003D38001C322AD7D
:1017A00007AC06ECF5CBAF058FCA22AD07AC06EC53
:1017B000F593AF058F9222C2DE75D90575F9FF75D5
:1017C0009601221216E87F551216F102185175E3A0
:1017D0004075E10175E20222E59154045391FB4208
:1017E0009122758E5475892243885022E5C854048D
:1017F00053C8FB42C82253984FEB4F4DF59822E552
:10180000C8C320E201D322E591C320E201D32253D1
:10181000C8FB53C87F227597DE7597AD2275A4115A
:1018200075D4CE2275A54175D5772253F77F75DA29
:101830004A2253F77F75DB302275E69075A8B022F7
:10184000E59120E2FB22439810223002FD22C2DE05
:1018500022D299228F9922AF99228F8C22222201A3
:101860000190307000064001904B1918000212C020
:1018700005DC0002BC012C461E2808030BB82328F7
:1018800000044C01904B19180004251C0BB80003F0
:10189000840140461E180005000072D80702BC01F2
:1018A0002C26404000010190307000064001904B12
:1018B0001918000212C005DC0002BC012C461E28CB
:1018C00008030BB8232800044C01904B191800049E
:1018D000251C0BB80003840140461E1800050000BB
:1018E00072D80702BC012C264040000101903070E4
:1018F00000064001904B1918000212C005DC0002DE
:10190000BC012C461E2808030BB8232800044C01F8
:10191000904B19180004251C0BB8000384014046A5
:101920001E180005000072D80702BC012C2640409A
:0119300000B6
:00000001FF

View File

@ -0,0 +1,207 @@
:020000040000FA
:10000000020779AB07AA06EB2401FEE43A900080D0
:10001000F0A3CEF0ED1490007DF08B828A83E0F5A2
:100020009922220204D0C204C29022020B03120CB5
:100030009C120CA3120CAA120C8012006E120B91CF
:10004000120BAA120BC3120C8A120C75120B5D0252
:100050000C5C53984FEB4F4DF598220208CC1200E0
:100060002E120C30D2AF120B77120C0A80F8E4F586
:10007000A922FF020A37020218E86480F8E933E88F
:100080003360110460F0ED33EC337009E8FCE9FDF6
:10009000EAFEEBFF220460DED3EB9FEA9EE99DE8D7
:1000A000C2E78CF0C2F795F0400CE8CCF8E9CDF946
:1000B000EACEFAEBCFFB1201E385D0F058047003CF
:1000C00020D5B3E80470075002B2D502022292D5BF
:1000D000EC0460F7E4CCC0E0C398F8603B9418608F
:1000E00008400DD0E0FB0201FAE4FBFAC9FC8028CD
:1000F000E830E406E4C9FBE4CAFCE830E305E4C9FF
:10010000CACBFCE854076010F8C3E913F9EA13FA04
:10011000EB13FBEC13FCD8F130F52FC3E49CFCEFA0
:100120009BFFEE9AFEED99FDD0E0FBEF4E4D4C703B
:100130001222DB0302021FEC2CFCEF33FFEE33FE36
:10014000ED33FDED30E7EB0201FAEF2BFFEE3AFE67
:10015000ED39FDD0E0FB50130BBB0003020222ED92
:1001600013FDEE13FEEF13FFEC13FC0201FA75F022
:1001700020800E75F010800575F0087D007E007FF0
:10018000003392D530D5031202E3EC334010EF3345
:10019000FFEE33FEED33FDEC33FCD5F0ED22E5F060
:1001A000247EA2D513CC92E7CDCEFF22EDD2E7CDAF
:1001B00033EC3392D524814006E4FFFEFDFC22FCA3
:1001C000E4CFCECDCC24E0501174FF80EDC3CC132E
:1001D000CCCD13CDCE13CECF13CF0470F030D5DEFF
:1001E0000202E3E9D2E7C933E833F892D5EDD2E76A
:1001F000CD33EC33FC5002B2D522EC30E7100FBF08
:10020000000C0EBE00080DBD00040BEB6014A2D55F
:10021000EB13FCED92E7FD2274FFFCFDFEFF22E4F0
:1002200080F8A2D574FF13FC7D80E480EFEF8DF0A1
:10023000A4A8F0CF8CF0A428CE8DF0A42EFE22BC72
:10024000000BBE0029EF8DF084FFADF022E4CCF866
:1002500075F008EF2FFFEE33FEEC33FCEE9DEC98CB
:100260004005FCEE9DFE0FD5F0E9E4CEFD22EDF851
:10027000F5F0EE8420D21CFEADF075F008EF2FFFF4
:10028000ED33FD4007985006D5F0F222C398FD0FDC
:10029000D5F0EA22E88FF0A4CC8BF0A42CFCE98EF8
:1002A000F0A42CFC8AF0EDA42CFCEA8EF0A4CDA8DE
:1002B000F08BF0A42DCC3825F0FDE98FF0A42CCDE7
:1002C00035F0FCEB8EF0A4FEA9F0EB8FF0A4CFC5C7
:1002D000F02ECD39FEE43CFCEAA42DCE35F0FDE451
:1002E0003CFC22C3E49FFFE49EFEE49DFDE49CFCF5
:1002F00022EB9FF5F0EA9E42F0E99D42F0E89C4532
:10030000F022E8600FECC313FCED13FDEE13FEEFDB
:1003100013FFD8F122E8600FEFC333FFEE33FEED99
:1003200033FDEC33FCD8F122E4F50BF50AF509F5C1
:1003300008F50CF50DF50EF50FF510F511F512F5A4
:1003400013F514F515F516F517900000E06401603B
:10035000030204C7F0E52C7015900004E0F524A317
:10036000E0F525A3E0F526A3E0F5271208ADE52585
:100370002527F50DE5243526F50CFEAF0D7C007D17
:100380000512023F8E108F11AE22AF237C007D0537
:1003900012023F8E128F13E4FBEBC3943040030232
:1003A000044F12086A12087BF583E0FCA3E0FD2FDE
:1003B000F50FEC3EF50EE50D2511FFE50C3510FEB1
:1003C000D3E50F9FE50E9E5014C3E50D9511FFE593
:1003D0000C9510FEC3E50F9FE50E9E5009052EE516
:1003E0002E7002052D2212086AFFD3ED9FEC9E406D
:1003F000221208A0EF4401F50BEEF50AEDF509EC29
:10040000F50812086A1208B812087C12087412085B
:10041000C2803712086A12087BF583E0FCA3E0C3B0
:100420009FEC9E501C1208A08F0B8E0A8D098C0821
:1004300012086A1208C212087C1208741208B880E6
:1004400009052EE52E7002052D220B0B0203999053
:100450000002E0FEA3E0FF2511FDE5103EFCC3E530
:10046000239DE5229C5027C3EF9511FFEE9510FECA
:10047000D3E5239FE5229E4015AF2BAE2AAD29ACD4
:1004800028AB0BAA0AA909A8081202F160311208C8
:10049000AD850B2B850A2A850929850828752C012D
:1004A000E4F52DF52EAE14AF15FC1208878E268FBD
:1004B00027AE16AF177C001208878E248F252205E1
:1004C0002CE4F52DF52E22052EE52E7002052D22A9
:1004D000C0E0C0F0C083C082C0D075D000C000C0F2
:1004E00001C002C003C004C005C006C007E598549F
:1004F00003F51EF4529890007CE0700302058AE533
:100500001E20E00302058A90007EE0FEA3E0FFF5D6
:10051000828E83E599F08F828E83E0FF20000B644A
:10052000AA60030205BCD200803A200137300034B3
:10053000EF64A0601EEF64A16019EF64A26014EF85
:1005400064A3600FEF64A4600AEF64A56005120C59
:10055000698069D201EF64A06008EF64A16003BF05
:10056000A202D20290007FE004F0700690007EE0CC
:1005700004F090007CE014F0E0FE6008BF550B3002
:1005800002086006120C691209E3E51E30E12D90A5
:10059000007DE06024900080E0FEA3E0F5828E8381
:1005A000E0F599900081E004F07006900080E0048E
:1005B000F090007DE014F08003120022D007D006F6
:1005C000D005D004D003D002D001D000D0D0D0824A
:1005D000D083D0F0D0E032E4F518F519F51DF51C04
:1005E000F51BF51A30AF6890006612096BF522ED25
:1005F000F52312096AF526EDF52712096AF524EDAF
:10060000F525A3E0FFE4FCFDFEFBFA7901F81202F8
:1006100094A804A905AA06AB0790006DE0FEE4FCCF
:10062000FD2BFBEA3EFAED39F9EC38F8A3E0FFE4E4
:10063000FEEB2FFFEE3AFEED39FDEC388F2B8E2AC4
:100640008D29F5287F0A7E00120BDCC291C2AFE42F
:10065000F51812095EAF23AE22120BF4852B1D850F
:100660002A1C85291B85281AE4F519E4FFFEE51BE1
:100670005480FDE4FCFBFAF9F8C31202F16011D2D8
:1006800080AF25AE24120BF4C280AF27AE268007C0
:1006900012095EAF25AE24120BF4AF1DAE1CAD1BCC
:1006A000AC1A78011203158F1D8E1C8D1B8C1A0538
:1006B00019E519C3941840B30518E518C394084008
:1006C00091D291D2AF7F0A7E00120BDC12092D125B
:1006D0000003120CC3E4F537220233000001370097
:1006E0000235000041007D0041007C00C100C101D5
:1006F000C102C105C104C1030139000138006064B1
:1007000000000000000000000000000000000000E9
:1007100000000000000000000000000000000000D9
:1007200000000000000000000000000000000000C9
:1007300000000000000000000000000000000000B9
:1007400000000000000000000000000000000000A9
:100750000000000000000000000000000000000099
:100760000000000000000D2200000000000000005A
:10077000000000000001210000787FE4F6D8FD753C
:1007800081390207C002005EE493A3F8E493A3401A
:1007900003F68001F208DFF48029E493A3F85407FC
:1007A000240CC8C333C4540F4420C8834004F456F7
:1007B000800146F6DFE4800B01020408102040802F
:1007C0009006D9E47E019360BCA3FF543F30E50955
:1007D000541FFEE493A360010ECF54C025E060A82F
:1007E00040B8E493A3FAE493A3F8E493A3C8C582C2
:1007F000C8CAC583CAF0A3C8C582C8CAC583CADF30
:10080000E9DEE780BEAB07AA06900001E07019C3DD
:10081000EB94C8EA9400405130934EA3EAF0A3EB66
:10082000F09000017401F0227C007D05AF03AE0260
:1008300012022DD3900003E09F900002E09E401032
:10084000E52112087DF583EAF0A3EBF0052180078E
:10085000E4900001F0F521E521C39430400BE4F56C
:100860002190000004F0E4A3F022EB25E02406F53B
:1008700082E43400F583E0FEA3E022FFEB25E024D0
:1008800004F582E43400227D1812023FAC06AD0765
:10089000E4120173E4FBFAF9783F12007D0201AC27
:1008A000AF0BAE0AAD09AC08780102031590000247
:1008B000E0F522A3E0F523222515F515EE3514F514
:1008C00014222517F517EE3516F51622C0E0C0F0F4
:1008D000C083C082C0D075D000C000C001C002C0BB
:1008E00003C004C005C006C00730D823C2D885FCA9
:1008F0002F85FB30C3E5309532F534E52F9531F582
:1009000033852F31853032AF34FE12080580035312
:10091000D879D007D006D005D004D003D002D001BA
:10092000D000D0D0D082D083D0F0D0E03290007010
:1009300074AAF074A0A3F0A37455F07E007F707DBC
:100940000322AF2BAE2AAD29AC28120302A3EFF08D
:1009500022120A7D120C207E007F707D0C22D28034
:10096000AF27AE26120BF4C28022A3E0FEA3E0FD67
:10097000EE2212022DEEA3F02275F00AA4A3F022BB
:10098000C3E52E9496E52D940022053930052AE51D
:1009900039C39414404C0538E538D394045002B25E
:1009A00096E4F539B290E538C394084035E4F5385B
:1009B000C296C290C205C20422300412E539C39423
:1009C0000A401F309602C296E4F539B290223003F5
:1009D00011E539D3940A400AE4F539B29020900227
:1009E000C20322900064E0FFB4AA0BA3E0B4A00607
:1009F000A3E064556040EF64AA7022900065E06453
:100A0000A1701AA3E0B45515120C2012092D120082
:100A100003E4F535F536120C947537012290006425
:100A2000E0B4AA12A3E0B4A50D90006FE0B455069F
:100A3000753702120C2022C0E0C0F0C083C082C013
:100A4000D075D000C000C001C002C003C004C00502
:100A5000C006C00712098A0536E53670020535530F
:100A6000917FD007D006D005D004D003D002D001AA
:100A7000D000D0D0D082D083D0F0D0E032900070BF
:100A800074AAF0A3EFF0AE22AF237C007D0A120916
:100A900072E523120979AE26AF27120972E52712F3
:100AA0000979AE24AF25120972E52512097978106B
:100AB0001209427808120942A3E52BF0A37455F0FD
:100AC00022E52CB40A03120CBD1209804015E52C56
:100AD000940A400FE4F52DF52E7FA3120951120060
:100AE00003801CC3E5369470E535941740149000DC
:100AF0007074AAF074A2120935120003120026E4E1
:100B0000F53722C0E0C0F0C083C082C0D075D000ED
:100B1000C000C001C002C003C004C005C006C007B9
:100B2000120328C2CFD007D006D005D004D003D0FE
:100B300002D001D000D0D0D082D083D0F0D0E0322B
:100B40001209804017E52CD394004010E4F52DF5F0
:100B50002E7FA4120951120003120CC322E5D854AF
:100B600040FFE5F75480FE53D8BF53F77F75DA3165
:100B7000EF42D8EE42F722E5377015120CB7EF704E
:100B80000F120CB1EF70097E007F647D0C120C4EC9
:100B900022AF885388AF758C0B758AD7758DCBEFD4
:100BA0005440FEEF54104E428822E5C8540453C806
:100BB000FB75CD4075CC9875CB4075CA9843C80479
:100BC00042C822E59154045391FB7595FF75940B2F
:100BD0007593B075923F439104429122AD07AC06E4
:100BE000D3ED9400EC9400400A120C40ED1D70F01F
:100BF0001C80ED22EF1FAC0670011E4C600B000044
:100C00000000000000000080EB22E53714600A14A9
:100C1000600A24027009020B40020AC11205D722A1
:100C2000E4F52CF52BF52AF529F528F522F52322F4
:100C3000C280D291C290C296E4FBFD7F10020052A6
:100C40007F927E09EF1F70011EEF4E70F722900019
:100C50007EEEF0A3EFF090007CEDF02275E690754B
:100C6000F31075A8B075B8102290007CE4F0C200B3
:100C7000C201C20222C2DE75D904759E01D2DE22F3
:100C800075E34075E10175E20122758E14758922C4
:100C900043885022D204E4F539D296227597DE7546
:100CA00097AD2275A41375D4CF2275A54375D507CA
:100CB0002290007DE0FF2290007CE0FF22D205E43C
:090CC000F53922D203E4F53922D2
:00000001FF