mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 20:56:35 +00:00
commit
a64b839729
@ -62,7 +62,7 @@ There is **NO CONFLICT** with MQTT, Home Assistant, Web, etc. Tests show fast re
|
|||||||
## Sonoff-Tasmota
|
## Sonoff-Tasmota
|
||||||
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
|
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
|
||||||
|
|
||||||
Current version is **5.12.0g** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
|
Current version is **5.12.0h** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
|
||||||
|
|
||||||
### ATTENTION All versions
|
### ATTENTION All versions
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# TasmotaSerial
|
# TasmotaSerial
|
||||||
|
|
||||||
Implementation of software serial library for the ESP8266 at 9600 baud
|
Implementation of software serial library for the ESP8266
|
||||||
|
|
||||||
Allows for several instances to be active at the same time.
|
Allows for several instances to be active at the same time.
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "TasmotaSerial",
|
"name": "TasmotaSerial",
|
||||||
"version": "1.0.0",
|
"version": "1.2.0",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"serial", "io", "TasmotaSerial"
|
"serial", "io", "TasmotaSerial"
|
||||||
],
|
],
|
||||||
"description": "Implementation of software serial for ESP8266 at 9600 baud.",
|
"description": "Implementation of software serial for ESP8266.",
|
||||||
"repository":
|
"repository":
|
||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
@ -1,8 +1,8 @@
|
|||||||
name=TasmotaSerial
|
name=TasmotaSerial
|
||||||
version=1.0
|
version=1.2.0
|
||||||
author=Theo Arends
|
author=Theo Arends
|
||||||
maintainer=Theo Arends <theo@arends.com>
|
maintainer=Theo Arends <theo@arends.com>
|
||||||
sentence=Implementation of software serial for ESP8266 at 9600 baud.
|
sentence=Implementation of software serial for ESP8266.
|
||||||
paragraph=
|
paragraph=
|
||||||
category=Signal Input/Output
|
category=Signal Input/Output
|
||||||
url=
|
url=
|
@ -87,9 +87,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin)
|
|||||||
m_in_pos = m_out_pos = 0;
|
m_in_pos = m_out_pos = 0;
|
||||||
if (m_rx_pin > -1) {
|
if (m_rx_pin > -1) {
|
||||||
m_buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE);
|
m_buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE);
|
||||||
if (m_buffer == NULL) {
|
if (m_buffer == NULL) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Use getCycleCount() loop to get as exact timing as possible
|
// Use getCycleCount() loop to get as exact timing as possible
|
||||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE;
|
m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE;
|
||||||
pinMode(m_rx_pin, INPUT);
|
pinMode(m_rx_pin, INPUT);
|
||||||
@ -111,7 +109,8 @@ bool TasmotaSerial::isValidGPIOpin(int pin)
|
|||||||
bool TasmotaSerial::begin(long speed) {
|
bool TasmotaSerial::begin(long speed) {
|
||||||
// Use getCycleCount() loop to get as exact timing as possible
|
// Use getCycleCount() loop to get as exact timing as possible
|
||||||
m_bit_time = ESP.getCpuFreqMHz() *1000000 /speed;
|
m_bit_time = ESP.getCpuFreqMHz() *1000000 /speed;
|
||||||
return m_valid && (speed <= TM_SERIAL_BAUDRATE);
|
m_high_speed = (speed > 9600);
|
||||||
|
return m_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TasmotaSerial::begin() {
|
bool TasmotaSerial::begin() {
|
||||||
@ -123,17 +122,13 @@ void TasmotaSerial::flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int TasmotaSerial::peek() {
|
int TasmotaSerial::peek() {
|
||||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) {
|
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return m_buffer[m_out_pos];
|
return m_buffer[m_out_pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
int TasmotaSerial::read()
|
int TasmotaSerial::read()
|
||||||
{
|
{
|
||||||
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) {
|
if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uint8_t ch = m_buffer[m_out_pos];
|
uint8_t ch = m_buffer[m_out_pos];
|
||||||
m_out_pos = (m_out_pos +1) % TM_SERIAL_BUFFER_SIZE;
|
m_out_pos = (m_out_pos +1) % TM_SERIAL_BUFFER_SIZE;
|
||||||
return ch;
|
return ch;
|
||||||
@ -142,23 +137,20 @@ int TasmotaSerial::read()
|
|||||||
int TasmotaSerial::available()
|
int TasmotaSerial::available()
|
||||||
{
|
{
|
||||||
int avail = m_in_pos - m_out_pos;
|
int avail = m_in_pos - m_out_pos;
|
||||||
if (avail < 0) {
|
if (avail < 0) avail += TM_SERIAL_BUFFER_SIZE;
|
||||||
avail += TM_SERIAL_BUFFER_SIZE;
|
|
||||||
}
|
|
||||||
return avail;
|
return avail;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TM_SERIAL_USE_IRAM
|
#ifdef TM_SERIAL_USE_IRAM
|
||||||
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts
|
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait) if (!m_high_speed) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts
|
||||||
#else
|
#else
|
||||||
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait); wait += m_bit_time; }
|
#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait); wait += m_bit_time; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t TasmotaSerial::write(uint8_t b)
|
size_t TasmotaSerial::write(uint8_t b)
|
||||||
{
|
{
|
||||||
if (-1 == m_tx_pin) {
|
if (-1 == m_tx_pin) return 0;
|
||||||
return 0;
|
if (m_high_speed) cli(); // Disable interrupts in order to get a clean transmit
|
||||||
}
|
|
||||||
unsigned long wait = m_bit_time;
|
unsigned long wait = m_bit_time;
|
||||||
digitalWrite(m_tx_pin, HIGH);
|
digitalWrite(m_tx_pin, HIGH);
|
||||||
unsigned long start = ESP.getCycleCount();
|
unsigned long start = ESP.getCycleCount();
|
||||||
@ -173,6 +165,7 @@ size_t TasmotaSerial::write(uint8_t b)
|
|||||||
// Stop bit
|
// Stop bit
|
||||||
digitalWrite(m_tx_pin, HIGH);
|
digitalWrite(m_tx_pin, HIGH);
|
||||||
TM_SERIAL_WAIT;
|
TM_SERIAL_WAIT;
|
||||||
|
if (m_high_speed) sei();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,9 +184,7 @@ void TasmotaSerial::rxRead()
|
|||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
TM_SERIAL_WAIT;
|
TM_SERIAL_WAIT;
|
||||||
rec >>= 1;
|
rec >>= 1;
|
||||||
if (digitalRead(m_rx_pin)) {
|
if (digitalRead(m_rx_pin)) rec |= 0x80;
|
||||||
rec |= 0x80;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Stop bit
|
// Stop bit
|
||||||
TM_SERIAL_WAIT;
|
TM_SERIAL_WAIT;
|
@ -20,12 +20,12 @@
|
|||||||
#ifndef TasmotaSerial_h
|
#ifndef TasmotaSerial_h
|
||||||
#define TasmotaSerial_h
|
#define TasmotaSerial_h
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* TasmotaSerial supports up to 9600 baud with fixed buffer size of 64 bytes using optional no iram
|
* TasmotaSerial supports up to 115200 baud with fixed buffer size of 64 bytes using optional no iram
|
||||||
*
|
*
|
||||||
* Based on EspSoftwareSerial v3.3.1 by Peter Lerup (https://github.com/plerup/espsoftwareserial)
|
* Based on EspSoftwareSerial v3.3.1 by Peter Lerup (https://github.com/plerup/espsoftwareserial)
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define TM_SERIAL_BAUDRATE 9600 // Max supported baudrate
|
#define TM_SERIAL_BAUDRATE 9600 // Default baudrate
|
||||||
#define TM_SERIAL_BUFFER_SIZE 64 // Receive buffer size
|
#define TM_SERIAL_BUFFER_SIZE 64 // Receive buffer size
|
||||||
|
|
||||||
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||||
@ -57,6 +57,7 @@ class TasmotaSerial : public Stream {
|
|||||||
|
|
||||||
// Member variables
|
// Member variables
|
||||||
bool m_valid;
|
bool m_valid;
|
||||||
|
bool m_high_speed;
|
||||||
int m_rx_pin;
|
int m_rx_pin;
|
||||||
int m_tx_pin;
|
int m_tx_pin;
|
||||||
unsigned long m_bit_time;
|
unsigned long m_bit_time;
|
@ -1,5 +1,15 @@
|
|||||||
/* 5.12.0g
|
/* 5.12.0h
|
||||||
* Add support for MQTT to hardware serial bridge using commands Baudrate and SerialSend. Currently supports 8N1 and text only (#2182)
|
* Add optional Arduino OTA support to be enabled in user_config.h (#1998)
|
||||||
|
* Add support for Software Serial bridge using commands SerialDelimiter, SBaudrate and SSerialSend. Supports 8N1 and text only (#2190)
|
||||||
|
* Add support for Hardware Serial bridge using commands SerialDelimiter, Baudrate and SerialSend. Supports 8N1 and text only (#2182)
|
||||||
|
* Add support for Zengge WF017 PWM Led strip controller (#2202)
|
||||||
|
* Add PWM status to command State if PWM enabled (#2203)
|
||||||
|
* Add command HSBColor Hue,Sat,Bri (#1642, #2203)
|
||||||
|
* Add command Channel 0..100 to control dimmer value for individual color channels (#2111, #2203)
|
||||||
|
* Add Channel status information (#2211)
|
||||||
|
* Add all FriendlyNames to Status information (#2208)
|
||||||
|
* Change status display of Ssid and SetOption
|
||||||
|
* Change default option SetOption15 from 0 to 1 providing better initial PWM experience
|
||||||
*
|
*
|
||||||
* 5.12.0f
|
* 5.12.0f
|
||||||
* Add compile time support for WS2812 BRG and RBG led configurations to be defined in user_config.h (#1690)
|
* Add compile time support for WS2812 BRG and RBG led configurations to be defined in user_config.h (#1690)
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
#define D_JSON_GATEWAY "Gateway"
|
#define D_JSON_GATEWAY "Gateway"
|
||||||
#define D_JSON_HEAPSIZE "Heap"
|
#define D_JSON_HEAPSIZE "Heap"
|
||||||
#define D_JSON_HIGH "High"
|
#define D_JSON_HIGH "High"
|
||||||
|
#define D_JSON_HSBCOLOR "HSBColor"
|
||||||
#define D_JSON_HUMIDITY "Humidity"
|
#define D_JSON_HUMIDITY "Humidity"
|
||||||
#define D_JSON_I2CSCAN_DEVICES_FOUND_AT "Device(s) found at"
|
#define D_JSON_I2CSCAN_DEVICES_FOUND_AT "Device(s) found at"
|
||||||
#define D_JSON_I2CSCAN_UNKNOWN_ERROR_AT "Unknown error at"
|
#define D_JSON_I2CSCAN_UNKNOWN_ERROR_AT "Unknown error at"
|
||||||
@ -242,13 +243,16 @@
|
|||||||
#define D_CMND_CFGDUMP "CfgDump"
|
#define D_CMND_CFGDUMP "CfgDump"
|
||||||
#define D_CMND_I2CSCAN "I2CScan"
|
#define D_CMND_I2CSCAN "I2CScan"
|
||||||
#define D_CMND_SERIALSEND "SerialSend"
|
#define D_CMND_SERIALSEND "SerialSend"
|
||||||
|
#define D_CMND_SERIALDELIMITER "SerialDelimiter"
|
||||||
#define D_CMND_BAUDRATE "Baudrate"
|
#define D_CMND_BAUDRATE "Baudrate"
|
||||||
#define D_CMND_EXCEPTION "Exception"
|
#define D_CMND_EXCEPTION "Exception"
|
||||||
|
|
||||||
// Commands xdrv_01_light.ino
|
// Commands xdrv_01_light.ino
|
||||||
|
#define D_CMND_CHANNEL "Channel"
|
||||||
#define D_CMND_COLOR "Color"
|
#define D_CMND_COLOR "Color"
|
||||||
#define D_CMND_COLORTEMPERATURE "CT"
|
#define D_CMND_COLORTEMPERATURE "CT"
|
||||||
#define D_CMND_DIMMER "Dimmer"
|
#define D_CMND_DIMMER "Dimmer"
|
||||||
|
#define D_CMND_HSBCOLOR "HSBColor"
|
||||||
#define D_CMND_LED "Led"
|
#define D_CMND_LED "Led"
|
||||||
#define D_CMND_LEDTABLE "LedTable"
|
#define D_CMND_LEDTABLE "LedTable"
|
||||||
#define D_CMND_FADE "Fade"
|
#define D_CMND_FADE "Fade"
|
||||||
@ -340,6 +344,11 @@
|
|||||||
#define D_CMND_DISP_SIZE "Size"
|
#define D_CMND_DISP_SIZE "Size"
|
||||||
#define D_CMND_DISP_TEXT "Text"
|
#define D_CMND_DISP_TEXT "Text"
|
||||||
|
|
||||||
|
// Commands xdrv_08_serial_bridge.ino
|
||||||
|
#define D_CMND_SSERIALSEND "SSerialSend"
|
||||||
|
#define D_CMND_SBAUDRATE "SBaudrate"
|
||||||
|
#define D_JSON_SSERIALRECEIVED "SSerialReceived"
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
#ifndef MY_LANGUAGE
|
#ifndef MY_LANGUAGE
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -427,6 +427,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -427,6 +427,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "Háttérvil"
|
#define D_SENSOR_BACKLIGHT "Háttérvil"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "Luz negra"
|
#define D_SENSOR_BACKLIGHT "Luz negra"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "A"
|
#define D_UNIT_AMPERE "A"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "А"
|
#define D_UNIT_AMPERE "А"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "安"
|
#define D_UNIT_AMPERE "安"
|
||||||
|
@ -412,6 +412,8 @@
|
|||||||
#define D_SENSOR_BACKLIGHT "BkLight"
|
#define D_SENSOR_BACKLIGHT "BkLight"
|
||||||
#define D_SENSOR_PMS5003 "PMS5003"
|
#define D_SENSOR_PMS5003 "PMS5003"
|
||||||
#define D_SENSOR_SDS0X1 "SDS0X1"
|
#define D_SENSOR_SDS0X1 "SDS0X1"
|
||||||
|
#define D_SENSOR_SBR_RX "SerBr Rx"
|
||||||
|
#define D_SENSOR_SBR_TX "SerBr Tx"
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
#define D_UNIT_AMPERE "安"
|
#define D_UNIT_AMPERE "安"
|
||||||
|
@ -192,9 +192,8 @@ struct SYSCFG {
|
|||||||
uint16_t ws_wakeup; // 3AA Not used since 5.8.0
|
uint16_t ws_wakeup; // 3AA Not used since 5.8.0
|
||||||
char friendlyname[MAX_FRIENDLYNAMES][33]; // 3AC
|
char friendlyname[MAX_FRIENDLYNAMES][33]; // 3AC
|
||||||
char switch_topic[33]; // 430
|
char switch_topic[33]; // 430
|
||||||
|
char serial_delimiter; // 451
|
||||||
byte free_451[2]; // 451
|
uint8_t sbaudrate; // 452
|
||||||
|
|
||||||
uint8_t sleep; // 453
|
uint8_t sleep; // 453
|
||||||
uint16_t domoticz_switch_idx[MAX_DOMOTICZ_IDX]; // 454
|
uint16_t domoticz_switch_idx[MAX_DOMOTICZ_IDX]; // 454
|
||||||
uint16_t domoticz_sensor_idx[MAX_DOMOTICZ_SNS_IDX]; // 45C
|
uint16_t domoticz_sensor_idx[MAX_DOMOTICZ_SNS_IDX]; // 45C
|
||||||
|
@ -450,6 +450,7 @@ void SettingsDefaultSet2()
|
|||||||
Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN;
|
Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN;
|
||||||
Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
|
Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
|
||||||
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
|
Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
|
||||||
|
Settings.flag.pwm_control = 1;
|
||||||
Settings.flag.hass_discovery = HOME_ASSISTANT_DISCOVERY_ENABLE;
|
Settings.flag.hass_discovery = HOME_ASSISTANT_DISCOVERY_ENABLE;
|
||||||
|
|
||||||
Settings.flag2.emulation = EMULATION;
|
Settings.flag2.emulation = EMULATION;
|
||||||
@ -458,6 +459,8 @@ void SettingsDefaultSet2()
|
|||||||
Settings.timezone = APP_TIMEZONE;
|
Settings.timezone = APP_TIMEZONE;
|
||||||
strlcpy(Settings.ota_url, OTA_URL, sizeof(Settings.ota_url));
|
strlcpy(Settings.ota_url, OTA_URL, sizeof(Settings.ota_url));
|
||||||
Settings.baudrate = APP_BAUDRATE / 1200;
|
Settings.baudrate = APP_BAUDRATE / 1200;
|
||||||
|
Settings.sbaudrate = SOFT_BAUDRATE / 1200;
|
||||||
|
Settings.serial_delimiter = 0xff;
|
||||||
|
|
||||||
Settings.seriallog_level = SERIAL_LOG_LEVEL;
|
Settings.seriallog_level = SERIAL_LOG_LEVEL;
|
||||||
// Settings.sta_active = 0;
|
// Settings.sta_active = 0;
|
||||||
@ -903,6 +906,10 @@ void SettingsDelta()
|
|||||||
if (Settings.version < 0x050C0007) {
|
if (Settings.version < 0x050C0007) {
|
||||||
Settings.baudrate = APP_BAUDRATE / 1200;
|
Settings.baudrate = APP_BAUDRATE / 1200;
|
||||||
}
|
}
|
||||||
|
if (Settings.version < 0x050C0008) {
|
||||||
|
Settings.sbaudrate = SOFT_BAUDRATE / 1200;
|
||||||
|
Settings.serial_delimiter = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
Settings.version = VERSION;
|
Settings.version = VERSION;
|
||||||
SettingsSave(1);
|
SettingsSave(1);
|
||||||
|
@ -98,6 +98,7 @@ typedef unsigned long power_t; // Power (Relay) type
|
|||||||
#define MAX_BACKLOG 16 // Max number of commands in backlog (chk backlog_index and backlog_pointer code)
|
#define MAX_BACKLOG 16 // Max number of commands in backlog (chk backlog_index and backlog_pointer code)
|
||||||
#define MIN_BACKLOG_DELAY 2 // Minimal backlog delay in 0.1 seconds
|
#define MIN_BACKLOG_DELAY 2 // Minimal backlog delay in 0.1 seconds
|
||||||
|
|
||||||
|
#define SOFT_BAUDRATE 9600 // Default software serial baudrate
|
||||||
#define APP_BAUDRATE 115200 // Default serial baudrate
|
#define APP_BAUDRATE 115200 // Default serial baudrate
|
||||||
#define SERIAL_POLLING 100 // Serial receive polling in ms
|
#define SERIAL_POLLING 100 // Serial receive polling in ms
|
||||||
#define MAX_STATUS 11 // Max number of status lines
|
#define MAX_STATUS 11 // Max number of status lines
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
|
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
|
||||||
====================================================*/
|
====================================================*/
|
||||||
|
|
||||||
#define VERSION 0x050C0007 // 5.12.0g
|
#define VERSION 0x050C0008 // 5.12.0h
|
||||||
|
|
||||||
// Location specific includes
|
// Location specific includes
|
||||||
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||||
@ -54,8 +54,14 @@
|
|||||||
#include <ESP8266WebServer.h> // WifiManager, Webserver
|
#include <ESP8266WebServer.h> // WifiManager, Webserver
|
||||||
#include <DNSServer.h> // WifiManager
|
#include <DNSServer.h> // WifiManager
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
|
#ifdef USE_ARDUINO_OTA
|
||||||
|
#include <ArduinoOTA.h> // Arduino OTA
|
||||||
|
#ifndef USE_DISCOVERY
|
||||||
|
#define USE_DISCOVERY
|
||||||
|
#endif
|
||||||
|
#endif // USE_ARDUINO_OTA
|
||||||
#ifdef USE_DISCOVERY
|
#ifdef USE_DISCOVERY
|
||||||
#include <ESP8266mDNS.h> // MQTT, Webserver
|
#include <ESP8266mDNS.h> // MQTT, Webserver, Arduino OTA
|
||||||
#endif // USE_DISCOVERY
|
#endif // USE_DISCOVERY
|
||||||
#ifdef USE_I2C
|
#ifdef USE_I2C
|
||||||
#include <Wire.h> // I2C support library
|
#include <Wire.h> // I2C support library
|
||||||
@ -76,7 +82,7 @@ enum TasmotaCommands {
|
|||||||
CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME,
|
CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME,
|
||||||
CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_WEBSERVER, CMND_WEBPASSWORD, CMND_WEBLOG, CMND_EMULATION,
|
CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_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_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE,
|
||||||
CMND_CFGDUMP, CMND_I2CSCAN, CMND_SERIALSEND, CMND_BAUDRATE, CMND_EXCEPTION };
|
CMND_CFGDUMP, CMND_I2CSCAN, CMND_SERIALSEND, CMND_BAUDRATE, CMND_SERIALDELIMITER, CMND_EXCEPTION };
|
||||||
const char kTasmotaCommands[] PROGMEM =
|
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 "|"
|
D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|"
|
||||||
D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SENSOR "|" D_CMND_SAVEDATA "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|"
|
D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SENSOR "|" D_CMND_SAVEDATA "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|"
|
||||||
@ -86,7 +92,7 @@ const char kTasmotaCommands[] PROGMEM =
|
|||||||
D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|"
|
D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|"
|
||||||
D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_EMULATION "|"
|
D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_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_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|"
|
||||||
D_CMND_CFGDUMP "|" D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE
|
D_CMND_CFGDUMP "|" D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER
|
||||||
#ifdef DEBUG_THEO
|
#ifdef DEBUG_THEO
|
||||||
"|" D_CMND_EXCEPTION
|
"|" D_CMND_EXCEPTION
|
||||||
#endif
|
#endif
|
||||||
@ -176,7 +182,6 @@ uint8_t i2c_flg = 0; // I2C configured
|
|||||||
uint8_t spi_flg = 0; // SPI configured
|
uint8_t spi_flg = 0; // SPI configured
|
||||||
uint8_t light_type = 0; // Light types
|
uint8_t light_type = 0; // Light types
|
||||||
bool pwm_present = false; // Any PWM channel configured with SetOption15 0
|
bool pwm_present = false; // Any PWM channel configured with SetOption15 0
|
||||||
|
|
||||||
boolean mdns_begun = false;
|
boolean mdns_begun = false;
|
||||||
|
|
||||||
char my_version[33]; // Composed version string
|
char my_version[33]; // Composed version string
|
||||||
@ -737,15 +742,9 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||||||
Settings.pwm_value[index -1] = payload;
|
Settings.pwm_value[index -1] = payload;
|
||||||
analogWrite(pin[GPIO_PWM1 + index -1], bitRead(pwm_inverted, index -1) ? Settings.pwm_range - payload : payload);
|
analogWrite(pin[GPIO_PWM1 + index -1], bitRead(pwm_inverted, index -1) ? Settings.pwm_range - payload : payload);
|
||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PWM "\":{"));
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{"));
|
||||||
bool first = true;
|
MqttShowPWMState(); // Render the PWM status to MQTT
|
||||||
for (byte i = 0; i < MAX_PWMS; i++) {
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||||
if (pin[GPIO_PWM1 + i] < 99) {
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_PWM "%d\":%d"), mqtt_data, first ? "" : ",", i+1, Settings.pwm_value[i]);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}}"),mqtt_data);
|
|
||||||
}
|
}
|
||||||
else if (CMND_PWMFREQUENCY == command_code) {
|
else if (CMND_PWMFREQUENCY == command_code) {
|
||||||
if ((1 == payload) || ((payload >= 100) && (payload <= 4000))) {
|
if ((1 == payload) || ((payload >= 100) && (payload <= 4000))) {
|
||||||
@ -821,15 +820,35 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
|
|||||||
}
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.baudrate * 1200);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.baudrate * 1200);
|
||||||
}
|
}
|
||||||
else if ((CMND_SERIALSEND == command_code) && (index > 0) && (index <= 2)) {
|
else if ((CMND_SERIALSEND == command_code) && (index > 0) && (index <= 3)) {
|
||||||
SetSeriallog(LOG_LEVEL_NONE);
|
SetSeriallog(LOG_LEVEL_NONE);
|
||||||
Settings.flag.mqtt_serial = 1;
|
Settings.flag.mqtt_serial = 1;
|
||||||
if (data_len > 0) {
|
if (data_len > 0) {
|
||||||
if (1 == index) Serial.printf("%s\n", dataBuf);
|
if (1 == index) {
|
||||||
if (2 == index) Serial.printf("%s", dataBuf);
|
Serial.printf("%s\n", dataBuf);
|
||||||
|
}
|
||||||
|
else if (2 == index) {
|
||||||
|
Serial.printf("%s", dataBuf);
|
||||||
|
}
|
||||||
|
else if (3 == index) {
|
||||||
|
uint16_t dat_len = data_len;
|
||||||
|
Serial.printf("%s", Unescape(dataBuf, &dat_len));
|
||||||
|
}
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (CMND_SERIALDELIMITER == command_code) {
|
||||||
|
if ((data_len > 0) && (payload < 256)) {
|
||||||
|
if (payload > 0) {
|
||||||
|
Settings.serial_delimiter = payload;
|
||||||
|
} else {
|
||||||
|
uint16_t dat_len = data_len;
|
||||||
|
Unescape(dataBuf, &dat_len);
|
||||||
|
Settings.serial_delimiter = dataBuf[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, Settings.serial_delimiter);
|
||||||
|
}
|
||||||
else if (CMND_SERIALLOG == command_code) {
|
else if (CMND_SERIALLOG == command_code) {
|
||||||
if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
|
if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
|
||||||
Settings.flag.mqtt_serial = 0;
|
Settings.flag.mqtt_serial = 0;
|
||||||
@ -1229,6 +1248,7 @@ void ExecuteCommand(char *cmnd)
|
|||||||
void PublishStatus(uint8_t payload)
|
void PublishStatus(uint8_t payload)
|
||||||
{
|
{
|
||||||
uint8_t option = 1;
|
uint8_t option = 1;
|
||||||
|
char stemp[MAX_FRIENDLYNAMES * (sizeof(Settings.friendlyname[0]) +4)];
|
||||||
|
|
||||||
// Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX
|
// Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX
|
||||||
if (!strcmp(Settings.mqtt_prefix[0],Settings.mqtt_prefix[1]) && (!payload)) option++;
|
if (!strcmp(Settings.mqtt_prefix[0],Settings.mqtt_prefix[1]) && (!payload)) option++;
|
||||||
@ -1237,8 +1257,13 @@ void PublishStatus(uint8_t payload)
|
|||||||
if (!energy_flg && (9 == payload)) payload = 99;
|
if (!energy_flg && (9 == payload)) payload = 99;
|
||||||
|
|
||||||
if ((0 == payload) || (99 == payload)) {
|
if ((0 == payload) || (99 == payload)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":\"%s\",\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"),
|
uint8_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : devices_present;
|
||||||
Settings.module +1, Settings.friendlyname[0], mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_power_retain);
|
stemp[0] = '\0';
|
||||||
|
for (byte i = 0; i < maxfn; i++) {
|
||||||
|
snprintf_P(stemp, sizeof(stemp), PSTR("%s%s\"%s\"" ), stemp, (i > 0 ? "," : ""), Settings.friendlyname[i]);
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"),
|
||||||
|
Settings.module +1, stemp, mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_power_retain);
|
||||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS));
|
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1255,8 +1280,8 @@ void PublishStatus(uint8_t payload)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((0 == payload) || (3 == payload)) {
|
if ((0 == payload) || (3 == payload)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d,\"" D_CMND_WEBLOG "\":%d,\"" D_CMND_SYSLOG "\":%d,\"" D_CMND_LOGHOST "\":\"%s\",\"" D_CMND_LOGPORT "\":%d,\"" D_CMND_SSID "1\":\"%s\",\"" D_CMND_SSID "2\":\"%s\",\"" D_CMND_TELEPERIOD "\":%d,\"" D_CMND_SETOPTION "\":\"%08X\"}}"),
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d,\"" D_CMND_WEBLOG "\":%d,\"" D_CMND_SYSLOG "\":%d,\"" D_CMND_LOGHOST "\":\"%s\",\"" D_CMND_LOGPORT "\":%d,\"" D_CMND_SSID "\":[\"%s\",\"%s\"],\"" D_CMND_TELEPERIOD "\":%d,\"" D_CMND_SETOPTION "\":[\"%08X\",\"%08X\"]}}"),
|
||||||
Settings.seriallog_level, Settings.weblog_level, Settings.syslog_level, Settings.syslog_host, Settings.syslog_port, Settings.sta_ssid[0], Settings.sta_ssid[1], Settings.tele_period, Settings.flag.data);
|
Settings.seriallog_level, Settings.weblog_level, Settings.syslog_level, Settings.syslog_host, Settings.syslog_port, Settings.sta_ssid[0], Settings.sta_ssid[1], Settings.tele_period, Settings.flag.data, Settings.flag2.data);
|
||||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "3"));
|
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1313,6 +1338,19 @@ void PublishStatus(uint8_t payload)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MqttShowPWMState()
|
||||||
|
{
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"" D_CMND_PWM "\":{"), mqtt_data);
|
||||||
|
bool first = true;
|
||||||
|
for (byte i = 0; i < MAX_PWMS; i++) {
|
||||||
|
if (pin[GPIO_PWM1 + i] < 99) {
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s\"" D_CMND_PWM "%d\":%d"), mqtt_data, first ? "" : ",", i+1, Settings.pwm_value[i]);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
|
||||||
|
}
|
||||||
|
|
||||||
void MqttShowState()
|
void MqttShowState()
|
||||||
{
|
{
|
||||||
char stemp1[33];
|
char stemp1[33];
|
||||||
@ -1331,6 +1369,11 @@ void MqttShowState()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pwm_present) {
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
||||||
|
MqttShowPWMState();
|
||||||
|
}
|
||||||
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_RSSI "\":%d,\"" D_JSON_APMAC_ADDRESS "\":\"%s\"}}"),
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_RSSI "\":%d,\"" D_JSON_APMAC_ADDRESS "\":\"%s\"}}"),
|
||||||
mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str());
|
mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str());
|
||||||
}
|
}
|
||||||
@ -1871,6 +1914,86 @@ void StateLoop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_ARDUINO_OTA
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Allow updating via the Arduino OTA-protocol.
|
||||||
|
*
|
||||||
|
* - Once started disables current wifi clients and udp
|
||||||
|
* - Perform restart when done to re-init wifi clients
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
bool arduino_ota_triggered = false;
|
||||||
|
uint16_t arduino_ota_progress_dot_count = 0;
|
||||||
|
|
||||||
|
void ArduinoOTAInit()
|
||||||
|
{
|
||||||
|
ArduinoOTA.setPort(8266);
|
||||||
|
ArduinoOTA.setHostname(Settings.hostname);
|
||||||
|
if (Settings.web_password[0] !=0) ArduinoOTA.setPassword(Settings.web_password);
|
||||||
|
|
||||||
|
ArduinoOTA.onStart([]()
|
||||||
|
{
|
||||||
|
SettingsSave(1); // Free flash for OTA update
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
if (Settings.webserver) StopWebserver();
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
|
#ifdef USE_ARILUX_RF
|
||||||
|
AriluxRfDisable(); // Prevent restart exception on Arilux Interrupt routine
|
||||||
|
#endif // USE_ARILUX_RF
|
||||||
|
if (Settings.flag.mqtt_enabled) MqttDisconnect();
|
||||||
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Arduino OTA " D_UPLOAD_STARTED));
|
||||||
|
AddLog(LOG_LEVEL_INFO);
|
||||||
|
arduino_ota_triggered = true;
|
||||||
|
arduino_ota_progress_dot_count = 0;
|
||||||
|
delay(100); // Allow time for message xfer
|
||||||
|
});
|
||||||
|
|
||||||
|
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
|
||||||
|
{
|
||||||
|
if ((LOG_LEVEL_DEBUG <= seriallog_level)) {
|
||||||
|
arduino_ota_progress_dot_count++;
|
||||||
|
Serial.printf(".");
|
||||||
|
if (!(arduino_ota_progress_dot_count % 80)) Serial.println();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ArduinoOTA.onError([](ota_error_t error)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
From ArduinoOTA.h:
|
||||||
|
typedef enum { OTA_AUTH_ERROR, OTA_BEGIN_ERROR, OTA_CONNECT_ERROR, OTA_RECEIVE_ERROR, OTA_END_ERROR } ota_error_t;
|
||||||
|
*/
|
||||||
|
char error_str[100];
|
||||||
|
|
||||||
|
if ((LOG_LEVEL_DEBUG <= seriallog_level) && arduino_ota_progress_dot_count) Serial.println();
|
||||||
|
switch (error) {
|
||||||
|
case OTA_BEGIN_ERROR: strncpy_P(error_str, PSTR(D_UPLOAD_ERR_2), sizeof(error_str)); break;
|
||||||
|
case OTA_RECEIVE_ERROR: strncpy_P(error_str, PSTR(D_UPLOAD_ERR_5), sizeof(error_str)); break;
|
||||||
|
case OTA_END_ERROR: strncpy_P(error_str, PSTR(D_UPLOAD_ERR_7), sizeof(error_str)); break;
|
||||||
|
default:
|
||||||
|
snprintf_P(error_str, sizeof(error_str), PSTR(D_UPLOAD_ERROR_CODE " %d"), error);
|
||||||
|
}
|
||||||
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Arduino OTA %s. " D_RESTARTING), error_str);
|
||||||
|
AddLog(LOG_LEVEL_INFO);
|
||||||
|
delay(100); // Allow time for message xfer
|
||||||
|
ESP.restart();
|
||||||
|
});
|
||||||
|
|
||||||
|
ArduinoOTA.onEnd([]()
|
||||||
|
{
|
||||||
|
if ((LOG_LEVEL_DEBUG <= seriallog_level)) Serial.println();
|
||||||
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Arduino OTA " D_SUCCESSFUL ". " D_RESTARTING));
|
||||||
|
AddLog(LOG_LEVEL_INFO);
|
||||||
|
delay(100); // Allow time for message xfer
|
||||||
|
ESP.restart();
|
||||||
|
});
|
||||||
|
|
||||||
|
ArduinoOTA.begin();
|
||||||
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_UPLOAD "Arduino OTA " D_ENABLED " " D_PORT " 8266"));
|
||||||
|
AddLog(LOG_LEVEL_INFO);
|
||||||
|
}
|
||||||
|
#endif // USE_ARDUINO_OTA
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
void SerialInput()
|
void SerialInput()
|
||||||
@ -1927,17 +2050,26 @@ void SerialInput()
|
|||||||
|
|
||||||
if (serial_in_byte > 127) { // binary data...
|
if (serial_in_byte > 127) { // binary data...
|
||||||
serial_in_byte_counter = 0;
|
serial_in_byte_counter = 0;
|
||||||
serial_polling_window = 0;
|
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!Settings.flag.mqtt_serial) {
|
||||||
if (isprint(serial_in_byte)) {
|
if (isprint(serial_in_byte)) {
|
||||||
if (serial_in_byte_counter < INPUT_BUFFER_SIZE -1) { // add char to string if it still fits
|
if (serial_in_byte_counter < INPUT_BUFFER_SIZE -1) { // add char to string if it still fits
|
||||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||||
serial_polling_window = millis();
|
|
||||||
} else {
|
} else {
|
||||||
serial_in_byte_counter = 0;
|
serial_in_byte_counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (serial_in_byte) {
|
||||||
|
if ((serial_in_byte_counter < INPUT_BUFFER_SIZE -1) && (serial_in_byte != Settings.serial_delimiter)) { // add char to string if it still fits
|
||||||
|
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||||
|
serial_polling_window = millis();
|
||||||
|
} else {
|
||||||
serial_polling_window = 0;
|
serial_polling_window = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1955,24 +2087,7 @@ void SerialInput()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------------*/
|
||||||
/*
|
|
||||||
else if (serial_in_byte == '\n') {
|
|
||||||
serial_in_buffer[serial_in_byte_counter] = 0; // serial data completed
|
|
||||||
if (!Settings.flag.mqtt_serial) {
|
|
||||||
seriallog_level = (Settings.seriallog_level < LOG_LEVEL_INFO) ? (byte)LOG_LEVEL_INFO : Settings.seriallog_level;
|
|
||||||
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), serial_in_buffer);
|
|
||||||
AddLog(LOG_LEVEL_INFO);
|
|
||||||
ExecuteCommand(serial_in_buffer);
|
|
||||||
} else {
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SERIALRECEIVED "\":\"%s\"}"), serial_in_buffer);
|
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED));
|
|
||||||
}
|
|
||||||
serial_in_byte_counter = 0;
|
|
||||||
serial_polling_window = 0;
|
|
||||||
Serial.flush();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
else if (!Settings.flag.mqtt_serial && (serial_in_byte == '\n')) {
|
else if (!Settings.flag.mqtt_serial && (serial_in_byte == '\n')) {
|
||||||
serial_in_buffer[serial_in_byte_counter] = 0; // serial data completed
|
serial_in_buffer[serial_in_byte_counter] = 0; // serial data completed
|
||||||
seriallog_level = (Settings.seriallog_level < LOG_LEVEL_INFO) ? (byte)LOG_LEVEL_INFO : Settings.seriallog_level;
|
seriallog_level = (Settings.seriallog_level < LOG_LEVEL_INFO) ? (byte)LOG_LEVEL_INFO : Settings.seriallog_level;
|
||||||
@ -1991,8 +2106,6 @@ void SerialInput()
|
|||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SERIALRECEIVED "\":\"%s\"}"), serial_in_buffer);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SERIALRECEIVED "\":\"%s\"}"), serial_in_buffer);
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED));
|
||||||
serial_in_byte_counter = 0;
|
serial_in_byte_counter = 0;
|
||||||
serial_polling_window = 0;
|
|
||||||
Serial.flush();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2289,6 +2402,11 @@ void setup()
|
|||||||
#endif // BE_MINIMAL
|
#endif // BE_MINIMAL
|
||||||
|
|
||||||
RtcInit();
|
RtcInit();
|
||||||
|
|
||||||
|
#ifdef USE_ARDUINO_OTA
|
||||||
|
ArduinoOTAInit();
|
||||||
|
#endif // USE_ARDUINO_OTA
|
||||||
|
|
||||||
XsnsCall(FUNC_INIT);
|
XsnsCall(FUNC_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2310,6 +2428,12 @@ void loop()
|
|||||||
|
|
||||||
SerialInput();
|
SerialInput();
|
||||||
|
|
||||||
|
#ifdef USE_ARDUINO_OTA
|
||||||
|
ArduinoOTA.handle();
|
||||||
|
// Once OTA is triggered, only handle that and dont do other stuff. (otherwise it fails)
|
||||||
|
while (arduino_ota_triggered) ArduinoOTA.handle();
|
||||||
|
#endif // USE_ARDUINO_OTA
|
||||||
|
|
||||||
// yield(); // yield == delay(0), delay contains yield, auto yield in loop
|
// yield(); // yield == delay(0), delay contains yield, auto yield in loop
|
||||||
delay(sleep); // https://github.com/esp8266/Arduino/issues/2021
|
delay(sleep); // https://github.com/esp8266/Arduino/issues/2021
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ void WifiWpsStatusCallback(wps_cb_status status);
|
|||||||
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
|
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
|
||||||
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
|
#define USE_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_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||||
|
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
|
||||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
#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_HVAC // Support for HVAC system using IR (+2k code)
|
||||||
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)
|
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)
|
||||||
|
@ -89,6 +89,8 @@ enum UserSelectablePins {
|
|||||||
GPIO_BACKLIGHT, // Display backlight control
|
GPIO_BACKLIGHT, // Display backlight control
|
||||||
GPIO_PMS5003, // Plantower PMS5003 Serial interface
|
GPIO_PMS5003, // Plantower PMS5003 Serial interface
|
||||||
GPIO_SDS0X1, // Nova Fitness SDS011 Serial interface
|
GPIO_SDS0X1, // Nova Fitness SDS011 Serial interface
|
||||||
|
GPIO_SBR_TX, // Serial Bridge Serial interface
|
||||||
|
GPIO_SBR_RX, // Serial Bridge Serial interface
|
||||||
GPIO_SENSOR_END };
|
GPIO_SENSOR_END };
|
||||||
|
|
||||||
// Programmer selectable GPIO functionality offset by user selectable GPIOs
|
// Programmer selectable GPIO functionality offset by user selectable GPIOs
|
||||||
@ -130,7 +132,8 @@ const char kSensorNames[] PROGMEM =
|
|||||||
D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|"
|
D_SENSOR_PZEM_TX "|" D_SENSOR_PZEM_RX "|"
|
||||||
D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|"
|
D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|"
|
||||||
D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|"
|
D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|"
|
||||||
D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1;
|
D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1 "|"
|
||||||
|
D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX;
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
@ -177,6 +180,7 @@ enum SupportedModules {
|
|||||||
SONOFF_DUAL_R2,
|
SONOFF_DUAL_R2,
|
||||||
ARILUX_LC06,
|
ARILUX_LC06,
|
||||||
SONOFF_S31,
|
SONOFF_S31,
|
||||||
|
ZENGGE_ZF_WF017,
|
||||||
MAXMODULE };
|
MAXMODULE };
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
@ -231,6 +235,7 @@ const uint8_t kNiceList[MAXMODULE] PROGMEM = {
|
|||||||
ARILUX_LC01,
|
ARILUX_LC01,
|
||||||
ARILUX_LC06,
|
ARILUX_LC06,
|
||||||
ARILUX_LC11,
|
ARILUX_LC11,
|
||||||
|
ZENGGE_ZF_WF017,
|
||||||
HUAFAN_SS,
|
HUAFAN_SS,
|
||||||
KMC_70011,
|
KMC_70011,
|
||||||
AILIGHT,
|
AILIGHT,
|
||||||
@ -786,6 +791,19 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
|||||||
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
|
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
|
||||||
GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off)
|
GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off)
|
||||||
0, 0, 0, 0
|
0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ "Zengge WF017", // Zenggee ZJ-WF017-A (ESP12S)) - https://www.ebay.com/p/Smartphone-Android-IOS-WiFi-Music-Controller-for-RGB-5050-3528-LED-Strip-Light/534446632?_trksid=p2047675.l2644
|
||||||
|
GPIO_KEY1, // GPIO00 Optional Button
|
||||||
|
0,
|
||||||
|
GPIO_USER, // GPIO02 Empty pad
|
||||||
|
0,
|
||||||
|
GPIO_USER, // GPIO04 W2 - PWM5
|
||||||
|
0,
|
||||||
|
0, 0, 0, 0, 0, 0, // Flash connection
|
||||||
|
GPIO_PWM2, // GPIO12 RGB LED Green
|
||||||
|
GPIO_PWM1, // GPIO13 RGB LED Red
|
||||||
|
GPIO_PWM3, // GPIO14 RGB LED Blue
|
||||||
|
0, 0, 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -816,20 +834,6 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
|||||||
0, 0
|
0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
{ "Zengge WF017", // Zenggee ZJ-WF017-A (ESP12S)) - https://www.ebay.com/p/Smartphone-Android-IOS-WiFi-Music-Controller-for-RGB-5050-3528-LED-Strip-Light/534446632?_trksid=p2047675.l2644
|
|
||||||
GPIO_KEY1, // GPIO00 Optional Button
|
|
||||||
0,
|
|
||||||
GPIO_USER, // GPIO02 Empty pad
|
|
||||||
0,
|
|
||||||
GPIO_USER, // GPIO04 W2 - PWM5
|
|
||||||
0,
|
|
||||||
0, 0, 0, 0, 0, 0, // Flash connection
|
|
||||||
GPIO_PWM2, // GPIO12 RGB LED Green
|
|
||||||
GPIO_PWM1, // GPIO13 RGB LED Red
|
|
||||||
GPIO_PWM3, // GPIO14 RGB LED Blue
|
|
||||||
0, 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
{ "SMPW701E", // SM-PW701E WLAN Socket (#1190)
|
{ "SMPW701E", // SM-PW701E WLAN Socket (#1190)
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
GPIO_LED1_INV, // GPIO04 Blue Led (0 = On, 1 = Off)
|
GPIO_LED1_INV, // GPIO04 Blue Led (0 = On, 1 = Off)
|
||||||
|
@ -197,6 +197,50 @@ char* dtostrfd(double number, unsigned char prec, char *s)
|
|||||||
return dtostrf(number, 1, prec, s);
|
return dtostrf(number, 1, prec, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* Unescape(char* buffer, uint16_t* size)
|
||||||
|
{
|
||||||
|
uint8_t* read = (uint8_t*)buffer;
|
||||||
|
uint8_t* write = (uint8_t*)buffer;
|
||||||
|
uint16_t start_size = *size;
|
||||||
|
uint16_t end_size = *size;
|
||||||
|
uint8_t che = 0;
|
||||||
|
|
||||||
|
while (start_size > 0) {
|
||||||
|
uint8_t ch = *read++;
|
||||||
|
start_size--;
|
||||||
|
if (ch != '\\') {
|
||||||
|
*write++ = ch;
|
||||||
|
} else {
|
||||||
|
if (start_size > 0) {
|
||||||
|
uint8_t chi = *read++;
|
||||||
|
start_size--;
|
||||||
|
end_size--;
|
||||||
|
switch (chi) {
|
||||||
|
case '\\': che = '\\'; break; // 5C Backslash
|
||||||
|
case 'a': che = '\a'; break; // 07 Bell (Alert)
|
||||||
|
case 'b': che = '\b'; break; // 08 Backspace
|
||||||
|
case 'e': che = '\e'; break; // 1B Escape
|
||||||
|
case 'f': che = '\f'; break; // 0C Formfeed
|
||||||
|
case 'n': che = '\n'; break; // 0A Linefeed (Newline)
|
||||||
|
case 'r': che = '\r'; break; // 0D Carriage return
|
||||||
|
case 's': che = ' '; break; // 20 Space
|
||||||
|
case 't': che = '\t'; break; // 09 Horizontal tab
|
||||||
|
case 'v': che = '\v'; break; // 0B Vertical tab
|
||||||
|
// case '?': che = '\?'; break; // 3F Question mark
|
||||||
|
default : {
|
||||||
|
che = chi;
|
||||||
|
*write++ = ch;
|
||||||
|
end_size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*write++ = che;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*size = end_size;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
boolean ParseIp(uint32_t* addr, const char* str)
|
boolean ParseIp(uint32_t* addr, const char* str)
|
||||||
{
|
{
|
||||||
uint8_t *part = (uint8_t*)addr;
|
uint8_t *part = (uint8_t*)addr;
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
|
|
||||||
// -- Ota -----------------------------------------
|
// -- Ota -----------------------------------------
|
||||||
#define OTA_URL "http://sonoff.maddox.co.uk/tasmota/sonoff.ino.bin" // [OtaUrl]
|
#define OTA_URL "http://sonoff.maddox.co.uk/tasmota/sonoff.ino.bin" // [OtaUrl]
|
||||||
|
//#define USE_ARDUINO_OTA // Add optional support for Arduino OTA (+4k5 code)
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Select ONE of possible MQTT library types below
|
* Select ONE of possible MQTT library types below
|
||||||
@ -223,6 +224,7 @@
|
|||||||
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
|
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
|
||||||
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
|
#define USE_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_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
|
||||||
|
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
|
||||||
|
|
||||||
// -- Low level interface devices -----------------
|
// -- Low level interface devices -----------------
|
||||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram)
|
||||||
|
@ -55,10 +55,12 @@
|
|||||||
|
|
||||||
enum LightCommands {
|
enum LightCommands {
|
||||||
CMND_COLOR, CMND_COLORTEMPERATURE, CMND_DIMMER, CMND_LED, CMND_LEDTABLE, CMND_FADE,
|
CMND_COLOR, CMND_COLORTEMPERATURE, CMND_DIMMER, CMND_LED, CMND_LEDTABLE, CMND_FADE,
|
||||||
CMND_PIXELS, CMND_ROTATION, CMND_SCHEME, CMND_SPEED, CMND_WAKEUP, CMND_WAKEUPDURATION, CMND_WIDTH, CMND_UNDOCA };
|
CMND_PIXELS, CMND_ROTATION, CMND_SCHEME, CMND_SPEED, CMND_WAKEUP, CMND_WAKEUPDURATION,
|
||||||
|
CMND_WIDTH, CMND_CHANNEL, CMND_HSBCOLOR, CMND_UNDOCA };
|
||||||
const char kLightCommands[] PROGMEM =
|
const char kLightCommands[] PROGMEM =
|
||||||
D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_LED "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|"
|
D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_LED "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|"
|
||||||
D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|" D_CMND_WIDTH "|UNDOCA" ;
|
D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|"
|
||||||
|
D_CMND_WIDTH "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR "|UNDOCA" ;
|
||||||
|
|
||||||
struct LRgbColor {
|
struct LRgbColor {
|
||||||
uint8_t R, G, B;
|
uint8_t R, G, B;
|
||||||
@ -535,6 +537,8 @@ void LightState(uint8_t append)
|
|||||||
{
|
{
|
||||||
char scolor[25];
|
char scolor[25];
|
||||||
char scommand[33];
|
char scommand[33];
|
||||||
|
float hsb[3];
|
||||||
|
int16_t h,s,b;
|
||||||
|
|
||||||
if (append) {
|
if (append) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data);
|
||||||
@ -546,6 +550,19 @@ void LightState(uint8_t append)
|
|||||||
mqtt_data, scommand, GetStateText(light_power), Settings.light_dimmer);
|
mqtt_data, scommand, GetStateText(light_power), Settings.light_dimmer);
|
||||||
if (light_subtype > LST_SINGLE) {
|
if (light_subtype > LST_SINGLE) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor));
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor));
|
||||||
|
// Add status for HSB
|
||||||
|
LightGetHsb(&hsb[0],&hsb[1],&hsb[2]);
|
||||||
|
// Scale these percentages up to the numbers expected byt he client
|
||||||
|
h = round(hsb[0] * 360);
|
||||||
|
s = round(hsb[1] * 100);
|
||||||
|
b = round(hsb[2] * 100);
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_HSBCOLOR "\":\"%d,%d,%d\""), mqtt_data, h,s,b);
|
||||||
|
// Add status for each channel
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_CHANNEL "\":[" ), mqtt_data);
|
||||||
|
for (byte i = 0; i < light_subtype; i++) {
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d" ), mqtt_data, (i > 0 ? "," : ""), round(light_current_color[i]/2.55));
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]" ), mqtt_data);
|
||||||
}
|
}
|
||||||
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLORTEMPERATURE "\":%d"), mqtt_data, LightGetColorTemp());
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLORTEMPERATURE "\":%d"), mqtt_data, LightGetColorTemp());
|
||||||
@ -1053,6 +1070,47 @@ boolean LightCommand()
|
|||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, scolor);
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, XdrvMailbox.index, scolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((CMND_CHANNEL == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= light_subtype ) ) {
|
||||||
|
// Set "Channel" directly - this allows Color and Direct PWM control to coexist
|
||||||
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
|
||||||
|
uint8_t level = XdrvMailbox.payload;
|
||||||
|
light_current_color[XdrvMailbox.index-1] = round(level * 2.55);
|
||||||
|
LightSetColor();
|
||||||
|
coldim = true;
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, round(light_current_color[XdrvMailbox.index -1] / 2.55));
|
||||||
|
}
|
||||||
|
else if ((CMND_HSBCOLOR == command_code) && ( light_subtype >= LST_RGB)) {
|
||||||
|
// Implement method to "direct set" color by HSB (HSB is passed comma separated, 0<H<360 0<S<100 0<B<100 )
|
||||||
|
uint16_t HSB[3];
|
||||||
|
bool validHSB = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
char *substr;
|
||||||
|
|
||||||
|
if (0 == i) {
|
||||||
|
substr = strtok(XdrvMailbox.data, ",");
|
||||||
|
} else {
|
||||||
|
substr = strtok(NULL, ",");
|
||||||
|
}
|
||||||
|
if (substr != NULL) {
|
||||||
|
HSB[i] = atoi(substr);
|
||||||
|
} else {
|
||||||
|
validHSB = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (validHSB) {
|
||||||
|
// Translate to fractional elements as required by LightHsbToRgb
|
||||||
|
// Keep the results <=1 in the event someone passes something
|
||||||
|
// out of range.
|
||||||
|
LightSetHsb(( (HSB[0]>360) ? (HSB[0] % 360) : HSB[0] ) /360.0,
|
||||||
|
( (HSB[1]>100) ? (HSB[1] % 100) : HSB[1] ) /100.0,
|
||||||
|
( (HSB[2]>100) ? (HSB[2] % 100) : HSB[2] ) /100.0,
|
||||||
|
0);
|
||||||
|
} else {
|
||||||
|
LightState(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifdef USE_WS2812 // ***********************************************************************
|
#ifdef USE_WS2812 // ***********************************************************************
|
||||||
else if ((CMND_LED == command_code) && (LT_WS2812 == light_type) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= Settings.light_pixels)) {
|
else if ((CMND_LED == command_code) && (LT_WS2812 == light_type) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= Settings.light_pixels)) {
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
149
sonoff/xdrv_08_serial_bridge.ino
Normal file
149
sonoff/xdrv_08_serial_bridge.ino
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
xdrv_08_serial_bridge.ino - serial bridge support for Sonoff-Tasmota
|
||||||
|
|
||||||
|
Copyright (C) 2018 Theo Arends and Dániel Zoltán Tolnai
|
||||||
|
|
||||||
|
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_SERIAL_BRIDGE
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Serial Bridge using Software Serial library (TasmotaSerial)
|
||||||
|
\*********************************************************************************************/
|
||||||
|
#define SERIAL_BRIDGE_BUFFER_SIZE 130
|
||||||
|
|
||||||
|
#include <TasmotaSerial.h>
|
||||||
|
|
||||||
|
enum SerialBridgeCommands { CMND_SSERIALSEND, CMND_SBAUDRATE };
|
||||||
|
const char kSerialBridgeCommands[] PROGMEM = D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE;
|
||||||
|
|
||||||
|
TasmotaSerial *SerialBridgeSerial;
|
||||||
|
|
||||||
|
uint8_t serial_bridge_active = 1;
|
||||||
|
uint8_t serial_bridge_in_byte_counter = 0;
|
||||||
|
unsigned long serial_bridge_polling_window = 0;
|
||||||
|
char serial_bridge_buffer[SERIAL_BRIDGE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
void SerialBridgeInput()
|
||||||
|
{
|
||||||
|
while (SerialBridgeSerial->available()) {
|
||||||
|
yield();
|
||||||
|
uint8_t serial_in_byte = SerialBridgeSerial->read();
|
||||||
|
|
||||||
|
if (serial_in_byte > 127) { // binary data...
|
||||||
|
serial_bridge_in_byte_counter = 0;
|
||||||
|
SerialBridgeSerial->flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (serial_in_byte) {
|
||||||
|
if ((serial_in_byte_counter < sizeof(serial_bridge_buffer) -1) && (serial_in_byte != Settings.serial_delimiter)) { // add char to string if it still fits
|
||||||
|
serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte;
|
||||||
|
serial_bridge_polling_window = millis(); // Wait for more data
|
||||||
|
} else {
|
||||||
|
serial_bridge_polling_window = 0; // Publish now
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serial_bridge_in_byte_counter && (millis() > (serial_bridge_polling_window + SERIAL_POLLING))) {
|
||||||
|
serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // serial data completed
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\"%s\"}"), serial_bridge_buffer);
|
||||||
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED));
|
||||||
|
serial_bridge_in_byte_counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
|
||||||
|
void SerialBridgeInit(void)
|
||||||
|
{
|
||||||
|
serial_bridge_active = 0;
|
||||||
|
if ((pin[GPIO_SBR_RX] < 99) && (pin[GPIO_SBR_TX] < 99)) {
|
||||||
|
SerialBridgeSerial = new TasmotaSerial(pin[GPIO_SBR_RX], pin[GPIO_SBR_TX]);
|
||||||
|
if (SerialBridgeSerial->begin(Settings.sbaudrate * 1200)) { // Baud rate is stored div 1200 so it fits into one byte
|
||||||
|
serial_bridge_active = 1;
|
||||||
|
SerialBridgeSerial->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Commands
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
boolean SerialBridgeCommand()
|
||||||
|
{
|
||||||
|
char command [CMDSZ];
|
||||||
|
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 (XdrvMailbox.data_len > 0) {
|
||||||
|
if (1 == XdrvMailbox.index) {
|
||||||
|
SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||||
|
SerialBridgeSerial->write("\n");
|
||||||
|
}
|
||||||
|
else if (2 == XdrvMailbox.index) {
|
||||||
|
SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len);
|
||||||
|
}
|
||||||
|
else if (3 == XdrvMailbox.index) {
|
||||||
|
SerialBridgeSerial->write(Unescape(XdrvMailbox.data, &XdrvMailbox.data_len), XdrvMailbox.data_len);
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CMND_SBAUDRATE == command_code) {
|
||||||
|
char *p;
|
||||||
|
int baud = strtol(XdrvMailbox.data, &p, 10);
|
||||||
|
if (baud > 0) {
|
||||||
|
baud /= 1200; // Make it a valid baudrate
|
||||||
|
Settings.sbaudrate = (1 == XdrvMailbox.payload) ? SOFT_BAUDRATE / 1200 : baud;
|
||||||
|
SerialBridgeSerial->begin(Settings.sbaudrate * 1200); // Reinitialize serial port with new baud rate
|
||||||
|
}
|
||||||
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_LVALUE, command, Settings.sbaudrate * 1200);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
serviced = false; // Unknown command
|
||||||
|
}
|
||||||
|
return serviced;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************\
|
||||||
|
* Interface
|
||||||
|
\*********************************************************************************************/
|
||||||
|
|
||||||
|
#define XDRV_08
|
||||||
|
|
||||||
|
boolean Xdrv08(byte function)
|
||||||
|
{
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
if (serial_bridge_active) {
|
||||||
|
switch (function) {
|
||||||
|
case FUNC_INIT:
|
||||||
|
SerialBridgeInit();
|
||||||
|
break;
|
||||||
|
case FUNC_LOOP:
|
||||||
|
SerialBridgeInput();
|
||||||
|
break;
|
||||||
|
case FUNC_COMMAND:
|
||||||
|
result = SerialBridgeCommand();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_SERIAL_BRIDGE
|
Loading…
x
Reference in New Issue
Block a user