diff --git a/README.md b/README.md index 3eca78b2b..6c1bf4e3d 100644 --- a/README.md +++ b/README.md @@ -13,16 +13,16 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute! ### Development [![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. ### Important User Compilation Information 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. -- 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. ### Version Information @@ -68,7 +68,7 @@ The following devices are supported: - [Luani HVIO board](https://luani.de/projekte/esp8266-hvio/) - 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. - 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_SR04 | x | - | - | x | x | -#### Typical file size +#### Typical File Size | ESP/Arduino library version | sonoff | classic | minimal | knx | allsensors | |-----------------------------|--------|---------|---------|------|------------| @@ -147,7 +147,7 @@ You can contribute to Sonoff-Tasmota by ### Credits -#### Libraries used +#### Libraries Used Libraries used with Sonoff-Tasmota are: - [ESP8266 core for Arduino](https://github.com/esp8266/Arduino) - [Adafruit BME680](https://github.com/adafruit/Adafruit_BME680) diff --git a/lib/C2Programmer-1.0.0/README.md b/lib/C2Programmer-1.0.0/README.md new file mode 100644 index 000000000..ff7295c8d --- /dev/null +++ b/lib/C2Programmer-1.0.0/README.md @@ -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. \ No newline at end of file diff --git a/lib/C2Programmer-1.0.0/keywords.txt b/lib/C2Programmer-1.0.0/keywords.txt new file mode 100644 index 000000000..80066aed8 --- /dev/null +++ b/lib/C2Programmer-1.0.0/keywords.txt @@ -0,0 +1,19 @@ +####################################### +# Syntax Coloring Map for C2Programmer +# (esp8266) +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/lib/C2Programmer-1.0.0/library.json b/lib/C2Programmer-1.0.0/library.json new file mode 100644 index 000000000..be074b8ed --- /dev/null +++ b/lib/C2Programmer-1.0.0/library.json @@ -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" +} diff --git a/lib/C2Programmer-1.0.0/library.properties b/lib/C2Programmer-1.0.0/library.properties new file mode 100644 index 000000000..affc5e809 --- /dev/null +++ b/lib/C2Programmer-1.0.0/library.properties @@ -0,0 +1,9 @@ +name=C2Programmer +version=1.0.0 +author=Lucas Hartmann +maintainer=Theo Arends +sentence=Implementation of C2 programmer allowing update of Sonoff Bridge RF chip. +paragraph= +category=Signal Input/Output +url= +architectures=esp8266 diff --git a/lib/C2Programmer-1.0.0/src/c2.cpp b/lib/C2Programmer-1.0.0/src/c2.cpp new file mode 100644 index 000000000..22bfbaedd --- /dev/null +++ b/lib/C2Programmer-1.0.0/src/c2.cpp @@ -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; diff --git a/lib/C2Programmer-1.0.0/src/c2.h b/lib/C2Programmer-1.0.0/src/c2.h new file mode 100644 index 000000000..bc744d02f --- /dev/null +++ b/lib/C2Programmer-1.0.0/src/c2.h @@ -0,0 +1,141 @@ +#ifndef C2_H +#define C2_H + +#include +#include + +//////////////////////////////// +// 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 diff --git a/lib/C2Programmer-1.0.0/src/ihx.cpp b/lib/C2Programmer-1.0.0/src/ihx.cpp new file mode 100644 index 000000000..9a0ad6fcd --- /dev/null +++ b/lib/C2Programmer-1.0.0/src/ihx.cpp @@ -0,0 +1,71 @@ +#include "ihx.h" +#include + +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; +} + + diff --git a/lib/C2Programmer-1.0.0/src/ihx.h b/lib/C2Programmer-1.0.0/src/ihx.h new file mode 100644 index 000000000..b9fe8bec8 --- /dev/null +++ b/lib/C2Programmer-1.0.0/src/ihx.h @@ -0,0 +1,39 @@ +#ifndef IHX_H +#define IHX_H + +#include + +// 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; diff --git a/platformio.ini b/platformio.ini index 90b89cb9c..cb5da39a9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,6 +30,7 @@ env_default = sonoff ;env_default = sonoff-PL ;env_default = sonoff-PT ;env_default = sonoff-RU +;env_default = sonoff-UK ;env_default = sonoff-TW [common] ; ************************************************************ @@ -46,7 +47,7 @@ platform = espressif8266@1.5.0 framework = arduino board = esp01_1m -board_flash_mode = dout +board_build.flash_mode = dout ; *** Fix espressif8266@1.7.0 induced undesired all warnings build_unflags = -Wall @@ -57,9 +58,6 @@ build_flags = -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH ; -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 monitor_speed = 115200 @@ -68,6 +66,8 @@ monitor_speed = 115200 upload_speed = 512000 upload_resetmethod = nodemcu 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_port = user@host:/path @@ -83,7 +83,7 @@ upload_port = COM5 platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} monitor_speed = ${common.monitor_speed} @@ -96,7 +96,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DBE_MINIMAL monitor_speed = ${common.monitor_speed} @@ -108,7 +108,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DUSE_CLASSIC monitor_speed = ${common.monitor_speed} @@ -120,7 +120,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DUSE_KNX_NO_EMULATION monitor_speed = ${common.monitor_speed} @@ -132,7 +132,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DUSE_ALL_SENSORS monitor_speed = ${common.monitor_speed} @@ -144,7 +144,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=bg-BG monitor_speed = ${common.monitor_speed} @@ -156,7 +156,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=pt-BR monitor_speed = ${common.monitor_speed} @@ -168,7 +168,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=zh-CN monitor_speed = ${common.monitor_speed} @@ -180,7 +180,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=cs-CZ monitor_speed = ${common.monitor_speed} @@ -192,7 +192,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=de-DE monitor_speed = ${common.monitor_speed} @@ -204,7 +204,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=es-AR monitor_speed = ${common.monitor_speed} @@ -216,7 +216,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=fr-FR monitor_speed = ${common.monitor_speed} @@ -228,7 +228,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=el-GR monitor_speed = ${common.monitor_speed} @@ -240,7 +240,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=hu-HU monitor_speed = ${common.monitor_speed} @@ -252,7 +252,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=it-IT monitor_speed = ${common.monitor_speed} @@ -264,7 +264,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=nl-NL monitor_speed = ${common.monitor_speed} @@ -276,7 +276,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=pl-PL monitor_speed = ${common.monitor_speed} @@ -288,7 +288,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=pt-PT monitor_speed = ${common.monitor_speed} @@ -300,7 +300,7 @@ extra_scripts = ${common.extra_scripts} platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=ru-RU monitor_speed = ${common.monitor_speed} @@ -308,11 +308,23 @@ upload_speed = ${common.upload_speed} upload_port = ${common.upload_port} 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] platform = ${common.platform} framework = ${common.framework} 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_flags = ${common.build_flags} -DMY_LANGUAGE=zh-TW monitor_speed = ${common.monitor_speed} diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 0ad53c457..318fff236 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -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 [(:,:)] (#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 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) @@ -7,7 +43,7 @@ * 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 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 timer re-trigger within one minute after restart (#2744) * Fix IRSend not accepting data value of 0 by David Conran (#2751) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 0890c5738..e0f1c2439 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -42,6 +42,7 @@ #define D_JSON_BUILDDATETIME "BuildDateTime" #define D_JSON_CO2 "CarbonDioxide" #define D_JSON_COMMAND "Command" +#define D_JSON_CONNECT_FAILED "Connect failed" #define D_JSON_COREVERSION "Core" #define D_JSON_COUNTER "Counter" #define D_JSON_CURRENT "Current" // As in Voltage and Current @@ -67,6 +68,7 @@ #define D_JSON_GATEWAY "Gateway" #define D_JSON_HEAPSIZE "Heap" #define D_JSON_HIGH "High" +#define D_JSON_HOST_NOT_FOUND "Host not found" #define D_JSON_HSBCOLOR "HSBColor" #define D_JSON_HUMIDITY "Humidity" #define D_JSON_I2CSCAN_DEVICES_FOUND_AT "Device(s) found at" @@ -133,6 +135,7 @@ #define D_JSON_VOLTAGE "Voltage" #define D_JSON_WIFI "Wifi" #define D_JSON_WRONG "Wrong" +#define D_JSON_WRONG_PARAMETERS "Wrong parameters" #define D_JSON_YESTERDAY "Yesterday" #define D_JSON_ZERO_POINT_CALIBRATION "Zero Point Calibration" @@ -213,14 +216,6 @@ #define D_WCFG_5_WAIT "Wait" #define D_CMND_FRIENDLYNAME "FriendlyName" #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_RESTART "Restart" #define D_JSON_ONE_TO_RESTART "1 to restart" @@ -238,7 +233,7 @@ #define D_CMND_SERIALDELIMITER "SerialDelimiter" #define D_CMND_BAUDRATE "Baudrate" -// Commands xdrv_00_mqtt.ino +// Commands xdrv_01_mqtt.ino #define D_CMND_MQTTHOST "MqttHost" #define D_CMND_MQTTPORT "MqttPort" #define D_CMND_MQTTRETRY "MqttRetry" @@ -263,37 +258,16 @@ #define D_CMND_SENSORRETAIN "SensorRetain" #define D_CMND_PUBLISH "Publish" -// Commands xdrv_01_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_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_02_webserver.ino +#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_WEBSEND "WebSend" +#define D_CMND_EMULATION "Emulation" // Commands xdrv_03_energy.ino #define D_CMND_POWERLOW "PowerLow" @@ -324,7 +298,39 @@ #define D_JSON_ENERGYMONITOR "EnergyMonitor" #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_RFHIGH "RfHigh" #define D_CMND_RFHOST "RfHost" @@ -339,8 +345,9 @@ #define D_CMND_RFLOW "RfLow" #define D_CMND_RFSYNC "RfSync" #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_IDX "Idx" #define D_CMND_KEYIDX "KeyIdx" @@ -348,18 +355,6 @@ #define D_CMND_SENSORIDX "SensorIdx" #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 #define D_CMND_SSERIALSEND "SSerialSend" #define D_CMND_SBAUDRATE "SBaudrate" @@ -380,6 +375,18 @@ #define D_CMND_LATITUDE "Latitude" #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 "********" @@ -505,7 +512,7 @@ const char kOptionToggle[] PROGMEM = "TOGGLE|" D_TOGGLE "|" D_ADMIN ; const char kOptionBlink[] PROGMEM = "BLINK|" D_BLINK ; const char kOptionBlinkOff[] PROGMEM = "BLINKOFF|" D_BLINKOFF ; -// webserver.ino +// xdrv_02_webserver.ino #ifdef USE_WEBSERVER const char HTTP_SNS_TEMP[] PROGMEM = "%s{s}%s " D_TEMPERATURE "{m}%s°%c{e}"; // {s} = , {m} = , {e} = const char HTTP_SNS_HUM[] PROGMEM = "%s{s}%s " D_HUMIDITY "{m}%s%%{e}"; // {s} = , {m} = , {e} = diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index 55482d55c..8f397bb82 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -28,7 +28,7 @@ * 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 + * Updated until v6.0.0a \*********************************************************************/ //#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_ERASED_SECTOR "Изтрит сектор" -// webserver.ino -#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Минимаен фърмуеър - моля надградете го" +// xdrv_02_webserver.ino +#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Минимален фърмуеър - моля надградете го" #define D_WEBSERVER_ACTIVE_ON "Уеб сървърът е активен на" #define D_WITH_IP_ADDRESS "с IP адрес" #define D_WEBSERVER_STOPPED "Уеб сървърът е спрян" @@ -321,13 +321,17 @@ #define D_UPLOAD_ERR_7 "Зареждането е прекъснато" #define D_UPLOAD_ERR_8 "Файлът е невалиден" #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_ENTER_COMMAND "Въвеждане на команда" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Включете ниво 2 на лога, ако очаквате отговор" #define D_NEED_USER_AND_PASSWORD "Очаква user=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Проверка на TLS отпечатък..." #define D_TLS_CONNECT_FAILED_TO "Неуспешно TLS свързване към" #define D_RETRY_IN "Повторно след" @@ -335,7 +339,7 @@ #define D_INSECURE "Нешифрована връзка, недействителен отпечатък" #define D_CONNECT_FAILED_TO "Грешка при свързването към" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast е изключен" #define D_MULTICAST_REJOINED "Multicast е повторно съединен" #define D_MULTICAST_JOIN_FAILED "Multicast грешка при присъединяването" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST аргументи" #define D_3_RESPONSE_PACKETS_SENT "Изпратени са 3 пакета за отговор" -// xdrv_05_domoticz.ino +// xdrv_07_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz параметри" #define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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 "Използвана енергия днес" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 9f939534a..eec72fc31 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "Použij defaultní hodnoty" #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_WEBSERVER_ACTIVE_ON "Aktivní Web server" #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_8 "Špatný soubor" #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_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_NEED_USER_AND_PASSWORD "Vyžadován uživatel=&heslo=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Verifikuj otisk TLS..." #define D_TLS_CONNECT_FAILED_TO "Nepřipojeno TLS do" #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_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_REJOINED "Multicast opět připojený" #define D_MULTICAST_JOIN_FAILED "Multicast neúspěšný" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST args" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Spotřeba Dnes" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 7d2e7285d..91a2bcfef 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "Standard verwenden" #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_WEBSERVER_ACTIVE_ON "Web-Server aktiv bei" #define D_WITH_IP_ADDRESS "mit IP-Adresse" @@ -321,13 +321,17 @@ #define D_UPLOAD_ERR_7 "Upload abgebrochen" #define D_UPLOAD_ERR_8 "Datei ungültig" #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_ENTER_COMMAND "Befehl eingeben" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Aktivere Web Log Level 2 falls Reaktion erwartet" #define D_NEED_USER_AND_PASSWORD "Benötige user=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "TLS-Fingerabdruck wird verifiziert..." #define D_TLS_CONNECT_FAILED_TO "TLS-Verbindung fehlgeschlagen an" #define D_RETRY_IN "Wiederversuch in" @@ -335,7 +339,7 @@ #define D_INSECURE "unsichere Verbindung aufgrund ungültigen Fingerabdrucks" #define D_CONNECT_FAILED_TO "Verbindung fehlgeschlagen aufgrund von" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast deaktiviert" #define D_MULTICAST_REJOINED "Multicast (wieder-)verbunden" #define D_MULTICAST_JOIN_FAILED "Multicast Verbindung fehlgeschlagen" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST-Argumente" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energie heute" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 97eefcd7b..2281e2faf 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "Χρήση προεπιλογών" #define D_ERASED_SECTOR "Διαγραμμένος τομέας" -// webserver.ino +// xdrv_02_webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - παρακαλώ αναβαθμήστε" #define D_WEBSERVER_ACTIVE_ON "Web διακομιστής ενεργός" #define D_WITH_IP_ADDRESS "με διεύθυνση IP" @@ -321,13 +321,17 @@ #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 "Ενεργοποιήστε το weblog 2 αν περιμένετε απάντηση" #define D_NEED_USER_AND_PASSWORD "Χρειάζεστε user=<όνομα χρήστη>&password=<κωδικό χρήστη>" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Επαλήθευση TLS fingerprint..." #define D_TLS_CONNECT_FAILED_TO "Αποτυχία TLS σύνδεσης" #define D_RETRY_IN "Επανάληψη σε" @@ -335,7 +339,7 @@ #define D_INSECURE "Μη ασφαλής σύνδεση λόγο ακατάλληλου Fingerprint" #define D_CONNECT_FAILED_TO "Αποτυχία σύνδεσης στο" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast απενεργοποιημένο" #define D_MULTICAST_REJOINED "Multicast επανασύνδεση" #define D_MULTICAST_JOIN_FAILED "Αποτυχία σύνδεσης Multicast" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST args" #define D_3_RESPONSE_PACKETS_SENT "3πλο πακέτο απάντησεης στάλθηκε" -// xdrv_05_domoticz.ino +// xdrv_07_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz παράμετροι" #define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #define D_SENT_TO "αποστολή σε" #define D_KNX_WARNING "Η Ομάδα Διευθύνσεων ( 0 / 0 / 0 ) είναι δεσμευμένη και δεν μπορεί να χρησιμοποιηθεί." #define D_KNX_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energy Σήμερα" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 9eb8c9d4a..f5f0d6e22 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -28,7 +28,7 @@ * 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 + * Updated until v5.14.0b \*********************************************************************/ //#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_ERASED_SECTOR "Erased sector" -// webserver.ino +// xdrv_02_webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - please upgrade" #define D_WEBSERVER_ACTIVE_ON "Web server active on" #define D_WITH_IP_ADDRESS "with IP address" @@ -321,13 +321,17 @@ #define D_UPLOAD_ERR_7 "Upload aborted" #define D_UPLOAD_ERR_8 "File invalid" #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_ENTER_COMMAND "Enter command" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Enable weblog 2 if response expected" #define D_NEED_USER_AND_PASSWORD "Need user=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Verify TLS fingerprint..." #define D_TLS_CONNECT_FAILED_TO "TLS Connect failed to" #define D_RETRY_IN "Retry in" @@ -335,7 +339,7 @@ #define D_INSECURE "Insecure connection due to invalid Fingerprint" #define D_CONNECT_FAILED_TO "Connect failed to" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast disabled" #define D_MULTICAST_REJOINED "Multicast (re)joined" #define D_MULTICAST_JOIN_FAILED "Multicast join failed" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST args" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energy Today" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index aff7b2665..37fa89589 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -28,7 +28,7 @@ * 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 + * Updated until v6.0.0a \*********************************************************************/ #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_ERASED_SECTOR "Sector borrado" -// webserver.ino +// xdrv_02_webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware MÍNIMO - actualice por favor" #define D_WEBSERVER_ACTIVE_ON "Servidor web activo en" #define D_WITH_IP_ADDRESS "con dirección IP" @@ -321,13 +321,17 @@ #define D_UPLOAD_ERR_7 "Carga cancelada" #define D_UPLOAD_ERR_8 "Archivo no válido" #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_ENTER_COMMAND "Ingresar comando" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 si desea respuesta" #define D_NEED_USER_AND_PASSWORD "Se necesita user=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Verificar TLS fingerprint..." #define D_TLS_CONNECT_FAILED_TO "Falló Conección TLS a" #define D_RETRY_IN "Reintentando" @@ -335,7 +339,7 @@ #define D_INSECURE "Conección insegura por Fingerprint no válido" #define D_CONNECT_FAILED_TO "Falló Conección a" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast deshabilitado" #define D_MULTICAST_REJOINED "Multicast (re)conectado" #define D_MULTICAST_JOIN_FAILED "Conección Multicast fallida" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST args" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Mejora de Comunicación" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energía Hoy" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index f37d3cfae..09f9ffe0f 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "Utiliser par défaut" #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_WEBSERVER_ACTIVE_ON "Serveur web actif sur" #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_8 "Fichier invalide" #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_ENTER_COMMAND "Saisir une commande" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Activer Weblog 2 si une réponse est attendue" #define D_NEED_USER_AND_PASSWORD "Nécessite utilisateur=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Vérification d'empreinte TLS ..." #define D_TLS_CONNECT_FAILED_TO "Échec de connexion TLS à" #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_CONNECT_FAILED_TO "Échec de connexion à" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast désactivé" #define D_MULTICAST_REJOINED "Multicast (re)joint" #define D_MULTICAST_JOIN_FAILED "Multicast échec abonnement" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST args" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xsns_03_energy.ino #define D_ENERGY_TODAY "Énergie aujourd'hui" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 4ebeffbf6..986b18fdf 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "Alapértelmezett beáll. használata" #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_WEBSERVER_ACTIVE_ON "Web szerver aktív a" #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_8 "Érvénytelen file" #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_ENTER_COMMAND "Parancsolj" #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ó=&jelszó=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "TLS fingerprint hitelesítése..." #define D_TLS_CONNECT_FAILED_TO "TLS Csatlakozás sikertelen a" #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_CONNECT_FAILED_TO "Sikertelen csatlakozás a" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast kikapcsolva" #define D_MULTICAST_REJOINED "Multicast (újra)csatlakozás" #define D_MULTICAST_JOIN_FAILED "Multicast csatlakozás sikertelen" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST args" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Mai Energia" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 16c11645b..eeac61384 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "Utilizzo valori default" #define D_ERASED_SECTOR "Settore cancellato" -// webserver.ino +// xdrv_02_webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - effettuare aggiornamento" #define D_WEBSERVER_ACTIVE_ON "Web server attivo su" #define D_WITH_IP_ADDRESS "con indirizzo IP" @@ -321,13 +321,17 @@ #define D_UPLOAD_ERR_7 "Invio annullato" #define D_UPLOAD_ERR_8 "File non valido" #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_ENTER_COMMAND "Inserire comando" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Abilitare weblog 2 se è attesa una risposta" #define D_NEED_USER_AND_PASSWORD "Richiesto user=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Verifica TLS fingerprint..." #define D_TLS_CONNECT_FAILED_TO "Connessione TLS fallita a" #define D_RETRY_IN "Nuovo tentativo in" @@ -335,7 +339,7 @@ #define D_INSECURE "Connessione insicura a causa di Fingerprint non valido" #define D_CONNECT_FAILED_TO "Connessione Fallita a" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast disabilitato" #define D_MULTICAST_REJOINED "Multicast (ri)associato" #define D_MULTICAST_JOIN_FAILED "Associazione Multicast fallita" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST argomenti" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Miglioramento Comunicazione" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia Oggi" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 262daee7b..a764cb667 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -28,7 +28,7 @@ * 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 + * Updated until v6.0.0a \*********************************************************************/ //#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_ERASED_SECTOR "Wis sector" -// webserver.ino +// xdrv_02_webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - opwaarderen" #define D_WEBSERVER_ACTIVE_ON "Webserver actief op" #define D_WITH_IP_ADDRESS "met IP adres" @@ -321,13 +321,17 @@ #define D_UPLOAD_ERR_7 "Opwaarderen afgebroken" #define D_UPLOAD_ERR_8 "Ongeldig bestand" #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_ENTER_COMMAND "Geef opdracht" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Schakel weblog 2 in indien antwoord verwacht" #define D_NEED_USER_AND_PASSWORD "Benodig user=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Controleer TLS vingerafdruk..." #define D_TLS_CONNECT_FAILED_TO "TLS Verbinding mislukt naar" #define D_RETRY_IN "Opnieuw proberen over" @@ -335,7 +339,7 @@ #define D_INSECURE "Door ongeldige vingerafdruk een onveilige verbinding" #define D_CONNECT_FAILED_TO "Verbinding mislukt naar" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast uitgeschakeld" #define D_MULTICAST_REJOINED "Multicast verbonden" #define D_MULTICAST_JOIN_FAILED "Multicast verbinding mislukt" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST argumenten" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Toets idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Verbeter verbinding" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Verbruik vandaag" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 683d43cb3..a039cf333 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "Użyj domyślnych" #define D_ERASED_SECTOR "Wymazany sektor" -// webserver.ino +// xdrv_02_webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Oprogramowanie MINIMAL - proszę uaktualnić" #define D_WEBSERVER_ACTIVE_ON "Aktywny serwer Web" #define D_WITH_IP_ADDRESS "z adresem IP" @@ -321,13 +321,17 @@ #define D_UPLOAD_ERR_7 "Wgrywanie przerwane" #define D_UPLOAD_ERR_8 "Błędny plik" #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_ENTER_COMMAND "Wprowadź polecenie" #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=&hasło=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Weryfikuj odcisk TLS..." #define D_TLS_CONNECT_FAILED_TO "Nieudane połączenie TLS do" #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_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_REJOINED "Multicast (re)dołączony" #define D_MULTICAST_JOIN_FAILED "Multicast nie powiodło się" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST args" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia Dzisiaj" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index 02bdec2e4..4bcf8efa2 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * 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) @@ -52,8 +52,8 @@ // Common #define D_ADMIN "Admin" -#define D_AIR_QUALITY "Qualidade do Ar" -#define D_AP "Pondo de acesso" // Ponto de Acesso +#define D_AIR_QUALITY "Qualidade do ar" +#define D_AP "Ponto de acesso" // Ponto de Acesso #define D_AS "como" #define D_AUTO "Auto" #define D_BLINK "Pulsar" @@ -64,16 +64,16 @@ #define D_BY "por" // Write by me #define D_BYTES "Bytes" #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_COLDLIGHT "Luz Fria" +#define D_COLDLIGHT "Luz fria" #define D_COMMAND "Comando" #define D_CONNECTED "Ligado" #define D_COUNT "Contagem" #define D_COUNTER "Contador" #define D_CURRENT "Corrente" // As in Voltage and Current #define D_DATA "Dados" -#define D_DARKLIGHT "Luz Escura" +#define D_DARKLIGHT "Luz escura" #define D_DEBUG "Depurar" #define D_DISABLED "Desabilitado" #define D_DISTANCE "Distância" @@ -91,8 +91,8 @@ #define D_FALLBACK_TOPIC "Tópico para retornar" #define D_FALSE "Falso" #define D_FILE "Arquivo" -#define D_FREE_MEMORY "Memória Livre" -#define D_FREQUENCY "Frequency" +#define D_FREE_MEMORY "Memória livre" +#define D_FREQUENCY "Frequência" #define D_GAS "Gás" #define D_GATEWAY "Gateway" #define D_GROUP "Grupo" @@ -103,7 +103,7 @@ #define D_IMMEDIATE "Imediato" // Button immediate #define D_INDEX "Índice" #define D_INFO "Informação" -#define D_INFRARED "Infrared" +#define D_INFRARED "Infravermelho" #define D_INITIALIZED "Inicializado" #define D_IP_ADDRESS "Endereço IP" #define D_LIGHT "Luz" @@ -122,9 +122,9 @@ #define D_PORT "Porta" #define D_POWER_FACTOR "Fator de potência" #define D_POWERUSAGE "Potência" -#define D_POWERUSAGE_ACTIVE "Active Power" -#define D_POWERUSAGE_APPARENT "Apparent Power" -#define D_POWERUSAGE_REACTIVE "Reactive Power" +#define D_POWERUSAGE_ACTIVE "Potência ativa" +#define D_POWERUSAGE_APPARENT "Potência aparente" +#define D_POWERUSAGE_REACTIVE "Potência reativa" #define D_PRESSURE "Pressão" #define D_PRESSUREATSEALEVEL "Pressão ao nível do mar" #define D_PROGRAM_FLASH_SIZE "Tamanho do programa na memória" @@ -168,10 +168,10 @@ #define D_WEB_SERVER "Servidor WEB" // 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_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_SET_BAUDRATE_TO "Ajuste da velocidade para" @@ -205,15 +205,15 @@ #define D_USE_DEFAULTS "Usar predefinições" #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_WEBSERVER_ACTIVE_ON "Servidor WEB ativo em" #define D_WITH_IP_ADDRESS "com o endereço IP" #define D_WEBSERVER_STOPPED "Servidor WEB parou" #define D_FILE_NOT_FOUND "Arquivo não encontrado" #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 "Wifimanager configura o Ponto de Acesso" +#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_TRYING_TO_CONNECT "Conectar o dispositivo à rede" #define D_RESTART_IN "Reinicia em" @@ -238,7 +238,7 @@ #define D_RESTORE_CONFIGURATION "Repor configuração" #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_GPIO "GPIO" #define D_SERIAL_IN "Entrada serial" @@ -282,12 +282,12 @@ #define D_SINGLE_DEVICE "Dispositivo único" #define D_MULTI_DEVICE "Múltiplos dispositivos" -#define D_SAVE_CONFIGURATION "Salvar configuração" -#define D_CONFIGURATION_SAVED "Configuração salva" +#define D_SAVE_CONFIGURATION "Gravar configuração" +#define D_CONFIGURATION_SAVED "Configuração gravada" #define D_CONFIGURATION_RESET "Reinicialização da configuração" #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_FLASH_WRITE_COUNT "Contagem de gravação flash" #define D_MAC_ADDRESS "Endereço MAC" @@ -321,13 +321,17 @@ #define D_UPLOAD_ERR_7 "Envio cancelado" #define D_UPLOAD_ERR_8 "Arquivo inválido" #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_ENTER_COMMAND "Inserir comando" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 se resposta esperada" #define D_NEED_USER_AND_PASSWORD "Necessário user=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Verifique a impressão digital TLS..." #define D_TLS_CONNECT_FAILED_TO "TLS não conseguiu ligar" #define D_RETRY_IN "Tentativa em" @@ -335,7 +339,7 @@ #define D_INSECURE "Ligação insegura devido à impressão digital inválida" #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_REJOINED "Multicast (re)ingressou" #define D_MULTICAST_JOIN_FAILED "Multicast falha no reingresso" @@ -355,15 +359,15 @@ #define D_HUE_POST_ARGS "Hue POST args" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Chave idx" #define D_DOMOTICZ_SWITCH_IDX "Interruptor idx" #define D_DOMOTICZ_SENSOR_IDX "Sensor idx" #define D_DOMOTICZ_TEMP "Temp" - #define D_DOMOTICZ_TEMP_HUM "Temp,Hum" - #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro" + #define D_DOMOTICZ_TEMP_HUM "Temp,Umi" + #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Umi,Pres" #define D_DOMOTICZ_POWER_ENERGY "Potência,Energia" #define D_DOMOTICZ_ILLUMINANCE "Luminância" #define D_DOMOTICZ_COUNT "Contagem/PM1" @@ -401,7 +405,9 @@ #define D_KNX_COMMAND_OTHER "Outros" #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_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 #define D_ENERGY_TODAY "Consumo energético de hoje" @@ -439,19 +445,19 @@ #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" #define D_SENSOR_IRSEND "IRsend" -#define D_SENSOR_SWITCH "Interruptor" // Suffix "1" -#define D_SENSOR_BUTTON "Botão" // Suffix "1" -#define D_SENSOR_RELAY "Relé" // Suffix "1i" -#define D_SENSOR_LED "Led" // Suffix "1i" -#define D_SENSOR_PWM "PWM" // Suffix "1" -#define D_SENSOR_COUNTER "Contador" // Suffix "1" +#define D_SENSOR_SWITCH "Interruptor" // Suffix "1" +#define D_SENSOR_BUTTON "Botão" // Suffix "1" +#define D_SENSOR_RELAY "Relé" // Suffix "1i" +#define D_SENSOR_LED "Led" // Suffix "1i" +#define D_SENSOR_PWM "PWM" // Suffix "1" +#define D_SENSOR_COUNTER "Contador" // Suffix "1" #define D_SENSOR_IRRECV "IRrecv" -#define D_SENSOR_MHZ_RX "MHZ Rx" -#define D_SENSOR_MHZ_TX "MHZ Tx" +#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_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 "Luz de fundo" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index 4cf9e0da3..4eeeb3965 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "Usar predefinições" #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_WEBSERVER_ACTIVE_ON "Servidor WEB ativo em" #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_8 "Ficheiro inválido" #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_ENTER_COMMAND "Inserir comando" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Habilitar weblog 2 se resposta esperada" #define D_NEED_USER_AND_PASSWORD "Necessário user=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Verifique a impressão digital TLS..." #define D_TLS_CONNECT_FAILED_TO "TLS não conseguiu ligar" #define D_RETRY_IN "Tentativa em" @@ -335,7 +339,7 @@ #define D_INSECURE "Ligação insegura devido à impressão digital inválida" #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_REJOINED "Multicast (re)ingressou" #define D_MULTICAST_JOIN_FAILED "Multicast falha no reingresso" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST args" #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_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Chave idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Consumo energético de hoje" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index 3336484e9..cda108cdc 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "Использовать значение по умолчанию" #define D_ERASED_SECTOR "Стереть сектор" -// webserver.ino +// xdrv_02_webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Прошивка MINIMAL - пожалуйста обновите" #define D_WEBSERVER_ACTIVE_ON "Веб-сервер активен" #define D_WITH_IP_ADDRESS "с IP-адресом" @@ -321,13 +321,17 @@ #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=&password=" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "Проверка TLS Fingerprint..." #define D_TLS_CONNECT_FAILED_TO "Сбой подключения TLS к" #define D_RETRY_IN "Повторить" @@ -335,7 +339,7 @@ #define D_INSECURE "Небезопасное соединение, недействительный Fingerprint" #define D_CONNECT_FAILED_TO "Ошибка подключения к" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "Multicast отключен" #define D_MULTICAST_REJOINED "Multicast (ре)соединился" #define D_MULTICAST_JOIN_FAILED "Multicast ошибка соединения" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST args" #define D_3_RESPONSE_PACKETS_SENT "3 ответных пакета получено" -// xdrv_05_domoticz.ino +// xdrv_07_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz parameters" #define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Энергия Сегодня" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h new file mode 100644 index 000000000..c0339b9e8 --- /dev/null +++ b/sonoff/language/uk-UK.h @@ -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 . +*/ + +#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=&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_ diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index 1c3ee0bb7..7a485feb0 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "使用默认设置" #define D_ERASED_SECTOR "擦除删除" -// webserver.ino +// xdrv_02_webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "固件版本过低 - 请升级" #define D_WEBSERVER_ACTIVE_ON "Web服务器:" #define D_WITH_IP_ADDRESS "IP地址:" @@ -321,13 +321,17 @@ #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 "如果预期响应,则启用Weblog 2" #define D_NEED_USER_AND_PASSWORD "需要 user=<用户名>&password=<密码>" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "验证 TLS 指纹..." #define D_TLS_CONNECT_FAILED_TO "TLS 连接失败" #define D_RETRY_IN "重试倒计时:" @@ -335,7 +339,7 @@ #define D_INSECURE "指纹无效导致连接不安全" #define D_CONNECT_FAILED_TO "连接失败:" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "组播已禁用" #define D_MULTICAST_REJOINED "组播已(重新)加入" #define D_MULTICAST_JOIN_FAILED "组播加入失败" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST 参数" #define D_3_RESPONSE_PACKETS_SENT "3 请求包发送" -// xdrv_05_domoticz.ino +// xdrv_07_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz 设置" #define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "今日用电量" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index e8505010f..e6adb4b0e 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -205,7 +205,7 @@ #define D_USE_DEFAULTS "使用默認設置" #define D_ERASED_SECTOR "擦除刪除" -// webserver.ino +// xdrv_02_webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "固件版本過低 - 請升級" #define D_WEBSERVER_ACTIVE_ON "Web服務器:" #define D_WITH_IP_ADDRESS "IP地址:" @@ -321,13 +321,17 @@ #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 "如果預期響應,則啟用Weblog 2" #define D_NEED_USER_AND_PASSWORD "需要 user=<用戶名>&password=<密碼>" -// xdrv_00_mqtt.ino +// xdrv_01_mqtt.ino #define D_FINGERPRINT "驗證 TLS 指紋..." #define D_TLS_CONNECT_FAILED_TO "TLS 連接失敗" #define D_RETRY_IN "重試倒計時:" @@ -335,7 +339,7 @@ #define D_INSECURE "指紋無效導致連接不安全" #define D_CONNECT_FAILED_TO "連接失敗:" -// xdrv_wemohue.ino +// xplg_wemohue.ino #define D_MULTICAST_DISABLED "組播已禁用" #define D_MULTICAST_REJOINED "組播已(重新)加入" #define D_MULTICAST_JOIN_FAILED "組播加入失敗" @@ -355,7 +359,7 @@ #define D_HUE_POST_ARGS "Hue POST 參數" #define D_3_RESPONSE_PACKETS_SENT "3 請求包發送" -// xdrv_05_domoticz.ino +// xdrv_07_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz 設置" #define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" @@ -402,6 +406,8 @@ #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_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "今日用電量" diff --git a/sonoff/settings.h b/sonoff/settings.h index ccb9509d2..bf947d350 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -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 no_power_on_check : 1; // bit 21 (v5.11.1i) uint32_t mqtt_serial : 1; // bit 22 (v5.12.0f) - uint32_t rules_enabled : 1; // bit 23 (v5.12.0j) - uint32_t rules_once : 1; // bit 24 (v5.12.0k) + 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) - free since v5.14.0b uint32_t knx_enabled : 1; // bit 25 (v5.12.0l) KNX uint32_t device_index_enable : 1; // bit 26 (v5.13.1a) uint32_t knx_enable_enhancement : 1; // bit 27 (v5.14.0a) KNX @@ -114,12 +114,21 @@ typedef union { }; } Timer; +/* struct SYSCFG { - unsigned long cfg_holder; // 000 + unsigned long cfg_holder; // 000 Pre v6 header unsigned long save_flag; // 004 unsigned long version; // 008 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 int8_t timezone; // 016 char ota_url[101]; // 017 @@ -163,11 +172,13 @@ struct SYSCFG { uint16_t pwm_frequency; // 2E6 power_t power; // 2E8 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 - uint8_t ex_power; // 2FA Not used since 5.8.0j + + byte free_2fa[1]; // 2FA + 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 byte free_312[1]; // 312 @@ -204,19 +215,9 @@ struct SYSCFG { uint16_t blinktime; // 39A uint16_t blinkcount; // 39C 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 switch_topic[33]; // 430 char serial_delimiter; // 451 @@ -232,9 +233,8 @@ struct SYSCFG { uint8_t light_color[5]; // 498 uint8_t light_correction; // 49D uint8_t light_dimmer; // 49E - - byte free_49F[2]; // 49F - + uint8_t rule_enabled; // 49F + uint8_t rule_once; // 4A0 uint8_t light_fade; // 4A1 uint8_t light_speed; // 4A2 uint8_t light_scheme; // 4A3 @@ -251,9 +251,9 @@ struct SYSCFG { byte free_542[2]; // 542 uint32_t ip_address[4]; // 544 - unsigned long energy_kWhtotal; // 554 + unsigned long energy_kWhtotal; // 554 char mqtt_fulltopic[100]; // 558 - SysBitfield2 flag2; // 5BC Add flag2 since 5.9.2 + SysBitfield2 flag2; // 5BC unsigned long pulse_counter[MAX_COUNTERS]; // 5C0 uint16_t pulse_counter_type; // 5D0 uint16_t pulse_counter_debounce; // 5D2 @@ -274,9 +274,11 @@ struct SYSCFG { byte free_6f6[216]; // 6F6 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; struct RTCMEM { diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 2d3f3c3d8..2b7803304 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -67,25 +67,25 @@ #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; 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() { - if (GetRtcSettingsHash() != rtc_settings_hash) { + if (GetRtcSettingsCrc() != rtc_settings_crc) { RtcSettings.valid = RTC_MEM_VALID; ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); - rtc_settings_hash = GetRtcSettingsHash(); + rtc_settings_crc = GetRtcSettingsCrc(); #ifdef DEBUG_THEO AddLog_P(LOG_LEVEL_DEBUG, PSTR("Dump: Save")); RtcSettingsDump(); @@ -111,7 +111,7 @@ void RtcSettingsLoad() RtcSettings.power = Settings.power; RtcSettingsSave(); } - rtc_settings_hash = GetRtcSettingsHash(); + rtc_settings_crc = GetRtcSettingsCrc(); } boolean RtcSettingsValid() @@ -133,16 +133,14 @@ extern "C" uint32_t _SPIFFS_end; // From libraries/EEPROM/EEPROM.cpp EEPROMClass #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 #define SETTINGS_LOCATION SPIFFS_END // No need for SPIFFS as it uses EEPROM area // Version 5.2 allow for more flash space #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; +uint8_t *settings_buffer = NULL; /********************************************************************************************/ /* @@ -167,15 +165,33 @@ void SetFlashModeDout() 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; 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() @@ -209,7 +225,7 @@ void SettingsSave(byte rotate) * stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1) */ #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) stop_flash_rotate = 1; } @@ -225,6 +241,8 @@ void SettingsSave(byte rotate) } } Settings.save_flag++; + Settings.cfg_size = sizeof(SYSCFG); + Settings.cfg_crc = GetSettingsCrc(); ESP.flashEraseSector(settings_location); ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); 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"), settings_location, Settings.save_flag, sizeof(SYSCFG)); AddLog(LOG_LEVEL_DEBUG); - settings_hash = GetSettingsHash(); + + settings_crc = Settings.cfg_crc; } #endif // BE_MINIMAL 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 */ struct SYSCFGH { - unsigned long cfg_holder; - unsigned long save_flag; + uint16_t cfg_holder; // 000 + uint16_t cfg_size; // 002 + unsigned long save_flag; // 004 } _SettingsH; + bool bad_crc = false; settings_location = SETTINGS_LOCATION +1; for (byte i = 0; i < CFG_ROTATES; i++) { settings_location--; 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)); - -// 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); -// 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)) { + if (Settings.version > 0x06000000) { bad_crc = (Settings.cfg_crc != GetSettingsCrc()); } + if (Settings.flag.stop_flash_rotate || bad_crc || (Settings.cfg_holder != _SettingsH.cfg_holder) || (Settings.save_flag > _SettingsH.save_flag)) { break; } delay(1); } - 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); + 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); 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(); } @@ -353,50 +364,110 @@ void SettingsDefaultSet1() { 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.version = VERSION; // Settings.bootcount = 0; +// Settings.cfg_crc = 0; } void SettingsDefaultSet2() { memset((char*)&Settings +16, 0x00, sizeof(SYSCFG) -16); - 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 = 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.flag.value_units = 0; +// Settings.flag.stop_flash_rotate = 0; 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)); + + // 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.sbaudrate = SOFT_BAUDRATE / 1200; Settings.serial_delimiter = 0xff; - 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; 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_ssid[1], STA_SSID2, sizeof(Settings.sta_ssid[1])); strlcpy(Settings.sta_pwd[1], STA_PASS2, sizeof(Settings.sta_pwd[1])); 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)); Settings.syslog_port = SYS_LOG_PORT; Settings.syslog_level = SYS_LOG_LEVEL; + + // Webserver + Settings.flag2.emulation = EMULATION; Settings.webserver = WEB_SERVER; 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]; strlcpy(fingerprint, MQTT_FINGERPRINT1, sizeof(fingerprint)); char *p = fingerprint; @@ -408,32 +479,14 @@ void SettingsDefaultSet2() for (byte i = 0; i < 20; i++) { 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.power = APP_POWER; - Settings.poweronstate = APP_POWERON_STATE; - Settings.ledstate = APP_LEDSTATE; - Settings.blinktime = APP_BLINKTIME; - Settings.blinkcount = APP_BLINKCOUNT; - Settings.sleep = APP_SLEEP; - - 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; - } - + // Energy + Settings.flag2.current_resolution = 3; +// Settings.flag2.voltage_resolution = 0; +// Settings.flag2.wattage_resolution = 0; + Settings.flag2.energy_resolution = ENERGY_RESOLUTION; + Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY; Settings.energy_power_delta = DEFAULT_POWER_DELTA; Settings.energy_power_calibration = HLW_PREF_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_energy = 0; // MaxEnergy // 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; RtcSettings.energy_kWhtotal = 0; - // 5.0.5 - strlcpy(Settings.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(Settings.mqtt_fulltopic)); - - // 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 + // RF Bridge +// for (byte i = 0; i < 17; i++) { Settings.rf_code[i][0] = 0; } memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9); - // 5.8.0 - Settings.light_pixels = WS2812_LEDS; -// Settings.light_rotation = 0; + // Domoticz + Settings.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER; +// 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; + + // 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_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++) { Settings.light_color[i] = 255; +// Settings.pwm_value[i] = 0; } - Settings.light_correction = 0; +// Settings.light_correction = 0; Settings.light_dimmer = 10; - Settings.light_fade = 0; +// Settings.light_fade = 0; Settings.light_speed = 1; - Settings.light_scheme = 0; +// Settings.light_scheme = 0; 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[1], NTP_SERVER2, sizeof(Settings.ntp_server[1])); 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; - for (byte i = 1; i < MAX_PULSETIMERS; i++) { - Settings.pulse_timer[i] = 0; - } + Settings.latitude = (int)((double)LATITUDE * 1000000); + Settings.longitude = (int)((double)LONGITUDE * 1000000); + 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() { @@ -685,132 +660,27 @@ void SettingsDefaultSet_5_13_1c() void SettingsDelta() { 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) { - for (byte i = 0; i < 17; i++) { - Settings.rf_code[i][0] = 0; - } + for (byte i = 0; i < 17; i++) { Settings.rf_code[i][0] = 0; } memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9); } if (Settings.version < 0x05080000) { - uint8_t cfg_wsflg = 0; - for (byte i = 0; i < MAX_GPIO_PIN; i++) { - if (GPIO_WS2812 == Settings.my_gp.io[i]) { - cfg_wsflg = 1; - } - } - if (!Settings.light_pixels && cfg_wsflg) { - Settings.light_pixels = WS2812_LEDS; - Settings.light_color[0] = Settings.ws_red; - Settings.light_color[1] = Settings.ws_green; - Settings.light_color[2] = Settings.ws_blue; - Settings.light_dimmer = Settings.ws_dimmer; - 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; - } + Settings.light_pixels = WS2812_LEDS; + Settings.light_width = 1; + Settings.light_color[0] = 255; + Settings.light_color[1] = 0; + Settings.light_color[2] = 0; + Settings.light_dimmer = 10; + Settings.light_correction = 0; + Settings.light_fade = 0; + Settings.light_speed = 1; + Settings.light_scheme = 0; + Settings.light_width = 1; + Settings.light_wakeup = 0; } if (Settings.version < 0x0508000A) { - Settings.power = Settings.ex_power; + Settings.power = 0; Settings.altitude = 0; } if (Settings.version < 0x0508000B) { @@ -862,15 +732,12 @@ void SettingsDelta() Settings.sbaudrate = SOFT_BAUDRATE / 1200; Settings.serial_delimiter = 0xff; } -// if (Settings.version < 0x050C0009) { -// memset(&Settings.timer, 0x00, sizeof(Timer) * MAX_TIMERS); -// } if (Settings.version < 0x050C000A) { Settings.latitude = (int)((double)LATITUDE * 1000000); Settings.longitude = (int)((double)LONGITUDE * 1000000); } if (Settings.version < 0x050C000B) { - memset(&Settings.rules, 0x00, sizeof(Settings.rules)); + Settings.rules[0][0] = '\0'; } if (Settings.version < 0x050C000D) { 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) { 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; SettingsSave(1); diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 369fb10cb..5d641f5fb 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -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_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 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 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 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 TOPSZ 100 // Max number of characters in topic string #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_ASTRONOMIC -18.0 -// Sensor definition for KNX Driver +// Sensor and Commands definition for KNX Driver #define KNX_TEMPERATURE 17 #define KNX_HUMIDITY 18 #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_START 24 #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 @@ -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 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, - FUNC_COMMAND, FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA, FUNC_SET_POWER, FUNC_SHOW_SENSOR}; +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_RULES_PROCESS}; 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 uint8_t light_device; // Light device number -#endif // _SONOFF_H_ \ No newline at end of file +#endif // _SONOFF_H_ diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index e88c03e7e..de3935c07 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x050E0001 // 5.14.0a +#define VERSION 0x06000001 // 6.0.0a // Location specific includes #include // 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_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_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_I2CSCAN, CMND_SERIALSEND, CMND_BAUDRATE, CMND_SERIALDELIMITER }; 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_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_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_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; + ShowSource(source); + if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) { // All on and stay on power = (1 << devices_present) -1; rpower = power; @@ -396,6 +398,8 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) memcpy(dataBuf, data +i, sizeof(dataBuf)); 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"), topicBuf, data_len, dataBuf); 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)) { if ((payload < 0) || (payload > 4)) payload = 9; // Settings.flag.device_index_enable = user_append_index; - ExecuteCommandPower(index, payload); + ExecuteCommandPower(index, payload, SRC_IGNORE); fallback_topic_flag = 0; return; } @@ -516,7 +520,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) Settings.poweronstate = payload; if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) { 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) { + mytmplt cmodule; + memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule)); for (byte i = 0; i < GPIO_SENSOR_END; i++) { if (!jsflg) { 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); } jsflg = 1; - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%d (%s)\""), mqtt_data, i, GetTextIndexed(stemp1, sizeof(stemp1), i, kSensorNames)); - if ((strlen(mqtt_data) > (LOGSZ - TOPSZ)) || (i == GPIO_SENSOR_END -1)) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]}"), mqtt_data); - MqttPublishPrefixTopic_P(RESULT_OR_STAT, type); - jsflg = 0; - lines++; + if (!GetUsedInModule(i, cmodule.gp.io)) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%d (%s)\""), mqtt_data, i, GetTextIndexed(stemp1, sizeof(stemp1), i, kSensorNames)); + if ((strlen(mqtt_data) > (LOGSZ - TOPSZ)) || (i == GPIO_SENSOR_END -1)) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]}"), mqtt_data); + MqttPublishPrefixTopic_P(RESULT_OR_STAT, type); + jsflg = 0; + lines++; + } } } 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; 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) { if ((payload >= 0) && (payload < 3601)) { Settings.tele_period = (1 == payload) ? TELE_PERIOD : payload; @@ -1028,7 +1004,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) break; case 99: AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING)); - ESP.restart(); + EspRestart(); break; default: 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); #endif // USE_DOMOTICZ result = true; -#ifdef USE_RULES } else { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":{\"State\":%d}}"), (key) ? "Switch" : "Button", device, state); - result = RulesProcess(); -#endif // USE_RULES + result = XdrvRulesProcess(); } #ifdef USE_KNX KnxSendButtonPower(key, device, state); @@ -1189,7 +1163,7 @@ boolean SendKey(byte key, byte device, byte state) return result; } -void ExecuteCommandPower(byte device, byte state) +void ExecuteCommandPower(byte device, byte state, int source) { // device = Relay number 1 and up // state 0 = Relay Off @@ -1201,6 +1175,8 @@ void ExecuteCommandPower(byte device, byte state) // state 7 = Relay On and no publishPowerState // state 9 = Show power state +// ShowSource(source); + uint8_t publish_power = 1; if ((POWER_OFF_NO_STATE == state) || (POWER_ON_NO_STATE == state)) { state &= 1; @@ -1218,7 +1194,7 @@ void ExecuteCommandPower(byte device, byte state) interlock_mutex = 1; for (byte i = 0; i < devices_present; 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; } @@ -1232,7 +1208,7 @@ void ExecuteCommandPower(byte device, byte state) case POWER_TOGGLE: power ^= mask; } - SetDevicePower(power); + SetDevicePower(power, source); #ifdef USE_DOMOTICZ DomoticzUpdatePowerState(device); #endif // USE_DOMOTICZ @@ -1259,7 +1235,7 @@ void ExecuteCommandPower(byte device, byte state) byte flag = (blink_mask & mask); blink_mask &= (POWER_MASK ^ mask); // Clear device mask 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; } if (publish_power) MqttPublishPowerState(device); @@ -1274,18 +1250,20 @@ void StopAllPowerBlink() if (blink_mask & mask) { blink_mask &= (POWER_MASK ^ mask); // Clear device mask 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 svalue[INPUT_BUFFER_SIZE]; char *start; char *token; + ShowSource(source); + token = strtok(cmnd, " "); if (token != NULL) { start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble @@ -1300,11 +1278,11 @@ void ExecuteCommand(char *cmnd) void PublishStatus(uint8_t payload) { - uint8_t option = 1; + uint8_t option = STAT; char stemp[MAX_FRIENDLYNAMES * (sizeof(Settings.friendlyname[0]) +4)]; // 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 (!energy_flg && (9 == payload)) payload = 99; @@ -1584,7 +1562,7 @@ void ButtonHandler() } if (button_pressed) { 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 { @@ -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); AddLog(LOG_LEVEL_DEBUG); 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 { 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 // Settings.flag.button_single = 0; snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_SETOPTION "13 0")); // Disable single press only - ExecuteCommand(scmnd); + ExecuteCommand(scmnd, SRC_BUTTON); } } else { 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 multipress[button_index] = 0; 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 restart_flag = 1; } 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 if (!Settings.flag.button_restrict) { 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 (!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)) { pulse_timer[i]--; if (!pulse_timer[i]) { -// ExecuteCommandPower(i +1, POWER_OFF); - ExecuteCommandPower(i +1, (POWER_ALL_OFF_PULSETIME_ON == Settings.poweronstate) ? POWER_ON : POWER_OFF); +// ExecuteCommandPower(i +1, POWER_OFF, SRC_PULSETIMER); + ExecuteCommandPower(i +1, (POWER_ALL_OFF_PULSETIME_ON == Settings.poweronstate) ? POWER_ON : POWER_OFF, SRC_PULSETIMER); } } } @@ -1802,7 +1780,7 @@ void StateLoop() } else { blink_power ^= 1; 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_pointer != backlog_index) && !backlog_delay && !backlog_mutex) { backlog_mutex = 1; - ExecuteCommand((char*)backlog[backlog_pointer].c_str()); + ExecuteCommand((char*)backlog[backlog_pointer].c_str(), SRC_BACKLOG); backlog_mutex = 0; backlog_pointer++; if (backlog_pointer >= MAX_BACKLOG) backlog_pointer = 0; @@ -1963,7 +1941,7 @@ void StateLoop() restart_flag--; if (restart_flag <= 0) { AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING)); - ESP.restart(); + EspRestart(); } } 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); AddLog(LOG_LEVEL_INFO); - delay(100); // Allow time for message xfer - ESP.restart(); + EspRestart(); }); ArduinoOTA.onEnd([]() @@ -2047,8 +2024,7 @@ void ArduinoOTAInit() 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)); AddLog(LOG_LEVEL_INFO); - delay(100); // Allow time for message xfer - ESP.restart(); + EspRestart(); }); ArduinoOTA.begin(); @@ -2156,7 +2132,7 @@ void SerialInput() 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); AddLog(LOG_LEVEL_INFO); - ExecuteCommand(serial_in_buffer); + ExecuteCommand(serial_in_buffer, SRC_SERIAL); serial_in_byte_counter = 0; serial_polling_window = 0; Serial.flush(); @@ -2168,6 +2144,7 @@ void SerialInput() 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); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED)); +// XdrvRulesProcess(); serial_in_byte_counter = 0; } } @@ -2347,7 +2324,7 @@ void GpioInit() } SetLedPower(Settings.ledstate &8); - XdrvCall(FUNC_INIT); + XdrvCall(FUNC_PRE_INIT); } extern "C" { @@ -2412,36 +2389,36 @@ void setup() if (MOTOR == Settings.module) Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo! if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) { - SetDevicePower(1); + SetDevicePower(1, SRC_RESTART); } else { if ((resetInfo.reason == REASON_DEFAULT_RST) || (resetInfo.reason == REASON_EXT_SYS_RST)) { switch (Settings.poweronstate) { case POWER_ALL_OFF: case POWER_ALL_OFF_PULSETIME_ON: power = 0; - SetDevicePower(power); + SetDevicePower(power, SRC_RESTART); break; case POWER_ALL_ON: // All on power = (1 << devices_present) -1; - SetDevicePower(power); + SetDevicePower(power, SRC_RESTART); break; case POWER_ALL_SAVED_TOGGLE: power = (Settings.power & ((1 << devices_present) -1)) ^ POWER_MASK; if (Settings.flag.save_state) { - SetDevicePower(power); + SetDevicePower(power, SRC_RESTART); } break; case POWER_ALL_SAVED: power = Settings.power & ((1 << devices_present) -1); if (Settings.flag.save_state) { - SetDevicePower(power); + SetDevicePower(power, SRC_RESTART); } break; } } else { power = Settings.power & ((1 << devices_present) -1); if (Settings.flag.save_state) { - SetDevicePower(power); + SetDevicePower(power, SRC_RESTART); } } } @@ -2472,6 +2449,7 @@ void setup() ArduinoOTAInit(); #endif // USE_ARDUINO_OTA + XdrvCall(FUNC_INIT); XsnsCall(FUNC_INIT); } @@ -2481,13 +2459,6 @@ void loop() 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 (!serial_local) SerialInput(); diff --git a/sonoff/support.ino b/sonoff/support.ino index 720649c9f..4268f38d0 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -244,6 +244,29 @@ char* LTrim(char* 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* write = dest; @@ -482,6 +505,96 @@ int GetStateNumber(char *state_text) 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) { Settings.baudrate = baudrate / 1200; @@ -516,13 +629,22 @@ uint32_t GetHash(const char *buffer, size_t size) 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 \*********************************************************************************************/ 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 |= 0x00000002; @@ -543,52 +665,52 @@ void GetFeatures() feature_drv1 |= 0x00000040; // sonoff.ino #endif #ifdef USE_WEBSERVER - feature_drv1 |= 0x00000080; // webserver.ino + feature_drv1 |= 0x00000080; // xdrv_02_webserver.ino #endif #ifdef WEBSERVER_ADVERTISE - feature_drv1 |= 0x00000100; // webserver.ino + feature_drv1 |= 0x00000100; // xdrv_02_webserver.ino #endif #ifdef USE_EMULATION feature_drv1 |= 0x00000200; // xplg_wemohue.ino #endif #if (MQTT_LIBRARY_TYPE == MQTT_PUBSUBCLIENT) - feature_drv1 |= 0x00000400; // xdrv_00_mqtt.ino + feature_drv1 |= 0x00000400; // xdrv_01_mqtt.ino #endif #if (MQTT_LIBRARY_TYPE == MQTT_TASMOTAMQTT) - feature_drv1 |= 0x00000800; // xdrv_00_mqtt.ino + feature_drv1 |= 0x00000800; // xdrv_01_mqtt.ino #endif #if (MQTT_LIBRARY_TYPE == MQTT_ESPMQTTARDUINO) - feature_drv1 |= 0x00001000; // xdrv_00_mqtt.ino + feature_drv1 |= 0x00001000; // xdrv_01_mqtt.ino #endif #ifdef MQTT_HOST_DISCOVERY - feature_drv1 |= 0x00002000; // xdrv_00_mqtt.ino + feature_drv1 |= 0x00002000; // xdrv_01_mqtt.ino #endif #ifdef USE_ARILUX_RF - feature_drv1 |= 0x00004000; // xdrv_01_light.ino + feature_drv1 |= 0x00004000; // xdrv_04_light.ino #endif #ifdef USE_WS2812 - feature_drv1 |= 0x00008000; // xdrv_01_light.ino + feature_drv1 |= 0x00008000; // xdrv_04_light.ino #endif #ifdef USE_WS2812_DMA - feature_drv1 |= 0x00010000; // xdrv_01_light.ino + feature_drv1 |= 0x00010000; // xdrv_04_light.ino #endif #ifdef USE_IR_REMOTE - feature_drv1 |= 0x00020000; // xdrv_02_irremote.ino + feature_drv1 |= 0x00020000; // xdrv_05_irremote.ino #endif #ifdef USE_IR_HVAC - feature_drv1 |= 0x00040000; // xdrv_02_irremote.ino + feature_drv1 |= 0x00040000; // xdrv_05_irremote.ino #endif #ifdef USE_IR_RECEIVE - feature_drv1 |= 0x00080000; // xdrv_02_irremote.ino + feature_drv1 |= 0x00080000; // xdrv_05_irremote.ino #endif #ifdef USE_DOMOTICZ - feature_drv1 |= 0x00100000; // xdrv_05_domoticz.ino + feature_drv1 |= 0x00100000; // xdrv_07_domoticz.ino #endif #ifdef USE_DISPLAY - feature_drv1 |= 0x00200000; // xdrv_06_display.ino + feature_drv1 |= 0x00200000; // xdrv_98_display.ino #endif #ifdef USE_HOME_ASSISTANT - feature_drv1 |= 0x00400000; // xdrv_07_home_assistant.ino + feature_drv1 |= 0x00400000; // xdrv_12_home_assistant.ino #endif #ifdef USE_SERIAL_BRIDGE 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 #endif + WiFi.persistent(false); // Solve possible wifi init errors WiFi.disconnect(true); // Delete SDK wifi config delay(200); WiFi.mode(WIFI_STA); // Disable AP mode @@ -1051,7 +1174,7 @@ void WifiCheck(uint8_t param) StartWebserver(Settings.webserver, WiFi.localIP()); #ifdef USE_DISCOVERY #ifdef WEBSERVER_ADVERTISE - MDNS.addService("http", "tcp", 80); + MDNS.addService("http", "tcp", WEB_PORT); #endif // WEBSERVER_ADVERTISE #endif // USE_DISCOVERY } else { @@ -1097,13 +1220,30 @@ int WifiState() void WifiConnect() { - WiFi.persistent(false); // Solve possible wifi init errors + WiFi.persistent(false); // Solve possible wifi init errors wifi_status = 0; wifi_retry_init = WIFI_RETRY_OFFSET_SEC + ((ESP.getChipId() & 0xF) * 2); wifi_retry = wifi_retry_init; 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 /*********************************************************************************************\ * 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"), GetTime(0).c_str(), GetTime(2).c_str(), GetTime(3).c_str()); AddLog(LOG_LEVEL_DEBUG); -#ifdef USE_RULES if (local_time < 1451602800) { // 2016-01-01 strncpy_P(mqtt_data, PSTR("{\"Time\":{\"Initialized\":1}}"), sizeof(mqtt_data)); } else { strncpy_P(mqtt_data, PSTR("{\"Time\":{\"Set\":1}}"), sizeof(mqtt_data)); } - RulesProcess(); -#endif // USE_RULES + XdrvRulesProcess(); } else { ntp_sync_minute++; // Try again in next minute } @@ -1698,7 +1836,7 @@ void AdcEvery50ms() adc_last_value = new_value; uint16_t value = adc_last_value / 10; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"ANALOG\":{\"A0div10\":%d}}"), (value > 99) ? 100 : value); - RulesProcess(); + XdrvRulesProcess(); } } } diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 91b0a137f..6e51d8e3d 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -44,7 +44,7 @@ \*********************************************************************************************/ // -- 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 ------------------------------------- #define PROJECT "sonoff" // PROJECT is used as the default topic delimiter @@ -178,7 +178,7 @@ * - 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 -------------------------------- // 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-PT // Portuguese in Portugal //#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-TW // Chinese (Traditional) in Taiwan @@ -262,6 +263,7 @@ #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_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_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) @@ -309,6 +311,8 @@ #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 \*********************************************************************************************/ diff --git a/sonoff/user_config_override_sample.h b/sonoff/user_config_override_sample.h index acd66cebe..8b3203904 100644 --- a/sonoff/user_config_override_sample.h +++ b/sonoff/user_config_override_sample.h @@ -47,7 +47,7 @@ Examples : // -- Master parameter control -------------------- #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 --------------- #undef STA_SSID1 diff --git a/sonoff/xdrv_00_mqtt.ino b/sonoff/xdrv_01_mqtt.ino similarity index 99% rename from sonoff/xdrv_00_mqtt.ino rename to sonoff/xdrv_01_mqtt.ino index c3eda47d2..7a2c5e666 100644 --- a/sonoff/xdrv_00_mqtt.ino +++ b/sonoff/xdrv_01_mqtt.ino @@ -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 @@ -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), Settings.mqtt_host, Settings.mqtt_port, state, mqtt_retry_counter); AddLog(LOG_LEVEL_INFO); -#ifdef USE_RULES strncpy_P(mqtt_data, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(mqtt_data)); - RulesProcess(); -#endif // USE_RULES + XdrvRulesProcess(); } void MqttConnected() @@ -370,17 +368,13 @@ void MqttConnected() tele_period = Settings.tele_period -9; } status_update_timer = 2; -#ifdef USE_RULES strncpy_P(mqtt_data, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(mqtt_data)); - RulesProcess(); -#endif // USE_RULES + XdrvRulesProcess(); XdrvCall(FUNC_MQTT_INIT); } mqtt_initial_connection_state = 0; -#ifdef USE_RULES strncpy_P(mqtt_data, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(mqtt_data)); - RulesProcess(); -#endif // USE_RULES + XdrvRulesProcess(); } #ifdef USE_MQTT_TLS @@ -751,9 +745,9 @@ bool MqttCommand() * Interface \*********************************************************************************************/ -#define XDRV_00 +#define XDRV_01 -boolean Xdrv00(byte function) +boolean Xdrv01(byte function) { boolean result = false; diff --git a/sonoff/webserver.ino b/sonoff/xdrv_02_webserver.ino similarity index 82% rename from sonoff/webserver.ino rename to sonoff/xdrv_02_webserver.ino index 0cb4cce27..1f699cfb0 100644 --- a/sonoff/webserver.ino +++ b/sonoff/xdrv_02_webserver.ino @@ -1,5 +1,5 @@ /* - webserver.ino - webserver for Sonoff-Tasmota + xdrv_02_webserver.ino - webserver for Sonoff-Tasmota Copyright (C) 2018 Theo Arends @@ -25,6 +25,12 @@ * 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 = "" "" @@ -328,7 +334,6 @@ uint8_t upload_progress_dot_count; uint8_t config_block_count = 0; uint8_t config_xor_on = 0; uint8_t config_xor_on_set = CONFIG_FILE_XOR; -uint8_t *settings_new = NULL; // Helper function to avoid code duplication (saves 4k Flash) 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 } +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) { if (!webserver_state) { @@ -568,22 +588,23 @@ void HandleAjaxStatusRefresh() WebGetArg("o", tmp, sizeof(tmp)); if (strlen(tmp)) { - ExecuteCommandPower(atoi(tmp), POWER_TOGGLE); + ShowWebSource(SRC_WEBGUI); + ExecuteCommandPower(atoi(tmp), POWER_TOGGLE, SRC_IGNORE); } WebGetArg("d", tmp, sizeof(tmp)); if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_DIMMER " %s"), tmp); - ExecuteCommand(svalue); + ExecuteWebCommand(svalue, SRC_WEBGUI); } WebGetArg("t", tmp, sizeof(tmp)); if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_COLORTEMPERATURE " %s"), tmp); - ExecuteCommand(svalue); + ExecuteWebCommand(svalue, SRC_WEBGUI); } WebGetArg("k", tmp, sizeof(tmp)); if (strlen(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}")); @@ -639,96 +660,6 @@ void HandleConfiguration() 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() { if (HttpUser()) { return; } @@ -1005,25 +936,34 @@ void HandleBackupConfiguration() if (HttpUser()) { return; } AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_BACKUP_CONFIGURATION)); - uint8_t buffer[sizeof(Settings)]; + if (!SettingsBufferAlloc()) { return; } WiFiClient myClient = WebServer->client(); - WebServer->setContentLength(sizeof(buffer)); + WebServer->setContentLength(sizeof(Settings)); char attachment[100]; 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); WebServer->sendHeader(F("Content-Disposition"), attachment); + WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), ""); - memcpy(buffer, &Settings, sizeof(buffer)); - buffer[0] = CONFIG_FILE_SIGN; - buffer[1] = (!config_xor_on_set) ? 0 : 1; - if (buffer[1]) { - for (uint16_t i = 2; i < sizeof(buffer); i++) { - buffer[i] ^= (config_xor_on_set +i); + memcpy(settings_buffer, &Settings, sizeof(Settings)); + if (config_xor_on_set) { + for (uint16_t i = 2; i < sizeof(Settings); i++) { + settings_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() @@ -1186,6 +1126,7 @@ void HandleSaveSettings() } ShowPage(page); + ShowWebSource(SRC_WEBGUI); restart_flag = 2; } else { HandleConfiguration(); @@ -1209,7 +1150,7 @@ void HandleResetConfiguration() ShowPage(page); snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RESET " 1")); - ExecuteCommand(svalue); + ExecuteWebCommand(svalue, SRC_WEBGUI); } void HandleRestoreConfiguration() @@ -1227,7 +1168,7 @@ void HandleRestoreConfiguration() ShowPage(page); upload_error = 0; - upload_file_type = 1; + upload_file_type = UPL_SETTINGS; } void HandleUpgradeFirmware() @@ -1246,7 +1187,7 @@ void HandleUpgradeFirmware() ShowPage(page); upload_error = 0; - upload_file_type = 0; + upload_file_type = UPL_TASMOTA; } void HandleUpgradeFirmwareStart() @@ -1261,7 +1202,7 @@ void HandleUpgradeFirmwareStart() WebGetArg("o", tmp, sizeof(tmp)); if (strlen(tmp)) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_OTAURL " %s"), tmp); - ExecuteCommand(svalue); + ExecuteWebCommand(svalue, SRC_WEBGUI); } String page = FPSTR(HTTP_HEAD); @@ -1273,15 +1214,7 @@ void HandleUpgradeFirmwareStart() ShowPage(page); snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_UPGRADE " 1")); - ExecuteCommand(svalue); -} - -void SettingsNewFree() -{ - if (settings_new != NULL) { - free(settings_new); - settings_new = NULL; - } + ExecuteWebCommand(svalue, SRC_WEBGUI); } void HandleUploadDone() @@ -1311,6 +1244,12 @@ void HandleUploadDone() 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 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: snprintf_P(error, sizeof(error), PSTR(D_UPLOAD_ERROR_CODE " %d"), upload_error); } @@ -1321,9 +1260,10 @@ void HandleUploadDone() } else { page += F("green'>" D_SUCCESSFUL "
"); 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("
"); page += FPSTR(HTTP_BTN_MAIN); ShowPage(page); @@ -1336,7 +1276,7 @@ void HandleUploadLoop() if (HTTP_USER == webserver_state) { return; } if (upload_error) { - if (!upload_file_type) { Update.end(); } + if (UPL_TASMOTA == upload_file_type) { Update.end(); } return; } @@ -1345,16 +1285,15 @@ void HandleUploadLoop() if (UPLOAD_FILE_START == upload.status) { restart_flag = 60; if (0 == upload.filename.c_str()[0]) { - upload_error = 1; + upload_error = 1; // No file selected return; } SettingsSave(1); // Free flash for upload snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str()); AddLog(LOG_LEVEL_INFO); - if (upload_file_type) { - SettingsNewFree(); - if (!(settings_new = (uint8_t *)malloc(sizeof(Settings)))) { - upload_error = 2; + if (UPL_SETTINGS == upload_file_type) { + if (!SettingsBufferAlloc()) { + upload_error = 2; // Not enough space return; } } else { @@ -1368,45 +1307,93 @@ void HandleUploadLoop() if (Settings.flag.mqtt_enabled) MqttDisconnect(); uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; 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; } } upload_progress_dot_count = 0; } else if (!upload_error && (UPLOAD_FILE_WRITE == upload.status)) { if (0 == upload.totalSize) { - if (upload_file_type) { - if (upload.buf[0] != CONFIG_FILE_SIGN) { - upload_error = 8; - return; - } - config_xor_on = upload.buf[1]; + if (UPL_SETTINGS == upload_file_type) { config_block_count = 0; - } else { - if (upload.buf[0] != 0xE9) { - upload_error = 3; - return; + } + else { +#ifdef USE_RF_FLASH + 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.currentSize > (sizeof(Settings) - (config_block_count * HTTP_UPLOAD_BUFLEN))) { - upload_error = 9; + upload_error = 9; // File too large 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++; } - } 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)) { - upload_error = 5; + upload_error = 5; // Upload buffer miscompare return; } if (_serialoutput) { @@ -1419,20 +1406,45 @@ void HandleUploadLoop() if (_serialoutput && (upload_progress_dot_count % 80)) { Serial.println(); } - if (upload_file_type) { - if (config_xor_on) { + if (UPL_SETTINGS == upload_file_type) { + if (config_xor_on_set) { 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(); - memcpy((char*)&Settings +16, settings_new +16, sizeof(Settings) -16); - memcpy((char*)&Settings +8, settings_new +8, 4); // Restore version and auto upgrade - SettingsNewFree(); - } else { + bool valid_settings = false; + unsigned long buffer_version = settings_buffer[11] << 24 | settings_buffer[10] << 16 | settings_buffer[9] << 8 | settings_buffer[8]; + if (buffer_version > 0x06000000) { + uint16_t buffer_size = settings_buffer[3] << 8 | settings_buffer[2]; + 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 (_serialoutput) { Update.printError(Serial); } - upload_error = 6; + upload_error = 6; // Upload failed. Enable logging 3 return; } } @@ -1443,8 +1455,8 @@ void HandleUploadLoop() } else if (UPLOAD_FILE_ABORTED == upload.status) { restart_flag = 0; MqttRetryCounter(0); - upload_error = 7; - if (!upload_file_type) { Update.end(); } + upload_error = 7; // Upload aborted + if (UPL_TASMOTA == upload_file_type) { Update.end(); } } delay(0); } @@ -1470,16 +1482,16 @@ void HandleHttpCommand() WebGetArg("user", tmp1, sizeof(tmp1)); char tmp2[100]; WebGetArg("password", tmp2, sizeof(tmp2)); - if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, Settings.web_password))) { - valid = 0; - } + if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, Settings.web_password))) { valid = 0; } } String message = F("{\"" D_RSLT_WARNING "\":\""); if (valid) { byte curridx = web_log_index; WebGetArg("cmnd", svalue, sizeof(svalue)); - if (strlen(svalue)) { ExecuteCommand(svalue); } + if (strlen(svalue)) { + ExecuteWebCommand(svalue, SRC_WEBCOMMAND); + } if (web_log_index != curridx) { byte counter = curridx; @@ -1538,7 +1550,7 @@ void HandleAjaxConsoleRefresh() if (strlen(svalue)) { snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue); AddLog(LOG_LEVEL_INFO); - ExecuteCommand(svalue); + ExecuteWebCommand(svalue, SRC_WEBCONSOLE); } WebGetArg("c2", svalue, sizeof(svalue)); @@ -1713,6 +1725,7 @@ void HandleRestart() } ShowPage(page); + ShowWebSource(SRC_WEBGUI); restart_flag = 2; } @@ -1765,4 +1778,202 @@ boolean ValidIpAddress(String str) } 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 diff --git a/sonoff/xdrv_03_energy.ino b/sonoff/xdrv_03_energy.ino index b3d717d65..180e9b858 100644 --- a/sonoff/xdrv_03_energy.ino +++ b/sonoff/xdrv_03_energy.ino @@ -281,6 +281,9 @@ long cf_pulses_last_time = CSE_PULSES_NOT_INITIALIZED; 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); uint8_t header = serial_in_buffer[0]; @@ -371,7 +374,12 @@ bool CseSerialInput() return 1; } } 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; } else { serial_in_byte_counter = 0; @@ -476,7 +484,17 @@ bool PzemReceiveReady() 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(); uint8_t len = 0; @@ -486,6 +504,10 @@ bool PzemRecieve(uint8_t resp, float *data) if (!c && !len) { continue; // skip 0 at startup } + if ((1 == len) && (buffer[0] == c)) { + len--; + continue; // fix skewed data + } 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 : ""); MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING); EnergyMqttShow(); - ExecuteCommandPower(1, POWER_OFF); + ExecuteCommandPower(1, POWER_OFF, SRC_MAXPOWER); if (!energy_mplr_counter) { energy_mplr_counter = Settings.param[P_MAX_POWER_RETRY] +1; } @@ -743,7 +765,7 @@ void EnergyMarginCheck() if (energy_mplr_counter) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_POWERMONITOR "\":\"%s\"}"), GetStateText(1)); MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_JSON_POWERMONITOR)); - ExecuteCommandPower(1, POWER_ON); + ExecuteCommandPower(1, POWER_ON, SRC_MAXPOWER); } else { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_MAXPOWERREACHEDRETRY "\":\"%s\"}"), GetStateText(0)); MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING); @@ -761,7 +783,7 @@ void EnergyMarginCheck() energy_max_energy_state = 1; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_ENERGYMONITOR "\":\"%s\"}"), GetStateText(1)); 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)) { 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 : ""); MqttPublishPrefixTopic_P(STAT, S_RSLT_WARNING); EnergyMqttShow(); - ExecuteCommandPower(1, POWER_OFF); + ExecuteCommandPower(1, POWER_OFF, SRC_MAXENERGY); } } #endif // FEATURE_POWER_LIMIT @@ -1143,7 +1165,7 @@ boolean Xdrv03(byte function) if (energy_flg) { switch (function) { - case FUNC_INIT: + case FUNC_PRE_INIT: EnergyDrvInit(); break; case FUNC_COMMAND: diff --git a/sonoff/xdrv_01_light.ino b/sonoff/xdrv_04_light.ino similarity index 99% rename from sonoff/xdrv_01_light.ino rename to sonoff/xdrv_04_light.ino index 6ea7ca7e9..7843192f7 100644 --- a/sonoff/xdrv_01_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -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 @@ -230,7 +230,7 @@ void AriluxRfHandler() } } if (strlen(command)) { - ExecuteCommand(command); + ExecuteCommand(command, SRC_LIGHT); } } } @@ -529,7 +529,7 @@ char* LightGetColor(uint8_t type, char* scolor) void LightPowerOn() { 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.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) { - ExecuteCommandPower(light_device, POWER_OFF_NO_STATE); + ExecuteCommandPower(light_device, POWER_OFF_NO_STATE, SRC_LIGHT); } #ifdef USE_DOMOTICZ DomoticzUpdatePowerState(light_device); @@ -1279,7 +1279,7 @@ boolean LightCommand() if (coldim) { LightPreparePower(); } - + return serviced; } @@ -1287,15 +1287,15 @@ boolean LightCommand() * Interface \*********************************************************************************************/ -#define XDRV_01 +#define XDRV_04 -boolean Xdrv01(byte function) +boolean Xdrv04(byte function) { boolean result = false; if (light_type) { switch (function) { - case FUNC_INIT: + case FUNC_PRE_INIT: LightInit(); break; case FUNC_EVERY_50_MSECOND: diff --git a/sonoff/xdrv_02_irremote.ino b/sonoff/xdrv_05_irremote.ino similarity index 98% rename from sonoff/xdrv_02_irremote.ino rename to sonoff/xdrv_05_irremote.ino index e2d4a1019..2688d6c2f 100644 --- a/sonoff/xdrv_02_irremote.ino +++ b/sonoff/xdrv_05_irremote.ino @@ -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 @@ -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\"}}"), GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, (uint32_t)results.value); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED)); + XdrvRulesProcess(); #ifdef USE_DOMOTICZ unsigned long value = results.value | (iridx << 28); // [Protocol:4, Data:28] DomoticzSensor(DZ_COUNT, value); // Send data as Domoticz Counter value @@ -392,15 +393,15 @@ boolean IrSendCommand() * Interface \*********************************************************************************************/ -#define XDRV_02 +#define XDRV_05 -boolean Xdrv02(byte function) +boolean Xdrv05(byte function) { boolean result = false; if ((pin[GPIO_IRSEND] < 99) || (pin[GPIO_IRRECV] < 99)) { switch (function) { - case FUNC_INIT: + case FUNC_PRE_INIT: if (pin[GPIO_IRSEND] < 99) { IrSendInit(); } diff --git a/sonoff/xdrv_04_snfbridge.ino b/sonoff/xdrv_06_snfbridge.ino similarity index 58% rename from sonoff/xdrv_04_snfbridge.ino rename to sonoff/xdrv_06_snfbridge.ino index 20c9fa3d1..155944005 100644 --- a/sonoff/xdrv_04_snfbridge.ino +++ b/sonoff/xdrv_06_snfbridge.ino @@ -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 it under the terms of the GNU General Public License as published by @@ -24,11 +24,12 @@ #define SFB_TIME_AVOID_DUPLICATE 2000 // Milliseconds 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 = - 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_raw_flag = 0; uint8_t sonoff_bridge_learn_key = 1; uint8_t sonoff_bridge_learn_active = 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_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() { 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}}"), sync_time, low_time, high_time, received_id, rfkey); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED)); + XdrvRulesProcess(); #ifdef USE_DOMOTICZ DomoticzSensor(DZ_COUNT, received_id); // Send rid as Domoticz Counter value #endif // USE_DOMOTICZ @@ -109,12 +311,28 @@ boolean SonoffBridgeSerialInput() { // iTead Rf Universal Transceiver Module Serial Protocol Version 1.0 (20170420) 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) { sonoff_bridge_expected_bytes = 2; // 0xA0, 0xA1, 0xA2 if (serial_in_byte >= 0xA3) { 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; 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; } +void SonoffBridgeSendCommand(byte code) +{ + Serial.write(0xAA); // Start of Text + Serial.write(code); // Command or Acknowledge + Serial.write(0x55); // End of Text +} + void SonoffBridgeSendAck() { Serial.write(0xAA); // Start of Text @@ -293,23 +518,64 @@ boolean SonoffBridgeCommand() } else { 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 - + return serviced; } +/*********************************************************************************************/ + +void SonoffBridgeInit() +{ + sonoff_bridge_receive_raw_flag = 0; + SonoffBridgeSendCommand(0xA7); // Stop reading RF signals enabling iTead default RF handling +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ -#define XDRV_04 +#define XDRV_06 -boolean Xdrv04(byte function) +boolean Xdrv06(byte function) { boolean result = false; if (SONOFF_BRIDGE == Settings.module) { switch (function) { + case FUNC_INIT: + SonoffBridgeInit(); + break; case FUNC_COMMAND: result = SonoffBridgeCommand(); break; diff --git a/sonoff/xdrv_05_domoticz.ino b/sonoff/xdrv_07_domoticz.ino similarity index 99% rename from sonoff/xdrv_05_domoticz.ino rename to sonoff/xdrv_07_domoticz.ino index bf9ae023e..f2b972326 100644 --- a/sonoff/xdrv_05_domoticz.ino +++ b/sonoff/xdrv_07_domoticz.ino @@ -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 @@ -265,7 +265,7 @@ boolean DomoticzCommand() else serviced = false; // Unknown command } else serviced = false; // Unknown command - + return serviced; } @@ -437,9 +437,9 @@ void DomoticzSaveSettings() * Interface \*********************************************************************************************/ -#define XDRV_05 +#define XDRV_07 -boolean Xdrv05(byte function) +boolean Xdrv07(byte function) { boolean result = false; diff --git a/sonoff/xdrv_08_serial_bridge.ino b/sonoff/xdrv_08_serial_bridge.ino index 455179f98..5d04c8059 100644 --- a/sonoff/xdrv_08_serial_bridge.ino +++ b/sonoff/xdrv_08_serial_bridge.ino @@ -61,6 +61,7 @@ void SerialBridgeInput() 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); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); +// XdrvRulesProcess(); serial_bridge_in_byte_counter = 0; } } @@ -134,7 +135,7 @@ boolean Xdrv08(byte function) if (serial_bridge_active) { switch (function) { - case FUNC_INIT: + case FUNC_PRE_INIT: SerialBridgeInit(); break; case FUNC_LOOP: diff --git a/sonoff/xdrv_09_timers.ino b/sonoff/xdrv_09_timers.ino index 7528dcfad..337846efc 100644 --- a/sonoff/xdrv_09_timers.ino +++ b/sonoff/xdrv_09_timers.ino @@ -287,10 +287,10 @@ void TimerEverySecond() #ifdef USE_RULES 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); - RulesProcess(); + XdrvRulesProcess(); } else #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; switch (function) { - case FUNC_INIT: + case FUNC_PRE_INIT: TimerSetRandomWindows(); break; case FUNC_EVERY_SECOND: diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino index 714924af1..65e8df730 100644 --- a/sonoff/xdrv_10_rules.ino +++ b/sonoff/xdrv_10_rules.ino @@ -86,10 +86,11 @@ uint8_t rules_quota = 0; long rules_new_power = -1; long rules_old_power = -1; -uint32_t rules_triggers = 0; -uint8_t rules_trigger_count = 0; +uint32_t rules_triggers[MAX_RULE_SETS] = { 0 }; +uint8_t rules_trigger_count[MAX_RULE_SETS] = { 0 }; uint8_t rules_teleperiod = 0; +char event_data[100]; 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 = {"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; if (pos > 0) { String rule_param = rule_name.substring(pos + 1); @@ -198,13 +199,13 @@ bool RulesRuleMatch(String &event, String &rule) } } 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) { rule_value = temp_value; } 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" } @@ -218,7 +219,7 @@ bool RulesRuleMatch(String &event, String &rule) 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"), -// 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); if (!root[rule_task][rule_name].success()) { return false; } @@ -231,13 +232,14 @@ bool RulesRuleMatch(String &event, String &rule) value = CharToDouble((char*)str_value); switch (compare) { case '>': - if (value > rule_value) match = true; + if (value > rule_value) { match = true; } break; case '<': - if (value < rule_value) match = true; + if (value < rule_value) { match = true; } break; 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; case ' ': match = true; // Json value but not needed @@ -247,13 +249,13 @@ bool RulesRuleMatch(String &event, String &rule) if (Settings.flag.rules_once) { if (match) { // Only allow match state changes - if (!bitRead(rules_triggers, rules_trigger_count)) { - bitSet(rules_triggers, rules_trigger_count); + if (!bitRead(rules_triggers[rule_set], rules_trigger_count[rule_set])) { + bitSet(rules_triggers[rule_set], rules_trigger_count[rule_set]); } else { match = false; } } 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; char stemp[10]; 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); - if (!Settings.flag.rules_enabled) { return serviced; } // Not enabled - if (!strlen(Settings.rules)) { return serviced; } // No rules + String rules = Settings.rules[rule_set]; - String event_saved = mqtt_data; - event_saved.toUpperCase(); - String rules = Settings.rules; - - rules_trigger_count = 0; + rules_trigger_count[rule_set] = 0; int plen = 0; while (true) { 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()); //AddLog(LOG_LEVEL_DEBUG); - if (RulesRuleMatch(event, event_trigger)) { + if (RulesRuleMatch(rule_set, event, event_trigger)) { commands.trim(); String ucommand = commands; 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); // MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RULE)); - ExecuteCommand(command); + ExecuteCommand(command, SRC_RULE); serviced = true; } - rules_trigger_count++; + rules_trigger_count[rule_set]++; } 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() { - if (Settings.rules[0] == '\0') { - Settings.flag.rules_enabled = 0; - Settings.flag.rules_once = 0; + for (byte i = 0; i < MAX_RULE_SETS; i++) { + if (Settings.rules[i][0] == '\0') { + bitWrite(Settings.rule_enabled, i, 0); + bitWrite(Settings.rule_once, i, 0); + } } rules_teleperiod = 0; } void RulesEvery50ms() { - if (Settings.flag.rules_enabled) { + if (Settings.rule_enabled) { // Any rule enabled if (rules_new_power != rules_old_power) { if (rules_old_power != -1) { for (byte i = 0; i < devices_present; i++) { @@ -361,7 +375,26 @@ void RulesEvery50ms() } } rules_old_power = rules_new_power; - } else { + } + else if(event_data[0]) { + char *event; + char *parameter; + event = strtok_r(event_data, "=", ¶meter); // 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++; if (rules_quota &1) { // Every 100 ms mqtt_data[0] = '\0'; @@ -381,7 +414,7 @@ void RulesEvery50ms() void RulesEverySecond() { - if (Settings.flag.rules_enabled) { + if (Settings.rule_enabled) { // Any rule enabled for (byte i = 0; i < MAX_RULE_TIMERS; i++) { if (rules_timer[i] != 0L) { // Timer active? if (TimeReached(rules_timer[i])) { // Timer finished? @@ -416,39 +449,32 @@ boolean RulesCommand() if (-1 == command_code) { serviced = false; // Unknown command } - else if (CMND_RULE == command_code) { - if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules))) { + else if ((CMND_RULE == command_code) && (index > 0) && (index <= MAX_RULE_SETS)) { + if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules[index -1]))) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) { switch (XdrvMailbox.payload) { case 0: // Off case 1: // On - Settings.flag.rules_enabled = XdrvMailbox.payload; + bitWrite(Settings.rule_enabled, index -1, XdrvMailbox.payload); break; case 2: // Toggle - Settings.flag.rules_enabled ^= 1; + bitWrite(Settings.rule_enabled, index -1, bitRead(Settings.rule_enabled, index -1) ^1); break; case 4: // Off case 5: // On - Settings.flag.rules_once = XdrvMailbox.payload &1; + bitWrite(Settings.rule_once, index -1, XdrvMailbox.payload &1); break; case 6: // Toggle - Settings.flag.rules_once ^= 1; + bitWrite(Settings.rule_once, index -1, bitRead(Settings.rule_once, index -1) ^1); break; } } else { -/* - 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)); + strlcpy(Settings.rules[index -1], ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(Settings.rules[index -1])); } - 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)) { if (XdrvMailbox.data_len > 0) { @@ -458,17 +484,7 @@ boolean RulesCommand() } else if (CMND_EVENT == command_code) { if (XdrvMailbox.data_len > 0) { - String event = XdrvMailbox.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(); + strlcpy(event_data, XdrvMailbox.data, sizeof(event_data)); } 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; switch (function) { - case FUNC_INIT: + case FUNC_PRE_INIT: RulesInit(); break; case FUNC_EVERY_50_MSECOND: @@ -515,6 +531,9 @@ boolean Xdrv10(byte function) case FUNC_COMMAND: result = RulesCommand(); break; + case FUNC_RULES_PROCESS: + result = RulesProcess(); + break; } return result; } diff --git a/sonoff/xdrv_11_knx.ino b/sonoff/xdrv_11_knx.ino index dfbdbb33b..eef88e001 100644 --- a/sonoff/xdrv_11_knx.ino +++ b/sonoff/xdrv_11_knx.ino @@ -115,6 +115,11 @@ device_parameters_t device_param[] = { { KNX_ENERGY_DAILY , false, false, KNX_Empty }, { KNX_ENERGY_START , 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} }; @@ -145,6 +150,11 @@ const char * device_param_ga[] = { D_ENERGY_TODAY , D_ENERGY_YESTERDAY , 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 }; @@ -175,9 +185,20 @@ const char *device_param_cb[] = { D_REPLY " " D_ENERGY_TODAY , D_REPLY " " D_ENERGY_YESTERDAY , 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 }; +// 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 ) { @@ -377,12 +398,20 @@ bool KNX_CONFIG_NOT_MATCH() { if ( !device_param[i].show ) { // device has this parameter ? // 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 ( (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+9) != KNX_Empty ) { return true; } } + if ( i > 15 ) // check sensors and others + { + if ( KNX_CB_Search(i+1) != KNX_Empty ) { return true; } + } } } return false; @@ -448,6 +477,14 @@ void KNX_INIT() 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 if (KNX_CONFIG_NOT_MATCH()) { Settings.knx_GA_registered = 0; @@ -494,18 +531,32 @@ void KNX_CB_Action(message_t const &msg, void *arg) case KNX_CT_WRITE: 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 { if (!toggle_inhibit) { - ExecuteCommandPower((chan->type) -8, 2); + ExecuteCommandPower((chan->type) -8, 2, SRC_KNX); if (Settings.flag.knx_enable_enhancement) { 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; + case KNX_CT_READ: 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); } } +#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; } } @@ -939,6 +1003,71 @@ void KNX_Save_Settings() #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 \*********************************************************************************************/ @@ -949,7 +1078,7 @@ boolean Xdrv11(byte function) { boolean result = false; switch (function) { - case FUNC_INIT: + case FUNC_PRE_INIT: KNX_INIT(); break; case FUNC_LOOP: @@ -960,9 +1089,9 @@ boolean Xdrv11(byte function) toggle_inhibit--; } break; -// case FUNC_COMMAND: -// result = KNXCommand(); -// break; + case FUNC_COMMAND: + result = KnxCommand(); + break; // case FUNC_SET_POWER: // break; } diff --git a/sonoff/xdrv_07_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino similarity index 98% rename from sonoff/xdrv_07_home_assistant.ino rename to sonoff/xdrv_12_home_assistant.ino index 657f8d5b7..ee008280b 100644 --- a/sonoff/xdrv_07_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -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 @@ -208,9 +208,9 @@ void HAssDiscovery(uint8_t mode) * Interface \*********************************************************************************************/ -#define XDRV_07 +#define XDRV_12 -boolean Xdrv07(byte function) +boolean Xdrv12(byte function) { boolean result = false; diff --git a/sonoff/xdrv_interface.ino b/sonoff/xdrv_interface.ino index 09f056ece..6080b103b 100644 --- a/sonoff/xdrv_interface.ino +++ b/sonoff/xdrv_interface.ino @@ -18,10 +18,6 @@ */ boolean (* const xdrv_func_ptr[])(byte) PROGMEM = { // Driver Function Pointers -#ifdef XDRV_00 - &Xdrv00, -#endif - #ifdef XDRV_01 &Xdrv01, #endif @@ -175,9 +171,15 @@ boolean XdrvMqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uint16_t return XdrvCall(FUNC_MQTT_DATA); } +boolean XdrvRulesProcess() +{ + return XdrvCall(FUNC_RULES_PROCESS); +} + /*********************************************************************************************\ * Function call to all xdrv * + * FUNC_PRE_INIT * FUNC_INIT * FUNC_LOOP * FUNC_MQTT_SUBSCRIBE @@ -188,6 +190,7 @@ boolean XdrvMqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uint16_t * FUNC_SHOW_SENSOR * FUNC_EVERY_SECOND * FUNC_EVERY_50_MSECOND + * FUNC_RULES_PROCESS \*********************************************************************************************/ boolean XdrvCall(byte Function) diff --git a/sonoff/xplg_wemohue.ino b/sonoff/xplg_wemohue.ino index aba8827b0..9a7cdeec7 100644 --- a/sonoff/xplg_wemohue.ino +++ b/sonoff/xplg_wemohue.ino @@ -387,10 +387,10 @@ void HandleUpnpEvent() //differentiate get and set state if (request.indexOf(F("SetBinaryState")) > 0) { if (request.indexOf(F("State>1 0) { - ExecuteCommandPower(devices_present, POWER_ON); + ExecuteCommandPower(devices_present, POWER_ON, SRC_WEMO); } else if (request.indexOf(F("State>0 0) { - ExecuteCommandPower(devices_present, POWER_OFF); + ExecuteCommandPower(devices_present, POWER_OFF, SRC_WEMO); } } else if(request.indexOf(F("GetBinaryState")) > 0){ @@ -660,10 +660,10 @@ void HueLights(String *path) on = hue_json["on"]; switch(on) { - case false : ExecuteCommandPower(device, POWER_OFF); + case false : ExecuteCommandPower(device, POWER_OFF, SRC_HUE); response.replace("{re", "false"); break; - case true : ExecuteCommandPower(device, POWER_ON); + case true : ExecuteCommandPower(device, POWER_ON, SRC_HUE); response.replace("{re", "true"); break; default : response.replace("{re", (power & (1 << (device-1))) ? "true" : "false"); diff --git a/sonoff/xsns_21_sgp30.ino b/sonoff/xsns_21_sgp30.ino index d30281155..5fef47bfd 100644 --- a/sonoff/xsns_21_sgp30.ino +++ b/sonoff/xsns_21_sgp30.ino @@ -76,8 +76,8 @@ void Sgp30Show(boolean json) #ifdef USE_DOMOTICZ if (0 == tele_period) DomoticzSensor(DZ_AIRQUALITY, sgp.eCO2); #endif // USE_DOMOTICZ - } else { #ifdef USE_WEBSERVER + } else { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SGP30, mqtt_data, sgp.eCO2, sgp.TVOC); #endif } diff --git a/sonoff/xsns_23_sdm120.ino b/sonoff/xsns_23_sdm120.ino index 937efc89e..5966f9cd3 100644 --- a/sonoff/xsns_23_sdm120.ino +++ b/sonoff/xsns_23_sdm120.ino @@ -262,8 +262,8 @@ void SDM120Show(boolean json) #ifdef USE_WEBSERVER } 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); - } #endif // USE_WEBSERVER + } } /*********************************************************************************************\ diff --git a/sonoff/xsns_24_si1145.ino b/sonoff/xsns_24_si1145.ino index 5ddd713d8..95ad930af 100644 --- a/sonoff/xsns_24_si1145.ino +++ b/sonoff/xsns_24_si1145.ino @@ -335,8 +335,8 @@ void Si1145Show(boolean json) #ifdef USE_DOMOTICZ if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, visible); #endif // USE_DOMOTICZ - } else { #ifdef USE_WEBSERVER + } else { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SI1145, mqtt_data, visible, infrared, uvindex /100, uvindex %100); #endif } diff --git a/sonoff/xsns_25_sdm630.ino b/sonoff/xsns_25_sdm630.ino index 40dc8d0f9..193c3a936 100644 --- a/sonoff/xsns_25_sdm630.ino +++ b/sonoff/xsns_25_sdm630.ino @@ -317,8 +317,8 @@ void SDM630Show(boolean json) active_power_l1, active_power_l2, active_power_l3, reactive_power_l1, reactive_power_l2, reactive_power_l3, power_factor_l1, power_factor_l2, power_factor_l3, energy_total); - } #endif // USE_WEBSERVER + } } /*********************************************************************************************\ diff --git a/sonoff/xsns_26_lm75ad.ino b/sonoff/xsns_26_lm75ad.ino new file mode 100644 index 000000000..be83fc79a --- /dev/null +++ b/sonoff/xsns_26_lm75ad.ino @@ -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 . +*/ + +#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 diff --git a/tools/fw_efm8bb1/RF_Bridge_00.hex b/tools/fw_efm8bb1/RF_Bridge_00.hex new file mode 100644 index 000000000..4fbda3662 --- /dev/null +++ b/tools/fw_efm8bb1/RF_Bridge_00.hex @@ -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 diff --git a/tools/fw_efm8bb1/RF_Bridge_iTead_Original.hex b/tools/fw_efm8bb1/RF_Bridge_iTead_Original.hex new file mode 100644 index 000000000..ee0e95356 --- /dev/null +++ b/tools/fw_efm8bb1/RF_Bridge_iTead_Original.hex @@ -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