Add command `SSerialSend9 0/1` to enable Serial Bridge console Tee for debugging purposes

This commit is contained in:
Theo Arends 2022-06-06 17:48:40 +02:00
parent a7d7b571ee
commit 44ce19f26f
8 changed files with 169 additions and 73 deletions

View File

@ -7,9 +7,11 @@ All notable changes to this project will be documented in this file.
### Added ### Added
- Support for HYTxxx temperature and humidity sensor (#15715) - Support for HYTxxx temperature and humidity sensor (#15715)
- Support for Sensirion SHT4X using define USE_SHT3X (#15349) - Support for Sensirion SHT4X using define USE_SHT3X (#15349)
- Command ``SSerialSend9 0/1`` to enable Serial Bridge console Tee for debugging purposes
### Changed ### Changed
- Restructured tasmota source directories taking benefit from PlatformIO Core v6.0.2 - Restructured tasmota source directories taking benefit from PlatformIO Core v6.0.2
- ESP32 increase Serial Bridge input buffer from 130 to 520 characters
### Fixed ### Fixed

View File

@ -112,6 +112,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Command ``EnergyExportActive<phase>`` to (p)reset energy export active for supported devices. Currently ADE7880 only [#13515](https://github.com/arendst/Tasmota/issues/13515) - Command ``EnergyExportActive<phase>`` to (p)reset energy export active for supported devices. Currently ADE7880 only [#13515](https://github.com/arendst/Tasmota/issues/13515)
- Command ``IfxRp ""|<policy>`` adds optional InfluxDb Retention Policy [#15513](https://github.com/arendst/Tasmota/issues/15513) - Command ``IfxRp ""|<policy>`` adds optional InfluxDb Retention Policy [#15513](https://github.com/arendst/Tasmota/issues/15513)
- Command ``SspmDisplay 2`` to display Sonoff SPM energy data in GUI for user tab-selected relay modules [#13447](https://github.com/arendst/Tasmota/issues/13447) - Command ``SspmDisplay 2`` to display Sonoff SPM energy data in GUI for user tab-selected relay modules [#13447](https://github.com/arendst/Tasmota/issues/13447)
- Command ``SSerialSend9 0/1`` to enable Serial Bridge console Tee for debugging purposes
- Support for Sonoff MS01 soil moisture sensor [#15335](https://github.com/arendst/Tasmota/issues/15335) - Support for Sonoff MS01 soil moisture sensor [#15335](https://github.com/arendst/Tasmota/issues/15335)
- Support for daisy chaining MAX7219 displays [#15345](https://github.com/arendst/Tasmota/issues/15345) - Support for daisy chaining MAX7219 displays [#15345](https://github.com/arendst/Tasmota/issues/15345)
- Support for Sensirion SHT4X using define USE_SHT3X [#15349](https://github.com/arendst/Tasmota/issues/15349) - Support for Sensirion SHT4X using define USE_SHT3X [#15349](https://github.com/arendst/Tasmota/issues/15349)
@ -129,6 +130,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Restructured tasmota source directories taking benefit from PlatformIO Core v6.0.2 - Restructured tasmota source directories taking benefit from PlatformIO Core v6.0.2
- Prepare to remove dedicated Home Assistant discovery in favour of Tasmota Discovery and hatasmota - Prepare to remove dedicated Home Assistant discovery in favour of Tasmota Discovery and hatasmota
- ESP32 Tasmota SafeBoot with changed partition scheme allowing larger binaries - ESP32 Tasmota SafeBoot with changed partition scheme allowing larger binaries
- ESP32 increase Serial Bridge input buffer from 130 to 520 characters
### Fixed ### Fixed
- Improv initial or erase device installation failing to provide Configure WiFi option - Improv initial or erase device installation failing to provide Configure WiFi option

43
boards/esp32s2usb.json Normal file
View File

@ -0,0 +1,43 @@
{
"build": {
"arduino":{
"ldscript": "esp32s2_out.ld"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_SERIAL_CONSOLE -DESP32_4M -DESP32S2",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dout",
"mcu": "esp32s2",
"variant": "esp32s2",
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s2.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
"name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
"variants/tasmota/tasmota32s2usb-safeboot.bin"
]
]
},
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html",
"vendor": "Espressif"
}

View File

@ -45,6 +45,9 @@ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack
extern "C" void resetPins(); extern "C" void resetPins();
extern "C" int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys, extern "C" int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys,
uint32_t runTimeCcys, int8_t alignPhase, uint32_t phaseOffsetCcys, bool autoPwm); uint32_t runTimeCcys, int8_t alignPhase, uint32_t phaseOffsetCcys, bool autoPwm);
#ifdef USE_SERIAL_BRIDGE
void SerialBridgeLog(const char *mxtime, const char *log_data = nullptr, const char *log_data_payload = nullptr, const char *log_data_retained = nullptr);
#endif
#ifdef USE_INFLUXDB #ifdef USE_INFLUXDB
void InfluxDbProcess(bool use_copy = false); void InfluxDbProcess(bool use_copy = false);
#endif #endif

View File

@ -289,7 +289,7 @@ typedef union {
uint32_t sspm_display : 1; // bit 8 (v10.0.0.4) - CMND_SSPMDISPLAY - Enable gui display of powered on relays only uint32_t sspm_display : 1; // bit 8 (v10.0.0.4) - CMND_SSPMDISPLAY - Enable gui display of powered on relays only
uint32_t local_ntp_server : 1; // bit 9 (v11.0.0.4) - CMND_RTCNTPSERVER - Enable local NTP server uint32_t local_ntp_server : 1; // bit 9 (v11.0.0.4) - CMND_RTCNTPSERVER - Enable local NTP server
uint32_t influxdb_sensor : 1; // bit 10 (v11.0.0.5) - CMND_IFXSENSOR - Enable sensor support in addition to teleperiod support uint32_t influxdb_sensor : 1; // bit 10 (v11.0.0.5) - CMND_IFXSENSOR - Enable sensor support in addition to teleperiod support
uint32_t spare11 : 1; // bit 11 uint32_t serbridge_console : 1; // bit 11 (v11.1.0.4) - CMND_SSERIALSEND9 - Enable logging tee to serialbridge
uint32_t spare12 : 1; // bit 12 uint32_t spare12 : 1; // bit 12
uint32_t spare13 : 1; // bit 13 uint32_t spare13 : 1; // bit 13
uint32_t spare14 : 1; // bit 14 uint32_t spare14 : 1; // bit 14

View File

@ -2594,6 +2594,9 @@ void AddLogData(uint32_t loglevel, const char* log_data, const char* log_data_pa
if ((loglevel <= TasmotaGlobal.seriallog_level) && if ((loglevel <= TasmotaGlobal.seriallog_level) &&
(TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) { (TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) {
TasConsole.printf("%s%s%s%s\r\n", mxtime, log_data, log_data_payload, log_data_retained); TasConsole.printf("%s%s%s%s\r\n", mxtime, log_data, log_data_payload, log_data_retained);
#ifdef USE_SERIAL_BRIDGE
SerialBridgeLog(mxtime, log_data, log_data_payload, log_data_retained);
#endif // USE_SERIAL_BRIDGE
} }
if (!TasmotaGlobal.log_buffer) { return; } // Leave now if there is no buffer available if (!TasmotaGlobal.log_buffer) { return; } // Leave now if there is no buffer available

View File

@ -1634,38 +1634,38 @@ void SerialInput(void)
/*-------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------*/
if (TasmotaGlobal.serial_in_byte > 127 && !Settings->flag.mqtt_serial_raw) { // Discard binary data above 127 if no raw reception allowed - CMND_SERIALSEND3 if (TasmotaGlobal.serial_in_byte > 127 && !Settings->flag.mqtt_serial_raw) { // Discard binary data above 127 if no raw reception allowed - CMND_SERIALSEND3
TasmotaGlobal.serial_in_byte_counter = 0; TasmotaGlobal.serial_in_byte_counter = 0;
Serial.flush(); Serial.flush();
return; return;
} }
if (!Settings->flag.mqtt_serial) { // SerialSend active - CMND_SERIALSEND and CMND_SERIALLOG if (!Settings->flag.mqtt_serial) { // SerialSend active - CMND_SERIALSEND and CMND_SERIALLOG
if (isprint(TasmotaGlobal.serial_in_byte)) { // Any char between 32 and 127 if (isprint(TasmotaGlobal.serial_in_byte)) { // Any char between 32 and 127
if (TasmotaGlobal.serial_in_byte_counter < INPUT_BUFFER_SIZE -1) { // Add char to string if it still fits if (TasmotaGlobal.serial_in_byte_counter < INPUT_BUFFER_SIZE -1) { // Add char to string if it still fits
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = TasmotaGlobal.serial_in_byte; TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = TasmotaGlobal.serial_in_byte;
} else { } else {
serial_buffer_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL) serial_buffer_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL)
} }
} }
} else { } else {
if (TasmotaGlobal.serial_in_byte || Settings->flag.mqtt_serial_raw) { // Any char between 1 and 127 or any char (0 - 255) - CMND_SERIALSEND3 if (TasmotaGlobal.serial_in_byte || Settings->flag.mqtt_serial_raw) { // Any char between 1 and 127 or any char (0 - 255) - CMND_SERIALSEND3
bool in_byte_is_delimiter = // Char is delimiter when... bool in_byte_is_delimiter = // Char is delimiter when...
(((Settings->serial_delimiter < 128) && (TasmotaGlobal.serial_in_byte == Settings->serial_delimiter)) || // Any char between 1 and 127 and being delimiter (((Settings->serial_delimiter < 128) && (TasmotaGlobal.serial_in_byte == Settings->serial_delimiter)) || // Any char between 1 and 127 and being delimiter
((Settings->serial_delimiter == 128) && !isprint(TasmotaGlobal.serial_in_byte))) && // Any char not between 32 and 127 ((Settings->serial_delimiter == 128) && !isprint(TasmotaGlobal.serial_in_byte))) && // Any char not between 32 and 127
!Settings->flag.mqtt_serial_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter !Settings->flag.mqtt_serial_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter
if ((TasmotaGlobal.serial_in_byte_counter < INPUT_BUFFER_SIZE -1) && // Add char to string if it still fits and ... if ((TasmotaGlobal.serial_in_byte_counter < INPUT_BUFFER_SIZE -1) && // Add char to string if it still fits and ...
!in_byte_is_delimiter) { // Char is not a delimiter !in_byte_is_delimiter) { // Char is not a delimiter
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = TasmotaGlobal.serial_in_byte; TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = TasmotaGlobal.serial_in_byte;
} }
if ((TasmotaGlobal.serial_in_byte_counter >= INPUT_BUFFER_SIZE -1) || // Send message when buffer is full or ... if ((TasmotaGlobal.serial_in_byte_counter >= INPUT_BUFFER_SIZE -1) || // Send message when buffer is full or ...
in_byte_is_delimiter) { // Char is delimiter in_byte_is_delimiter) { // Char is delimiter
serial_polling_window = 0; // Reception done - send mqtt serial_polling_window = 0; // Reception done - send mqtt
break; break;
} }
serial_polling_window = millis(); // Wait for next char serial_polling_window = millis(); // Wait for next char
} }
} }
@ -1674,8 +1674,8 @@ void SerialInput(void)
* Sonoff SC 19200 baud serial interface * Sonoff SC 19200 baud serial interface
\*-------------------------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------------------------*/
if (SONOFF_SC == TasmotaGlobal.module_type) { if (SONOFF_SC == TasmotaGlobal.module_type) {
if (TasmotaGlobal.serial_in_byte == '\x1B') { // Sonoff SC status from ATMEGA328P if (TasmotaGlobal.serial_in_byte == '\x1B') { // Sonoff SC status from ATMEGA328P
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed
SonoffScSerialInput(TasmotaGlobal.serial_in_buffer); SonoffScSerialInput(TasmotaGlobal.serial_in_buffer);
TasmotaGlobal.serial_in_byte_counter = 0; TasmotaGlobal.serial_in_byte_counter = 0;
Serial.flush(); Serial.flush();
@ -1689,8 +1689,8 @@ void SerialInput(void)
if (tasconsole_serial) { if (tasconsole_serial) {
#endif // ESP32 #endif // ESP32
if (!Settings->flag.mqtt_serial && (TasmotaGlobal.serial_in_byte == '\n')) { // CMND_SERIALSEND and CMND_SERIALLOG if (!Settings->flag.mqtt_serial && (TasmotaGlobal.serial_in_byte == '\n')) { // CMND_SERIALSEND and CMND_SERIALLOG
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed
TasmotaGlobal.seriallog_level = (Settings->seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings->seriallog_level; TasmotaGlobal.seriallog_level = (Settings->seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings->seriallog_level;
if (serial_buffer_overrun) { if (serial_buffer_overrun) {
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "Serial buffer overrun")); AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "Serial buffer overrun"));
@ -1711,7 +1711,7 @@ void SerialInput(void)
} // endWhile } // endWhile
if (Settings->flag.mqtt_serial && TasmotaGlobal.serial_in_byte_counter && (millis() > (serial_polling_window + SERIAL_POLLING))) { // CMND_SERIALSEND and CMND_SERIALLOG if (Settings->flag.mqtt_serial && TasmotaGlobal.serial_in_byte_counter && (millis() > (serial_polling_window + SERIAL_POLLING))) { // CMND_SERIALSEND and CMND_SERIALLOG
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed
bool assume_json = (!Settings->flag.mqtt_serial_raw && (TasmotaGlobal.serial_in_buffer[0] == '{')); bool assume_json = (!Settings->flag.mqtt_serial_raw && (TasmotaGlobal.serial_in_buffer[0] == '{'));
if (serial_buffer_overrun) { if (serial_buffer_overrun) {
@ -1758,7 +1758,7 @@ void TasConsoleInput(void) {
console_buffer_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL) console_buffer_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL)
} }
} }
if (console_in_byte == '\n') { else if (console_in_byte == '\n') {
TasmotaGlobal.seriallog_level = (Settings->seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings->seriallog_level; TasmotaGlobal.seriallog_level = (Settings->seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings->seriallog_level;
if (console_buffer_overrun) { if (console_buffer_overrun) {
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "Console buffer overrun")); AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "Console buffer overrun"));

View File

@ -25,7 +25,11 @@
#define XDRV_08 8 #define XDRV_08 8
#define HARDWARE_FALLBACK 2 #define HARDWARE_FALLBACK 2
const uint8_t SERIAL_BRIDGE_BUFFER_SIZE = 130; #ifdef ESP8266
const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = 130;
#else
const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = INPUT_BUFFER_SIZE;
#endif
const char kSerialBridgeCommands[] PROGMEM = "|" // No prefix const char kSerialBridgeCommands[] PROGMEM = "|" // No prefix
D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE "|" D_CMND_SSERIALCONFIG; D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE "|" D_CMND_SSERIALCONFIG;
@ -40,7 +44,6 @@ TasmotaSerial *SerialBridgeSerial = nullptr;
unsigned long serial_bridge_polling_window = 0; unsigned long serial_bridge_polling_window = 0;
char *serial_bridge_buffer = nullptr; char *serial_bridge_buffer = nullptr;
int serial_bridge_in_byte_counter = 0; int serial_bridge_in_byte_counter = 0;
bool serial_bridge_active = true;
bool serial_bridge_raw = false; bool serial_bridge_raw = false;
/********************************************************************************************/ /********************************************************************************************/
@ -59,68 +62,104 @@ void SetSSerialConfig(uint32_t serial_config) {
} }
} }
void SerialBridgeLog(const char *mxtime, const char *log_data, const char *log_data_payload, const char *log_data_retained) {
if (Settings->sbflag1.serbridge_console && serial_bridge_buffer) {
char empty[2] = { 0 };
if (!log_data) { log_data = empty; }
if (!log_data_payload) { log_data_payload = empty; }
if (!log_data_retained) { log_data_retained = empty; }
SerialBridgeSerial->printf("%s%s%s%s\r\n", mxtime, log_data, log_data_payload, log_data_retained);
}
}
/********************************************************************************************/ /********************************************************************************************/
void SerialBridgeInput(void) { void SerialBridgeInput(void) {
while (SerialBridgeSerial->available()) { while (SerialBridgeSerial->available()) {
yield(); yield();
uint8_t serial_in_byte = SerialBridgeSerial->read(); uint8_t serial_in_byte = SerialBridgeSerial->read();
serial_bridge_raw = Settings->serial_delimiter == 254;
if ((serial_in_byte > 127) && !serial_bridge_raw) { // Discard binary data above 127 if no raw reception allowed
serial_bridge_in_byte_counter = 0;
SerialBridgeSerial->flush();
return;
}
if (serial_in_byte || serial_bridge_raw) { // Any char between 1 and 127 or any char (0 - 255)
bool in_byte_is_delimiter = // Char is delimiter when...
(((Settings->serial_delimiter < 128) && (serial_in_byte == Settings->serial_delimiter)) || // Any char between 1 and 127 and being delimiter
((Settings->serial_delimiter == 128) && !isprint(serial_in_byte))) && // Any char not between 32 and 127
!serial_bridge_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter
if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) && // Add char to string if it still fits and ... if (Settings->sbflag1.serbridge_console) {
!in_byte_is_delimiter) { // Char is not a delimiter static bool serial_bridge_overrun = false;
serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte;
if (isprint(serial_in_byte)) { // Any char between 32 and 127
if (serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) { // Add char to string if it still fits
serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte;
} else {
serial_bridge_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL)
}
} }
else if (serial_in_byte == '\n') {
if ((serial_bridge_in_byte_counter >= SERIAL_BRIDGE_BUFFER_SIZE -1) || // Send message when buffer is full or ... serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // Serial data completed
in_byte_is_delimiter) { // Char is delimiter TasmotaGlobal.seriallog_level = (Settings->seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings->seriallog_level;
serial_bridge_polling_window = 0; // Publish now if (serial_bridge_overrun) {
break; AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "SSerial buffer overrun"));
} else {
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), serial_bridge_buffer);
ExecuteCommand(serial_bridge_buffer, SRC_SERIAL);
}
serial_bridge_in_byte_counter = 0;
serial_bridge_overrun = false;
SerialBridgeSerial->flush();
return;
} }
} else {
serial_bridge_raw = (254 == Settings->serial_delimiter);
if ((serial_in_byte > 127) && !serial_bridge_raw) { // Discard binary data above 127 if no raw reception allowed
serial_bridge_in_byte_counter = 0;
SerialBridgeSerial->flush();
return;
}
if (serial_in_byte || serial_bridge_raw) { // Any char between 1 and 127 or any char (0 - 255)
bool in_byte_is_delimiter = // Char is delimiter when...
(((Settings->serial_delimiter < 128) && (serial_in_byte == Settings->serial_delimiter)) || // Any char between 1 and 127 and being delimiter
((Settings->serial_delimiter == 128) && !isprint(serial_in_byte))) && // Any char not between 32 and 127
!serial_bridge_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter
serial_bridge_polling_window = millis(); // Wait for more data if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) && // Add char to string if it still fits and ...
!in_byte_is_delimiter) { // Char is not a delimiter
serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte;
}
if ((serial_bridge_in_byte_counter >= SERIAL_BRIDGE_BUFFER_SIZE -1) || // Send message when buffer is full or ...
in_byte_is_delimiter) { // Char is delimiter
serial_bridge_polling_window = 0; // Publish now
break;
}
}
serial_bridge_polling_window = millis(); // Wait for more data
} }
} }
if (serial_bridge_in_byte_counter && (millis() > (serial_bridge_polling_window + SERIAL_POLLING))) { if (!Settings->sbflag1.serbridge_console) {
serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // Serial data completed if (serial_bridge_in_byte_counter && (millis() > (serial_bridge_polling_window + SERIAL_POLLING))) {
bool assume_json = (!serial_bridge_raw && (serial_bridge_buffer[0] == '{')); serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // Serial data completed
bool assume_json = (!serial_bridge_raw && (serial_bridge_buffer[0] == '{'));
Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":")); Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":"));
if (assume_json) { if (assume_json) {
ResponseAppend_P(serial_bridge_buffer); ResponseAppend_P(serial_bridge_buffer);
} else {
ResponseAppend_P(PSTR("\""));
if (serial_bridge_raw) {
char hex_char[(serial_bridge_in_byte_counter * 2) + 2];
ResponseAppend_P(ToHex_P((unsigned char*)serial_bridge_buffer, serial_bridge_in_byte_counter, hex_char, sizeof(hex_char)));
} else { } else {
ResponseAppend_P(EscapeJSONString(serial_bridge_buffer).c_str()); ResponseAppend_P(PSTR("\""));
if (serial_bridge_raw) {
char hex_char[(serial_bridge_in_byte_counter * 2) + 2];
ResponseAppend_P(ToHex_P((unsigned char*)serial_bridge_buffer, serial_bridge_in_byte_counter, hex_char, sizeof(hex_char)));
} else {
ResponseAppend_P(EscapeJSONString(serial_bridge_buffer).c_str());
}
ResponseAppend_P(PSTR("\""));
} }
ResponseAppend_P(PSTR("\"")); ResponseJsonEnd();
}
ResponseJsonEnd();
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED));
serial_bridge_in_byte_counter = 0; serial_bridge_in_byte_counter = 0;
}
} }
} }
/********************************************************************************************/ /********************************************************************************************/
void SerialBridgeInit(void) void SerialBridgeInit(void) {
{
serial_bridge_active = false;
if (PinUsed(GPIO_SBR_RX) && PinUsed(GPIO_SBR_TX)) { if (PinUsed(GPIO_SBR_RX) && PinUsed(GPIO_SBR_TX)) {
SerialBridgeSerial = new TasmotaSerial(Pin(GPIO_SBR_RX), Pin(GPIO_SBR_TX), HARDWARE_FALLBACK); SerialBridgeSerial = new TasmotaSerial(Pin(GPIO_SBR_RX), Pin(GPIO_SBR_TX), HARDWARE_FALLBACK);
if (SetSSerialBegin()) { if (SetSSerialBegin()) {
@ -130,7 +169,6 @@ void SerialBridgeInit(void)
} else { } else {
serial_bridge_buffer = (char*)(malloc(SERIAL_BRIDGE_BUFFER_SIZE)); serial_bridge_buffer = (char*)(malloc(SERIAL_BRIDGE_BUFFER_SIZE));
} }
serial_bridge_active = true;
SerialBridgeSerial->flush(); SerialBridgeSerial->flush();
} }
} }
@ -140,10 +178,10 @@ void SerialBridgeInit(void)
* Commands * Commands
\*********************************************************************************************/ \*********************************************************************************************/
void CmndSSerialSend(void) void CmndSSerialSend(void) {
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) {
serial_bridge_raw = (XdrvMailbox.index > 3); serial_bridge_raw = (XdrvMailbox.index > 3);
Settings->sbflag1.serbridge_console = 0; // Disable console Tee
if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len > 0) {
if (1 == XdrvMailbox.index) { if (1 == XdrvMailbox.index) {
SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len); // "Hello Tiger" SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len); // "Hello Tiger"
@ -183,6 +221,12 @@ void CmndSSerialSend(void)
ResponseCmndDone(); ResponseCmndDone();
} }
} }
if (9 == XdrvMailbox.index) {
if (XdrvMailbox.payload >= 0) {
Settings->sbflag1.serbridge_console = XdrvMailbox.payload &1;
}
ResponseCmndStateText(Settings->sbflag1.serbridge_console);
}
} }
void CmndSBaudrate(void) { void CmndSBaudrate(void) {
@ -219,17 +263,16 @@ void CmndSSerialConfig(void) {
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
bool Xdrv08(uint8_t function) bool Xdrv08(uint8_t function) {
{
bool result = false; bool result = false;
if (serial_bridge_active) { if (FUNC_PRE_INIT == function) {
SerialBridgeInit();
}
else if (serial_bridge_buffer) {
switch (function) { switch (function) {
case FUNC_LOOP: case FUNC_LOOP:
if (SerialBridgeSerial) { SerialBridgeInput(); } SerialBridgeInput();
break;
case FUNC_PRE_INIT:
SerialBridgeInit();
break; break;
case FUNC_COMMAND: case FUNC_COMMAND:
result = DecodeCommand(kSerialBridgeCommands, SerialBridgeCommand); result = DecodeCommand(kSerialBridgeCommands, SerialBridgeCommand);