mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
v5.14.0
Release v5.14.0
This commit is contained in:
parent
f20e9b8447
commit
3ad1f43b78
12
.gitignore
vendored
12
.gitignore
vendored
@ -2,13 +2,13 @@
|
||||
.DS_Store
|
||||
.fuse_hidden*
|
||||
|
||||
## Project files ######.pioenvs
|
||||
## Project files ######
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.clang_complete
|
||||
.gcc-flags.json
|
||||
.vscode
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
sonoff/user_config_override.h
|
||||
.pioenvs
|
||||
build
|
||||
|
||||
## Visual Studio Code specific ######
|
||||
.vscode
|
||||
|
13
README.md
13
README.md
@ -108,6 +108,7 @@ Different firmware images are released based on Features and Sensors selection g
|
||||
| USE_BH1750 | x | x | - | x | x |
|
||||
| USE_VEML6070 | - | - | - | - | x |
|
||||
| USE_TSL2561 | - | - | - | - | x |
|
||||
| USE_SI1145 | - | - | - | - | x |
|
||||
| USE_ADS1115 | - | - | - | - | x |
|
||||
| USE_ADS1115_I2CDEV | - | - | - | - | - |
|
||||
| USE_INA219 | - | - | - | - | x |
|
||||
@ -119,6 +120,7 @@ Different firmware images are released based on Features and Sensors selection g
|
||||
| USE_NOVA_SDS | x | - | - | x | x |
|
||||
| USE_PZEM004T | x | x | - | x | x |
|
||||
| USE_SERIAL_BRIDGE | x | - | - | x | x |
|
||||
| USE_SDM120 | - | - | - | - | x |
|
||||
| USE_IR_REMOTE | x | x | - | x | x |
|
||||
| USE_IR_HVAC | - | - | - | - | x |
|
||||
| USE_IR_RECEIVE | x | - | - | x | x |
|
||||
@ -129,11 +131,11 @@ Different firmware images are released based on Features and Sensors selection g
|
||||
|
||||
#### Typical file size
|
||||
|
||||
| ESP/Arduino library version | sonoff | classic | minimal | knx | allsensors |
|
||||
|--------------------------------|--------|---------|---------|------|------------|
|
||||
| ESP/Arduino lib v2.3.0 | 526k | 488k | 427k | 535k | 549k |
|
||||
| ESP/Arduino lib v2.4.0 | 531k | 496k | 435k | 540k | 552k |
|
||||
| ESP/Arduino lib v2.4.1 | 534k | 499k | 437k | 543k | 555k |
|
||||
| ESP/Arduino library version | sonoff | classic | minimal | knx | allsensors |
|
||||
|-----------------------------|--------|---------|---------|------|------------|
|
||||
| ESP/Arduino lib v2.3.0 | 529k | 490k | 429k | 538k | 554k |
|
||||
| ESP/Arduino lib v2.4.0 | 534k | 498k | 436k | 542k | 558k |
|
||||
| ESP/Arduino lib v2.4.1 | 536k | 501k | 439k | 545k | 560k |
|
||||
|
||||
### Contribute
|
||||
You can contribute to Sonoff-Tasmota by
|
||||
@ -182,6 +184,7 @@ People helping to keep the show on the road:
|
||||
- Gerhard Mutz for his SGP30 and Sunrise/Sunset driver
|
||||
- Nuno Ferreira for his HC-SR04 driver
|
||||
- Adrian Scillato for his (security)fixes and implementing and maintaining KNX
|
||||
- Gennaro Tortone for implementing and maintaining Eastron drivers
|
||||
- Raymond Mouthaan for managing Wemos Wiki information
|
||||
- Norbert Richter, Frogmore42 and Jason2866 for providing many issue answers
|
||||
- Many more providing Tips, Pocs or PRs
|
||||
|
@ -1,200 +0,0 @@
|
||||
/*
|
||||
TasmotaSerial.cpp - Minimal implementation of software serial for Tasmota
|
||||
|
||||
Copyright (C) 2018 Theo Arends
|
||||
|
||||
This library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// The Arduino standard GPIO routines are not enough,
|
||||
// must use some from the Espressif SDK as well
|
||||
extern "C" {
|
||||
#include "gpio.h"
|
||||
}
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
// As the Arduino attachInterrupt has no parameter, lists of objects
|
||||
// and callbacks corresponding to each possible GPIO pins have to be defined
|
||||
TasmotaSerial *ObjList[16];
|
||||
|
||||
#ifdef TM_SERIAL_USE_IRAM
|
||||
void ICACHE_RAM_ATTR sws_isr_0() { ObjList[0]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR sws_isr_1() { ObjList[1]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR sws_isr_2() { ObjList[2]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR sws_isr_3() { ObjList[3]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR sws_isr_4() { ObjList[4]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR sws_isr_5() { ObjList[5]->rxRead(); };
|
||||
// Pin 6 to 11 can not be used
|
||||
void ICACHE_RAM_ATTR sws_isr_12() { ObjList[12]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR sws_isr_13() { ObjList[13]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR sws_isr_14() { ObjList[14]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR sws_isr_15() { ObjList[15]->rxRead(); };
|
||||
#else
|
||||
void sws_isr_0() { ObjList[0]->rxRead(); };
|
||||
void sws_isr_1() { ObjList[1]->rxRead(); };
|
||||
void sws_isr_2() { ObjList[2]->rxRead(); };
|
||||
void sws_isr_3() { ObjList[3]->rxRead(); };
|
||||
void sws_isr_4() { ObjList[4]->rxRead(); };
|
||||
void sws_isr_5() { ObjList[5]->rxRead(); };
|
||||
// Pin 6 to 11 can not be used
|
||||
void sws_isr_12() { ObjList[12]->rxRead(); };
|
||||
void sws_isr_13() { ObjList[13]->rxRead(); };
|
||||
void sws_isr_14() { ObjList[14]->rxRead(); };
|
||||
void sws_isr_15() { ObjList[15]->rxRead(); };
|
||||
#endif // TM_SERIAL_USE_IRAM
|
||||
|
||||
static void (*ISRList[16])() = {
|
||||
sws_isr_0,
|
||||
sws_isr_1,
|
||||
sws_isr_2,
|
||||
sws_isr_3,
|
||||
sws_isr_4,
|
||||
sws_isr_5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
sws_isr_12,
|
||||
sws_isr_13,
|
||||
sws_isr_14,
|
||||
sws_isr_15
|
||||
};
|
||||
|
||||
TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin)
|
||||
{
|
||||
m_valid = false;
|
||||
if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) {
|
||||
return;
|
||||
}
|
||||
m_rx_pin = receive_pin;
|
||||
m_tx_pin = transmit_pin;
|
||||
m_in_pos = m_out_pos = 0;
|
||||
if (m_rx_pin > -1) {
|
||||
m_buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE);
|
||||
if (m_buffer == NULL) return;
|
||||
// Use getCycleCount() loop to get as exact timing as possible
|
||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE;
|
||||
pinMode(m_rx_pin, INPUT);
|
||||
ObjList[m_rx_pin] = this;
|
||||
attachInterrupt(m_rx_pin, ISRList[m_rx_pin], FALLING);
|
||||
}
|
||||
if (m_tx_pin > -1) {
|
||||
pinMode(m_tx_pin, OUTPUT);
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
}
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
bool TasmotaSerial::isValidGPIOpin(int pin)
|
||||
{
|
||||
return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15);
|
||||
}
|
||||
|
||||
bool TasmotaSerial::begin(long speed) {
|
||||
// Use getCycleCount() loop to get as exact timing as possible
|
||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /speed;
|
||||
m_high_speed = (speed > 9600);
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
bool TasmotaSerial::begin() {
|
||||
return begin(TM_SERIAL_BAUDRATE);
|
||||
}
|
||||
|
||||
void TasmotaSerial::flush() {
|
||||
m_in_pos = m_out_pos = 0;
|
||||
}
|
||||
|
||||
int TasmotaSerial::peek() {
|
||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1;
|
||||
return m_buffer[m_out_pos];
|
||||
}
|
||||
|
||||
int TasmotaSerial::read()
|
||||
{
|
||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1;
|
||||
uint8_t ch = m_buffer[m_out_pos];
|
||||
m_out_pos = (m_out_pos +1) % TM_SERIAL_BUFFER_SIZE;
|
||||
return ch;
|
||||
}
|
||||
|
||||
int TasmotaSerial::available()
|
||||
{
|
||||
int avail = m_in_pos - m_out_pos;
|
||||
if (avail < 0) avail += TM_SERIAL_BUFFER_SIZE;
|
||||
return avail;
|
||||
}
|
||||
|
||||
#ifdef TM_SERIAL_USE_IRAM
|
||||
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait) if (!m_high_speed) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts
|
||||
#else
|
||||
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait); wait += m_bit_time; }
|
||||
#endif
|
||||
|
||||
size_t TasmotaSerial::write(uint8_t b)
|
||||
{
|
||||
if (-1 == m_tx_pin) return 0;
|
||||
if (m_high_speed) cli(); // Disable interrupts in order to get a clean transmit
|
||||
unsigned long wait = m_bit_time;
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
unsigned long start = ESP.getCycleCount();
|
||||
// Start bit;
|
||||
digitalWrite(m_tx_pin, LOW);
|
||||
TM_SERIAL_WAIT;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
digitalWrite(m_tx_pin, (b & 1) ? HIGH : LOW);
|
||||
TM_SERIAL_WAIT;
|
||||
b >>= 1;
|
||||
}
|
||||
// Stop bit
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
TM_SERIAL_WAIT;
|
||||
if (m_high_speed) sei();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef TM_SERIAL_USE_IRAM
|
||||
void ICACHE_RAM_ATTR TasmotaSerial::rxRead()
|
||||
{
|
||||
#else
|
||||
void TasmotaSerial::rxRead()
|
||||
{
|
||||
#endif
|
||||
// Advance the starting point for the samples but compensate for the
|
||||
// initial delay which occurs before the interrupt is delivered
|
||||
unsigned long wait = m_bit_time + m_bit_time/3 - 500;
|
||||
unsigned long start = ESP.getCycleCount();
|
||||
uint8_t rec = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
TM_SERIAL_WAIT;
|
||||
rec >>= 1;
|
||||
if (digitalRead(m_rx_pin)) rec |= 0x80;
|
||||
}
|
||||
// Stop bit
|
||||
TM_SERIAL_WAIT;
|
||||
// Store the received value in the buffer unless we have an overflow
|
||||
int next = (m_in_pos+1) % TM_SERIAL_BUFFER_SIZE;
|
||||
if (next != (int)m_out_pos) {
|
||||
m_buffer[m_in_pos] = rec;
|
||||
m_in_pos = next;
|
||||
}
|
||||
// Must clear this bit in the interrupt register,
|
||||
// it gets set even when interrupts are disabled
|
||||
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << m_rx_pin);
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
# TasmotaSerial
|
||||
|
||||
Implementation of software serial library for the ESP8266
|
||||
Implementation of software serial with hardware serial fallback library for the ESP8266
|
||||
|
||||
Allows for several instances to be active at the same time.
|
||||
|
||||
Please note that due to the fact that the ESP always have other activities ongoing, there will be some inexactness in interrupt
|
||||
timings. This may lead to bit errors when having heavy data traffic.
|
||||
Please note that due to the fact that the ESP always have other activities ongoing, there will be some inexactness in interrupt timings. This may lead to bit errors when having heavy data traffic.
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "TasmotaSerial",
|
||||
"version": "1.2.0",
|
||||
"version": "2.0.0",
|
||||
"keywords": [
|
||||
"serial", "io", "TasmotaSerial"
|
||||
],
|
||||
"description": "Implementation of software serial for ESP8266.",
|
||||
"description": "Implementation of software serial with hardware serial fallback for ESP8266.",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
@ -1,8 +1,8 @@
|
||||
name=TasmotaSerial
|
||||
version=1.2.0
|
||||
version=2.0.0
|
||||
author=Theo Arends
|
||||
maintainer=Theo Arends <theo@arends.com>
|
||||
sentence=Implementation of software serial for ESP8266.
|
||||
sentence=Implementation of software serial with hardware serial fallback for ESP8266.
|
||||
paragraph=
|
||||
category=Signal Input/Output
|
||||
url=
|
234
lib/TasmotaSerial-2.0.0/src/TasmotaSerial.cpp
Normal file
234
lib/TasmotaSerial-2.0.0/src/TasmotaSerial.cpp
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
TasmotaSerial.cpp - Minimal implementation of software serial for Tasmota
|
||||
|
||||
Copyright (C) 2018 Theo Arends
|
||||
|
||||
This library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// The Arduino standard GPIO routines are not enough,
|
||||
// must use some from the Espressif SDK as well
|
||||
extern "C" {
|
||||
#include "gpio.h"
|
||||
}
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
// As the Arduino attachInterrupt has no parameter, lists of objects
|
||||
// and callbacks corresponding to each possible GPIO pins have to be defined
|
||||
TasmotaSerial *tms_obj_list[16];
|
||||
|
||||
#ifdef TM_SERIAL_USE_IRAM
|
||||
void ICACHE_RAM_ATTR tms_isr_0() { tms_obj_list[0]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR tms_isr_1() { tms_obj_list[1]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR tms_isr_2() { tms_obj_list[2]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR tms_isr_3() { tms_obj_list[3]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR tms_isr_4() { tms_obj_list[4]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR tms_isr_5() { tms_obj_list[5]->rxRead(); };
|
||||
// Pin 6 to 11 can not be used
|
||||
void ICACHE_RAM_ATTR tms_isr_12() { tms_obj_list[12]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR tms_isr_13() { tms_obj_list[13]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR tms_isr_14() { tms_obj_list[14]->rxRead(); };
|
||||
void ICACHE_RAM_ATTR tms_isr_15() { tms_obj_list[15]->rxRead(); };
|
||||
#else
|
||||
void tms_isr_0() { tms_obj_list[0]->rxRead(); };
|
||||
void tms_isr_1() { tms_obj_list[1]->rxRead(); };
|
||||
void tms_isr_2() { tms_obj_list[2]->rxRead(); };
|
||||
void tms_isr_3() { tms_obj_list[3]->rxRead(); };
|
||||
void tms_isr_4() { tms_obj_list[4]->rxRead(); };
|
||||
void tms_isr_5() { tms_obj_list[5]->rxRead(); };
|
||||
// Pin 6 to 11 can not be used
|
||||
void tms_isr_12() { tms_obj_list[12]->rxRead(); };
|
||||
void tms_isr_13() { tms_obj_list[13]->rxRead(); };
|
||||
void tms_isr_14() { tms_obj_list[14]->rxRead(); };
|
||||
void tms_isr_15() { tms_obj_list[15]->rxRead(); };
|
||||
#endif // TM_SERIAL_USE_IRAM
|
||||
|
||||
static void (*ISRList[16])() = {
|
||||
tms_isr_0,
|
||||
tms_isr_1,
|
||||
tms_isr_2,
|
||||
tms_isr_3,
|
||||
tms_isr_4,
|
||||
tms_isr_5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
tms_isr_12,
|
||||
tms_isr_13,
|
||||
tms_isr_14,
|
||||
tms_isr_15
|
||||
};
|
||||
|
||||
TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, bool hardware_fallback)
|
||||
{
|
||||
m_valid = false;
|
||||
m_hardserial = 0;
|
||||
if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) {
|
||||
return;
|
||||
}
|
||||
m_rx_pin = receive_pin;
|
||||
m_tx_pin = transmit_pin;
|
||||
m_in_pos = m_out_pos = 0;
|
||||
if (hardware_fallback && (((1 == m_rx_pin) && (3 == m_tx_pin)) || ((3 == m_rx_pin) && (-1 == m_tx_pin)) || ((-1 == m_rx_pin) && (1 == m_tx_pin)))) {
|
||||
m_hardserial = 1;
|
||||
} else {
|
||||
if (m_rx_pin > -1) {
|
||||
m_buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE);
|
||||
if (m_buffer == NULL) return;
|
||||
// Use getCycleCount() loop to get as exact timing as possible
|
||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE;
|
||||
pinMode(m_rx_pin, INPUT);
|
||||
tms_obj_list[m_rx_pin] = this;
|
||||
attachInterrupt(m_rx_pin, ISRList[m_rx_pin], FALLING);
|
||||
}
|
||||
if (m_tx_pin > -1) {
|
||||
pinMode(m_tx_pin, OUTPUT);
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
}
|
||||
}
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
bool TasmotaSerial::isValidGPIOpin(int pin)
|
||||
{
|
||||
return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15);
|
||||
}
|
||||
|
||||
bool TasmotaSerial::begin(long speed) {
|
||||
if (m_hardserial) {
|
||||
Serial.flush();
|
||||
Serial.begin(speed, SERIAL_8N1);
|
||||
} else {
|
||||
// Use getCycleCount() loop to get as exact timing as possible
|
||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /speed;
|
||||
m_high_speed = (speed > 9600);
|
||||
}
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
bool TasmotaSerial::begin() {
|
||||
return begin(TM_SERIAL_BAUDRATE);
|
||||
}
|
||||
|
||||
bool TasmotaSerial::hardwareSerial() {
|
||||
return m_hardserial;
|
||||
}
|
||||
|
||||
void TasmotaSerial::flush() {
|
||||
if (m_hardserial) {
|
||||
Serial.flush();
|
||||
} else {
|
||||
m_in_pos = m_out_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int TasmotaSerial::peek() {
|
||||
if (m_hardserial) {
|
||||
return Serial.peek();
|
||||
} else {
|
||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1;
|
||||
return m_buffer[m_out_pos];
|
||||
}
|
||||
}
|
||||
|
||||
int TasmotaSerial::read()
|
||||
{
|
||||
if (m_hardserial) {
|
||||
return Serial.read();
|
||||
} else {
|
||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1;
|
||||
uint8_t ch = m_buffer[m_out_pos];
|
||||
m_out_pos = (m_out_pos +1) % TM_SERIAL_BUFFER_SIZE;
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
|
||||
int TasmotaSerial::available()
|
||||
{
|
||||
if (m_hardserial) {
|
||||
return Serial.available();
|
||||
} else {
|
||||
int avail = m_in_pos - m_out_pos;
|
||||
if (avail < 0) avail += TM_SERIAL_BUFFER_SIZE;
|
||||
return avail;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TM_SERIAL_USE_IRAM
|
||||
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait) if (!m_high_speed) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts
|
||||
#else
|
||||
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait); wait += m_bit_time; }
|
||||
#endif
|
||||
|
||||
size_t TasmotaSerial::write(uint8_t b)
|
||||
{
|
||||
if (m_hardserial) {
|
||||
return Serial.write(b);
|
||||
} else {
|
||||
if (-1 == m_tx_pin) return 0;
|
||||
if (m_high_speed) cli(); // Disable interrupts in order to get a clean transmit
|
||||
unsigned long wait = m_bit_time;
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
unsigned long start = ESP.getCycleCount();
|
||||
// Start bit;
|
||||
digitalWrite(m_tx_pin, LOW);
|
||||
TM_SERIAL_WAIT;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
digitalWrite(m_tx_pin, (b & 1) ? HIGH : LOW);
|
||||
TM_SERIAL_WAIT;
|
||||
b >>= 1;
|
||||
}
|
||||
// Stop bit
|
||||
digitalWrite(m_tx_pin, HIGH);
|
||||
TM_SERIAL_WAIT;
|
||||
if (m_high_speed) sei();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TM_SERIAL_USE_IRAM
|
||||
void ICACHE_RAM_ATTR TasmotaSerial::rxRead()
|
||||
{
|
||||
#else
|
||||
void TasmotaSerial::rxRead()
|
||||
{
|
||||
#endif
|
||||
// Advance the starting point for the samples but compensate for the
|
||||
// initial delay which occurs before the interrupt is delivered
|
||||
unsigned long wait = m_bit_time + m_bit_time/3 - 500;
|
||||
unsigned long start = ESP.getCycleCount();
|
||||
uint8_t rec = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
TM_SERIAL_WAIT;
|
||||
rec >>= 1;
|
||||
if (digitalRead(m_rx_pin)) rec |= 0x80;
|
||||
}
|
||||
// Stop bit
|
||||
TM_SERIAL_WAIT;
|
||||
// Store the received value in the buffer unless we have an overflow
|
||||
int next = (m_in_pos+1) % TM_SERIAL_BUFFER_SIZE;
|
||||
if (next != (int)m_out_pos) {
|
||||
m_buffer[m_in_pos] = rec;
|
||||
m_in_pos = next;
|
||||
}
|
||||
// Must clear this bit in the interrupt register,
|
||||
// it gets set even when interrupts are disabled
|
||||
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << m_rx_pin);
|
||||
}
|
@ -37,9 +37,10 @@
|
||||
|
||||
class TasmotaSerial : public Stream {
|
||||
public:
|
||||
TasmotaSerial(int receive_pin, int transmit_pin);
|
||||
TasmotaSerial(int receive_pin, int transmit_pin, bool hardware_fallback = false);
|
||||
bool begin(long speed);
|
||||
bool begin();
|
||||
bool hardwareSerial();
|
||||
int peek();
|
||||
|
||||
virtual size_t write(uint8_t byte);
|
||||
@ -57,6 +58,7 @@ class TasmotaSerial : public Stream {
|
||||
|
||||
// Member variables
|
||||
bool m_valid;
|
||||
bool m_hardserial;
|
||||
bool m_high_speed;
|
||||
int m_rx_pin;
|
||||
int m_tx_pin;
|
@ -17,6 +17,7 @@ src_dir = sonoff
|
||||
;env_default = sonoff-knx
|
||||
;env_default = sonoff-allsensors
|
||||
;env_default = sonoff-BG
|
||||
;env_default = sonoff-BR
|
||||
;env_default = sonoff-CN
|
||||
;env_default = sonoff-CZ
|
||||
;env_default = sonoff-DE
|
||||
@ -33,8 +34,8 @@ src_dir = sonoff
|
||||
|
||||
[common] ; ************************************************************
|
||||
; *** Esp8266 core for Arduino version
|
||||
;platform = espressif8266@1.5.0 ; v2.3.0
|
||||
platform = espressif8266@1.6.0 ; v2.4.0
|
||||
platform = espressif8266@1.5.0 ; v2.3.0
|
||||
;platform = espressif8266@1.6.0 ; v2.4.0
|
||||
;platform = espressif8266@1.7.0 ; v2.4.1
|
||||
;platform = espressif8266
|
||||
|
||||
@ -146,6 +147,18 @@ upload_speed = ${common.upload_speed}
|
||||
upload_port = ${common.upload_port}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
|
||||
[env:sonoff-BR]
|
||||
platform = ${common.platform}
|
||||
framework = ${common.framework}
|
||||
board = ${common.board}
|
||||
board_flash_mode = ${common.board_flash_mode}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags} -DMY_LANGUAGE=pt-BR
|
||||
monitor_baud = ${common.monitor_baud}
|
||||
upload_speed = ${common.upload_speed}
|
||||
upload_port = ${common.upload_port}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
|
||||
[env:sonoff-CN]
|
||||
platform = ${common.platform}
|
||||
framework = ${common.framework}
|
||||
|
@ -1,4 +1,26 @@
|
||||
/* 5.13.1 20180501
|
||||
/* 5.14.0 20180515
|
||||
* Update language files
|
||||
* Update TasmotaSerial to 2.0.0 allowing Hardware Serial Fallback when correct connections are configured
|
||||
* Change command handling
|
||||
* Change user_config(_override).h defines TIME_STD and TIME_DST
|
||||
* Change user_config(_override).h otaurl to http://sonoff.maddox.co.uk/tasmota/sonoff.bin (#2588, #2602)
|
||||
* Fix configuration restore regression from 5.13.1
|
||||
* Fix compile error when ADC is enabled and Rules are disabled (#2608)
|
||||
* Fix rule power trigger when no backlog command is used (#2613)
|
||||
* Fix several timer data input and output errors (#2597, #2620)
|
||||
* Fix KNX config error (#2628)
|
||||
* Fix sensor MHZ-19 vanishing data over time (#2659)
|
||||
* Fix KNX reconnection issue (#2679)
|
||||
* Fix DST and STD time for Southern Hemisphere (#2684, #2714)
|
||||
* Add Portuguese in Brazil language file
|
||||
* Add SetOption26 to enforce use of indexes even when only one relay is present (#1055)
|
||||
* Add support for sensor SI1145 UV Index / IR / Visible light (#2496)
|
||||
* Add rule state test for On/Off in addition to 0/1 (#2613)
|
||||
* Add hardware serial option to MHZ-19 sensor (#2659)
|
||||
* Add Eastron SDM120 energy meter (#2694)
|
||||
* Add user entry DST/STD using commands TimeStd and TimeDst (See wiki for parameter syntax) (#2721)
|
||||
*
|
||||
* 5.13.1 20180501
|
||||
* Fix JSON buffers size too small for execution in some situations (#2580)
|
||||
* Fix configuration restore (#2591)
|
||||
* Add define MODULE for user selecting default model although it preferably should not be changed (#569, #2589)
|
||||
|
@ -60,6 +60,7 @@
|
||||
#define D_JSON_FLASHMODE "FlashMode"
|
||||
#define D_JSON_FLASHSIZE "FlashSize"
|
||||
#define D_JSON_FREEMEMORY "Free"
|
||||
#define D_JSON_FREQUENCY "Frequency"
|
||||
#define D_JSON_FROM "from"
|
||||
#define D_JSON_GAS "Gas"
|
||||
#define D_JSON_GATEWAY "Gateway"
|
||||
@ -72,6 +73,7 @@
|
||||
#define D_JSON_I2CSCAN_NO_DEVICES_FOUND "No devices found"
|
||||
#define D_JSON_ID "Id"
|
||||
#define D_JSON_ILLUMINANCE "Illuminance"
|
||||
#define D_JSON_INFRARED "Infrared"
|
||||
#define D_JSON_UNKNOWN "Unknown"
|
||||
#define D_JSON_LIGHT "Light"
|
||||
#define D_JSON_LOCAL_TIME "Local"
|
||||
@ -86,10 +88,14 @@
|
||||
#define D_JSON_PERIOD "Period"
|
||||
#define D_JSON_POWERFACTOR "Factor"
|
||||
#define D_JSON_POWERUSAGE "Power"
|
||||
#define D_JSON_ACTIVE_POWERUSAGE "ActivePower"
|
||||
#define D_JSON_APPARENT_POWERUSAGE "ApparentPower"
|
||||
#define D_JSON_REACTIVE_POWERUSAGE "ReactivePower"
|
||||
#define D_JSON_PRESSURE "Pressure"
|
||||
#define D_JSON_PRESSUREATSEALEVEL "SeaPressure"
|
||||
#define D_JSON_PROGRAMFLASHSIZE "ProgramFlashSize"
|
||||
#define D_JSON_PROGRAMSIZE "ProgramSize"
|
||||
#define D_JSON_RESET "Reset"
|
||||
#define D_JSON_RESTARTING "Restarting"
|
||||
#define D_JSON_RESTARTREASON "RestartReason"
|
||||
#define D_JSON_RSSI "RSSI"
|
||||
@ -119,6 +125,7 @@
|
||||
#define D_JSON_TYPE "Type"
|
||||
#define D_JSON_UPTIME "Uptime"
|
||||
#define D_JSON_UTC_TIME "UTC"
|
||||
#define D_JSON_UVINDEX "UvIndex"
|
||||
#define D_JSON_UV_LEVEL "UvLevel"
|
||||
#define D_JSON_VCC "Vcc"
|
||||
#define D_JSON_VERSION "Version"
|
||||
@ -220,6 +227,8 @@
|
||||
#define D_JSON_RESET_AND_RESTARTING "Reset and Restarting"
|
||||
#define D_JSON_ONE_TO_RESET "1 to reset"
|
||||
#define D_CMND_TIMEZONE "Timezone"
|
||||
#define D_CMND_TIMESTD "TimeStd"
|
||||
#define D_CMND_TIMEDST "TimeDst"
|
||||
#define D_CMND_ALTITUDE "Altitude"
|
||||
#define D_CMND_LEDPOWER "LedPower"
|
||||
#define D_CMND_LEDSTATE "LedState"
|
||||
@ -486,6 +495,12 @@ const char kPrefixes[3][PRFX_MAX_STRING_LENGTH] PROGMEM = {
|
||||
// support.ino
|
||||
static const char kMonthNames[] = D_MONTH3LIST;
|
||||
|
||||
const char kOptionOff[] PROGMEM = "OFF|" D_OFF "|" D_FALSE "|" D_STOP "|" D_CELSIUS ;
|
||||
const char kOptionOn[] PROGMEM = "ON|" D_ON "|" D_TRUE "|" D_START "|" D_FAHRENHEIT "|" D_USER ;
|
||||
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
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_SNS_TEMP[] PROGMEM = "%s{s}%s " D_TEMPERATURE "{m}%s°%c{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
|
@ -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.12.0m
|
||||
* Updated until v5.14.0
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
@ -61,7 +61,7 @@
|
||||
#define D_BRIGHTLIGHT "Яркост"
|
||||
#define D_BUTTON "Бутон"
|
||||
#define D_BY "от" // Written by me
|
||||
#define D_BYTES "Байт"
|
||||
#define D_BYTES "Байта"
|
||||
#define D_CELSIUS "Целзий"
|
||||
#define D_CO2 "Въглероден диоксид"
|
||||
#define D_CODE "код" // Button code
|
||||
@ -75,7 +75,7 @@
|
||||
#define D_DARKLIGHT "Тъмна"
|
||||
#define D_DEBUG "Дебъгване"
|
||||
#define D_DISABLED "Деактивиран"
|
||||
#define D_DISTANCE "Distance"
|
||||
#define D_DISTANCE "Разстояние"
|
||||
#define D_DNS_SERVER "DNS Сървър"
|
||||
#define D_DONE "Изпълнено"
|
||||
#define D_DST_TIME "DST"
|
||||
@ -86,11 +86,12 @@
|
||||
#define D_ERROR "Грешка"
|
||||
#define D_FAHRENHEIT "Фаренхайт"
|
||||
#define D_FAILED "Неуспешно"
|
||||
#define D_FALLBACK "Обратна връзка"
|
||||
#define D_FALLBACK_TOPIC "Топик на обратната връзка"
|
||||
#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 "Група"
|
||||
@ -98,9 +99,10 @@
|
||||
#define D_HOSTNAME "Име на хоста"
|
||||
#define D_HUMIDITY "Влажност"
|
||||
#define D_ILLUMINANCE "Осветеност"
|
||||
#define D_IMMEDIATE "моментален" // Button immediate
|
||||
#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 "Светлина"
|
||||
@ -119,6 +121,9 @@
|
||||
#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 "Размер на флаш паметта за програми"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Време от стартирането"
|
||||
#define D_USER "Потребител"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV индекс"
|
||||
#define D_UV_LEVEL "Ниво на ултравиолетово излъчване"
|
||||
#define D_VERSION "Версия"
|
||||
#define D_VOLTAGE "Напрежение"
|
||||
@ -199,7 +205,7 @@
|
||||
#define D_ERASED_SECTOR "Изтрит сектор"
|
||||
|
||||
// webserver.ino
|
||||
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Фърмуеър MINIMAL - моля надградете го"
|
||||
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Минимаен фърмуеър - моля надградете го"
|
||||
#define D_WEBSERVER_ACTIVE_ON "Уеб сървърът е активен на"
|
||||
#define D_WITH_IP_ADDRESS "с IP адрес"
|
||||
#define D_WEBSERVER_STOPPED "Уеб сървърът е спрян"
|
||||
@ -268,12 +274,12 @@
|
||||
|
||||
#define D_OTHER_PARAMETERS "Други параметри"
|
||||
#define D_WEB_ADMIN_PASSWORD "Парола на уеб администратора"
|
||||
#define D_MQTT_ENABLE "активиране на MQTT"
|
||||
#define D_FRIENDLY_NAME "приятелско име"
|
||||
#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_SINGLE_DEVICE "Единично"
|
||||
#define D_MULTI_DEVICE "Мулти"
|
||||
|
||||
#define D_SAVE_CONFIGURATION "Запазване на конфигурацията"
|
||||
#define D_CONFIGURATION_SAVED "Конфигурацията е запазена"
|
||||
@ -293,7 +299,7 @@
|
||||
#define D_MQTT_FULL_TOPIC "MQTT пълен топик"
|
||||
#define D_MDNS_DISCOVERY "mDNS откриване"
|
||||
#define D_MDNS_ADVERTISE "mDNS транслация"
|
||||
#define D_ESP_CHIP_ID "ID на чипа ESP"
|
||||
#define D_ESP_CHIP_ID "ID на ESP чипа"
|
||||
#define D_FLASH_CHIP_ID "ID на чипа на флаш паметта"
|
||||
#define D_FLASH_CHIP_SIZE "Размер на флаш паметта"
|
||||
#define D_FREE_PROGRAM_SPACE "Свободно пространство за програми"
|
||||
@ -310,7 +316,7 @@
|
||||
#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_6 "Грешка при зареждането. Включено е ниво 3 на лога"
|
||||
#define D_UPLOAD_ERR_7 "Зареждането е прекъснато"
|
||||
#define D_UPLOAD_ERR_8 "Файлът е невалиден"
|
||||
#define D_UPLOAD_ERR_9 "Файлът е прекалено голям"
|
||||
@ -342,7 +348,7 @@
|
||||
#define D_RESPONSE_SENT "Отговорът е изпратен"
|
||||
|
||||
#define D_HUE "Hue"
|
||||
#define D_HUE_BRIDGE_SETUP "Hue мост настройка"
|
||||
#define D_HUE_BRIDGE_SETUP "Настройка на Hue bridge"
|
||||
#define D_HUE_API_NOT_IMPLEMENTED "Hue API не е внедрено"
|
||||
#define D_HUE_API "Hue API"
|
||||
#define D_HUE_POST_ARGS "Hue POST аргументи"
|
||||
@ -407,9 +413,9 @@
|
||||
|
||||
// xsns_06_dht.ino
|
||||
#define D_TIMEOUT_WAITING_FOR "Изтекло време за очакване на"
|
||||
#define D_START_SIGNAL_LOW "стартов сигнал нисък"
|
||||
#define D_START_SIGNAL_HIGH "стартов сигнал висок"
|
||||
#define D_PULSE "импулс"
|
||||
#define D_START_SIGNAL_LOW "Нисък стартов сигнал"
|
||||
#define D_START_SIGNAL_HIGH "Висок стартов сигнал"
|
||||
#define D_PULSE "Импулс"
|
||||
#define D_CHECKSUM_FAILURE "Грешка в контролната сума"
|
||||
|
||||
// xsns_07_sht1x.ino
|
||||
@ -419,10 +425,10 @@
|
||||
// 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 "Particals"
|
||||
#define D_PARTICALS_BEYOND "Частици"
|
||||
|
||||
// sonoff_template.h
|
||||
#define D_SENSOR_NONE "няма"
|
||||
#define D_SENSOR_NONE "Няма"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
#define D_SENSOR_SI7021 "SI7021"
|
||||
@ -453,29 +459,34 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "А"
|
||||
#define D_UNIT_CENTIMETER "см"
|
||||
#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_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m3"
|
||||
#define D_UNIT_MICROMETER "µm"
|
||||
#define D_UNIT_MICROSECOND "µs"
|
||||
#define D_UNIT_MILLIAMPERE "mA"
|
||||
#define D_UNIT_MILLISECOND "ms"
|
||||
#define D_UNIT_MINUTE "min"
|
||||
#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_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "s"
|
||||
#define D_UNIT_SECTORS "сектори"
|
||||
#define D_UNIT_VOLT "В"
|
||||
#define D_UNIT_WATT "Вт"
|
||||
#define D_UNIT_WATTHOUR "Вт/ч"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
||||
// Log message prefix
|
||||
#define D_LOG_APPLICATION "APP: " // Application
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "Nepravda"
|
||||
#define D_FILE "Soubor"
|
||||
#define D_FREE_MEMORY "Volná paměť"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "Plyn"
|
||||
#define D_GATEWAY "Výchozí brána"
|
||||
#define D_GROUP "Skupina"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "Okamžité" // Button immediate
|
||||
#define D_INDEX "Index"
|
||||
#define D_INFO "Informace"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Inicializovaný"
|
||||
#define D_IP_ADDRESS "Adresa IP"
|
||||
#define D_LIGHT "Světlo"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Port"
|
||||
#define D_POWER_FACTOR "Účiník"
|
||||
#define D_POWERUSAGE "Příkon"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "Tlak"
|
||||
#define D_PRESSUREATSEALEVEL "Tlak na úrovni hladiny moře"
|
||||
#define D_PROGRAM_FLASH_SIZE "Velikost paměti flash"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Uptime"
|
||||
#define D_USER "Uživatel"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV Index"
|
||||
#define D_UV_LEVEL "úroveň UV"
|
||||
#define D_VERSION "Verze"
|
||||
#define D_VOLTAGE "Napětí"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "hod"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "sektory"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "falsch"
|
||||
#define D_FILE "Datei"
|
||||
#define D_FREE_MEMORY "Freier Arbeitsspeicher"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "Gas"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Gruppe"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "direkt" // Button immediate
|
||||
#define D_INDEX "Index"
|
||||
#define D_INFO "Info"
|
||||
#define D_INFRARED "Infrarot"
|
||||
#define D_INITIALIZED "initialisiert"
|
||||
#define D_IP_ADDRESS "IP-Adresse"
|
||||
#define D_LIGHT "Licht"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Port"
|
||||
#define D_POWER_FACTOR "Leistungsfaktor"
|
||||
#define D_POWERUSAGE "Leistung"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "Luftdruck"
|
||||
#define D_PRESSUREATSEALEVEL "Luftdruck auf Meereshöhe"
|
||||
#define D_PROGRAM_FLASH_SIZE "Ges. Flash Speicher"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Laufzeit"
|
||||
#define D_USER "Benutzer"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV-Index"
|
||||
#define D_UV_LEVEL "UV-Level"
|
||||
#define D_VERSION "Version"
|
||||
#define D_VOLTAGE "Spannung"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "h"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sek"
|
||||
#define D_UNIT_SECTORS "Sektoren"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "Λάθος"
|
||||
#define D_FILE "Αρχείο"
|
||||
#define D_FREE_MEMORY "Ελεύθερη Μνήμη"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "Γκάζι"
|
||||
#define D_GATEWAY "Πύλη"
|
||||
#define D_GROUP "Ομάδα"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "Φωτεινότητα" // Button immediate
|
||||
#define D_INDEX "Κατάλογος"
|
||||
#define D_INFO "Πληροφορίες"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Αρχικό"
|
||||
#define D_IP_ADDRESS "IP Address"
|
||||
#define D_LIGHT "Light"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Πόρτα"
|
||||
#define D_POWER_FACTOR "Παράγοντας ισχύος"
|
||||
#define D_POWERUSAGE "Ισχύης"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "Πίεση"
|
||||
#define D_PRESSUREATSEALEVEL "Πίεση στην επιφάνεια της Θάλασσας"
|
||||
#define D_PROGRAM_FLASH_SIZE "Μέγεθος Προγράμματος Flash"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Uptime"
|
||||
#define D_USER "Χρήστης"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV Index"
|
||||
#define D_UV_LEVEL "Επίπεδο UV"
|
||||
#define D_VERSION "Έκδοση"
|
||||
#define D_VOLTAGE "Τάση"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "Hr"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "sectors"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
@ -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.12.0n
|
||||
* Updated until v5.14.0
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "False"
|
||||
#define D_FILE "File"
|
||||
#define D_FREE_MEMORY "Free Memory"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "Gas"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Group"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "immediate" // Button immediate
|
||||
#define D_INDEX "Index"
|
||||
#define D_INFO "Info"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Initialized"
|
||||
#define D_IP_ADDRESS "IP Address"
|
||||
#define D_LIGHT "Light"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Port"
|
||||
#define D_POWER_FACTOR "Power Factor"
|
||||
#define D_POWERUSAGE "Power"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "Pressure"
|
||||
#define D_PRESSUREATSEALEVEL "SeaPressure"
|
||||
#define D_PROGRAM_FLASH_SIZE "Program Flash Size"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Uptime"
|
||||
#define D_USER "User"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV Index"
|
||||
#define D_UV_LEVEL "UV Level"
|
||||
#define D_VERSION "Version"
|
||||
#define D_VOLTAGE "Voltage"
|
||||
@ -453,6 +459,8 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
@ -473,9 +481,12 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "sectors"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
|
||||
// Log message prefix
|
||||
#define D_LOG_APPLICATION "APP: " // Application
|
||||
|
@ -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.12.0m
|
||||
* Updated until v5.14.0
|
||||
\*********************************************************************/
|
||||
|
||||
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "Falso"
|
||||
#define D_FILE "Archivo"
|
||||
#define D_FREE_MEMORY "Memoria Libre"
|
||||
#define D_FREQUENCY "Frecuencia"
|
||||
#define D_GAS "Gas"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Grupo"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "inmediato" // Button immediate
|
||||
#define D_INDEX "Índice"
|
||||
#define D_INFO "Información"
|
||||
#define D_INFRARED "Infrarrojo"
|
||||
#define D_INITIALIZED "Inicializado"
|
||||
#define D_IP_ADDRESS "Dirección IP"
|
||||
#define D_LIGHT "Luz"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Puerto"
|
||||
#define D_POWER_FACTOR "Factor de Potencia"
|
||||
#define D_POWERUSAGE "Potencia"
|
||||
#define D_POWERUSAGE_ACTIVE "Potencia Activa"
|
||||
#define D_POWERUSAGE_APPARENT "Potencia Aparente"
|
||||
#define D_POWERUSAGE_REACTIVE "Potencia Reactiva"
|
||||
#define D_PRESSURE "Presión"
|
||||
#define D_PRESSUREATSEALEVEL "Presión al nivel del mar"
|
||||
#define D_PROGRAM_FLASH_SIZE "Tamaño de Flash de Programa"
|
||||
@ -130,7 +135,7 @@
|
||||
#define D_RESTART_REASON "Causa Reinicio"
|
||||
#define D_RESTORE "Restauración"
|
||||
#define D_RETAINED "Grabado"
|
||||
#define D_RULE "Rule"
|
||||
#define D_RULE "Regla"
|
||||
#define D_SAVE "Grabar"
|
||||
#define D_SENSOR "Sensor"
|
||||
#define D_SSID "SSId"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Tiempo Encendido"
|
||||
#define D_USER "Usuario"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "Índice UV"
|
||||
#define D_UV_LEVEL "Nivel UV"
|
||||
#define D_VERSION "Versión"
|
||||
#define D_VOLTAGE "Tensión"
|
||||
@ -199,7 +205,7 @@
|
||||
#define D_ERASED_SECTOR "Sector borrado"
|
||||
|
||||
// webserver.ino
|
||||
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "firmware MÍNIMO - actualice por favor"
|
||||
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Firmware MÍNIMO - actualice por favor"
|
||||
#define D_WEBSERVER_ACTIVE_ON "Servidor web activo en"
|
||||
#define D_WITH_IP_ADDRESS "con dirección IP"
|
||||
#define D_WEBSERVER_STOPPED "Servidor web detenido"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "Hr"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "seg"
|
||||
#define D_UNIT_SECTORS "sectores"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "Faux"
|
||||
#define D_FILE "Fichier"
|
||||
#define D_FREE_MEMORY "Mémoire libre"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "Gaz"
|
||||
#define D_GATEWAY "Passerelle"
|
||||
#define D_GROUP "Groupe"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "immédiat" // Button immediate
|
||||
#define D_INDEX "Index"
|
||||
#define D_INFO "Info"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Initialisé"
|
||||
#define D_IP_ADDRESS "Adresse IP"
|
||||
#define D_LIGHT "Lumière"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Port"
|
||||
#define D_POWER_FACTOR "Facteur de puissance"
|
||||
#define D_POWERUSAGE "Puissance"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "Pression"
|
||||
#define D_PRESSUREATSEALEVEL "PressionMer"
|
||||
#define D_PROGRAM_FLASH_SIZE "Taille Flash Programme"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Durée d'activité"
|
||||
#define D_USER "Utilisateur"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "Index UV"
|
||||
#define D_UV_LEVEL "Niveau UV"
|
||||
#define D_VERSION "Version"
|
||||
#define D_VOLTAGE "Tension"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "h"
|
||||
#define D_UNIT_KILOOHM "kΩ"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "secteurs"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "Hamis"
|
||||
#define D_FILE "File"
|
||||
#define D_FREE_MEMORY "Szabad Memória"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "Gáz"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Csoport"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "azonnali" // Button immediate
|
||||
#define D_INDEX "Index"
|
||||
#define D_INFO "Info"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Inicializálva"
|
||||
#define D_IP_ADDRESS "IP Cím"
|
||||
#define D_LIGHT "Fény"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Port"
|
||||
#define D_POWER_FACTOR "Teljesítmény tényező"
|
||||
#define D_POWERUSAGE "Energiafelhasználás"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "Nyomás"
|
||||
#define D_PRESSUREATSEALEVEL "Tengerszinti nyomás"
|
||||
#define D_PROGRAM_FLASH_SIZE "Program Flash Méret"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Üzemidő"
|
||||
#define D_USER "Felhasználó"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV Index"
|
||||
#define D_UV_LEVEL "UV Szint"
|
||||
#define D_VERSION "Verzió"
|
||||
#define D_VOLTAGE "Feszültség"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "ó"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "m"
|
||||
#define D_UNIT_SECTORS "szektorok"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
it-IT.h - localization for Italian - Italy for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Gennaro Tortone
|
||||
Copyright (C) 2018 Gennaro Tortone - some mods by Antonio Fragola
|
||||
|
||||
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
|
||||
@ -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.12.0
|
||||
* Updated until v5.14.0
|
||||
\*********************************************************************/
|
||||
|
||||
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
@ -51,7 +51,7 @@
|
||||
|
||||
// Common
|
||||
#define D_ADMIN "Admin"
|
||||
#define D_AIR_QUALITY "Qualita' dell'aria"
|
||||
#define D_AIR_QUALITY "Qualità dell'aria"
|
||||
#define D_AP "AP" // Access Point
|
||||
#define D_AS "come"
|
||||
#define D_AUTO "AUTO"
|
||||
@ -91,16 +91,18 @@
|
||||
#define D_FALSE "Falso"
|
||||
#define D_FILE "File"
|
||||
#define D_FREE_MEMORY "Memoria Libera"
|
||||
#define D_FREQUENCY "Frequenza"
|
||||
#define D_GAS "Gas"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Gruppo"
|
||||
#define D_HOST "Host"
|
||||
#define D_HOSTNAME "Nome Host"
|
||||
#define D_HUMIDITY "Umidita'"
|
||||
#define D_HUMIDITY "Umidità"
|
||||
#define D_ILLUMINANCE "Illuminazione"
|
||||
#define D_IMMEDIATE "immediato" // Button immediate
|
||||
#define D_INDEX "Indice"
|
||||
#define D_INFO "Info"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Inizializzato"
|
||||
#define D_IP_ADDRESS "Indirizzo IP"
|
||||
#define D_LIGHT "Luce"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Porta"
|
||||
#define D_POWER_FACTOR "Fattore di potenza"
|
||||
#define D_POWERUSAGE "Potenza"
|
||||
#define D_POWERUSAGE_ACTIVE "Potenza Attiva"
|
||||
#define D_POWERUSAGE_APPARENT "Potenza Apparente"
|
||||
#define D_POWERUSAGE_REACTIVE "Potenza Reattiva"
|
||||
#define D_PRESSURE "Pressione"
|
||||
#define D_PRESSUREATSEALEVEL "Pressione al livello del mare"
|
||||
#define D_PROGRAM_FLASH_SIZE "Dimensione Flash Programma"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Uptime"
|
||||
#define D_USER "Utente"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "Indice UV"
|
||||
#define D_UV_LEVEL "Livello UV"
|
||||
#define D_VERSION "Versione"
|
||||
#define D_VOLTAGE "Tensione"
|
||||
@ -180,7 +186,7 @@
|
||||
#define D_FAILED_TO_START "partenza fallita"
|
||||
#define D_PATCH_ISSUE_2186 "Patch issue 2186"
|
||||
#define D_CONNECTING_TO_AP "Connessione ad AP"
|
||||
#define D_IN_MODE "in modalita'"
|
||||
#define D_IN_MODE "in modalità"
|
||||
#define D_CONNECT_FAILED_NO_IP_ADDRESS "Connessione fallita, indirizzo IP non ricevuto"
|
||||
#define D_CONNECT_FAILED_AP_NOT_REACHED "Connessione fallita, AP non raggiungibile"
|
||||
#define D_CONNECT_FAILED_WRONG_PASSWORD "Connessione fallita, password AP non corretta"
|
||||
@ -211,7 +217,7 @@
|
||||
|
||||
#define D_RESTART_IN "Riavvio in"
|
||||
#define D_SECONDS "secondi"
|
||||
#define D_DEVICE_WILL_RESTART "Il dispositivo verra' riavviato tra pochi secondi"
|
||||
#define D_DEVICE_WILL_RESTART "Il dispositivo verrà riavviato tra pochi secondi"
|
||||
#define D_BUTTON_TOGGLE "On/Off"
|
||||
#define D_CONFIGURATION "Configurazione"
|
||||
#define D_INFORMATION "Informazioni"
|
||||
@ -229,7 +235,7 @@
|
||||
#define D_RESET_CONFIGURATION "Reset Configurazione"
|
||||
#define D_BACKUP_CONFIGURATION "Backup Configurazione"
|
||||
#define D_RESTORE_CONFIGURATION "Ripristino Configurazione"
|
||||
#define D_MAIN_MENU "Menu' Principale"
|
||||
#define D_MAIN_MENU "Menu Principale"
|
||||
|
||||
#define D_MODULE_PARAMETERS "Parametri del modulo"
|
||||
#define D_MODULE_TYPE "Tipo modulo"
|
||||
@ -243,7 +249,7 @@
|
||||
#define D_NO_NETWORKS_FOUND "Nessuna rete trovata"
|
||||
#define D_REFRESH_TO_SCAN_AGAIN "Ricarica per nuova scansione"
|
||||
#define D_DUPLICATE_ACCESSPOINT "AccessPoint duplicato"
|
||||
#define D_SKIPPING_LOW_QUALITY "Ignorato a causa di bassa qualita'"
|
||||
#define D_SKIPPING_LOW_QUALITY "Ignorato a causa di bassa qualità"
|
||||
#define D_RSSI "RSSI"
|
||||
#define D_WEP "WEP"
|
||||
#define D_WPA_PSK "WPA PSK"
|
||||
@ -317,7 +323,7 @@
|
||||
#define D_UPLOAD_ERROR_CODE "Codice errore invio"
|
||||
|
||||
#define D_ENTER_COMMAND "Inserire comando"
|
||||
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Abilitare weblog 2 se e' attesa una risposta"
|
||||
#define D_ENABLE_WEBLOG_FOR_RESPONSE "Abilitare weblog 2 se è attesa una risposta"
|
||||
#define D_NEED_USER_AND_PASSWORD "Richiesto user=<username>&password=<password>"
|
||||
|
||||
// xdrv_00_mqtt.ino
|
||||
@ -366,34 +372,34 @@
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Intervallo di aggiornamento"
|
||||
|
||||
// xdrv_09_timers.ino
|
||||
#define D_CONFIGURE_TIMER "Configure Timer"
|
||||
#define D_TIMER_PARAMETERS "Timer parameters"
|
||||
#define D_TIMER_ARM "Arm"
|
||||
#define D_TIMER_TIME "Time"
|
||||
#define D_TIMER_DAYS "Days"
|
||||
#define D_TIMER_REPEAT "Repeat"
|
||||
#define D_CONFIGURE_TIMER "Configura Timer"
|
||||
#define D_TIMER_PARAMETERS "Parametri Timer"
|
||||
#define D_TIMER_ARM "Attiva"
|
||||
#define D_TIMER_TIME "Ora"
|
||||
#define D_TIMER_DAYS "Giorni"
|
||||
#define D_TIMER_REPEAT "Ripeti"
|
||||
#define D_TIMER_OUTPUT "Output"
|
||||
#define D_TIMER_ACTION "Action"
|
||||
#define D_TIMER_ACTION "Azione"
|
||||
|
||||
// xdrv_10_knx.ino
|
||||
#define D_CONFIGURE_KNX "Configure KNX"
|
||||
#define D_KNX_PARAMETERS "KNX Parameters"
|
||||
#define D_KNX_GENERAL_CONFIG "General"
|
||||
#define D_KNX_PHYSICAL_ADDRESS "Physical Address"
|
||||
#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Must be unique on the KNX network )"
|
||||
#define D_KNX_ENABLE "Enable KNX"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data to Send to Group Addresses"
|
||||
#define D_ADD "Add"
|
||||
#define D_DELETE "Delete"
|
||||
#define D_REPLY "Reply"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_READ "Group Addresses to Receive Data from"
|
||||
#define D_CONFIGURE_KNX "Configura KNX"
|
||||
#define D_KNX_PARAMETERS "Parametri KNX"
|
||||
#define D_KNX_GENERAL_CONFIG "Generale"
|
||||
#define D_KNX_PHYSICAL_ADDRESS "Indirizzo Fisico"
|
||||
#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Deve essere univoco nella rete KNX )"
|
||||
#define D_KNX_ENABLE "Abilita KNX"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_WRITE "Dati da Inviare al Gruppo di Indirizzi"
|
||||
#define D_ADD "Aggiungi"
|
||||
#define D_DELETE "Elimina"
|
||||
#define D_REPLY "Rispondi"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_READ "Gruppo di Indirizzi da cui Ricevere Dati"
|
||||
#define D_LOG_KNX "KNX: "
|
||||
#define D_RECEIVED_FROM "Received from"
|
||||
#define D_KNX_COMMAND_WRITE "Write"
|
||||
#define D_KNX_COMMAND_READ "Read"
|
||||
#define D_KNX_COMMAND_OTHER "Other"
|
||||
#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_RECEIVED_FROM "Ricevuto Da"
|
||||
#define D_KNX_COMMAND_WRITE "Scrivi"
|
||||
#define D_KNX_COMMAND_READ "Leggi"
|
||||
#define D_KNX_COMMAND_OTHER "Altro"
|
||||
#define D_SENT_TO "invia a"
|
||||
#define D_KNX_WARNING "L'indirizzo del gruppo ( 0 / 0 / 0 ) è riservato e non può essere usato."
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Energia Oggi"
|
||||
@ -422,7 +428,7 @@
|
||||
#define D_PARTICALS_BEYOND "Particelle"
|
||||
|
||||
// sonoff_template.h
|
||||
#define D_SENSOR_NONE "None"
|
||||
#define D_SENSOR_NONE "Nessuno"
|
||||
#define D_SENSOR_DHT11 "DHT11"
|
||||
#define D_SENSOR_AM2301 "AM2301"
|
||||
#define D_SENSOR_SI7021 "SI7021"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "Hr"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "settori"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
@ -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.12.0l
|
||||
* Updated until v5.14.0
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "Onwaar"
|
||||
#define D_FILE "Bestand"
|
||||
#define D_FREE_MEMORY "Vrij geheugen"
|
||||
#define D_FREQUENCY "Frequentie"
|
||||
#define D_GAS "Gas"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Groep"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "onmiddelijk" // Button immediate
|
||||
#define D_INDEX "Index"
|
||||
#define D_INFO "Info"
|
||||
#define D_INFRARED "Infrarood"
|
||||
#define D_INITIALIZED "Geinitialiseerd"
|
||||
#define D_IP_ADDRESS "IP Adres"
|
||||
#define D_LIGHT "Licht"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Poort"
|
||||
#define D_POWER_FACTOR "Arbeidsfactor"
|
||||
#define D_POWERUSAGE "Vermogen"
|
||||
#define D_POWERUSAGE_ACTIVE "Werkelijk vermogen"
|
||||
#define D_POWERUSAGE_APPARENT "Schijnbaar vermogen"
|
||||
#define D_POWERUSAGE_REACTIVE "Blindvermogen"
|
||||
#define D_PRESSURE "Luchtdruk"
|
||||
#define D_PRESSUREATSEALEVEL "ZeeLuchtdruk"
|
||||
#define D_PROGRAM_FLASH_SIZE "Programma Flash Grootte"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Bedrijfstijd"
|
||||
#define D_USER "Gebruiker"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV-index"
|
||||
#define D_UV_LEVEL "UV niveau"
|
||||
#define D_VERSION "Versie"
|
||||
#define D_VOLTAGE "Spanning"
|
||||
@ -376,24 +382,24 @@
|
||||
#define D_TIMER_ACTION "Actie"
|
||||
|
||||
// xdrv_10_knx.ino
|
||||
#define D_CONFIGURE_KNX "Configure KNX"
|
||||
#define D_CONFIGURE_KNX "Configureer KNX"
|
||||
#define D_KNX_PARAMETERS "KNX Parameters"
|
||||
#define D_KNX_GENERAL_CONFIG "General"
|
||||
#define D_KNX_PHYSICAL_ADDRESS "Physical Address"
|
||||
#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Must be unique on the KNX network )"
|
||||
#define D_KNX_ENABLE "Enable KNX"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data to Send to Group Addresses"
|
||||
#define D_ADD "Add"
|
||||
#define D_DELETE "Delete"
|
||||
#define D_REPLY "Reply"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_READ "Group Addresses to Receive Data from"
|
||||
#define D_KNX_GENERAL_CONFIG "Algemeen"
|
||||
#define D_KNX_PHYSICAL_ADDRESS "Eigen adres"
|
||||
#define D_KNX_PHYSICAL_ADDRESS_NOTE "(Moet uniek zijn op het KNX netwerk)"
|
||||
#define D_KNX_ENABLE "KNX inschakelen"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_WRITE "Stuur gegevens naar groep adressen"
|
||||
#define D_ADD "Toevoegen"
|
||||
#define D_DELETE "Verwijder"
|
||||
#define D_REPLY "Antwoord"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_READ "Ontvang gegevens van groep adressen"
|
||||
#define D_LOG_KNX "KNX: "
|
||||
#define D_RECEIVED_FROM "Received from"
|
||||
#define D_KNX_COMMAND_WRITE "Write"
|
||||
#define D_KNX_COMMAND_READ "Read"
|
||||
#define D_KNX_COMMAND_OTHER "Other"
|
||||
#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_RECEIVED_FROM "Ontvangen van"
|
||||
#define D_KNX_COMMAND_WRITE "Schrijven"
|
||||
#define D_KNX_COMMAND_READ "Lezen"
|
||||
#define D_KNX_COMMAND_OTHER "Overige"
|
||||
#define D_SENT_TO "verzend naar"
|
||||
#define D_KNX_WARNING "Groep adres (0/0/0) is gereserveerd en mag niet worden gebruikt."
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Verbruik vandaag"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "h"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "sectoren"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
@ -43,7 +43,7 @@
|
||||
#define D_HOUR_MINUTE_SEPARATOR ":"
|
||||
#define D_MINUTE_SECOND_SEPARATOR ":"
|
||||
|
||||
#define D_DAY3LIST "PonWtoŚroCzwPiąSobNie"
|
||||
#define D_DAY3LIST "NiePonWtoŚroCzwPiąSob"
|
||||
#define D_MONTH3LIST "StyLutMarKwiMajCzeLipSieWrzPaźLisGru"
|
||||
|
||||
// Non JSON decimal separator
|
||||
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "Fałsz"
|
||||
#define D_FILE "Plik"
|
||||
#define D_FREE_MEMORY "Wolna pamięć"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "Gas"
|
||||
#define D_GATEWAY "Brama"
|
||||
#define D_GROUP "Grupa"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "Natychmiastowe" // Button immediate
|
||||
#define D_INDEX "Indeks"
|
||||
#define D_INFO "Informacja"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Zainicjowany"
|
||||
#define D_IP_ADDRESS "Adres IP"
|
||||
#define D_LIGHT "Światło"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Port"
|
||||
#define D_POWER_FACTOR "Współczynik mocy"
|
||||
#define D_POWERUSAGE "Moc"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "Ciśnienie"
|
||||
#define D_PRESSUREATSEALEVEL "Ciśnienie na poziomie morza"
|
||||
#define D_PROGRAM_FLASH_SIZE "Wielkość programu flash"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Uptime"
|
||||
#define D_USER "Użytkownik"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV Index"
|
||||
#define D_UV_LEVEL "Poziom UV"
|
||||
#define D_VERSION "Wersja"
|
||||
#define D_VOLTAGE "Napięcie"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "Godz"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "sektory"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
516
sonoff/language/pt-BR.h
Normal file
516
sonoff/language/pt-BR.h
Normal file
@ -0,0 +1,516 @@
|
||||
/*
|
||||
pt-BR.h - localization for Portuguese - Brazil for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Fabiano Bovo
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _LANGUAGE_PT_BR_H_
|
||||
#define _LANGUAGE_PT_BR_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.13.0
|
||||
\*********************************************************************/
|
||||
|
||||
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
|
||||
|
||||
// HTML (ISO 639-1) Language Code
|
||||
#define D_HTML_LANGUAGE "pt"
|
||||
|
||||
// "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 "DomSegTerQuaQuiSexSab"
|
||||
#define D_MONTH3LIST "JanFevMarAbrMaiJunJulAgoSepOutNovDez"
|
||||
|
||||
// Non JSON decimal separator
|
||||
#define D_DECIMAL_SEPARATOR ","
|
||||
|
||||
// Common
|
||||
#define D_ADMIN "Admin"
|
||||
#define D_AIR_QUALITY "Qualidade do Ar"
|
||||
#define D_AP "Pondo de acesso" // Ponto de Acesso
|
||||
#define D_AS "como"
|
||||
#define D_AUTO "Auto"
|
||||
#define D_BLINK "Pulsar"
|
||||
#define D_BLINKOFF "Pulsar desligado"
|
||||
#define D_BOOT_COUNT "Contagem de inicialização"
|
||||
#define D_BRIGHTLIGHT "Brilho"
|
||||
#define D_BUTTON "Botão"
|
||||
#define D_BY "por" // Write by me
|
||||
#define D_BYTES "Bytes"
|
||||
#define D_CELSIUS "Celsius"
|
||||
#define D_CO2 "Dióxido de Carbono"
|
||||
#define D_CODE "Código" // Button code
|
||||
#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_DEBUG "Depurar"
|
||||
#define D_DISABLED "Desabilitado"
|
||||
#define D_DISTANCE "Distância"
|
||||
#define D_DNS_SERVER "Servidor DNS"
|
||||
#define D_DONE "Concluído"
|
||||
#define D_DST_TIME "DST"
|
||||
#define D_ECO2 "eCO2"
|
||||
#define D_EMULATION "Emulação"
|
||||
#define D_ENABLED "Habilitado"
|
||||
#define D_ERASE "Apagar"
|
||||
#define D_ERROR "Erro"
|
||||
#define D_FAHRENHEIT "Fahrenheit"
|
||||
#define D_FAILED "Falha"
|
||||
#define D_FALLBACK "Retornar"
|
||||
#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_GAS "Gás"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Grupo"
|
||||
#define D_HOST "Anfitrião"
|
||||
#define D_HOSTNAME "Nome do anfitrião"
|
||||
#define D_HUMIDITY "Umidade"
|
||||
#define D_ILLUMINANCE "Luminância"
|
||||
#define D_IMMEDIATE "Imediato" // Button immediate
|
||||
#define D_INDEX "Índice"
|
||||
#define D_INFO "Informação"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Inicializado"
|
||||
#define D_IP_ADDRESS "Endereço IP"
|
||||
#define D_LIGHT "Luz"
|
||||
#define D_LWT "LWT"
|
||||
#define D_MODULE "Módulo"
|
||||
#define D_MQTT "MQTT"
|
||||
#define D_MULTI_PRESS "multi-pressão"
|
||||
#define D_NOISE "Ruído"
|
||||
#define D_NONE "Nenhum"
|
||||
#define D_OFF "Desligado"
|
||||
#define D_OFFLINE "Desconectado"
|
||||
#define D_OK "Ok"
|
||||
#define D_ON "Ligado"
|
||||
#define D_ONLINE "Conectado"
|
||||
#define D_PASSWORD "Senha"
|
||||
#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_PRESSURE "Pressão"
|
||||
#define D_PRESSUREATSEALEVEL "Pressão ao nível do mar"
|
||||
#define D_PROGRAM_FLASH_SIZE "Tamanho do programa na memória"
|
||||
#define D_PROGRAM_SIZE "Tamanho do programa"
|
||||
#define D_PROJECT "Projeto"
|
||||
#define D_RECEIVED "Recebido"
|
||||
#define D_RESTART "Reiniciar"
|
||||
#define D_RESTARTING "Reiniciando"
|
||||
#define D_RESTART_REASON "Motivo do reinício"
|
||||
#define D_RESTORE "Restauração"
|
||||
#define D_RETAINED "Manter"
|
||||
#define D_RULE "Regra"
|
||||
#define D_SAVE "Salvar"
|
||||
#define D_SENSOR "Sensor"
|
||||
#define D_SSID "SSId"
|
||||
#define D_START "Iniciar"
|
||||
#define D_STD_TIME "STD"
|
||||
#define D_STOP "Parar"
|
||||
#define D_SUBNET_MASK "Máscara sub rede"
|
||||
#define D_SUBSCRIBE_TO "Subescrever para"
|
||||
#define D_SUCCESSFUL "Successo"
|
||||
#define D_SUNRISE "Nascer do sol"
|
||||
#define D_SUNSET "Por do sol"
|
||||
#define D_TEMPERATURE "Temperatura"
|
||||
#define D_TO "Para"
|
||||
#define D_TOGGLE "Inverter"
|
||||
#define D_TOPIC "Tópico"
|
||||
#define D_TRANSMIT "Transmitir"
|
||||
#define D_TRUE "Verdadeiro"
|
||||
#define D_TVOC "TVOC"
|
||||
#define D_UPGRADE "atualização"
|
||||
#define D_UPLOAD "Enviar"
|
||||
#define D_UPTIME "Tempo de atividade"
|
||||
#define D_USER "Usuário"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "Índice UV"
|
||||
#define D_UV_LEVEL "Nível UV"
|
||||
#define D_VERSION "Versão"
|
||||
#define D_VOLTAGE "Voltagem"
|
||||
#define D_WARMLIGHT "Luz quente"
|
||||
#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_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_SYSLOG_LOGGING_REENABLED "Registro do Syslog reativado"
|
||||
|
||||
#define D_SET_BAUDRATE_TO "Ajuste da velocidade para"
|
||||
#define D_RECEIVED_TOPIC "Tópico recebido"
|
||||
#define D_DATA_SIZE "Tamanho de dados"
|
||||
#define D_ANALOG_INPUT "Entrada analógica"
|
||||
|
||||
// support.ino
|
||||
#define D_OSWATCH "osWatch"
|
||||
#define D_BLOCKED_LOOP "Loop bloqueado"
|
||||
#define D_WPS_FAILED_WITH_STATUS "WPSconfig falha de estado"
|
||||
#define D_ACTIVE_FOR_3_MINUTES "Ativo por 3 minutos"
|
||||
#define D_FAILED_TO_START "Falha ao iníciar"
|
||||
#define D_PATCH_ISSUE_2186 "Questão 2186"
|
||||
#define D_CONNECTING_TO_AP "Ligando ao PA"
|
||||
#define D_IN_MODE "em modo"
|
||||
#define D_CONNECT_FAILED_NO_IP_ADDRESS "A ligação falhou porque nenhum endereço IP foi recebido"
|
||||
#define D_CONNECT_FAILED_AP_NOT_REACHED "A ligação falhou porque o PA não pôde ser alcançado"
|
||||
#define D_CONNECT_FAILED_WRONG_PASSWORD "A ligação falhou porque a senha está incorreta"
|
||||
#define D_CONNECT_FAILED_AP_TIMEOUT "A ligação falhou porque o tempo foi excedido"
|
||||
#define D_ATTEMPTING_CONNECTION "Ligando..."
|
||||
#define D_CHECKING_CONNECTION "Verificando ligação..."
|
||||
#define D_QUERY_DONE "Consulta finalizada. Serviço MQTT não encontrado"
|
||||
#define D_MQTT_SERVICE_FOUND "Serviço MQTT encontrado em"
|
||||
#define D_FOUND_AT "encontrado em"
|
||||
#define D_SYSLOG_HOST_NOT_FOUND "Syslog anfitrião não encontrado"
|
||||
|
||||
// settings.ino
|
||||
#define D_SAVED_TO_FLASH_AT "Guardado na flash em"
|
||||
#define D_LOADED_FROM_FLASH_AT "Lido da flash em"
|
||||
#define D_USE_DEFAULTS "Usar predefinições"
|
||||
#define D_ERASED_SECTOR "Apagar setores"
|
||||
|
||||
// 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_TRYING_TO_CONNECT "Conectar o dispositivo à rede"
|
||||
|
||||
#define D_RESTART_IN "Reinicia em"
|
||||
#define D_SECONDS "segundos"
|
||||
#define D_DEVICE_WILL_RESTART "O dispositivo irá reiniciar dentro de alguns segundos"
|
||||
#define D_BUTTON_TOGGLE "Comandar"
|
||||
#define D_CONFIGURATION "Configuração"
|
||||
#define D_INFORMATION "Informação"
|
||||
#define D_FIRMWARE_UPGRADE "Atualização de Firmware"
|
||||
#define D_CONSOLE "Console"
|
||||
#define D_CONFIRM_RESTART "Confirmar o reinicio"
|
||||
|
||||
#define D_CONFIGURE_MODULE "Configurar Módulo"
|
||||
#define D_CONFIGURE_WIFI "Configurar WiFi"
|
||||
#define D_CONFIGURE_MQTT "Configurar MQTT"
|
||||
#define D_CONFIGURE_DOMOTICZ "Configurar Domoticz"
|
||||
#define D_CONFIGURE_LOGGING "Configurar Logging"
|
||||
#define D_CONFIGURE_OTHER "Configurar outras opções"
|
||||
#define D_CONFIRM_RESET_CONFIGURATION "Confirmar limpeza de configuração"
|
||||
#define D_RESET_CONFIGURATION "Apagar configuração"
|
||||
#define D_BACKUP_CONFIGURATION "Salvar configuração"
|
||||
#define D_RESTORE_CONFIGURATION "Repor configuração"
|
||||
#define D_MAIN_MENU "Menu principal"
|
||||
|
||||
#define D_MODULE_PARAMETERS "Parametros do módulo"
|
||||
#define D_MODULE_TYPE "Tipo de módulo"
|
||||
#define D_GPIO "GPIO"
|
||||
#define D_SERIAL_IN "Entrada serial"
|
||||
#define D_SERIAL_OUT "Saída serial"
|
||||
|
||||
#define D_WIFI_PARAMETERS "Parâmetros do wifi"
|
||||
#define D_SCAN_FOR_WIFI_NETWORKS "Encontrar redes wifi"
|
||||
#define D_SCAN_DONE "Busca finalizada"
|
||||
#define D_NO_NETWORKS_FOUND "Sem redes"
|
||||
#define D_REFRESH_TO_SCAN_AGAIN "Nova busca"
|
||||
#define D_DUPLICATE_ACCESSPOINT "Ponto de Acesso duplicado"
|
||||
#define D_SKIPPING_LOW_QUALITY "Ignorado devido à baixa qualidade do sinal"
|
||||
#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 "Senha AP1"
|
||||
#define D_AP2_SSID "AP2 SSId"
|
||||
#define D_AP2_PASSWORD "Senha AP2"
|
||||
|
||||
#define D_MQTT_PARAMETERS "Parâmetros MQTT"
|
||||
#define D_CLIENT "Cliente"
|
||||
#define D_FULL_TOPIC "Tópico completo"
|
||||
|
||||
#define D_LOGGING_PARAMETERS "Parâmetros Logging"
|
||||
#define D_SERIAL_LOG_LEVEL "Nível de registro serial"
|
||||
#define D_WEB_LOG_LEVEL "Nível de registro WEB"
|
||||
#define D_SYS_LOG_LEVEL "Nível de registro Syslog"
|
||||
#define D_MORE_DEBUG "Depurar mais"
|
||||
#define D_SYSLOG_HOST "Syslog anfitrião"
|
||||
#define D_SYSLOG_PORT "Porta Syslog"
|
||||
#define D_TELEMETRY_PERIOD "Período de telemetria"
|
||||
|
||||
#define D_OTHER_PARAMETERS "Outros parâmetros"
|
||||
#define D_WEB_ADMIN_PASSWORD "Senha de WEB Admin"
|
||||
#define D_MQTT_ENABLE "MQTT habilitado"
|
||||
#define D_FRIENDLY_NAME "Nome amigável"
|
||||
#define D_BELKIN_WEMO "Belkin WeMo"
|
||||
#define D_HUE_BRIDGE "Hue Bridge"
|
||||
#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_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_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"
|
||||
#define D_MQTT_HOST "MQTT Servidor"
|
||||
#define D_MQTT_PORT "MQTT Porta"
|
||||
#define D_MQTT_CLIENT "MQTT Cliente"
|
||||
#define D_MQTT_USER "MQTT Usuário"
|
||||
#define D_MQTT_TOPIC "MQTT Tópico"
|
||||
#define D_MQTT_GROUP_TOPIC "MQTT Tópico Grupo"
|
||||
#define D_MQTT_FULL_TOPIC "MQTT Tópico Completo"
|
||||
#define D_MDNS_DISCOVERY "Descobrir mDNS"
|
||||
#define D_MDNS_ADVERTISE "Anunciar mDNS"
|
||||
#define D_ESP_CHIP_ID "ESP Chip Id"
|
||||
#define D_FLASH_CHIP_ID "Flash Chip Id"
|
||||
#define D_FLASH_CHIP_SIZE "Flash Size"
|
||||
#define D_FREE_PROGRAM_SPACE "Espaço Livre Programa"
|
||||
|
||||
#define D_UPGRADE_BY_WEBSERVER "Atualizar pelo servidor WEB"
|
||||
#define D_OTA_URL "OTA Url"
|
||||
#define D_START_UPGRADE "Iniciar atualização"
|
||||
#define D_UPGRADE_BY_FILE_UPLOAD "Atualização por arquivo local"
|
||||
#define D_UPLOAD_STARTED "Início do envio"
|
||||
#define D_UPGRADE_STARTED "Atualização iniciada"
|
||||
#define D_UPLOAD_DONE "Atualização finalizada"
|
||||
#define D_UPLOAD_ERR_1 "Nenhum arquivo selecionado"
|
||||
#define D_UPLOAD_ERR_2 "Não existe memória disponível"
|
||||
#define D_UPLOAD_ERR_3 "Byte mágico não é 0xE9"
|
||||
#define D_UPLOAD_ERR_4 "O tamanho do programa é maior do que o tamanho da memória"
|
||||
#define D_UPLOAD_ERR_5 "Envio buffer miscompare"
|
||||
#define D_UPLOAD_ERR_6 "Falha no envio. Habilitar logging 3"
|
||||
#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_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=<nome usuário>&password=<senha>"
|
||||
|
||||
// xdrv_00_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"
|
||||
#define D_VERIFIED "Verificado impressão digital "
|
||||
#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
|
||||
#define D_MULTICAST_DISABLED "Multicast desabilitado"
|
||||
#define D_MULTICAST_REJOINED "Multicast (re)ingressou"
|
||||
#define D_MULTICAST_JOIN_FAILED "Multicast falha no reingresso"
|
||||
#define D_FAILED_TO_SEND_RESPONSE "Falha no envio de reposta"
|
||||
|
||||
#define D_WEMO "WeMo"
|
||||
#define D_WEMO_BASIC_EVENT "WeMo evento básico"
|
||||
#define D_WEMO_EVENT_SERVICE "WeMo evento de serviço"
|
||||
#define D_WEMO_META_SERVICE "WeMo serviço meta"
|
||||
#define D_WEMO_SETUP "WeMo configuração"
|
||||
#define D_RESPONSE_SENT "Resposta enviada"
|
||||
|
||||
#define D_HUE "Hue"
|
||||
#define D_HUE_BRIDGE_SETUP "Hue setup"
|
||||
#define D_HUE_API_NOT_IMPLEMENTED "Hue API nao implementada"
|
||||
#define D_HUE_API "Hue API"
|
||||
#define D_HUE_POST_ARGS "Hue POST args"
|
||||
#define D_3_RESPONSE_PACKETS_SENT "3 pacotes de resposta enviados"
|
||||
|
||||
// xdrv_05_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_POWER_ENERGY "Potência,Energia"
|
||||
#define D_DOMOTICZ_ILLUMINANCE "Luminância"
|
||||
#define D_DOMOTICZ_COUNT "Contagem/PM1"
|
||||
#define D_DOMOTICZ_VOLTAGE "Voltagem/PM2.5"
|
||||
#define D_DOMOTICZ_CURRENT "Corrente/PM10"
|
||||
#define D_DOMOTICZ_AIRQUALITY "Qualidade do ar"
|
||||
#define D_DOMOTICZ_UPDATE_TIMER "Tempo de atualização"
|
||||
|
||||
// xdrv_09_timers.ino
|
||||
#define D_CONFIGURE_TIMER "Configurar temporizador"
|
||||
#define D_TIMER_PARAMETERS "Parâmetros"
|
||||
#define D_TIMER_ARM "Habilitar"
|
||||
#define D_TIMER_TIME "Horário"
|
||||
#define D_TIMER_DAYS "Dias"
|
||||
#define D_TIMER_REPEAT "Repetir"
|
||||
#define D_TIMER_OUTPUT "Saída"
|
||||
#define D_TIMER_ACTION "Ação"
|
||||
|
||||
// xdrv_10_knx.ino
|
||||
#define D_CONFIGURE_KNX "Configurar KNX"
|
||||
#define D_KNX_PARAMETERS "Parâmetros KNX"
|
||||
#define D_KNX_GENERAL_CONFIG "Geral"
|
||||
#define D_KNX_PHYSICAL_ADDRESS "Endereço físico"
|
||||
#define D_KNX_PHYSICAL_ADDRESS_NOTE "(Deve ser único na rede KNX)"
|
||||
#define D_KNX_ENABLE "Habilitar KNX"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_WRITE "Endereço do grupo para enviar"
|
||||
#define D_ADD "Adicionar"
|
||||
#define D_DELETE "Remover"
|
||||
#define D_REPLY "Responder"
|
||||
#define D_KNX_GROUP_ADDRESS_TO_READ "Endereço do grupo para receber"
|
||||
#define D_LOG_KNX "KNX: "
|
||||
#define D_RECEIVED_FROM "Recebido de"
|
||||
#define D_KNX_COMMAND_WRITE "Escrever"
|
||||
#define D_KNX_COMMAND_READ "Ler"
|
||||
#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."
|
||||
|
||||
// xdrv_03_energy.ino
|
||||
#define D_ENERGY_TODAY "Consumo energético de hoje"
|
||||
#define D_ENERGY_YESTERDAY "Consumo energético de ontem"
|
||||
#define D_ENERGY_TOTAL "Consumo total de energia"
|
||||
|
||||
// xsns_05_ds18b20.ino
|
||||
#define D_SENSOR_BUSY "Sensor ocupado"
|
||||
#define D_SENSOR_CRC_ERROR "Erro sensor CRC"
|
||||
#define D_SENSORS_FOUND "Sensores encontrados"
|
||||
|
||||
// xsns_06_dht.ino
|
||||
#define D_TIMEOUT_WAITING_FOR "Fim do tempo de espera"
|
||||
#define D_START_SIGNAL_LOW "Sinal de início baixo"
|
||||
#define D_START_SIGNAL_HIGH "Sinal de início elevado"
|
||||
#define D_PULSE "pulso"
|
||||
#define D_CHECKSUM_FAILURE "Falha checksum"
|
||||
|
||||
// xsns_07_sht1x.ino
|
||||
#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor não aceitou o comando ACK"
|
||||
#define D_SHT1X_FOUND "SHT1X encontrado"
|
||||
|
||||
// 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 "Partículas"
|
||||
|
||||
// sonoff_template.h
|
||||
#define D_SENSOR_NONE "Nenhum"
|
||||
#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 "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_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 "Luz de fundo"
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "H"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
#define D_UNIT_LUX "lx"
|
||||
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3"
|
||||
#define D_UNIT_MICROMETER "um"
|
||||
#define D_UNIT_MICROSECOND "us"
|
||||
#define D_UNIT_MILLIAMPERE "mA"
|
||||
#define D_UNIT_MILLISECOND "ms"
|
||||
#define D_UNIT_MINUTE "M"
|
||||
#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 "hPa"
|
||||
#define D_UNIT_SECOND "s"
|
||||
#define D_UNIT_SECTORS "setores"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "W/h"
|
||||
|
||||
// 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_PT_BR_H_
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
pt-PT.h - localization for Portuguese - Portugal for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Theo Arends and Paulo Paiva
|
||||
Copyright (C) 2018 Paulo Paiva
|
||||
|
||||
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
|
||||
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "Falso"
|
||||
#define D_FILE "Ficheiro"
|
||||
#define D_FREE_MEMORY "Memoria Livre"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "Gás"
|
||||
#define D_GATEWAY "Gateway"
|
||||
#define D_GROUP "Grupo"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "Immediato" // Button immediate
|
||||
#define D_INDEX "Indíce"
|
||||
#define D_INFO "Info"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Inicializado"
|
||||
#define D_IP_ADDRESS "Endereço IP"
|
||||
#define D_LIGHT "Luz"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Porta"
|
||||
#define D_POWER_FACTOR "Factor 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_PRESSURE "Pressão"
|
||||
#define D_PRESSUREATSEALEVEL "Pressão ao nível do Mar"
|
||||
#define D_PROGRAM_FLASH_SIZE "Tamanho do Programa na Flash"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Tempo de Atividade"
|
||||
#define D_USER "Utilizador"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "Indíce UV"
|
||||
#define D_UV_LEVEL "Nível UV"
|
||||
#define D_VERSION "Versão"
|
||||
#define D_VOLTAGE "Voltagem"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "A"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "Hr"
|
||||
#define D_UNIT_KILOOHM "kOhm"
|
||||
#define D_UNIT_KILOWATTHOUR "kWh"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "hPa"
|
||||
#define D_UNIT_SECOND "sec"
|
||||
#define D_UNIT_SECTORS "sectors"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "V"
|
||||
#define D_UNIT_WATT "W"
|
||||
#define D_UNIT_WATTHOUR "Wh"
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "Ложно"
|
||||
#define D_FILE "Файл"
|
||||
#define D_FREE_MEMORY "Свободная память"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "Газ"
|
||||
#define D_GATEWAY "Шлюз"
|
||||
#define D_GROUP "Группа"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "немедленно" // Button immediate
|
||||
#define D_INDEX "Индекс"
|
||||
#define D_INFO "Инфо"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "Инициализировано"
|
||||
#define D_IP_ADDRESS "IP Адрес"
|
||||
#define D_LIGHT "Свет"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "Порт"
|
||||
#define D_POWER_FACTOR "Коэффициент Мощности"
|
||||
#define D_POWERUSAGE "Мощность"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "Давление"
|
||||
#define D_PRESSUREATSEALEVEL "Давление на уровне моря"
|
||||
#define D_PROGRAM_FLASH_SIZE "Размер Flash для программ"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "Uptime"
|
||||
#define D_USER "Пользователь"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV Index"
|
||||
#define D_UV_LEVEL "УФ уровень"
|
||||
#define D_VERSION "Версия"
|
||||
#define D_VOLTAGE "Напряжение"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "А"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "Ч"
|
||||
#define D_UNIT_KILOOHM "кОм"
|
||||
#define D_UNIT_KILOWATTHOUR "кВт"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "гПа"
|
||||
#define D_UNIT_SECOND "сек"
|
||||
#define D_UNIT_SECTORS "секторов"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "В"
|
||||
#define D_UNIT_WATT "Вт"
|
||||
#define D_UNIT_WATTHOUR "ВтЧ"
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "False"
|
||||
#define D_FILE "文件:"
|
||||
#define D_FREE_MEMORY "空闲内存"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "气体"
|
||||
#define D_GATEWAY "网关"
|
||||
#define D_GROUP "组:"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "immediate" // Button immediate
|
||||
#define D_INDEX "索引:"
|
||||
#define D_INFO "信息"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "初始化完成"
|
||||
#define D_IP_ADDRESS "IP地址"
|
||||
#define D_LIGHT "灯"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "端口"
|
||||
#define D_POWER_FACTOR "功率因数"
|
||||
#define D_POWERUSAGE "功率"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "气压"
|
||||
#define D_PRESSUREATSEALEVEL "海平面气压"
|
||||
#define D_PROGRAM_FLASH_SIZE "固件 Flash 大小"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "运行时间"
|
||||
#define D_USER "用户名"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV Index"
|
||||
#define D_UV_LEVEL "紫外线水平"
|
||||
#define D_VERSION "版本"
|
||||
#define D_VOLTAGE "电压"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "安"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "时"
|
||||
#define D_UNIT_KILOOHM "千欧"
|
||||
#define D_UNIT_KILOWATTHOUR "千瓦时"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "百帕"
|
||||
#define D_UNIT_SECOND "秒"
|
||||
#define D_UNIT_SECTORS "扇区"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "伏"
|
||||
#define D_UNIT_WATT "瓦"
|
||||
#define D_UNIT_WATTHOUR "瓦时"
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define D_FALSE "False"
|
||||
#define D_FILE "文件:"
|
||||
#define D_FREE_MEMORY "可用記憶體"
|
||||
#define D_FREQUENCY "Frequency"
|
||||
#define D_GAS "氣體"
|
||||
#define D_GATEWAY "網關"
|
||||
#define D_GROUP "組:"
|
||||
@ -101,6 +102,7 @@
|
||||
#define D_IMMEDIATE "immediate" // Button immediate
|
||||
#define D_INDEX "索引:"
|
||||
#define D_INFO "信息"
|
||||
#define D_INFRARED "Infrared"
|
||||
#define D_INITIALIZED "初始化完成"
|
||||
#define D_IP_ADDRESS "IP地址"
|
||||
#define D_LIGHT "燈"
|
||||
@ -119,6 +121,9 @@
|
||||
#define D_PORT "端口"
|
||||
#define D_POWER_FACTOR "功率因數"
|
||||
#define D_POWERUSAGE "功率"
|
||||
#define D_POWERUSAGE_ACTIVE "Active Power"
|
||||
#define D_POWERUSAGE_APPARENT "Apparent Power"
|
||||
#define D_POWERUSAGE_REACTIVE "Reactive Power"
|
||||
#define D_PRESSURE "氣壓"
|
||||
#define D_PRESSUREATSEALEVEL "海平面氣壓"
|
||||
#define D_PROGRAM_FLASH_SIZE "韌體 Flash 大小"
|
||||
@ -154,6 +159,7 @@
|
||||
#define D_UPTIME "運行時間"
|
||||
#define D_USER "用戶名"
|
||||
#define D_UTC_TIME "UTC"
|
||||
#define D_UV_INDEX "UV Index"
|
||||
#define D_UV_LEVEL "紫外線等級"
|
||||
#define D_VERSION "版本"
|
||||
#define D_VOLTAGE "電壓"
|
||||
@ -453,10 +459,13 @@
|
||||
#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"
|
||||
|
||||
// Units
|
||||
#define D_UNIT_AMPERE "安"
|
||||
#define D_UNIT_CENTIMETER "cm"
|
||||
#define D_UNIT_HERTZ "Hz"
|
||||
#define D_UNIT_HOUR "時"
|
||||
#define D_UNIT_KILOOHM "千歐"
|
||||
#define D_UNIT_KILOWATTHOUR "千瓦時"
|
||||
@ -473,6 +482,8 @@
|
||||
#define D_UNIT_PRESSURE "百帕"
|
||||
#define D_UNIT_SECOND "秒"
|
||||
#define D_UNIT_SECTORS "扇區"
|
||||
#define D_UNIT_VA "VA"
|
||||
#define D_UNIT_VAR "VAr"
|
||||
#define D_UNIT_VOLT "伏"
|
||||
#define D_UNIT_WATT "瓦"
|
||||
#define D_UNIT_WATTHOUR "瓦時"
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef _SETTINGS_H_
|
||||
#define _SETTINGS_H_
|
||||
|
||||
#define PARAM8_SIZE 23 // Number of param bytes
|
||||
#define PARAM8_SIZE 18 // Number of param bytes
|
||||
|
||||
typedef union { // Restricted by MISRA-C Rule 18.4 but so usefull...
|
||||
uint32_t data; // Allow bit manipulation using SetOption
|
||||
@ -51,7 +51,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
||||
uint32_t rules_enabled : 1; // bit 23 (v5.12.0j)
|
||||
uint32_t rules_once : 1; // bit 24 (v5.12.0k)
|
||||
uint32_t knx_enabled : 1; // bit 25 (v5.12.0l) KNX
|
||||
uint32_t spare26 : 1;
|
||||
uint32_t device_index_enable : 1; // bit 26 (v5.13.1a)
|
||||
uint32_t spare27 : 1;
|
||||
uint32_t spare28 : 1;
|
||||
uint32_t spare29 : 1;
|
||||
@ -89,6 +89,17 @@ typedef union {
|
||||
};
|
||||
} SysBitfield2;
|
||||
|
||||
typedef union {
|
||||
uint16_t data;
|
||||
struct {
|
||||
uint16_t hemis : 1; // bit 0 = 0=Northern, 1=Southern Hemisphere (=Opposite DST/STD)
|
||||
uint16_t week : 3; // bits 1 - 3 = 0=Last week of the month, 1=First, 2=Second, 3=Third, 4=Fourth
|
||||
uint16_t month : 4; // bits 4 - 7 = 1=Jan, 2=Feb, ... 12=Dec
|
||||
uint16_t dow : 3; // bits 8 - 10 = day of week, 1=Sun, 2=Mon, ... 7=Sat
|
||||
uint16_t hour : 5; // bits 11 - 15 = 0-23
|
||||
};
|
||||
} TimeRule;
|
||||
|
||||
typedef union {
|
||||
uint32_t data;
|
||||
struct {
|
||||
@ -148,9 +159,7 @@ struct SYSCFG {
|
||||
uint8_t display_address[8]; // 2D8
|
||||
uint8_t display_dimmer; // 2E0
|
||||
uint8_t display_size; // 2E1
|
||||
|
||||
uint8_t free_2E2[4]; // 2E2
|
||||
|
||||
TimeRule tflag[2]; // 2E2
|
||||
uint16_t pwm_frequency; // 2E6
|
||||
power_t power; // 2E8
|
||||
uint16_t pwm_value[MAX_PWMS]; // 2EC
|
||||
@ -159,6 +168,10 @@ struct SYSCFG {
|
||||
uint8_t ex_power; // 2FA Not used since 5.8.0j
|
||||
uint8_t ledstate; // 2FB
|
||||
uint8_t param[PARAM8_SIZE]; // 2FC was domoticz_in_topic until 5.1.6
|
||||
int16_t toffset[2]; // 30E
|
||||
|
||||
byte free_312[1]; // 312
|
||||
|
||||
char state_text[4][11]; // 313
|
||||
uint8_t energy_power_delta; // 33F
|
||||
uint16_t domoticz_update_timer; // 340
|
||||
@ -289,19 +302,6 @@ struct TIME_T {
|
||||
unsigned long valid;
|
||||
} RtcTime;
|
||||
|
||||
struct TimeChangeRule
|
||||
{
|
||||
uint8_t hemis; // 0-Northern, 1=Southern Hemisphere (=Opposite DST/STD)
|
||||
uint8_t week; // 1=First, 2=Second, 3=Third, 4=Fourth, or 0=Last week of the month
|
||||
uint8_t dow; // day of week, 1=Sun, 2=Mon, ... 7=Sat
|
||||
uint8_t month; // 1=Jan, 2=Feb, ... 12=Dec
|
||||
uint8_t hour; // 0-23
|
||||
int offset; // offset from UTC in minutes
|
||||
};
|
||||
|
||||
TimeChangeRule DaylightSavingTime = { TIME_DST }; // Daylight Saving Time
|
||||
TimeChangeRule StandardTime = { TIME_STD }; // Standard Time
|
||||
|
||||
struct XDRVMAILBOX {
|
||||
uint16_t valid;
|
||||
uint16_t index;
|
||||
|
@ -521,6 +521,8 @@ void SettingsDefaultSet2()
|
||||
|
||||
Settings.latitude = (int)((double)LATITUDE * 1000000);
|
||||
Settings.longitude = (int)((double)LONGITUDE * 1000000);
|
||||
|
||||
SettingsDefaultSet_5_13_1c();
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
@ -652,6 +654,32 @@ void SettingsDefaultSet_5_10_1()
|
||||
Settings.display_size = 1;
|
||||
}
|
||||
|
||||
void SettingsResetStd()
|
||||
{
|
||||
Settings.tflag[0].hemis = TIME_STD_HEMISPHERE;
|
||||
Settings.tflag[0].week = TIME_STD_WEEK;
|
||||
Settings.tflag[0].dow = TIME_STD_DAY;
|
||||
Settings.tflag[0].month = TIME_STD_MONTH;
|
||||
Settings.tflag[0].hour = TIME_STD_HOUR;
|
||||
Settings.toffset[0] = TIME_STD_OFFSET;
|
||||
}
|
||||
|
||||
void SettingsResetDst()
|
||||
{
|
||||
Settings.tflag[1].hemis = TIME_DST_HEMISPHERE;
|
||||
Settings.tflag[1].week = TIME_DST_WEEK;
|
||||
Settings.tflag[1].dow = TIME_DST_DAY;
|
||||
Settings.tflag[1].month = TIME_DST_MONTH;
|
||||
Settings.tflag[1].hour = TIME_DST_HOUR;
|
||||
Settings.toffset[1] = TIME_DST_OFFSET;
|
||||
}
|
||||
|
||||
void SettingsDefaultSet_5_13_1c()
|
||||
{
|
||||
SettingsResetStd();
|
||||
SettingsResetDst();
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void SettingsDelta()
|
||||
@ -852,10 +880,14 @@ void SettingsDelta()
|
||||
memset(&Settings.knx_physsical_addr, 0x00, 0x800 - 0x6b8); // Reset until 0x800 for future use
|
||||
}
|
||||
if (Settings.version < 0x050C000F) {
|
||||
Settings.energy_kWhtoday /= 1000;
|
||||
Settings.energy_kWhyesterday /= 1000;
|
||||
RtcSettings.energy_kWhtoday /= 1000;
|
||||
Settings.energy_kWhtoday /= 1000;
|
||||
Settings.energy_kWhyesterday /= 1000;
|
||||
RtcSettings.energy_kWhtoday /= 1000;
|
||||
}
|
||||
if (Settings.version < 0x050D0103) {
|
||||
SettingsDefaultSet_5_13_1c();
|
||||
}
|
||||
|
||||
Settings.version = VERSION;
|
||||
SettingsSave(1);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
|
||||
====================================================*/
|
||||
|
||||
#define VERSION 0x050D0100 // 5.13.1
|
||||
#define VERSION 0x050E0000 // 5.14.0
|
||||
|
||||
// Location specific includes
|
||||
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
@ -83,7 +83,7 @@ enum TasmotaCommands {
|
||||
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_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE,
|
||||
CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_TIMESTD, CMND_TIMEDST, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE,
|
||||
CMND_I2CSCAN, CMND_SERIALSEND, CMND_BAUDRATE, CMND_SERIALDELIMITER };
|
||||
const char kTasmotaCommands[] PROGMEM =
|
||||
D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|"
|
||||
@ -93,19 +93,14 @@ const char kTasmotaCommands[] PROGMEM =
|
||||
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_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|"
|
||||
D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|"
|
||||
D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER;
|
||||
|
||||
const char kOptionOff[] PROGMEM = "OFF|" D_OFF "|" D_FALSE "|" D_STOP "|" D_CELSIUS ;
|
||||
const char kOptionOn[] PROGMEM = "ON|" D_ON "|" D_TRUE "|" D_START "|" D_FAHRENHEIT "|" D_USER ;
|
||||
const char kOptionToggle[] PROGMEM = "TOGGLE|" D_TOGGLE "|" D_ADMIN ;
|
||||
const char kOptionBlink[] PROGMEM = "BLINK|" D_BLINK ;
|
||||
const char kOptionBlinkOff[] PROGMEM = "BLINKOFF|" D_BLINKOFF ;
|
||||
|
||||
// Global variables
|
||||
int baudrate = APP_BAUDRATE; // Serial interface baud rate
|
||||
SerialConfig serial_config = SERIAL_8N1; // Serial interface configuration 8 data bits, No parity, 1 stop bit
|
||||
byte serial_in_byte; // Received byte
|
||||
uint8_t serial_local = 0; // Handle serial locally;
|
||||
unsigned long serial_polling_window = 0; // Serial polling window
|
||||
int serial_in_byte_counter = 0; // Index in receive buffer
|
||||
byte dual_hex_code = 0; // Sonoff dual input flag
|
||||
@ -182,6 +177,7 @@ uint8_t light_type = 0; // Light types
|
||||
bool pwm_present = false; // Any PWM channel configured with SetOption15 0
|
||||
boolean mdns_begun = false;
|
||||
unsigned long features = 0UL;
|
||||
uint8_t ntp_force_sync = 0; // Force NTP sync
|
||||
|
||||
char my_version[33]; // Composed version string
|
||||
char my_hostname[33]; // Composed Wifi hostname
|
||||
@ -381,6 +377,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
byte jsflg = 0;
|
||||
byte lines = 1;
|
||||
uint8_t grpflg = 0;
|
||||
// uint8_t user_append_index = 0;
|
||||
uint16_t i = 0;
|
||||
uint16_t index;
|
||||
uint32_t address;
|
||||
@ -412,7 +409,10 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
while (isdigit(type[i-1])) {
|
||||
i--;
|
||||
}
|
||||
if (i < strlen(type)) index = atoi(type +i);
|
||||
if (i < strlen(type)) {
|
||||
index = atoi(type +i);
|
||||
// user_append_index = 1;
|
||||
}
|
||||
type[i] = '\0';
|
||||
}
|
||||
|
||||
@ -436,38 +436,41 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
}
|
||||
backlog_delay = MIN_BACKLOG_DELAY; // Reset backlog delay
|
||||
|
||||
if ((GetCommandCode(command, sizeof(command), dataBuf, kOptionOff) >= 0) || !strcasecmp(dataBuf, Settings.state_text[0])) {
|
||||
payload = 0;
|
||||
}
|
||||
if ((GetCommandCode(command, sizeof(command), dataBuf, kOptionOn) >= 0) || !strcasecmp(dataBuf, Settings.state_text[1])) {
|
||||
payload = 1;
|
||||
}
|
||||
if ((GetCommandCode(command, sizeof(command), dataBuf, kOptionToggle) >= 0) || !strcasecmp(dataBuf, Settings.state_text[2])) {
|
||||
payload = 2;
|
||||
}
|
||||
if (GetCommandCode(command, sizeof(command), dataBuf, kOptionBlink) >= 0) {
|
||||
payload = 3;
|
||||
}
|
||||
if (GetCommandCode(command, sizeof(command), dataBuf, kOptionBlinkOff) >= 0) {
|
||||
payload = 4;
|
||||
}
|
||||
int temp_payload = GetStateNumber(dataBuf);
|
||||
if (temp_payload > -1) { payload = temp_payload; }
|
||||
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR("RSLT: Payload %d, Payload16 %d"), payload, payload16);
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
int command_code = GetCommandCode(command, sizeof(command), type, kTasmotaCommands);
|
||||
if (CMND_BACKLOG == command_code) {
|
||||
if (-1 == command_code) {
|
||||
if (!XdrvCommand(grpflg, type, index, dataBuf, data_len, payload, payload16)) {
|
||||
type = NULL; // Unknown command
|
||||
}
|
||||
}
|
||||
else if (CMND_BACKLOG == command_code) {
|
||||
if (data_len) {
|
||||
uint8_t bl_pointer = (!backlog_pointer) ? MAX_BACKLOG -1 : backlog_pointer;
|
||||
bl_pointer--;
|
||||
char *blcommand = strtok(dataBuf, ";");
|
||||
while ((blcommand != NULL) && (backlog_index != bl_pointer)) {
|
||||
backlog[backlog_index] = String(blcommand);
|
||||
backlog_index++;
|
||||
if (backlog_index >= MAX_BACKLOG) backlog_index = 0;
|
||||
while(true) {
|
||||
blcommand = LTrim(blcommand);
|
||||
if (!strncasecmp_P(blcommand, PSTR(D_CMND_BACKLOG), strlen(D_CMND_BACKLOG))) {
|
||||
blcommand += strlen(D_CMND_BACKLOG); // Skip unnecessary command Backlog
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*blcommand != '\0') {
|
||||
backlog[backlog_index] = String(blcommand);
|
||||
backlog_index++;
|
||||
if (backlog_index >= MAX_BACKLOG) backlog_index = 0;
|
||||
}
|
||||
blcommand = strtok(NULL, ";");
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_APPENDED);
|
||||
// snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_APPENDED);
|
||||
mqtt_data[0] = '\0';
|
||||
} else {
|
||||
uint8_t blflag = (backlog_pointer == backlog_index);
|
||||
backlog_pointer = backlog_index;
|
||||
@ -480,6 +483,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);
|
||||
fallback_topic_flag = 0;
|
||||
return;
|
||||
@ -555,7 +559,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
XsnsCall(FUNC_COMMAND);
|
||||
// if (!XsnsCall(FUNC_COMMAND)) type = NULL;
|
||||
}
|
||||
else if ((CMND_SETOPTION == command_code) && ((index <= 21) || ((index > 31) && (index <= P_MAX_PARAM8 + 31)))) {
|
||||
else if ((CMND_SETOPTION == command_code) && ((index <= 26) || ((index > 31) && (index <= P_MAX_PARAM8 + 31)))) {
|
||||
if (index <= 31) {
|
||||
ptype = 0; // SetOption0 .. 31
|
||||
} else {
|
||||
@ -587,6 +591,9 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
case 21: // no_power_on_check
|
||||
// case 22: // mqtt_serial - use commands SerialSend and SerialLog
|
||||
// case 23: // rules_enabled - use command Rule
|
||||
// case 24: // rules_once
|
||||
// case 25: // knx_enabled
|
||||
case 26: // device_index_enable
|
||||
bitWrite(Settings.flag.data, index, payload);
|
||||
}
|
||||
if (12 == index) { // stop_flash_rotate
|
||||
@ -1040,6 +1047,47 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
if ((data_len > 0) && (((payload >= -13) && (payload <= 14)) || (99 == payload))) Settings.timezone = payload;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.timezone);
|
||||
}
|
||||
else if ((CMND_TIMESTD == command_code) || (CMND_TIMEDST == command_code)) {
|
||||
// TimeStd 0/1, 0/1/2/3/4, 1..12, 1..7, 0..23, +/-780
|
||||
uint8_t ts = 0;
|
||||
if (CMND_TIMEDST == command_code) { ts = 1; }
|
||||
if (data_len > 0) {
|
||||
if (strstr(dataBuf, ",")) { // Process parameter entry
|
||||
uint8_t tpos = 0; // Parameter index
|
||||
int value = 0;
|
||||
p = dataBuf; // Parameters like "1, 2,3 , 4 ,5, -120" or ",,,,,+240"
|
||||
char *q = p; // Value entered flag
|
||||
while (p && (tpos < 7)) {
|
||||
if (p > q) { // Any value entered
|
||||
if (1 == tpos) { Settings.tflag[ts].hemis = value &1; }
|
||||
if (2 == tpos) { Settings.tflag[ts].week = (value < 0) ? 0 : (value > 4) ? 4 : value; }
|
||||
if (3 == tpos) { Settings.tflag[ts].month = (value < 1) ? 1 : (value > 12) ? 12 : value; }
|
||||
if (4 == tpos) { Settings.tflag[ts].dow = (value < 1) ? 1 : (value > 7) ? 7 : value; }
|
||||
if (5 == tpos) { Settings.tflag[ts].hour = (value < 0) ? 0 : (value > 23) ? 23 : value; }
|
||||
if (6 == tpos) { Settings.toffset[ts] = (value < -900) ? -900 : (value > 900) ? 900 : value; }
|
||||
}
|
||||
p = LTrim(p); // Skip spaces
|
||||
if (tpos && (*p == ',')) { p++; } // Skip separator
|
||||
p = LTrim(p); // Skip spaces
|
||||
q = p; // Reset any value entered flag
|
||||
value = strtol(p, &p, 10);
|
||||
tpos++; // Next parameter
|
||||
}
|
||||
ntp_force_sync = 1;
|
||||
} else {
|
||||
if (0 == payload) {
|
||||
if (0 == ts) {
|
||||
SettingsResetStd();
|
||||
} else {
|
||||
SettingsResetDst();
|
||||
}
|
||||
}
|
||||
ntp_force_sync = 1;
|
||||
}
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":{\"Hemisphere\":%d,\"Week\":%d,\"Month\":%d,\"Day\":%d,\"Hour\":%d,\"Offset\":%d\"}}"),
|
||||
command, Settings.tflag[ts].hemis, Settings.tflag[ts].week, Settings.tflag[ts].month, Settings.tflag[ts].dow, Settings.tflag[ts].hour, Settings.toffset[ts]);
|
||||
}
|
||||
else if (CMND_ALTITUDE == command_code) {
|
||||
if ((data_len > 0) && ((payload >= -30000) && (payload <= 30000))) Settings.altitude = payload;
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.altitude);
|
||||
@ -1073,12 +1121,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
||||
I2cScan(mqtt_data, sizeof(mqtt_data));
|
||||
}
|
||||
#endif // USE_I2C
|
||||
else if (XdrvCommand(grpflg, type, index, dataBuf, data_len, payload, payload16)) {
|
||||
// Serviced
|
||||
}
|
||||
else {
|
||||
type = NULL;
|
||||
}
|
||||
else type = NULL; // Unknown command
|
||||
}
|
||||
if (type == NULL) {
|
||||
blinks = 201;
|
||||
@ -1374,7 +1417,7 @@ void MqttShowState()
|
||||
if (i == light_device -1) {
|
||||
LightState(1);
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":\"%s\""), mqtt_data, GetPowerDevice(stemp1, i +1, sizeof(stemp1)), GetStateText(bitRead(power, i)));
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":\"%s\""), mqtt_data, GetPowerDevice(stemp1, i +1, sizeof(stemp1), Settings.flag.device_index_enable), GetStateText(bitRead(power, i)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2439,7 +2482,7 @@ void loop()
|
||||
|
||||
if (millis() >= state_loop_timer) StateLoop();
|
||||
|
||||
SerialInput();
|
||||
if (!serial_local) SerialInput();
|
||||
|
||||
#ifdef USE_ARDUINO_OTA
|
||||
ArduinoOTA.handle();
|
||||
|
@ -71,6 +71,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
||||
#define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code)
|
||||
#define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code)
|
||||
#define USE_TSL2561 // Add I2C code for TSL2561 sensor using library Adafruit TSL2561 Arduino (+1k2 code)
|
||||
#define USE_SI1145 // Add I2C code for SI1145/46/47 sensor (+1k code)
|
||||
#define USE_ADS1115 // Add I2C code for ADS1115 16 bit A/D converter based on Adafruit ADS1x15 library (no library needed) (+0k7 code)
|
||||
//#define USE_ADS1115_I2CDEV // Add I2C code for ADS1115 16 bit A/D converter using library i2cdevlib-Core and i2cdevlib-ADS1115 (+2k code)
|
||||
#define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code)
|
||||
@ -87,6 +88,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
||||
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
|
||||
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
|
||||
#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
|
||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
||||
#define USE_IR_HVAC // Support for HVAC system using IR (+2k code)
|
||||
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)
|
||||
@ -232,6 +234,9 @@ void KNX_CB_Action(message_t const &msg, void *arg);
|
||||
#ifdef USE_SERIAL_BRIDGE
|
||||
#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge
|
||||
#endif
|
||||
#ifdef USE_SDM120
|
||||
#undef USE_SDM120 // Disable support for SDM120
|
||||
#endif
|
||||
#ifdef USE_IR_REMOTE
|
||||
#undef USE_IR_REMOTE // Disable IR driver
|
||||
#endif
|
||||
|
@ -93,6 +93,8 @@ enum UserSelectablePins {
|
||||
GPIO_SBR_RX, // Serial Bridge Serial interface
|
||||
GPIO_SR04_TRIG, // SR04 Trigger pin
|
||||
GPIO_SR04_ECHO, // SR04 Echo pin
|
||||
GPIO_SDM120_TX, // SDM120 Serial interface
|
||||
GPIO_SDM120_RX, // SDM120 Serial interface
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
// Programmer selectable GPIO functionality offset by user selectable GPIOs
|
||||
@ -136,7 +138,8 @@ const char kSensorNames[] PROGMEM =
|
||||
D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|"
|
||||
D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1 "|"
|
||||
D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|"
|
||||
D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO;
|
||||
D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|"
|
||||
D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX;
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
|
@ -35,6 +35,10 @@ byte oswatch_blocked_loop = 0;
|
||||
//void OsWatchTicker() ICACHE_RAM_ATTR;
|
||||
#endif // USE_WS2812_DMA
|
||||
|
||||
#ifdef USE_KNX
|
||||
bool knx_started = false;
|
||||
#endif // USE_KNX
|
||||
|
||||
void OsWatchTicker()
|
||||
{
|
||||
unsigned long t = millis();
|
||||
@ -232,6 +236,14 @@ char* UpperCase_P(char* dest, const char* source)
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* LTrim(char* p)
|
||||
{
|
||||
while ((*p != '\0') && (isblank(*p))) {
|
||||
p++; // Trim leading spaces
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
char* NoAlNumToUnderscore(char* dest, const char* source)
|
||||
{
|
||||
char* write = dest;
|
||||
@ -447,6 +459,29 @@ int GetCommandCode(char* destination, size_t destination_size, const char* needl
|
||||
return result;
|
||||
}
|
||||
|
||||
int GetStateNumber(char *state_text)
|
||||
{
|
||||
char command[CMDSZ];
|
||||
int state_number = -1;
|
||||
|
||||
if ((GetCommandCode(command, sizeof(command), state_text, kOptionOff) >= 0) || !strcasecmp(state_text, Settings.state_text[0])) {
|
||||
state_number = 0;
|
||||
}
|
||||
else if ((GetCommandCode(command, sizeof(command), state_text, kOptionOn) >= 0) || !strcasecmp(state_text, Settings.state_text[1])) {
|
||||
state_number = 1;
|
||||
}
|
||||
else if ((GetCommandCode(command, sizeof(command), state_text, kOptionToggle) >= 0) || !strcasecmp(state_text, Settings.state_text[2])) {
|
||||
state_number = 2;
|
||||
}
|
||||
else if (GetCommandCode(command, sizeof(command), state_text, kOptionBlink) >= 0) {
|
||||
state_number = 3;
|
||||
}
|
||||
else if (GetCommandCode(command, sizeof(command), state_text, kOptionBlinkOff) >= 0) {
|
||||
state_number = 4;
|
||||
}
|
||||
return state_number;
|
||||
}
|
||||
|
||||
void SetSerialBaudrate(int baudrate)
|
||||
{
|
||||
Settings.baudrate = baudrate / 1200;
|
||||
@ -463,6 +498,15 @@ void SetSerialBaudrate(int baudrate)
|
||||
}
|
||||
}
|
||||
|
||||
void ClaimSerial()
|
||||
{
|
||||
serial_local = 1;
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("SNS: Hardware Serial"));
|
||||
SetSeriallog(LOG_LEVEL_NONE);
|
||||
baudrate = Serial.baudRate();
|
||||
Settings.baudrate = baudrate / 1200;
|
||||
}
|
||||
|
||||
uint32_t GetHash(const char *buffer, size_t size)
|
||||
{
|
||||
uint32_t hash = 0;
|
||||
@ -790,11 +834,20 @@ void WifiCheck(uint8_t param)
|
||||
}
|
||||
#endif // USE_EMULATION
|
||||
#endif // USE_WEBSERVER
|
||||
#ifdef USE_KNX
|
||||
if (!knx_started && Settings.flag.knx_enabled) {
|
||||
KNXStart();
|
||||
knx_started = true;
|
||||
}
|
||||
#endif // USE_KNX
|
||||
} else {
|
||||
#if defined(USE_WEBSERVER) && defined(USE_EMULATION)
|
||||
UdpDisconnect();
|
||||
#endif // USE_EMULATION
|
||||
mdns_begun = false;
|
||||
#ifdef USE_KNX
|
||||
knx_started = false;
|
||||
#endif // USE_KNX
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1243,7 +1296,7 @@ uint32_t MakeTime(TIME_T &tm)
|
||||
return seconds;
|
||||
}
|
||||
|
||||
uint32_t RuleToTime(TimeChangeRule r, int yr)
|
||||
uint32_t RuleToTime(TimeRule r, int yr)
|
||||
{
|
||||
TIME_T tm;
|
||||
uint32_t t;
|
||||
@ -1312,9 +1365,10 @@ void RtcSecond()
|
||||
|
||||
if ((ntp_sync_minute > 59) && (RtcTime.minute > 2)) ntp_sync_minute = 1; // If sync prepare for a new cycle
|
||||
uint8_t offset = (uptime < 30) ? RtcTime.second : (((ESP.getChipId() & 0xF) * 3) + 3) ; // First try ASAP to sync. If fails try once every 60 seconds based on chip id
|
||||
if ((WL_CONNECTED == WiFi.status()) && (offset == RtcTime.second) && ((RtcTime.year < 2016) || (ntp_sync_minute == RtcTime.minute))) {
|
||||
if ((WL_CONNECTED == WiFi.status()) && (offset == RtcTime.second) && ((RtcTime.year < 2016) || (ntp_sync_minute == RtcTime.minute) || ntp_force_sync)) {
|
||||
ntp_time = sntp_get_current_timestamp();
|
||||
if (ntp_time > 1451602800) { // Fix NTP bug in core 2.4.1/SDK 2.2.1 (returns Thu Jan 01 08:00:10 1970 after power on)
|
||||
ntp_force_sync = 0;
|
||||
utc_time = ntp_time;
|
||||
ntp_sync_minute = 60; // Sync so block further requests
|
||||
if (restart_time == 0) {
|
||||
@ -1322,8 +1376,8 @@ void RtcSecond()
|
||||
}
|
||||
BreakTime(utc_time, tmpTime);
|
||||
RtcTime.year = tmpTime.year + 1970;
|
||||
daylight_saving_time = RuleToTime(DaylightSavingTime, RtcTime.year);
|
||||
standard_time = RuleToTime(StandardTime, RtcTime.year);
|
||||
daylight_saving_time = RuleToTime(Settings.tflag[1], RtcTime.year);
|
||||
standard_time = RuleToTime(Settings.tflag[0], RtcTime.year);
|
||||
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);
|
||||
@ -1344,17 +1398,22 @@ void RtcSecond()
|
||||
if (local_time > 1451602800) { // 2016-01-01
|
||||
int32_t time_offset = Settings.timezone * SECS_PER_HOUR;
|
||||
if (99 == Settings.timezone) {
|
||||
if (DaylightSavingTime.hemis) {
|
||||
dstoffset = StandardTime.offset * SECS_PER_MIN; // Southern hemisphere
|
||||
stdoffset = DaylightSavingTime.offset * SECS_PER_MIN;
|
||||
dstoffset = Settings.toffset[1] * SECS_PER_MIN;
|
||||
stdoffset = Settings.toffset[0] * SECS_PER_MIN;
|
||||
if (Settings.tflag[1].hemis) {
|
||||
// Southern hemisphere
|
||||
if ((utc_time >= (standard_time - dstoffset)) && (utc_time < (daylight_saving_time - stdoffset))) {
|
||||
time_offset = stdoffset; // Standard Time
|
||||
} else {
|
||||
time_offset = dstoffset; // Daylight Saving Time
|
||||
}
|
||||
} else {
|
||||
dstoffset = DaylightSavingTime.offset * SECS_PER_MIN; // Northern hemisphere
|
||||
stdoffset = StandardTime.offset * SECS_PER_MIN;
|
||||
}
|
||||
if ((utc_time >= (daylight_saving_time - stdoffset)) && (utc_time < (standard_time - dstoffset))) {
|
||||
time_offset = dstoffset; // Daylight Saving Time
|
||||
} else {
|
||||
time_offset = stdoffset; // Standard Time
|
||||
// Northern hemisphere
|
||||
if ((utc_time >= (daylight_saving_time - stdoffset)) && (utc_time < (standard_time - dstoffset))) {
|
||||
time_offset = dstoffset; // Daylight Saving Time
|
||||
} else {
|
||||
time_offset = stdoffset; // Standard Time
|
||||
}
|
||||
}
|
||||
}
|
||||
local_time += time_offset;
|
||||
@ -1400,6 +1459,7 @@ uint16_t AdcRead()
|
||||
return analog;
|
||||
}
|
||||
|
||||
#ifdef USE_RULES
|
||||
void AdcEvery50ms()
|
||||
{
|
||||
adc_counter++;
|
||||
@ -1413,6 +1473,7 @@ void AdcEvery50ms()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // USE_RULES
|
||||
|
||||
void AdcShow(boolean json)
|
||||
{
|
||||
@ -1439,9 +1500,11 @@ boolean Xsns02(byte function)
|
||||
|
||||
if (pin[GPIO_ADC0] < 99) {
|
||||
switch (function) {
|
||||
#ifdef USE_RULES
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
AdcEvery50ms();
|
||||
break;
|
||||
#endif // USE_RULES
|
||||
case FUNC_JSON_APPEND:
|
||||
AdcShow(1);
|
||||
break;
|
||||
|
@ -74,7 +74,7 @@
|
||||
#define WEB_LOG_LEVEL LOG_LEVEL_INFO // [WebLog] (LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE)
|
||||
|
||||
// -- Ota -----------------------------------------
|
||||
#define OTA_URL "http://sonoff.maddox.co.uk/tasmota/sonoff.ino.bin" // [OtaUrl]
|
||||
#define OTA_URL "http://sonoff.maddox.co.uk/tasmota/sonoff.bin" // [OtaUrl]
|
||||
|
||||
// -- MQTT ----------------------------------------
|
||||
#define MQTT_USE 1 // [SetOption3] Select default MQTT use (0 = Off, 1 = On)
|
||||
@ -129,6 +129,22 @@
|
||||
#define NTP_SERVER2 "nl.pool.ntp.org" // [NtpServer2] Select second NTP server by name or IP address (5.39.184.5)
|
||||
#define NTP_SERVER3 "0.nl.pool.ntp.org" // [NtpServer3] Select third NTP server by name or IP address (93.94.224.67)
|
||||
|
||||
// -- Time - Start Daylight Saving Time and timezone offset from UTC in minutes
|
||||
#define TIME_DST_HEMISPHERE North // [TimeDst] Hemisphere (0 or North, 1 or South)
|
||||
#define TIME_DST_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth)
|
||||
#define TIME_DST_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat)
|
||||
#define TIME_DST_MONTH Mar // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec)
|
||||
#define TIME_DST_HOUR 2 // Hour (0 to 23)
|
||||
#define TIME_DST_OFFSET +120 // Offset from UTC in minutes (-780 to +780)
|
||||
|
||||
// -- Time - Start Standard Time and timezone offset from UTC in minutes
|
||||
#define TIME_STD_HEMISPHERE North // [TimeStd] Hemisphere (0 or North, 1 or South)
|
||||
#define TIME_STD_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth)
|
||||
#define TIME_STD_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat)
|
||||
#define TIME_STD_MONTH Oct // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec)
|
||||
#define TIME_STD_HOUR 3 // Hour (0 to 23)
|
||||
#define TIME_STD_OFFSET +60 // Offset from UTC in minutes (-780 to +780)
|
||||
|
||||
// -- Location ------------------------------------
|
||||
#define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset
|
||||
#define LONGITUDE 2.294442 // [Longitude] Your location to be used with sunrise and sunset
|
||||
@ -177,6 +193,7 @@
|
||||
//#define MY_LANGUAGE it-IT // Italian in Italy
|
||||
//#define MY_LANGUAGE nl-NL // Dutch in the Netherlands
|
||||
//#define MY_LANGUAGE pl-PL // Polish in Poland
|
||||
//#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 zh-CN // Chinese (Simplified) in China
|
||||
@ -222,12 +239,6 @@
|
||||
#define WEBSERVER_ADVERTISE // Provide access to webserver by name <Hostname>.local/
|
||||
#define MQTT_HOST_DISCOVERY // Find MQTT host server (overrides MQTT_HOST if found)
|
||||
|
||||
// -- Time - Start Daylight Saving Time and timezone offset from UTC in minutes
|
||||
#define TIME_DST North, Last, Sun, Mar, 2, +120 // Northern Hemisphere, Last sunday in march at 02:00 +120 minutes
|
||||
|
||||
// -- Time - Start Standard Time and timezone offset from UTC in minutes
|
||||
#define TIME_STD North, Last, Sun, Oct, 3, +60 // Northern Hemisphere, Last sunday in october 02:00 +60 minutes
|
||||
|
||||
// -- Time ----------------------------------------
|
||||
#define USE_TIMERS // Add support for up to 16 timers (+2k2 code)
|
||||
#define USE_TIMERS_WEB // Add timer webpage support (+4k5 code)
|
||||
@ -257,6 +268,7 @@
|
||||
#define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code)
|
||||
// #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code)
|
||||
// #define USE_TSL2561 // Add I2C code for TSL2561 sensor using library Joba_Tsl2561 (+2k3 code)
|
||||
// #define USE_SI1145 // Add I2C code for SI1145/46/47 sensor (+1k code)
|
||||
// #define USE_ADS1115 // Add I2C code for ADS1115 16 bit A/D converter based on Adafruit ADS1x15 library (no library needed) (+0k7 code)
|
||||
// #define USE_ADS1115_I2CDEV // Add I2C code for ADS1115 16 bit A/D converter using library i2cdevlib-Core and i2cdevlib-ADS1115 (+2k code)
|
||||
// #define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code)
|
||||
@ -279,6 +291,8 @@
|
||||
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
|
||||
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
|
||||
//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
|
||||
#define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud)
|
||||
|
||||
// -- Low level interface devices -----------------
|
||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
||||
|
@ -330,6 +330,8 @@ uint8_t upload_file_type;
|
||||
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)
|
||||
@ -390,9 +392,6 @@ void StartWebserver(int type, IPAddress ipweb)
|
||||
}
|
||||
#endif // USE_EMULATION
|
||||
WebServer->onNotFound(HandleNotFound);
|
||||
#ifdef USE_KNX
|
||||
KNXStart();
|
||||
#endif // USE_KNX
|
||||
}
|
||||
reset_web_log_flag = 0;
|
||||
WebServer->begin(); // Web server start
|
||||
@ -738,7 +737,7 @@ void HandleModuleConfiguration()
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
if (GPIO_USER == cmodule.gp.io[i]) {
|
||||
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:126px'><select id='g%d' name='g%d'></select></td></tr>"),
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:146px'><select id='g%d' name='g%d'></select></td></tr>"),
|
||||
(WEMOS==Settings.module)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
|
||||
page += mqtt_data;
|
||||
}
|
||||
@ -977,10 +976,10 @@ void HandleBackupConfiguration()
|
||||
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
|
||||
memcpy(buffer, &Settings, sizeof(buffer));
|
||||
buffer[0] = CONFIG_FILE_SIGN;
|
||||
buffer[1] = (!CONFIG_FILE_XOR)?0:1;
|
||||
buffer[1] = (!config_xor_on_set) ? 0 : 1;
|
||||
if (buffer[1]) {
|
||||
for (uint16_t i = 2; i < sizeof(buffer); i++) {
|
||||
buffer[i] ^= (CONFIG_FILE_XOR +i);
|
||||
buffer[i] ^= (config_xor_on_set +i);
|
||||
}
|
||||
}
|
||||
myClient.write((const char*)buffer, sizeof(buffer));
|
||||
@ -1236,6 +1235,14 @@ void HandleUpgradeFirmwareStart()
|
||||
ExecuteCommand(svalue);
|
||||
}
|
||||
|
||||
void SettingsNewFree()
|
||||
{
|
||||
if (settings_new != NULL) {
|
||||
free(settings_new);
|
||||
settings_new = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleUploadDone()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
@ -1275,6 +1282,7 @@ void HandleUploadDone()
|
||||
page += FPSTR(HTTP_MSG_RSTRT);
|
||||
restart_flag = 2;
|
||||
}
|
||||
SettingsNewFree();
|
||||
page += F("</div><br/>");
|
||||
page += FPSTR(HTTP_BTN_MAIN);
|
||||
ShowPage(page);
|
||||
@ -1302,7 +1310,13 @@ void HandleUploadLoop()
|
||||
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) {
|
||||
if (upload_file_type) {
|
||||
SettingsNewFree();
|
||||
if (!(settings_new = (uint8_t *)malloc(sizeof(Settings)))) {
|
||||
upload_error = 2;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
MqttRetryCounter(60);
|
||||
#ifdef USE_EMULATION
|
||||
UdpDisconnect();
|
||||
@ -1343,22 +1357,10 @@ void HandleUploadLoop()
|
||||
if (upload_file_type) { // config
|
||||
if (!upload_error) {
|
||||
if (upload.currentSize > (sizeof(Settings) - (config_block_count * HTTP_UPLOAD_BUFLEN))) {
|
||||
if (config_block_count) { SettingsDefault(); }
|
||||
upload_error = 9;
|
||||
return;
|
||||
}
|
||||
if (config_xor_on) {
|
||||
for (uint16_t i = 2; i < upload.currentSize; i++) {
|
||||
upload.buf[i] ^= (CONFIG_FILE_XOR +i);
|
||||
}
|
||||
}
|
||||
if (0 == config_block_count) {
|
||||
SettingsDefaultSet2();
|
||||
memcpy((char*)&Settings +16, upload.buf +16, upload.currentSize -16);
|
||||
memcpy((char*)&Settings +8, upload.buf +8, 4); // Restore version and auto upgrade
|
||||
} else {
|
||||
memcpy((char*)&Settings +(config_block_count * HTTP_UPLOAD_BUFLEN), upload.buf, upload.currentSize);
|
||||
}
|
||||
memcpy(settings_new + (config_block_count * HTTP_UPLOAD_BUFLEN), upload.buf, upload.currentSize);
|
||||
config_block_count++;
|
||||
}
|
||||
} else { // firmware
|
||||
@ -1376,7 +1378,17 @@ void HandleUploadLoop()
|
||||
if (_serialoutput && (upload_progress_dot_count % 80)) {
|
||||
Serial.println();
|
||||
}
|
||||
if (!upload_file_type) {
|
||||
if (upload_file_type) {
|
||||
if (config_xor_on) {
|
||||
for (uint16_t i = 2; i < sizeof(Settings); i++) {
|
||||
settings_new[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 {
|
||||
if (!Update.end(true)) { // true to set the size to the current progress
|
||||
if (_serialoutput) { Update.printError(Serial); }
|
||||
upload_error = 6;
|
||||
@ -1407,7 +1419,7 @@ void HandlePreflightRequest()
|
||||
void HandleHttpCommand()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
char svalue[INPUT_BUFFER_SIZE]; // big to serve Backlog
|
||||
char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog
|
||||
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND));
|
||||
|
||||
@ -1477,7 +1489,7 @@ void HandleConsole()
|
||||
void HandleAjaxConsoleRefresh()
|
||||
{
|
||||
if (HttpUser()) { return; }
|
||||
char svalue[INPUT_BUFFER_SIZE]; // big to serve Backlog
|
||||
char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog
|
||||
byte cflg = 1;
|
||||
byte counter = 0; // Initial start, should never be 0 again
|
||||
|
||||
|
@ -280,10 +280,9 @@ void MqttPublishPowerState(byte device)
|
||||
char stopic[TOPSZ];
|
||||
char scommand[33];
|
||||
|
||||
if ((device < 1) || (device > devices_present)) {
|
||||
device = 1;
|
||||
}
|
||||
GetPowerDevice(scommand, device, sizeof(scommand));
|
||||
if ((device < 1) || (device > devices_present)) { device = 1; }
|
||||
GetPowerDevice(scommand, device, sizeof(scommand), Settings.flag.device_index_enable);
|
||||
|
||||
GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, scommand, GetStateText(bitRead(power, device -1)));
|
||||
MqttPublish(stopic);
|
||||
@ -301,7 +300,7 @@ void MqttPublishPowerBlinkState(byte device)
|
||||
device = 1;
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"" D_JSON_BLINK " %s\"}"),
|
||||
GetPowerDevice(scommand, device, sizeof(scommand)), GetStateText(bitRead(blink_mask, device -1)));
|
||||
GetPowerDevice(scommand, device, sizeof(scommand), Settings.flag.device_index_enable), GetStateText(bitRead(blink_mask, device -1)));
|
||||
|
||||
MqttPublishPrefixTopic_P(RESULT_OR_STAT, S_RSLT_POWER);
|
||||
}
|
||||
@ -541,7 +540,10 @@ bool MqttCommand()
|
||||
char *dataBuf = XdrvMailbox.data;
|
||||
|
||||
int command_code = GetCommandCode(command, sizeof(command), type, kMqttCommands);
|
||||
if (CMND_MQTTHOST == command_code) {
|
||||
if (-1 == command_code) {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
else if (CMND_MQTTHOST == command_code) {
|
||||
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_host))) {
|
||||
strlcpy(Settings.mqtt_host, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host));
|
||||
restart_flag = 2;
|
||||
@ -720,7 +722,7 @@ bool MqttCommand()
|
||||
if ((payload >= 0) && (payload <= 1)) {
|
||||
if (!payload) {
|
||||
for(i = 1; i <= devices_present; i++) { // Clear MQTT retain in broker
|
||||
GetTopic_P(stemp1, STAT, mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand)));
|
||||
GetTopic_P(stemp1, STAT, mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand), Settings.flag.device_index_enable));
|
||||
mqtt_data[0] = '\0';
|
||||
MqttPublish(stemp1, Settings.flag.mqtt_power_retain);
|
||||
}
|
||||
@ -740,7 +742,8 @@ bool MqttCommand()
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_sensor_retain));
|
||||
}
|
||||
else serviced = false;
|
||||
else serviced = false; // Unknown command
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
|
@ -545,7 +545,7 @@ void LightState(uint8_t append)
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
|
||||
}
|
||||
GetPowerDevice(scommand, light_device, sizeof(scommand));
|
||||
GetPowerDevice(scommand, light_device, sizeof(scommand), Settings.flag.device_index_enable);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d"),
|
||||
mqtt_data, scommand, GetStateText(light_power), Settings.light_dimmer);
|
||||
if (light_subtype > LST_SINGLE) {
|
||||
@ -1034,7 +1034,10 @@ boolean LightCommand()
|
||||
char option = (1 == XdrvMailbox.data_len) ? XdrvMailbox.data[0] : '\0';
|
||||
|
||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kLightCommands);
|
||||
if ((CMND_COLOR == command_code) && (light_subtype > LST_SINGLE) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) {
|
||||
if (-1 == command_code) {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
else if ((CMND_COLOR == command_code) && (light_subtype > LST_SINGLE) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
valid_entry = LightColorEntry(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||
if (valid_entry) {
|
||||
@ -1272,9 +1275,11 @@ boolean LightCommand()
|
||||
else {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
|
||||
if (coldim) {
|
||||
LightPreparePower();
|
||||
}
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
|
@ -384,6 +384,7 @@ boolean IrSendCommand()
|
||||
}
|
||||
#endif // USE_IR_HVAC
|
||||
else serviced = false; // Unknown command
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
|
@ -408,6 +408,8 @@ void CseEverySecond()
|
||||
*
|
||||
* Source: Victor Ferrer https://github.com/vicfergar/Sonoff-MQTT-OTA-Arduino
|
||||
* Based on: PZEM004T library https://github.com/olehs/PZEM004T
|
||||
*
|
||||
* Hardware Serial will be selected if GPIO1 = [PZEM Rx] and [GPIO3 = PZEM Tx]
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
@ -434,6 +436,8 @@ TasmotaSerial *PzemSerial;
|
||||
|
||||
#define PZEM_DEFAULT_READ_TIMEOUT 500
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
struct PZEMCommand {
|
||||
uint8_t command;
|
||||
uint8_t addr[4];
|
||||
@ -564,12 +568,6 @@ void PzemEvery200ms()
|
||||
}
|
||||
}
|
||||
|
||||
bool PzemInit()
|
||||
{
|
||||
PzemSerial = new TasmotaSerial(pin[GPIO_PZEM_RX], pin[GPIO_PZEM_TX]);
|
||||
return PzemSerial->begin();
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
#endif // USE_PZEM004T
|
||||
|
||||
@ -803,7 +801,10 @@ boolean EnergyCommand()
|
||||
unsigned long nvalue = 0;
|
||||
|
||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kEnergyCommands);
|
||||
if (CMND_POWERDELTA == command_code) {
|
||||
if (-1 == command_code) {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
else if (CMND_POWERDELTA == command_code) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 101)) {
|
||||
Settings.energy_power_delta = (1 == XdrvMailbox.payload) ? DEFAULT_POWER_DELTA : XdrvMailbox.payload;
|
||||
}
|
||||
@ -1005,16 +1006,16 @@ boolean EnergyCommand()
|
||||
unit = UNIT_HOUR;
|
||||
}
|
||||
#endif // FEATURE_POWER_LIMIT
|
||||
else {
|
||||
serviced = false;
|
||||
}
|
||||
if (!status_flag) {
|
||||
else serviced = false; // Unknown command
|
||||
|
||||
if (serviced && !status_flag) {
|
||||
if (Settings.flag.value_units) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE_SPACE_UNIT, command, nvalue, GetTextIndexed(sunit, sizeof(sunit), unit, kUnitNames));
|
||||
} else {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, nvalue);
|
||||
}
|
||||
}
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
@ -1030,7 +1031,7 @@ void EnergyDrvInit()
|
||||
serial_config = SERIAL_8E1;
|
||||
energy_flg = ENERGY_CSE7766;
|
||||
#ifdef USE_PZEM004T
|
||||
} else if ((pin[GPIO_PZEM_RX] < 99) && (pin[GPIO_PZEM_TX])) { // Any device with a Pzem004T
|
||||
} else if ((pin[GPIO_PZEM_RX] < 99) && (pin[GPIO_PZEM_TX] < 99)) { // Any device with a Pzem004T
|
||||
energy_flg = ENERGY_PZEM004T;
|
||||
#endif // USE_PZEM004T
|
||||
}
|
||||
@ -1041,8 +1042,13 @@ void EnergySnsInit()
|
||||
if (ENERGY_HLW8012 == energy_flg) HlwInit();
|
||||
|
||||
#ifdef USE_PZEM004T
|
||||
if ((ENERGY_PZEM004T == energy_flg) && !PzemInit()) { // PzemInit needs to be done here as earlier (serial) interrupts may lead to Exceptions
|
||||
energy_flg = ENERGY_NONE;
|
||||
if (ENERGY_PZEM004T == energy_flg) { // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions
|
||||
PzemSerial = new TasmotaSerial(pin[GPIO_PZEM_RX], pin[GPIO_PZEM_TX], 1);
|
||||
if (PzemSerial->begin(9600)) {
|
||||
if (PzemSerial->hardwareSerial()) { ClaimSerial(); }
|
||||
} else {
|
||||
energy_flg = ENERGY_NONE;
|
||||
}
|
||||
}
|
||||
#endif // USE_PZEM004T
|
||||
|
||||
|
@ -198,7 +198,10 @@ boolean SonoffBridgeCommand()
|
||||
boolean serviced = true;
|
||||
|
||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kSonoffBridgeCommands);
|
||||
if ((command_code >= CMND_RFSYNC) && (command_code <= CMND_RFCODE)) { // RfSync, RfLow, RfHigh, RfHost and RfCode
|
||||
if (-1 == command_code) {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
else if ((command_code >= CMND_RFSYNC) && (command_code <= CMND_RFCODE)) { // RfSync, RfLow, RfHigh, RfHost and RfCode
|
||||
char *p;
|
||||
char stemp [10];
|
||||
uint32_t code = 0;
|
||||
@ -290,7 +293,8 @@ 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 serviced = false;
|
||||
} else serviced = false; // Unknown command
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,10 @@ boolean DomoticzCommand()
|
||||
|
||||
if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_DOMOTICZ), dmtcz_len)) { // Prefix
|
||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic +dmtcz_len, kDomoticzCommands);
|
||||
if ((CMND_IDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
||||
if (-1 == command_code) {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
else if ((CMND_IDX == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) {
|
||||
if (XdrvMailbox.payload >= 0) {
|
||||
Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload;
|
||||
restart_flag = 2;
|
||||
@ -259,9 +262,10 @@ boolean DomoticzCommand()
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_DOMOTICZ "%s\":%d}"), command, Settings.domoticz_update_timer);
|
||||
}
|
||||
else serviced = false;
|
||||
else serviced = false; // Unknown command
|
||||
}
|
||||
else serviced = false;
|
||||
else serviced = false; // Unknown command
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ void HAssDiscoverRelay()
|
||||
} else {
|
||||
snprintf_P(name, sizeof(name), Settings.friendlyname[i -1]);
|
||||
}
|
||||
GetPowerDevice(value_template, i, sizeof(value_template));
|
||||
GetPowerDevice(value_template, i, sizeof(value_template), Settings.flag.device_index_enable);
|
||||
GetTopic_P(command_topic, CMND, mqtt_topic, value_template);
|
||||
GetTopic_P(state_topic, STAT, mqtt_topic, S_RSLT_RESULT);
|
||||
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
||||
@ -171,7 +171,7 @@ void HAssDiscoverButton()
|
||||
} else {
|
||||
snprintf_P(name, sizeof(name), PSTR("%s BTN"), Settings.friendlyname[button_index]);
|
||||
}
|
||||
GetPowerDevice(value_template, button_index+1, sizeof(value_template));
|
||||
GetPowerDevice(value_template, button_index+1, sizeof(value_template), Settings.flag.device_index_enable);
|
||||
GetTopic_P(state_topic, CMND, key_topic, value_template); // State of button is sent as CMND TOGGLE
|
||||
GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_BUTTON, name, state_topic, Settings.state_text[2], availability_topic);
|
||||
|
@ -89,7 +89,10 @@ boolean SerialBridgeCommand()
|
||||
boolean serviced = true;
|
||||
|
||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kSerialBridgeCommands);
|
||||
if ((CMND_SSERIALSEND == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
|
||||
if (-1 == command_code) {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
else if ((CMND_SSERIALSEND == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
if (1 == XdrvMailbox.index) {
|
||||
SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||
@ -114,9 +117,8 @@ boolean SerialBridgeCommand()
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, Settings.sbaudrate * 1200);
|
||||
}
|
||||
else {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
else serviced = false; // Unknown command
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
||||
|
@ -302,6 +302,7 @@ void TimerEverySecond()
|
||||
void PrepShowTimer(uint8_t index)
|
||||
{
|
||||
char days[8] = { 0 };
|
||||
char sign[2] = { 0 };
|
||||
char soutput[80];
|
||||
|
||||
Timer xtimer = Settings.timer[index -1];
|
||||
@ -318,10 +319,13 @@ void PrepShowTimer(uint8_t index)
|
||||
#ifdef USE_SUNRISE
|
||||
int16_t hour = xtimer.time / 60;
|
||||
if ((1 == xtimer.mode) || (2 == xtimer.mode)) { // Sunrise or Sunset
|
||||
if (hour > 11) { hour = (hour -12) * -1; }
|
||||
if (hour > 11) {
|
||||
hour -= 12;
|
||||
sign[0] = '-';
|
||||
}
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_TIMER "%d\":{\"" D_JSON_TIMER_ARM "\":%d,\"" D_JSON_TIMER_MODE "\":%d,\"" D_JSON_TIMER_TIME "\":\"%02d:%02d\",\"" D_JSON_TIMER_WINDOW "\":%d,\"" D_JSON_TIMER_DAYS "\":\"%s\",\"" D_JSON_TIMER_REPEAT "\":%d%s,\"" D_JSON_TIMER_ACTION "\":%d}"),
|
||||
mqtt_data, index, xtimer.arm, xtimer.mode, hour, xtimer.time % 60, xtimer.window, days, xtimer.repeat, soutput, xtimer.power);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_TIMER "%d\":{\"" D_JSON_TIMER_ARM "\":%d,\"" D_JSON_TIMER_MODE "\":%d,\"" D_JSON_TIMER_TIME "\":\"%s%02d:%02d\",\"" D_JSON_TIMER_WINDOW "\":%d,\"" D_JSON_TIMER_DAYS "\":\"%s\",\"" D_JSON_TIMER_REPEAT "\":%d%s,\"" D_JSON_TIMER_ACTION "\":%d}"),
|
||||
mqtt_data, index, xtimer.arm, xtimer.mode, sign, hour, xtimer.time % 60, xtimer.window, days, xtimer.repeat, soutput, xtimer.power);
|
||||
#else
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_TIMER "%d\":{\"" D_JSON_TIMER_ARM "\":%d,\"" D_JSON_TIMER_TIME "\":\"%02d:%02d\",\"" D_JSON_TIMER_WINDOW "\":%d,\"" D_JSON_TIMER_DAYS "\":\"%s\",\"" D_JSON_TIMER_REPEAT "\":%d%s,\"" D_JSON_TIMER_ACTION "\":%d}"),
|
||||
mqtt_data, index, xtimer.arm, xtimer.time / 60, xtimer.time % 60, xtimer.window, days, xtimer.repeat, soutput, xtimer.power);
|
||||
@ -341,7 +345,10 @@ boolean TimerCommand()
|
||||
|
||||
UpperCase(dataBufUc, XdrvMailbox.data);
|
||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kTimerCommands);
|
||||
if ((CMND_TIMER == command_code) && (index > 0) && (index <= MAX_TIMERS)) {
|
||||
if (-1 == command_code) {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
else if ((CMND_TIMER == command_code) && (index > 0) && (index <= MAX_TIMERS)) {
|
||||
uint8_t error = 0;
|
||||
if (XdrvMailbox.data_len) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= MAX_TIMERS)) {
|
||||
@ -374,13 +381,18 @@ boolean TimerCommand()
|
||||
if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_TIME))].success()) {
|
||||
uint16_t itime = 0;
|
||||
int8_t value = 0;
|
||||
uint8_t sign = 0;
|
||||
char time_str[10];
|
||||
|
||||
snprintf(time_str, sizeof(time_str), root[parm_uc]);
|
||||
const char *substr = strtok(time_str, ":");
|
||||
if (substr != NULL) {
|
||||
if (strchr(substr, '-')) {
|
||||
sign = 1;
|
||||
substr++;
|
||||
}
|
||||
value = atoi(substr);
|
||||
if (value < 0) { value = abs(value) +12; } // Allow entering timer offset from -11:59 to -00:01 converted to 12:01 to 23:59
|
||||
if (sign) { value += 12; } // Allow entering timer offset from -11:59 to -00:01 converted to 12:01 to 23:59
|
||||
if (value > 23) { value = 23; }
|
||||
itime = value * 60;
|
||||
substr = strtok(NULL, ":");
|
||||
@ -401,14 +413,13 @@ boolean TimerCommand()
|
||||
// SMTWTFS = 1234567 = 0011001 = 00TW00S = --TW--S
|
||||
Settings.timer[index].days = 0;
|
||||
const char *tday = root[parm_uc];
|
||||
char ch = '.';
|
||||
|
||||
uint8_t i = 0;
|
||||
char ch = *tday++;
|
||||
while ((ch != '\0') && (i < 7)) {
|
||||
ch = *tday++;
|
||||
if (ch == '-') { ch = '0'; }
|
||||
uint8_t mask = 1 << i++;
|
||||
Settings.timer[index].days |= (ch == '0') ? 0 : mask;
|
||||
ch = *tday++;
|
||||
}
|
||||
}
|
||||
if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_REPEAT))].success()) {
|
||||
@ -419,7 +430,7 @@ boolean TimerCommand()
|
||||
Settings.timer[index].device = (device < devices_present) ? device : 0;
|
||||
}
|
||||
if (root[UpperCase_P(parm_uc, PSTR(D_JSON_TIMER_ACTION))].success()) {
|
||||
uint8_t action = ((uint8_t)root[parm_uc] -1) & 0x03;
|
||||
uint8_t action = (uint8_t)root[parm_uc] & 0x03;
|
||||
Settings.timer[index].power = (devices_present) ? action : 3; // If no devices than only allow rules
|
||||
}
|
||||
|
||||
@ -476,7 +487,7 @@ boolean TimerCommand()
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, lbuff);
|
||||
}
|
||||
#endif
|
||||
else serviced = false;
|
||||
else serviced = false; // Unknown command
|
||||
|
||||
return serviced;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
* on power1#state=1 do color 001000 endon
|
||||
* on button1#state do publish cmnd/ring2/power %value% endon on button2#state do publish cmnd/strip1/power %value% endon
|
||||
* on switch1#state do power2 %value% endon
|
||||
* on analog#a0div10 do publish cmnd/ring2/dimmer %value% endon
|
||||
*
|
||||
* Notes:
|
||||
* Spaces after <on>, around <do> and before <endon> are mandatory
|
||||
@ -80,7 +81,8 @@ const char kRulesCommands[] PROGMEM = D_CMND_RULE "|" D_CMND_RULETIMER "|" D_CMN
|
||||
String rules_event_value;
|
||||
unsigned long rules_timer[MAX_RULE_TIMERS] = { 0 };
|
||||
uint8_t rules_quota = 0;
|
||||
long rules_power = -1;
|
||||
long rules_new_power = -1;
|
||||
long rules_old_power = -1;
|
||||
|
||||
uint32_t rules_triggers = 0;
|
||||
uint8_t rules_trigger_count = 0;
|
||||
@ -172,11 +174,16 @@ bool RulesRuleMatch(String &event, String &rule)
|
||||
}
|
||||
}
|
||||
|
||||
String tmp_value = "none";
|
||||
char tmp_value[CMDSZ] = { 0 };
|
||||
double rule_value = 0;
|
||||
if (pos > 0) {
|
||||
tmp_value = rule_name.substring(pos + 1); // "0.100"
|
||||
rule_value = CharToDouble((char*)tmp_value.c_str()); // 0.1 - This saves 9k code over toFLoat()!
|
||||
snprintf(tmp_value, sizeof(tmp_value), rule_name.substring(pos + 1).c_str());
|
||||
int temp_value = GetStateNumber(tmp_value);
|
||||
if (temp_value > -1) {
|
||||
rule_value = temp_value;
|
||||
} else {
|
||||
rule_value = CharToDouble((char*)tmp_value); // 0.1 - This saves 9k code over toFLoat()!
|
||||
}
|
||||
rule_name = rule_name.substring(0, pos); // "CURRENT"
|
||||
}
|
||||
|
||||
@ -188,9 +195,9 @@ bool RulesRuleMatch(String &event, String &rule)
|
||||
double value = 0;
|
||||
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.c_str(), rules_trigger_count, bitRead(rules_triggers, rules_trigger_count), event.c_str(), (str_value) ? str_value : "none");
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
//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");
|
||||
//AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
if (!root[rule_task][rule_name].success()) { return false; }
|
||||
// No value but rule_name is ok
|
||||
@ -239,6 +246,11 @@ bool RulesProcess()
|
||||
char vars[RULES_MAX_VARS][10] = { 0 };
|
||||
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);
|
||||
//AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
if (!Settings.flag.rules_enabled) { return serviced; } // Not enabled
|
||||
if (!strlen(Settings.rules)) { return serviced; } // No rules
|
||||
|
||||
@ -265,21 +277,21 @@ bool RulesProcess()
|
||||
if (plen == -1) { return serviced; } // Bad syntax - No endon
|
||||
String commands = rules.substring(pevt +4, plen); // "Backlog Dimmer 10;Color 100000"
|
||||
plen += 6;
|
||||
|
||||
// snprintf_P(log_data, sizeof(log_data), PSTR("RUL: Trigger |%s|, Commands |%s|"), event_trigger.c_str(), commands.c_str());
|
||||
// AddLog(LOG_LEVEL_DEBUG);
|
||||
|
||||
rules_event_value = "";
|
||||
String event = event_saved;
|
||||
|
||||
//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)) {
|
||||
commands.trim();
|
||||
String ucommand = commands;
|
||||
ucommand.toUpperCase();
|
||||
if (ucommand.startsWith("VAR")) {
|
||||
uint8_t idx = ucommand.charAt(3) - '1';
|
||||
// idx -= '1';
|
||||
if ((idx >= 0) && (idx < RULES_MAX_VARS)) { snprintf(vars[idx], sizeof(vars[idx]), rules_event_value.c_str()); }
|
||||
} else {
|
||||
// if (!ucommand.startsWith("BACKLOG")) { commands = "backlog " + commands; } // Always use Backlog to prevent power race condition
|
||||
commands.replace(F("%value%"), rules_event_value);
|
||||
for (byte i = 0; i < RULES_MAX_VARS; i++) {
|
||||
if (strlen(vars[i])) {
|
||||
@ -316,40 +328,33 @@ void RulesInit()
|
||||
rules_teleperiod = 0;
|
||||
}
|
||||
|
||||
void RulesSetPower()
|
||||
{
|
||||
if (Settings.flag.rules_enabled) {
|
||||
uint16_t new_power = XdrvMailbox.index;
|
||||
if (rules_power == -1) rules_power = new_power;
|
||||
uint16_t old_power = rules_power;
|
||||
rules_power = new_power;
|
||||
for (byte i = 0; i < devices_present; i++) {
|
||||
uint8_t new_state = new_power &1;
|
||||
uint8_t old_state = old_power &1;
|
||||
if (new_state != old_state) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Power%d\":{\"State\":%d}}"), i +1, new_state);
|
||||
RulesProcess();
|
||||
}
|
||||
new_power >>= 1;
|
||||
old_power >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RulesEvery50ms()
|
||||
{
|
||||
if (Settings.flag.rules_enabled) {
|
||||
rules_quota++;
|
||||
if (rules_quota &1) { // Every 100 ms
|
||||
mqtt_data[0] = '\0';
|
||||
uint16_t tele_period_save = tele_period;
|
||||
tele_period = 2; // Do not allow HA updates during next function call
|
||||
XsnsNextCall(FUNC_JSON_APPEND); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||
tele_period = tele_period_save;
|
||||
if (strlen(mqtt_data)) {
|
||||
mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
RulesProcess();
|
||||
if (rules_new_power != rules_old_power) {
|
||||
if (rules_old_power != -1) {
|
||||
for (byte i = 0; i < devices_present; i++) {
|
||||
uint8_t new_state = (rules_new_power >> i) &1;
|
||||
if (new_state != ((rules_old_power >> i) &1)) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"Power%d\":{\"State\":%d}}"), i +1, new_state);
|
||||
RulesProcess();
|
||||
}
|
||||
}
|
||||
}
|
||||
rules_old_power = rules_new_power;
|
||||
} else {
|
||||
rules_quota++;
|
||||
if (rules_quota &1) { // Every 100 ms
|
||||
mqtt_data[0] = '\0';
|
||||
uint16_t tele_period_save = tele_period;
|
||||
tele_period = 2; // Do not allow HA updates during next function call
|
||||
XsnsNextCall(FUNC_JSON_APPEND); // ,"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||
tele_period = tele_period_save;
|
||||
if (strlen(mqtt_data)) {
|
||||
mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||
RulesProcess();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -370,6 +375,11 @@ void RulesEverySecond()
|
||||
}
|
||||
}
|
||||
|
||||
void RulesSetPower()
|
||||
{
|
||||
rules_new_power = XdrvMailbox.index;
|
||||
}
|
||||
|
||||
void RulesTeleperiod()
|
||||
{
|
||||
rules_teleperiod = 1;
|
||||
@ -384,7 +394,10 @@ boolean RulesCommand()
|
||||
uint8_t index = XdrvMailbox.index;
|
||||
|
||||
int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic, kRulesCommands);
|
||||
if (CMND_RULE == command_code) {
|
||||
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))) {
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) {
|
||||
switch (XdrvMailbox.payload) {
|
||||
@ -440,7 +453,7 @@ boolean RulesCommand()
|
||||
}
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||
}
|
||||
else serviced = false;
|
||||
else serviced = false; // Unknown command
|
||||
|
||||
return serviced;
|
||||
}
|
||||
@ -459,15 +472,15 @@ boolean Xdrv10(byte function)
|
||||
case FUNC_INIT:
|
||||
RulesInit();
|
||||
break;
|
||||
case FUNC_SET_POWER:
|
||||
RulesSetPower();
|
||||
break;
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
RulesEvery50ms();
|
||||
break;
|
||||
case FUNC_EVERY_SECOND:
|
||||
RulesEverySecond();
|
||||
break;
|
||||
case FUNC_SET_POWER:
|
||||
RulesSetPower();
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
result = RulesCommand();
|
||||
break;
|
||||
|
@ -108,14 +108,14 @@ device_parameters_t device_param[] = {
|
||||
|
||||
// device parameters (information that can be sent)
|
||||
const char * device_param_ga[] = {
|
||||
D_SENSOR_RELAY " 1", // Relay 1
|
||||
D_SENSOR_RELAY " 2", // Relay 2
|
||||
D_SENSOR_RELAY " 3", // Relay 3
|
||||
D_SENSOR_RELAY " 4", // Relay 4
|
||||
D_SENSOR_RELAY " 5", // Relay 5
|
||||
D_SENSOR_RELAY " 6", // Relay 6
|
||||
D_SENSOR_RELAY " 7", // Relay 7
|
||||
D_SENSOR_RELAY " 8", // Relay 8
|
||||
D_TIMER_OUTPUT " 1", // Relay 1
|
||||
D_TIMER_OUTPUT " 2", // Relay 2
|
||||
D_TIMER_OUTPUT " 3", // Relay 3
|
||||
D_TIMER_OUTPUT " 4", // Relay 4
|
||||
D_TIMER_OUTPUT " 5", // Relay 5
|
||||
D_TIMER_OUTPUT " 6", // Relay 6
|
||||
D_TIMER_OUTPUT " 7", // Relay 7
|
||||
D_TIMER_OUTPUT " 8", // Relay 8
|
||||
D_SENSOR_BUTTON " 1", // Button 1
|
||||
D_SENSOR_BUTTON " 2", // Button 2
|
||||
D_SENSOR_BUTTON " 3", // Button 3
|
||||
@ -131,22 +131,22 @@ const char * device_param_ga[] = {
|
||||
|
||||
// device actions (posible actions to be performed on the device)
|
||||
const char *device_param_cb[] = {
|
||||
D_SENSOR_RELAY " 1", // Set Relay 1 (1-On or 0-OFF)
|
||||
D_SENSOR_RELAY " 2",
|
||||
D_SENSOR_RELAY " 3",
|
||||
D_SENSOR_RELAY " 4",
|
||||
D_SENSOR_RELAY " 5",
|
||||
D_SENSOR_RELAY " 6",
|
||||
D_SENSOR_RELAY " 7",
|
||||
D_SENSOR_RELAY " 8",
|
||||
D_SENSOR_RELAY " 1 " D_BUTTON_TOGGLE, // Relay 1 Toggle (1 or 0 will toggle)
|
||||
D_SENSOR_RELAY " 2 " D_BUTTON_TOGGLE,
|
||||
D_SENSOR_RELAY " 3 " D_BUTTON_TOGGLE,
|
||||
D_SENSOR_RELAY " 4 " D_BUTTON_TOGGLE,
|
||||
D_SENSOR_RELAY " 5 " D_BUTTON_TOGGLE,
|
||||
D_SENSOR_RELAY " 6 " D_BUTTON_TOGGLE,
|
||||
D_SENSOR_RELAY " 7 " D_BUTTON_TOGGLE,
|
||||
D_SENSOR_RELAY " 8 " D_BUTTON_TOGGLE,
|
||||
D_TIMER_OUTPUT " 1", // Set Relay 1 (1-On or 0-OFF)
|
||||
D_TIMER_OUTPUT " 2",
|
||||
D_TIMER_OUTPUT " 3",
|
||||
D_TIMER_OUTPUT " 4",
|
||||
D_TIMER_OUTPUT " 5",
|
||||
D_TIMER_OUTPUT " 6",
|
||||
D_TIMER_OUTPUT " 7",
|
||||
D_TIMER_OUTPUT " 8",
|
||||
D_TIMER_OUTPUT " 1 " D_BUTTON_TOGGLE, // Relay 1 Toggle (1 or 0 will toggle)
|
||||
D_TIMER_OUTPUT " 2 " D_BUTTON_TOGGLE,
|
||||
D_TIMER_OUTPUT " 3 " D_BUTTON_TOGGLE,
|
||||
D_TIMER_OUTPUT " 4 " D_BUTTON_TOGGLE,
|
||||
D_TIMER_OUTPUT " 5 " D_BUTTON_TOGGLE,
|
||||
D_TIMER_OUTPUT " 6 " D_BUTTON_TOGGLE,
|
||||
D_TIMER_OUTPUT " 7 " D_BUTTON_TOGGLE,
|
||||
D_TIMER_OUTPUT " 8 " D_BUTTON_TOGGLE,
|
||||
D_REPLY " " D_TEMPERATURE, // Reply Temperature
|
||||
D_REPLY " " D_HUMIDITY, // Reply Humidity
|
||||
nullptr
|
||||
@ -347,7 +347,7 @@ void KNX_DEL_CB( byte CBnum )
|
||||
|
||||
bool KNX_CONFIG_NOT_MATCH()
|
||||
{
|
||||
for (int i = 0; i < KNX_MAX_device_param; ++i)
|
||||
for (byte i = 0; i < KNX_MAX_device_param; ++i)
|
||||
{
|
||||
if ( !device_param[i].show ) { // device has this parameter ?
|
||||
// if not, search for all registered group address to this parameter for deletion
|
||||
@ -355,7 +355,7 @@ bool KNX_CONFIG_NOT_MATCH()
|
||||
if ( (i < 8) || (i > 15) ) // check relays and sensors (i from 8 to 16 are toggle relays parameters)
|
||||
{
|
||||
if ( KNX_CB_Search(i+1) != KNX_Empty ) { return true; }
|
||||
if ( KNX_CB_Search(i+8) != KNX_Empty ) { return true; }
|
||||
if ( KNX_CB_Search(i+9) != KNX_Empty ) { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -384,13 +384,17 @@ void KNX_INIT()
|
||||
// Read Configuration
|
||||
// Check which relays, buttons and sensors where configured for this device
|
||||
// and activate options according to the hardware
|
||||
for (int i = GPIO_REL1; i < GPIO_REL8 + 1; ++i)
|
||||
/*for (int i = GPIO_REL1; i < GPIO_REL8 + 1; ++i)
|
||||
{
|
||||
if (GetUsedInModule(i, my_module.gp.io)) { device_param[i - GPIO_REL1].show = true; }
|
||||
}
|
||||
for (int i = GPIO_REL1_INV; i < GPIO_REL8_INV + 1; ++i)
|
||||
{
|
||||
if (GetUsedInModule(i, my_module.gp.io)) { device_param[i - GPIO_REL1_INV].show = true; }
|
||||
}*/
|
||||
for (int i = 0; i < devices_present; ++i)
|
||||
{
|
||||
device_param[i].show = true;
|
||||
}
|
||||
for (int i = GPIO_SWT1; i < GPIO_SWT4 + 1; ++i)
|
||||
{
|
||||
@ -520,7 +524,7 @@ void KnxSendButtonPower(byte key, byte device, byte state)
|
||||
knx.write_1bit(KNX_addr, !(state == 0));
|
||||
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_KNX "%s = %d " D_SENT_TO " %d.%d.%d"),
|
||||
device_param_ga[device + 8], !(state == 0),
|
||||
device_param_ga[device + 7], !(state == 0),
|
||||
KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member);
|
||||
AddLog(LOG_LEVEL_INFO);
|
||||
|
||||
@ -642,8 +646,9 @@ void HandleKNXConfiguration()
|
||||
stmp = WebServer->arg("GA_FDEF");
|
||||
byte GA_FDEF = stmp.toInt();
|
||||
|
||||
KNX_ADD_GA( GAop, GA_FNUM, GA_AREA, GA_FDEF );
|
||||
|
||||
if (GAop) {
|
||||
KNX_ADD_GA( GAop, GA_FNUM, GA_AREA, GA_FDEF );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -657,8 +662,9 @@ void HandleKNXConfiguration()
|
||||
stmp = WebServer->arg("CB_FDEF");
|
||||
byte CB_FDEF = stmp.toInt();
|
||||
|
||||
KNX_ADD_CB( CBop, CB_FNUM, CB_AREA, CB_FDEF );
|
||||
|
||||
if (CBop) {
|
||||
KNX_ADD_CB( CBop, CB_FNUM, CB_AREA, CB_FDEF );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( WebServer->hasArg("btn_del_ga") )
|
||||
@ -732,6 +738,7 @@ void HandleKNXConfiguration()
|
||||
page.replace(F("GAfdef"), String(KNX_addr.ga.member));
|
||||
}
|
||||
}
|
||||
|
||||
page += FPSTR(HTTP_FORM_KNX3);
|
||||
page += FPSTR(HTTP_FORM_KNX_GA);
|
||||
page.replace(F("GAfnum"), F("CB_FNUM"));
|
||||
@ -765,6 +772,7 @@ void HandleKNXConfiguration()
|
||||
page.replace(F("btndis"), F("disabled"));
|
||||
}
|
||||
page.replace(F("fncbtnadd"), F("CBwarning"));
|
||||
|
||||
for (byte i = 0; i < Settings.knx_CB_registered ; ++i)
|
||||
{
|
||||
if ( Settings.knx_CB_param[i] )
|
||||
@ -812,7 +820,6 @@ void KNX_Save_Settings()
|
||||
{
|
||||
String stmp;
|
||||
address_t KNX_addr;
|
||||
byte i;
|
||||
|
||||
Settings.flag.knx_enabled = WebServer->hasArg("b1");
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_KNX D_ENABLED ": %d "),
|
||||
@ -834,7 +841,7 @@ void KNX_Save_Settings()
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_KNX "GA: %d"),
|
||||
Settings.knx_GA_registered );
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
for (i = 0; i < Settings.knx_GA_registered ; ++i)
|
||||
for (byte i = 0; i < Settings.knx_GA_registered ; ++i)
|
||||
{
|
||||
KNX_addr.value = Settings.knx_GA_addr[i];
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_KNX "GA #%d: %s " D_TO " %d/%d/%d"),
|
||||
@ -846,7 +853,7 @@ void KNX_Save_Settings()
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_KNX "CB: %d"),
|
||||
Settings.knx_CB_registered );
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
for (i = 0; i < Settings.knx_CB_registered ; ++i)
|
||||
for (byte i = 0; i < Settings.knx_CB_registered ; ++i)
|
||||
{
|
||||
KNX_addr.value = Settings.knx_CB_addr[i];
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_KNX "CB #%d: %d/%d/%d " D_TO " %s"),
|
||||
|
@ -24,7 +24,9 @@
|
||||
/*********************************************************************************************\
|
||||
* MH-Z19 - CO2 sensor
|
||||
*
|
||||
* Adapted from EspEasy plugin P049 by Dmitry (rel22 ___ inbox.ru)
|
||||
* Adapted from EspEasy plugin P049 by Dmitry (rel22 ___ inbox.ru)
|
||||
*
|
||||
* Hardware Serial will be selected if GPIO1 = [MHZ Rx] and GPIO3 = [MHZ Tx]
|
||||
**********************************************************************************************
|
||||
* Filter usage
|
||||
*
|
||||
@ -64,17 +66,20 @@ enum MhzFilterOptions {MHZ19_FILTER_OFF, MHZ19_FILTER_OFF_ALLSAMPLES, MHZ19_FILT
|
||||
#define CO2_HIGH 1200 // Above this CO2 value show red light
|
||||
#endif
|
||||
|
||||
#define MHZ19_READ_TIMEOUT 500 // Must be way less than 1000
|
||||
#define MHZ19_READ_TIMEOUT 400 // Must be way less than 1000 but enough to read 9 bytes at 9600 bps
|
||||
#define MHZ19_RETRY_COUNT 8
|
||||
|
||||
TasmotaSerial *MhzSerial;
|
||||
|
||||
const char kMhzTypes[] PROGMEM = "MHZ19|MHZ19B";
|
||||
|
||||
const uint8_t mhz_cmnd_read_ppm[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
|
||||
const uint8_t mhz_cmnd_abc_enable[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6};
|
||||
const uint8_t mhz_cmnd_abc_disable[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86};
|
||||
const uint8_t mhz_cmnd_zeropoint[9] = {0xff, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78};
|
||||
enum MhzCommands { MHZ_CMND_READPPM, MHZ_CMND_ABCENABLE, MHZ_CMND_ABCDISABLE, MHZ_CMND_ZEROPOINT, MHZ_CMND_RESET };
|
||||
const uint8_t kMhzCommands[][2] PROGMEM = {
|
||||
{0x86,0x00}, // mhz_cmnd_read_ppm
|
||||
{0x79,0xA0}, // mhz_cmnd_abc_enable
|
||||
{0x79,0x00}, // mhz_cmnd_abc_disable
|
||||
{0x87,0x00}, // mhz_cmnd_zeropoint
|
||||
{0x8D,0x00}}; // mhz_cmnd_reset
|
||||
|
||||
uint8_t mhz_type = 1;
|
||||
uint16_t mhz_last_ppm = 0;
|
||||
@ -84,13 +89,42 @@ bool mhz_abc_must_apply = false;
|
||||
char mhz_types[7];
|
||||
|
||||
float mhz_temperature = 0;
|
||||
uint8_t mhz_timer = 0;
|
||||
uint8_t mhz_retry = MHZ19_RETRY_COUNT;
|
||||
|
||||
uint8_t mhz_received = 0;
|
||||
uint8_t mhz_state = 0;
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
byte MhzCalculateChecksum(byte *array)
|
||||
{
|
||||
byte checksum = 0;
|
||||
for (byte i = 1; i < 8; i++) {
|
||||
checksum += array[i];
|
||||
}
|
||||
checksum = 255 - checksum;
|
||||
return (checksum +1);
|
||||
}
|
||||
|
||||
size_t MhzSendCmd(byte command_id)
|
||||
{
|
||||
uint8_t mhz_send[9] = { 0 };
|
||||
|
||||
mhz_send[0] = 0xFF; // Start byte, fixed
|
||||
mhz_send[1] = 0x01; // Sensor number, 0x01 by default
|
||||
memcpy_P(&mhz_send[2], kMhzCommands[command_id], sizeof(kMhzCommands[0]));
|
||||
/*
|
||||
mhz_send[4] = 0x00;
|
||||
mhz_send[5] = 0x00;
|
||||
mhz_send[6] = 0x00;
|
||||
mhz_send[7] = 0x00;
|
||||
*/
|
||||
mhz_send[8] = MhzCalculateChecksum(mhz_send);
|
||||
|
||||
return MhzSerial->write(mhz_send, sizeof(mhz_send));
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
bool MhzCheckAndApplyFilter(uint16_t ppm, uint8_t s)
|
||||
{
|
||||
if (1 == s) {
|
||||
@ -126,89 +160,84 @@ bool MhzCheckAndApplyFilter(uint16_t ppm, uint8_t s)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mhz50ms()
|
||||
void MhzEverySecond()
|
||||
{
|
||||
mhz_state++;
|
||||
if (4 == mhz_state) { // Every 200 mSec
|
||||
if (8 == mhz_state) { // Every 8 sec start a MH-Z19 measuring cycle (which takes 1005 +5% ms)
|
||||
mhz_state = 0;
|
||||
|
||||
uint8_t mhz_response[9];
|
||||
|
||||
mhz_timer++;
|
||||
if (6 == mhz_timer) { // MH-Z19 measuring cycle takes 1005 +5% ms
|
||||
mhz_timer = 0;
|
||||
|
||||
MhzSerial->flush();
|
||||
MhzSerial->write(mhz_cmnd_read_ppm, 9);
|
||||
if (mhz_retry) {
|
||||
mhz_retry--;
|
||||
if (!mhz_retry) {
|
||||
mhz_last_ppm = 0;
|
||||
mhz_temperature = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 == mhz_timer) {
|
||||
if (mhz_retry) {
|
||||
mhz_retry--;
|
||||
if (!mhz_retry) {
|
||||
mhz_last_ppm = 0;
|
||||
mhz_temperature = 0;
|
||||
}
|
||||
}
|
||||
MhzSerial->flush(); // Sync reception
|
||||
MhzSendCmd(MHZ_CMND_READPPM);
|
||||
mhz_received = 0;
|
||||
}
|
||||
|
||||
unsigned long start = millis();
|
||||
uint8_t counter = 0;
|
||||
while (((millis() - start) < MHZ19_READ_TIMEOUT) && (counter < 9)) {
|
||||
if (MhzSerial->available() > 0) {
|
||||
mhz_response[counter++] = MhzSerial->read();
|
||||
}
|
||||
}
|
||||
if ((mhz_state > 2) && !mhz_received) { // Start reading response after 3 seconds every second until received
|
||||
uint8_t mhz_response[9];
|
||||
|
||||
AddLogSerial(LOG_LEVEL_DEBUG_MORE, mhz_response, counter);
|
||||
|
||||
if (counter < 9) {
|
||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 comms timeout"));
|
||||
return;
|
||||
}
|
||||
|
||||
byte crc = 0;
|
||||
for (uint8_t i = 1; i < 8; i++) {
|
||||
crc += mhz_response[i];
|
||||
}
|
||||
crc = 255 - crc;
|
||||
crc++;
|
||||
if (mhz_response[8] != crc) {
|
||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 crc error"));
|
||||
return;
|
||||
}
|
||||
if (0xFF != mhz_response[0] || 0x86 != mhz_response[1]) {
|
||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 bad response"));
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t u = (mhz_response[6] << 8) | mhz_response[7];
|
||||
if (15000 == u) { // During (and only ever at) sensor boot, 'u' is reported as 15000
|
||||
if (!mhz_abc_enable) {
|
||||
// After bootup of the sensor the ABC will be enabled.
|
||||
// Thus only actively disable after bootup.
|
||||
mhz_abc_must_apply = true;
|
||||
}
|
||||
unsigned long start = millis();
|
||||
uint8_t counter = 0;
|
||||
while (((millis() - start) < MHZ19_READ_TIMEOUT) && (counter < 9)) {
|
||||
if (MhzSerial->available() > 0) {
|
||||
mhz_response[counter++] = MhzSerial->read();
|
||||
} else {
|
||||
uint16_t ppm = (mhz_response[2] << 8) | mhz_response[3];
|
||||
mhz_temperature = ConvertTemp((float)mhz_response[4] - 40);
|
||||
uint8_t s = mhz_response[5];
|
||||
mhz_type = (s) ? 1 : 2;
|
||||
if (MhzCheckAndApplyFilter(ppm, s)) {
|
||||
mhz_retry = MHZ19_RETRY_COUNT;
|
||||
LightSetSignal(CO2_LOW, CO2_HIGH, mhz_last_ppm);
|
||||
delay(5);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == s || 64 == s) { // Reading is stable.
|
||||
if (mhz_abc_must_apply) {
|
||||
mhz_abc_must_apply = false;
|
||||
if (mhz_abc_enable) {
|
||||
MhzSerial->write(mhz_cmnd_abc_enable, 9); // Sent sensor ABC Enable
|
||||
} else {
|
||||
MhzSerial->write(mhz_cmnd_abc_disable, 9); // Sent sensor ABC Disable
|
||||
}
|
||||
AddLogSerial(LOG_LEVEL_DEBUG_MORE, mhz_response, counter);
|
||||
|
||||
if (counter < 9) {
|
||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 comms timeout"));
|
||||
return;
|
||||
}
|
||||
|
||||
byte crc = MhzCalculateChecksum(mhz_response);
|
||||
if (mhz_response[8] != crc) {
|
||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 crc error"));
|
||||
return;
|
||||
}
|
||||
if (0xFF != mhz_response[0] || 0x86 != mhz_response[1]) {
|
||||
// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 bad response"));
|
||||
return;
|
||||
}
|
||||
|
||||
mhz_received = 1;
|
||||
|
||||
uint16_t u = (mhz_response[6] << 8) | mhz_response[7];
|
||||
if (15000 == u) { // During (and only ever at) sensor boot, 'u' is reported as 15000
|
||||
if (!mhz_abc_enable) {
|
||||
// After bootup of the sensor the ABC will be enabled.
|
||||
// Thus only actively disable after bootup.
|
||||
mhz_abc_must_apply = true;
|
||||
}
|
||||
} else {
|
||||
uint16_t ppm = (mhz_response[2] << 8) | mhz_response[3];
|
||||
mhz_temperature = ConvertTemp((float)mhz_response[4] - 40);
|
||||
uint8_t s = mhz_response[5];
|
||||
mhz_type = (s) ? 1 : 2;
|
||||
if (MhzCheckAndApplyFilter(ppm, s)) {
|
||||
mhz_retry = MHZ19_RETRY_COUNT;
|
||||
LightSetSignal(CO2_LOW, CO2_HIGH, mhz_last_ppm);
|
||||
|
||||
if (0 == s || 64 == s) { // Reading is stable.
|
||||
if (mhz_abc_must_apply) {
|
||||
mhz_abc_must_apply = false;
|
||||
if (mhz_abc_enable) {
|
||||
MhzSendCmd(MHZ_CMND_ABCENABLE);
|
||||
} else {
|
||||
MhzSendCmd(MHZ_CMND_ABCDISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,6 +254,8 @@ void Mhz50ms()
|
||||
2 - Manual start = ABC Off
|
||||
|
||||
3 - Optional filter settings
|
||||
|
||||
9 - Reset
|
||||
*/
|
||||
|
||||
bool MhzCommandSensor()
|
||||
@ -233,9 +264,13 @@ bool MhzCommandSensor()
|
||||
|
||||
switch (XdrvMailbox.payload) {
|
||||
case 2:
|
||||
MhzSerial->write(mhz_cmnd_zeropoint, 9);
|
||||
MhzSendCmd(MHZ_CMND_ZEROPOINT);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_ZERO_POINT_CALIBRATION);
|
||||
break;
|
||||
case 9:
|
||||
MhzSendCmd(MHZ_CMND_RESET);
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RESET);
|
||||
break;
|
||||
default:
|
||||
serviced = false;
|
||||
}
|
||||
@ -249,10 +284,12 @@ void MhzInit()
|
||||
{
|
||||
mhz_type = 0;
|
||||
if ((pin[GPIO_MHZ_RXD] < 99) && (pin[GPIO_MHZ_TXD] < 99)) {
|
||||
MhzSerial = new TasmotaSerial(pin[GPIO_MHZ_RXD], pin[GPIO_MHZ_TXD]);
|
||||
if (MhzSerial->begin()) {
|
||||
MhzSerial = new TasmotaSerial(pin[GPIO_MHZ_RXD], pin[GPIO_MHZ_TXD], 1);
|
||||
if (MhzSerial->begin(9600)) {
|
||||
if (MhzSerial->hardwareSerial()) { ClaimSerial(); }
|
||||
mhz_type = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,8 +325,8 @@ boolean Xsns15(byte function)
|
||||
case FUNC_INIT:
|
||||
MhzInit();
|
||||
break;
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
Mhz50ms();
|
||||
case FUNC_EVERY_SECOND:
|
||||
MhzEverySecond();
|
||||
break;
|
||||
case FUNC_COMMAND:
|
||||
if (XSNS_15 == XdrvMailbox.index) {
|
||||
|
@ -22,9 +22,9 @@
|
||||
/*********************************************************************************************\
|
||||
* TSL2561 - Light Intensity
|
||||
*
|
||||
* I2C Addresses: 0x29 (low), 0x39 (float) or 0x49 (high)
|
||||
*
|
||||
* Using library https://github.com/joba-1/Joba_Tsl2561
|
||||
*
|
||||
* I2C Addresses: 0x29 (low), 0x39 (float) or 0x49 (high)
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <Tsl2561Util.h>
|
||||
@ -112,5 +112,5 @@ boolean Xsns16(byte function)
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_TSL2561_JOBA
|
||||
#endif // USE_TSL2561
|
||||
#endif // USE_I2C
|
||||
|
@ -22,6 +22,8 @@
|
||||
* SenseAir K30, K70 and S8 - CO2 sensor
|
||||
*
|
||||
* Adapted from EspEasy plugin P052 by Mikael Trieb (mikael__AT__triebconsulting.se)
|
||||
*
|
||||
* Hardware Serial will be selected if GPIO1 = [SAir Rx] and GPIO3 = [SAir Tx]
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
@ -191,8 +193,9 @@ void SenseairInit()
|
||||
{
|
||||
senseair_type = 0;
|
||||
if ((pin[GPIO_SAIR_RX] < 99) && (pin[GPIO_SAIR_TX] < 99)) {
|
||||
SensairSerial = new TasmotaSerial(pin[GPIO_SAIR_RX], pin[GPIO_SAIR_TX]);
|
||||
if (SensairSerial->begin()) {
|
||||
SensairSerial = new TasmotaSerial(pin[GPIO_SAIR_RX], pin[GPIO_SAIR_TX], 1);
|
||||
if (SensairSerial->begin(9600)) {
|
||||
if (SensairSerial->hardwareSerial()) { ClaimSerial(); }
|
||||
senseair_type = 1;
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
/*********************************************************************************************\
|
||||
* PlanTower PMS5003 and PMS7003 particle concentration sensor
|
||||
* For background information see http://aqicn.org/sensor/pms5003-7003/
|
||||
*
|
||||
* Hardware Serial will be selected if GPIO3 = [PMS5003]
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
@ -39,6 +41,8 @@ struct pms5003data {
|
||||
uint16_t checksum;
|
||||
} pms_data;
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
boolean PmsReadData()
|
||||
{
|
||||
if (! PmsSerial->available()) {
|
||||
@ -97,10 +101,10 @@ void PmsSecond() // Every second
|
||||
void PmsInit()
|
||||
{
|
||||
pms_type = 0;
|
||||
|
||||
if (pin[GPIO_PMS5003] < 99) {
|
||||
PmsSerial = new TasmotaSerial(pin[GPIO_PMS5003], -1);
|
||||
if (PmsSerial->begin()) {
|
||||
PmsSerial = new TasmotaSerial(pin[GPIO_PMS5003], -1, 1);
|
||||
if (PmsSerial->begin(9600)) {
|
||||
if (PmsSerial->hardwareSerial()) { ClaimSerial(); }
|
||||
pms_type = 1;
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
/*********************************************************************************************\
|
||||
* Nova Fitness SDS011 (and possibly SDS021) particle concentration sensor
|
||||
* For background information see http://aqicn.org/sensor/sds011/
|
||||
*
|
||||
* Hardware Serial will be selected if GPIO3 = [SDS0X01]
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
@ -81,10 +83,10 @@ void NovaSdsSecond() // Every second
|
||||
void NovaSdsInit()
|
||||
{
|
||||
novasds_type = 0;
|
||||
|
||||
if (pin[GPIO_SDS0X1] < 99) {
|
||||
NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1], -1);
|
||||
if (NovaSdsSerial->begin()) {
|
||||
NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1], -1, 1);
|
||||
if (NovaSdsSerial->begin(9600)) {
|
||||
if (NovaSdsSerial->hardwareSerial()) { ClaimSerial(); }
|
||||
novasds_type = 1;
|
||||
}
|
||||
}
|
||||
|
300
sonoff/xsns_23_sdm120.ino
Normal file
300
sonoff/xsns_23_sdm120.ino
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
xsns_23_sdm120.ino - Eastron SDM120-Modbus energy meter support for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Gennaro Tortone
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_SDM120
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Eastron SDM120-Modbus energy meter
|
||||
*
|
||||
* Based on: https://github.com/reaper7/SDM_Energy_Meter
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
TasmotaSerial *SDM120Serial;
|
||||
|
||||
uint8_t sdm120_type = 1;
|
||||
uint8_t sdm120_state = 0;
|
||||
|
||||
float sdm120_voltage = 0;
|
||||
float sdm120_current = 0;
|
||||
float sdm120_active_power = 0;
|
||||
float sdm120_apparent_power = 0;
|
||||
float sdm120_reactive_power = 0;
|
||||
float sdm120_power_factor = 0;
|
||||
float sdm120_frequency = 0;
|
||||
float sdm120_energy_total = 0;
|
||||
|
||||
bool SDM120_ModbusReceiveReady()
|
||||
{
|
||||
return (SDM120Serial->available() > 1);
|
||||
}
|
||||
|
||||
void SDM120_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t register_count)
|
||||
{
|
||||
uint8_t frame[8];
|
||||
|
||||
frame[0] = 0x01; // default SDM120 Modbus address
|
||||
frame[1] = function_code;
|
||||
frame[2] = (uint8_t)(start_address >> 8);
|
||||
frame[3] = (uint8_t)(start_address);
|
||||
frame[4] = (uint8_t)(register_count >> 8);
|
||||
frame[5] = (uint8_t)(register_count);
|
||||
|
||||
uint16_t crc = SDM120_calculateCRC(frame, 6); // calculate out crc only from first 6 bytes
|
||||
frame[6] = lowByte(crc);
|
||||
frame[7] = highByte(crc);
|
||||
|
||||
while (SDM120Serial->available() > 0) { // read serial if any old data is available
|
||||
SDM120Serial->read();
|
||||
}
|
||||
|
||||
SDM120Serial->flush();
|
||||
SDM120Serial->write(frame, sizeof(frame));
|
||||
}
|
||||
|
||||
uint8_t SDM120_ModbusReceive(float *value)
|
||||
{
|
||||
uint8_t buffer[9];
|
||||
|
||||
*value = NAN;
|
||||
uint8_t len = 0;
|
||||
while (SDM120Serial->available() > 0) {
|
||||
buffer[len++] = (uint8_t)SDM120Serial->read();
|
||||
}
|
||||
|
||||
if (len < 9)
|
||||
return 3; // SDM_ERR_NOT_ENOUGHT_BYTES
|
||||
|
||||
if (len == 9) {
|
||||
|
||||
if (buffer[0] == 0x01 && buffer[1] == 0x04 && buffer[2] == 4) { // check node number, op code and reply bytes count
|
||||
|
||||
if((SDM120_calculateCRC(buffer, 7)) == ((buffer[8] << 8) | buffer[7])) { //calculate crc from first 7 bytes and compare with received crc (bytes 7 & 8)
|
||||
|
||||
((uint8_t*)value)[3] = buffer[3];
|
||||
((uint8_t*)value)[2] = buffer[4];
|
||||
((uint8_t*)value)[1] = buffer[5];
|
||||
((uint8_t*)value)[0] = buffer[6];
|
||||
|
||||
} else return 1; // SDM_ERR_CRC_ERROR
|
||||
|
||||
} else return 2; // SDM_ERR_WRONG_BYTES
|
||||
}
|
||||
|
||||
return 0; // SDM_ERR_NO_ERROR
|
||||
}
|
||||
|
||||
uint16_t SDM120_calculateCRC(uint8_t *frame, uint8_t num)
|
||||
{
|
||||
uint16_t crc, flag;
|
||||
crc = 0xFFFF;
|
||||
for (uint8_t i = 0; i < num; i++) {
|
||||
crc ^= frame[i];
|
||||
for (uint8_t j = 8; j; j--) {
|
||||
if ((crc & 0x0001) != 0) { // If the LSB is set
|
||||
crc >>= 1; // Shift right and XOR 0xA001
|
||||
crc ^= 0xA001;
|
||||
} else { // Else LSB is not set
|
||||
crc >>= 1; // Just shift right
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
const uint16_t sdm120_start_addresses[] {
|
||||
0x0000, // SDM120C_VOLTAGE [V]
|
||||
0x0006, // SDM120C_CURRENT [A]
|
||||
0x000C, // SDM120C_POWER [W]
|
||||
0x0012, // SDM120C_APPARENT_POWER [VA]
|
||||
0x0018, // SDM120C_REACTIVE_POWER [VAR]
|
||||
0x001E, // SDM120C_POWER_FACTOR
|
||||
0x0046, // SDM120C_FREQUENCY [Hz]
|
||||
0x0156 // SDM120C_TOTAL_ACTIVE_ENERGY [Wh]
|
||||
};
|
||||
|
||||
uint8_t sdm120_read_state = 0;
|
||||
uint8_t sdm120_send_retry = 0;
|
||||
|
||||
void SDM12050ms() // Every 50 mSec
|
||||
{
|
||||
sdm120_state++;
|
||||
if (6 == sdm120_state) { // Every 300 mSec
|
||||
sdm120_state = 0;
|
||||
|
||||
float value = 0;
|
||||
bool data_ready = SDM120_ModbusReceiveReady();
|
||||
|
||||
if (data_ready) {
|
||||
uint8_t error = SDM120_ModbusReceive(&value);
|
||||
if (error) {
|
||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SDM120 response error %d"), error);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
} else {
|
||||
switch(sdm120_read_state) {
|
||||
case 0:
|
||||
sdm120_voltage = value;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
sdm120_current = value;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
sdm120_active_power = value;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
sdm120_apparent_power = value;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
sdm120_reactive_power = value;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
sdm120_power_factor = value;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
sdm120_frequency = value;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
sdm120_energy_total = value;
|
||||
break;
|
||||
} // end switch
|
||||
|
||||
sdm120_read_state++;
|
||||
|
||||
if (sizeof(sdm120_start_addresses)/2 == sdm120_read_state) {
|
||||
sdm120_read_state = 0;
|
||||
}
|
||||
}
|
||||
} // end data ready
|
||||
|
||||
if (0 == sdm120_send_retry || data_ready) {
|
||||
sdm120_send_retry = 5;
|
||||
SDM120_ModbusSend(0x04, sdm120_start_addresses[sdm120_read_state], 2);
|
||||
} else {
|
||||
sdm120_send_retry--;
|
||||
}
|
||||
} // end 300 ms
|
||||
}
|
||||
|
||||
void SDM120Init()
|
||||
{
|
||||
sdm120_type = 0;
|
||||
if ((pin[GPIO_SDM120_RX] < 99) && (pin[GPIO_SDM120_TX] < 99)) {
|
||||
SDM120Serial = new TasmotaSerial(pin[GPIO_SDM120_RX], pin[GPIO_SDM120_TX], 1);
|
||||
#ifdef SDM120_SPEED
|
||||
if (SDM120Serial->begin(SDM120_SPEED)) {
|
||||
#else
|
||||
if (SDM120Serial->begin(2400)) {
|
||||
#endif
|
||||
if (SDM120Serial->hardwareSerial()) { ClaimSerial(); }
|
||||
sdm120_type = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_SNS_SDM120_DATA[] PROGMEM = "%s"
|
||||
"{s}SDM120 " D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
|
||||
"{s}SDM120 " D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
|
||||
"{s}SDM120 " D_POWERUSAGE_ACTIVE "{m}%s " D_UNIT_WATT "{e}"
|
||||
"{s}SDM120 " D_POWERUSAGE_APPARENT "{m}%s " D_UNIT_VA "{e}"
|
||||
"{s}SDM120 " D_POWERUSAGE_REACTIVE "{m}%s " D_UNIT_VAR "{e}"
|
||||
"{s}SDM120 " D_POWER_FACTOR "{m}%s{e}"
|
||||
"{s}SDM120 " D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"
|
||||
"{s}SDM120 " D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}";
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
void SDM120Show(boolean json)
|
||||
{
|
||||
char voltage[10];
|
||||
char current[10];
|
||||
char active_power[10];
|
||||
char apparent_power[10];
|
||||
char reactive_power[10];
|
||||
char power_factor[10];
|
||||
char frequency[10];
|
||||
char energy_total[10];
|
||||
|
||||
dtostrfd(sdm120_voltage, Settings.flag2.voltage_resolution, voltage);
|
||||
dtostrfd(sdm120_current, Settings.flag2.current_resolution, current);
|
||||
dtostrfd(sdm120_active_power, Settings.flag2.wattage_resolution, active_power);
|
||||
dtostrfd(sdm120_apparent_power, Settings.flag2.wattage_resolution, apparent_power);
|
||||
dtostrfd(sdm120_reactive_power, Settings.flag2.wattage_resolution, reactive_power);
|
||||
dtostrfd(sdm120_power_factor, 2, power_factor);
|
||||
dtostrfd(sdm120_frequency, 2, frequency);
|
||||
dtostrfd(sdm120_energy_total, Settings.flag2.energy_resolution, energy_total);
|
||||
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_POWERFACTOR "\":%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s}"),
|
||||
mqtt_data, energy_total, active_power, apparent_power, reactive_power, frequency, power_factor, voltage, current);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if (0 == tele_period) {
|
||||
DomoticzSensor(DZ_VOLTAGE, voltage);
|
||||
DomoticzSensor(DZ_CURRENT, current);
|
||||
DomoticzSensorPowerEnergy((uint16_t)sdm120_active_power, energy_total);
|
||||
}
|
||||
#endif // USE_DOMOTICZ
|
||||
#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
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XSNS_23
|
||||
|
||||
boolean Xsns23(byte function)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (sdm120_type) {
|
||||
switch (function) {
|
||||
case FUNC_INIT:
|
||||
SDM120Init();
|
||||
break;
|
||||
case FUNC_EVERY_50_MSECOND:
|
||||
SDM12050ms();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
SDM120Show(1);
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_APPEND:
|
||||
SDM120Show(0);
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_SDM120
|
377
sonoff/xsns_24_si1145.ino
Normal file
377
sonoff/xsns_24_si1145.ino
Normal file
@ -0,0 +1,377 @@
|
||||
/*
|
||||
xsns_24_si1145.ino - SI1145/46/47 UV Index / IR / Visible light sensor support for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2018 Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef USE_I2C
|
||||
#ifdef USE_SI1145
|
||||
/*********************************************************************************************\
|
||||
* SI1145/46/47 - UV Index / IR / Visible light
|
||||
*
|
||||
* Based on library https://github.com/SeeedDocument/Grove-Sunlight_Sensor/
|
||||
*
|
||||
* I2C Addresses: 0x60
|
||||
\*********************************************************************************************/
|
||||
|
||||
uint8_t si1145_type = 0;
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
#define SI114X_ADDR 0X60
|
||||
//
|
||||
//commands
|
||||
//
|
||||
#define SI114X_QUERY 0X80
|
||||
#define SI114X_SET 0XA0
|
||||
#define SI114X_NOP 0X00
|
||||
#define SI114X_RESET 0X01
|
||||
#define SI114X_BUSADDR 0X02
|
||||
#define SI114X_PS_FORCE 0X05
|
||||
#define SI114X_GET_CAL 0X12
|
||||
#define SI114X_ALS_FORCE 0X06
|
||||
#define SI114X_PSALS_FORCE 0X07
|
||||
#define SI114X_PS_PAUSE 0X09
|
||||
#define SI114X_ALS_PAUSE 0X0A
|
||||
#define SI114X_PSALS_PAUSE 0X0B
|
||||
#define SI114X_PS_AUTO 0X0D
|
||||
#define SI114X_ALS_AUTO 0X0E
|
||||
#define SI114X_PSALS_AUTO 0X0F
|
||||
//
|
||||
//IIC REGISTERS
|
||||
//
|
||||
#define SI114X_PART_ID 0X00
|
||||
#define SI114X_REV_ID 0X01
|
||||
#define SI114X_SEQ_ID 0X02
|
||||
#define SI114X_INT_CFG 0X03
|
||||
#define SI114X_IRQ_ENABLE 0X04
|
||||
#define SI114X_IRQ_MODE1 0x05
|
||||
#define SI114X_IRQ_MODE2 0x06
|
||||
#define SI114X_HW_KEY 0X07
|
||||
#define SI114X_MEAS_RATE0 0X08
|
||||
#define SI114X_MEAS_RATE1 0X09
|
||||
#define SI114X_PS_RATE 0X0A
|
||||
#define SI114X_PS_LED21 0X0F
|
||||
#define SI114X_PS_LED3 0X10
|
||||
#define SI114X_UCOEFF0 0X13
|
||||
#define SI114X_UCOEFF1 0X14
|
||||
#define SI114X_UCOEFF2 0X15
|
||||
#define SI114X_UCOEFF3 0X16
|
||||
#define SI114X_WR 0X17
|
||||
#define SI114X_COMMAND 0X18
|
||||
#define SI114X_RESPONSE 0X20
|
||||
#define SI114X_IRQ_STATUS 0X21
|
||||
#define SI114X_ALS_VIS_DATA0 0X22
|
||||
#define SI114X_ALS_VIS_DATA1 0X23
|
||||
#define SI114X_ALS_IR_DATA0 0X24
|
||||
#define SI114X_ALS_IR_DATA1 0X25
|
||||
#define SI114X_PS1_DATA0 0X26
|
||||
#define SI114X_PS1_DATA1 0X27
|
||||
#define SI114X_PS2_DATA0 0X28
|
||||
#define SI114X_PS2_DATA1 0X29
|
||||
#define SI114X_PS3_DATA0 0X2A
|
||||
#define SI114X_PS3_DATA1 0X2B
|
||||
#define SI114X_AUX_DATA0_UVINDEX0 0X2C
|
||||
#define SI114X_AUX_DATA1_UVINDEX1 0X2D
|
||||
#define SI114X_RD 0X2E
|
||||
#define SI114X_CHIP_STAT 0X30
|
||||
//
|
||||
//Parameters
|
||||
//
|
||||
#define SI114X_CHLIST 0X01
|
||||
#define SI114X_CHLIST_ENUV 0x80
|
||||
#define SI114X_CHLIST_ENAUX 0x40
|
||||
#define SI114X_CHLIST_ENALSIR 0x20
|
||||
#define SI114X_CHLIST_ENALSVIS 0x10
|
||||
#define SI114X_CHLIST_ENPS1 0x01
|
||||
#define SI114X_CHLIST_ENPS2 0x02
|
||||
#define SI114X_CHLIST_ENPS3 0x04
|
||||
|
||||
#define SI114X_PSLED12_SELECT 0X02
|
||||
#define SI114X_PSLED3_SELECT 0X03
|
||||
|
||||
#define SI114X_PS_ENCODE 0X05
|
||||
#define SI114X_ALS_ENCODE 0X06
|
||||
|
||||
#define SI114X_PS1_ADCMUX 0X07
|
||||
#define SI114X_PS2_ADCMUX 0X08
|
||||
#define SI114X_PS3_ADCMUX 0X09
|
||||
|
||||
#define SI114X_PS_ADC_COUNTER 0X0A
|
||||
#define SI114X_PS_ADC_GAIN 0X0B
|
||||
#define SI114X_PS_ADC_MISC 0X0C
|
||||
|
||||
#define SI114X_ALS_IR_ADC_MUX 0X0E
|
||||
#define SI114X_AUX_ADC_MUX 0X0F
|
||||
|
||||
#define SI114X_ALS_VIS_ADC_COUNTER 0X10
|
||||
#define SI114X_ALS_VIS_ADC_GAIN 0X11
|
||||
#define SI114X_ALS_VIS_ADC_MISC 0X12
|
||||
|
||||
#define SI114X_LED_REC 0X1C
|
||||
|
||||
#define SI114X_ALS_IR_ADC_COUNTER 0X1D
|
||||
#define SI114X_ALS_IR_ADC_GAIN 0X1E
|
||||
#define SI114X_ALS_IR_ADC_MISC 0X1F
|
||||
//
|
||||
//USER SETTINGS DEFINE
|
||||
//
|
||||
//ADCMUX
|
||||
#define SI114X_ADCMUX_SMALL_IR 0x00
|
||||
#define SI114X_ADCMUX_VISIABLE 0x02
|
||||
#define SI114X_ADCMUX_LARGE_IR 0x03
|
||||
#define SI114X_ADCMUX_NO 0x06
|
||||
#define SI114X_ADCMUX_GND 0x25
|
||||
#define SI114X_ADCMUX_TEMPERATURE 0x65
|
||||
#define SI114X_ADCMUX_VDD 0x75
|
||||
//LED SEL
|
||||
#define SI114X_PSLED12_SELECT_PS1_NONE 0x00
|
||||
#define SI114X_PSLED12_SELECT_PS1_LED1 0x01
|
||||
#define SI114X_PSLED12_SELECT_PS1_LED2 0x02
|
||||
#define SI114X_PSLED12_SELECT_PS1_LED3 0x04
|
||||
#define SI114X_PSLED12_SELECT_PS2_NONE 0x00
|
||||
#define SI114X_PSLED12_SELECT_PS2_LED1 0x10
|
||||
#define SI114X_PSLED12_SELECT_PS2_LED2 0x20
|
||||
#define SI114X_PSLED12_SELECT_PS2_LED3 0x40
|
||||
#define SI114X_PSLED3_SELECT_PS2_NONE 0x00
|
||||
#define SI114X_PSLED3_SELECT_PS2_LED1 0x10
|
||||
#define SI114X_PSLED3_SELECT_PS2_LED2 0x20
|
||||
#define SI114X_PSLED3_SELECT_PS2_LED3 0x40
|
||||
//ADC GAIN DIV
|
||||
#define SI114X_ADC_GAIN_DIV1 0X00
|
||||
#define SI114X_ADC_GAIN_DIV2 0X01
|
||||
#define SI114X_ADC_GAIN_DIV4 0X02
|
||||
#define SI114X_ADC_GAIN_DIV8 0X03
|
||||
#define SI114X_ADC_GAIN_DIV16 0X04
|
||||
#define SI114X_ADC_GAIN_DIV32 0X05
|
||||
//LED CURRENT
|
||||
#define SI114X_LED_CURRENT_5MA 0X01
|
||||
#define SI114X_LED_CURRENT_11MA 0X02
|
||||
#define SI114X_LED_CURRENT_22MA 0X03
|
||||
#define SI114X_LED_CURRENT_45MA 0X04
|
||||
//Recovery period the ADC takes before making a PS measurement
|
||||
#define SI114X_ADC_COUNTER_1ADCCLK 0X00
|
||||
#define SI114X_ADC_COUNTER_7ADCCLK 0X01
|
||||
#define SI114X_ADC_COUNTER_15ADCCLK 0X02
|
||||
#define SI114X_ADC_COUNTER_31ADCCLK 0X03
|
||||
#define SI114X_ADC_COUNTER_63ADCCLK 0X04
|
||||
#define SI114X_ADC_COUNTER_127ADCCLK 0X05
|
||||
#define SI114X_ADC_COUNTER_255ADCCLK 0X06
|
||||
#define SI114X_ADC_COUNTER_511ADCCLK 0X07
|
||||
//ADC MISC
|
||||
#define SI114X_ADC_MISC_LOWRANGE 0X00
|
||||
#define SI114X_ADC_MISC_HIGHRANGE 0X20
|
||||
#define SI114X_ADC_MISC_ADC_NORMALPROXIMITY 0X00
|
||||
#define SI114X_ADC_MISC_ADC_RAWADC 0X04
|
||||
//INT OE
|
||||
#define SI114X_INT_CFG_INTOE 0X01
|
||||
//IRQ ENABLE
|
||||
#define SI114X_IRQEN_ALS 0x01
|
||||
#define SI114X_IRQEN_PS1 0x04
|
||||
#define SI114X_IRQEN_PS2 0x08
|
||||
#define SI114X_IRQEN_PS3 0x10
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
uint8_t Si1145ReadByte(uint8_t reg)
|
||||
{
|
||||
return I2cRead8(SI114X_ADDR, reg);
|
||||
}
|
||||
|
||||
uint16_t Si1145ReadHalfWord(uint8_t reg)
|
||||
{
|
||||
return I2cRead16LE(SI114X_ADDR, reg);
|
||||
}
|
||||
|
||||
bool Si1145WriteByte(uint8_t reg, uint16_t val)
|
||||
{
|
||||
I2cWrite8(SI114X_ADDR, reg, val);
|
||||
}
|
||||
|
||||
uint8_t Si1145WriteParamData(uint8_t p, uint8_t v)
|
||||
{
|
||||
Si1145WriteByte(SI114X_WR, v);
|
||||
Si1145WriteByte(SI114X_COMMAND, p | SI114X_SET);
|
||||
return Si1145ReadByte(SI114X_RD);
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
bool Si1145Present()
|
||||
{
|
||||
return (Si1145ReadByte(SI114X_PART_ID) == 0X45);
|
||||
}
|
||||
|
||||
void Si1145Reset()
|
||||
{
|
||||
Si1145WriteByte(SI114X_MEAS_RATE0, 0);
|
||||
Si1145WriteByte(SI114X_MEAS_RATE1, 0);
|
||||
Si1145WriteByte(SI114X_IRQ_ENABLE, 0);
|
||||
Si1145WriteByte(SI114X_IRQ_MODE1, 0);
|
||||
Si1145WriteByte(SI114X_IRQ_MODE2, 0);
|
||||
Si1145WriteByte(SI114X_INT_CFG, 0);
|
||||
Si1145WriteByte(SI114X_IRQ_STATUS, 0xFF);
|
||||
|
||||
Si1145WriteByte(SI114X_COMMAND, SI114X_RESET);
|
||||
delay(10);
|
||||
Si1145WriteByte(SI114X_HW_KEY, 0x17);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void Si1145DeInit()
|
||||
{
|
||||
//ENABLE UV reading
|
||||
//these reg must be set to the fixed value
|
||||
Si1145WriteByte(SI114X_UCOEFF0, 0x29);
|
||||
Si1145WriteByte(SI114X_UCOEFF1, 0x89);
|
||||
Si1145WriteByte(SI114X_UCOEFF2, 0x02);
|
||||
Si1145WriteByte(SI114X_UCOEFF3, 0x00);
|
||||
Si1145WriteParamData(SI114X_CHLIST, SI114X_CHLIST_ENUV | SI114X_CHLIST_ENALSIR | SI114X_CHLIST_ENALSVIS | SI114X_CHLIST_ENPS1);
|
||||
//
|
||||
//set LED1 CURRENT(22.4mA)(It is a normal value for many LED)
|
||||
//
|
||||
Si1145WriteParamData(SI114X_PS1_ADCMUX, SI114X_ADCMUX_LARGE_IR);
|
||||
Si1145WriteByte(SI114X_PS_LED21, SI114X_LED_CURRENT_22MA);
|
||||
Si1145WriteParamData(SI114X_PSLED12_SELECT, SI114X_PSLED12_SELECT_PS1_LED1);
|
||||
//
|
||||
//PS ADC SETTING
|
||||
//
|
||||
Si1145WriteParamData(SI114X_PS_ADC_GAIN, SI114X_ADC_GAIN_DIV1);
|
||||
Si1145WriteParamData(SI114X_PS_ADC_COUNTER, SI114X_ADC_COUNTER_511ADCCLK);
|
||||
Si1145WriteParamData(SI114X_PS_ADC_MISC, SI114X_ADC_MISC_HIGHRANGE | SI114X_ADC_MISC_ADC_RAWADC);
|
||||
//
|
||||
//VIS ADC SETTING
|
||||
//
|
||||
Si1145WriteParamData(SI114X_ALS_VIS_ADC_GAIN, SI114X_ADC_GAIN_DIV1);
|
||||
Si1145WriteParamData(SI114X_ALS_VIS_ADC_COUNTER, SI114X_ADC_COUNTER_511ADCCLK);
|
||||
Si1145WriteParamData(SI114X_ALS_VIS_ADC_MISC, SI114X_ADC_MISC_HIGHRANGE);
|
||||
//
|
||||
//IR ADC SETTING
|
||||
//
|
||||
Si1145WriteParamData(SI114X_ALS_IR_ADC_GAIN, SI114X_ADC_GAIN_DIV1);
|
||||
Si1145WriteParamData(SI114X_ALS_IR_ADC_COUNTER, SI114X_ADC_COUNTER_511ADCCLK);
|
||||
Si1145WriteParamData(SI114X_ALS_IR_ADC_MISC, SI114X_ADC_MISC_HIGHRANGE);
|
||||
//
|
||||
//interrupt enable
|
||||
//
|
||||
Si1145WriteByte(SI114X_INT_CFG, SI114X_INT_CFG_INTOE);
|
||||
Si1145WriteByte(SI114X_IRQ_ENABLE, SI114X_IRQEN_ALS);
|
||||
//
|
||||
//AUTO RUN
|
||||
//
|
||||
Si1145WriteByte(SI114X_MEAS_RATE0, 0xFF);
|
||||
Si1145WriteByte(SI114X_COMMAND, SI114X_PSALS_AUTO);
|
||||
}
|
||||
|
||||
boolean Si1145Begin()
|
||||
{
|
||||
if (!Si1145Present()) { return false; }
|
||||
|
||||
Si1145Reset();
|
||||
Si1145DeInit();
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns the UV index * 100 (divide by 100 to get the index)
|
||||
uint16_t Si1145ReadUV()
|
||||
{
|
||||
return Si1145ReadHalfWord(SI114X_AUX_DATA0_UVINDEX0);
|
||||
}
|
||||
|
||||
// returns visible+IR light levels
|
||||
uint16_t Si1145ReadVisible()
|
||||
{
|
||||
return Si1145ReadHalfWord(SI114X_ALS_VIS_DATA0);
|
||||
}
|
||||
|
||||
// returns IR light levels
|
||||
uint16_t Si1145ReadIR()
|
||||
{
|
||||
return Si1145ReadHalfWord(SI114X_ALS_IR_DATA0);
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void Si1145Update()
|
||||
{
|
||||
if (!si1145_type) {
|
||||
if (Si1145Begin()) {
|
||||
si1145_type = 1;
|
||||
snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, "SI1145", SI114X_ADDR);
|
||||
AddLog(LOG_LEVEL_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
const char HTTP_SNS_SI1145[] PROGMEM = "%s"
|
||||
"{s}SI1145 " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}" // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
|
||||
"{s}SI1145 " D_INFRARED "{m}%d " D_UNIT_LUX "{e}"
|
||||
"{s}SI1145 " D_UV_INDEX "{m}%d.%d{e}";
|
||||
#endif // USE_WEBSERVER
|
||||
|
||||
void Si1145Show(boolean json)
|
||||
{
|
||||
if (si1145_type && Si1145Present()) {
|
||||
uint16_t visible = Si1145ReadVisible();
|
||||
uint16_t infrared = Si1145ReadIR();
|
||||
uint16_t uvindex = Si1145ReadUV();
|
||||
if (json) {
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SI1145\":{\"" D_JSON_ILLUMINANCE "\":%d,\"" D_JSON_INFRARED "\":%d,\"" D_JSON_UVINDEX "\":%d.%d}"),
|
||||
mqtt_data, visible, infrared, uvindex /100, uvindex %100);
|
||||
#ifdef USE_DOMOTICZ
|
||||
if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, visible);
|
||||
#endif // USE_DOMOTICZ
|
||||
} else {
|
||||
#ifdef USE_WEBSERVER
|
||||
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SI1145, mqtt_data, visible, infrared, uvindex /100, uvindex %100);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
si1145_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XSNS_24
|
||||
|
||||
boolean Xsns24(byte function)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (i2c_flg) {
|
||||
switch (function) {
|
||||
case FUNC_EVERY_SECOND:
|
||||
Si1145Update();
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
Si1145Show(1);
|
||||
break;
|
||||
#ifdef USE_WEBSERVER
|
||||
case FUNC_WEB_APPEND:
|
||||
Si1145Show(0);
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_SI1145
|
||||
#endif // USE_I2C
|
Loading…
x
Reference in New Issue
Block a user