2018-03-20 13:31:11 +00:00
/*
2019-10-27 10:13:24 +00:00
xdrv_08_serial_bridge . ino - serial bridge support for Tasmota
2018-03-20 13:31:11 +00:00
2021-01-01 12:44:04 +00:00
Copyright ( C ) 2021 Theo Arends and Dániel Zoltán Tolnai
2018-03-20 13:31:11 +00:00
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 )
2024-06-11 11:41:19 +01:00
*
* SBaudrate < baudrate > - Set baudrate
* SBaudrate 9600
* SSerialConfig < config > - Set serial config
* SSerialConfig 8 N1
* SSerialBuffer < size > - Set serial receive buffer
* SSerialSend " Hello Tiger " - Send " Hello Tiger \n "
* SSerialSend - Set to text decoding
* SSerialSend1 " Hello Tiger " - Send " Hello Tiger \n "
* SSerialSend2 " Hello Tiger " - Send " Hello Tiger "
* SSerialSend3 " Hello Tiger " - Send " Hello Tiger \f "
* SSerialSend4 - Set to binary decoding
* SSerialSend4 " Hello Tiger " - Send " Hello Tiger " and set to binary decoding
* SSerialSend5 " AA004566 " - Send " AA004566 " as hex values
* SSerialSend6 " 72,101,108,108 " - Send decimals as hex values
2024-06-11 16:27:39 +01:00
* SSerialMode 0 - Default mode ( Console tee off , 115200 bps , 8 N1 )
* SSerialMode 1 - Enable console tee
* SSerialMode 2 - Enable dump of serial data in log level 4
* SSerialMode 3 - Enable Sonoff WTS01 sensor decoding ( ESP32 only )
2024-06-11 11:41:19 +01:00
* SerialDelimiter 255 - Receive data between 32 and 127 only
* SerialDelimiter 254 - Receive hexadecimal data
* SerialDelimiter 128 - Receive no data between 32 and 127
2018-03-20 13:31:11 +00:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-11-07 09:30:03 +00:00
# define XDRV_08 8
2020-08-30 11:09:18 +01:00
# define HARDWARE_FALLBACK 2
2018-11-07 09:30:03 +00:00
2022-06-06 17:08:02 +01:00
# define USE_SERIAL_BRIDGE_TEE
2024-06-11 16:27:39 +01:00
# ifdef ESP32
# define USE_SERIAL_BRIDGE_WTS01
# endif // ESP32
2022-11-18 15:21:54 +00:00
# ifdef SERIAL_BRIDGE_BUFFER_SIZE
const uint16_t SERIAL_BRIDGE_BUFSIZE = SERIAL_BRIDGE_BUFFER_SIZE ;
# else
# ifdef ESP8266
const uint16_t SERIAL_BRIDGE_BUFSIZE = MIN_INPUT_BUFFER_SIZE ; // 256
# else
const uint16_t SERIAL_BRIDGE_BUFSIZE = INPUT_BUFFER_SIZE ; // 800
# endif // ESP32
# endif // SERIAL_BRIDGE_BUFFER_SIZE
2024-06-11 16:27:39 +01:00
enum SerialBridgeModes { SB_NONE , SB_TEE , SB_DUMP , SB_WTS01 } ;
2019-08-11 17:12:18 +01:00
const char kSerialBridgeCommands [ ] PROGMEM = " | " // No prefix
2024-06-11 16:27:39 +01:00
D_CMND_SSERIALSEND " | " D_CMND_SBAUDRATE " | " D_CMND_SSERIALBUFFER " | " D_CMND_SSERIALCONFIG " | " D_CMND_SSERIALMODE ;
2018-03-20 13:31:11 +00:00
2019-11-24 11:24:35 +00:00
void ( * const SerialBridgeCommand [ ] ) ( void ) PROGMEM = {
2024-06-11 16:27:39 +01:00
& CmndSSerialSend , & CmndSBaudrate , & CmndSSerialBuffer , & CmndSSerialConfig , & CmndSSerialMode } ;
2018-03-20 13:31:11 +00:00
2019-08-11 17:12:18 +01:00
# include <TasmotaSerial.h>
2019-03-26 17:26:50 +00:00
TasmotaSerial * SerialBridgeSerial = nullptr ;
2018-03-20 13:31:11 +00:00
2019-03-26 17:26:50 +00:00
char * serial_bridge_buffer = nullptr ;
2024-06-11 16:27:39 +01:00
struct {
uint32_t polling_window ;
int in_byte_counter = 0 ;
float temperature ;
bool raw = false ;
} SBridge ;
2018-03-20 13:31:11 +00:00
2021-12-25 11:58:24 +00:00
/********************************************************************************************/
bool SetSSerialBegin ( void ) {
2021-12-30 13:39:22 +00:00
return SerialBridgeSerial - > begin ( Settings - > sbaudrate * 300 , ConvertSerialConfig ( Settings - > sserial_config ) ) ; // Reinitialize serial port with new baud rate
2021-12-25 11:58:24 +00:00
}
void SetSSerialConfig ( uint32_t serial_config ) {
if ( serial_config > TS_SERIAL_8O2 ) {
serial_config = TS_SERIAL_8N1 ;
}
if ( serial_config ! = Settings - > sserial_config ) {
Settings - > sserial_config = serial_config ;
SetSSerialBegin ( ) ;
}
}
2022-06-07 09:03:12 +01:00
void SerialBridgePrintf ( PGM_P formatP , . . . ) {
2022-06-06 17:08:02 +01:00
# ifdef USE_SERIAL_BRIDGE_TEE
2024-06-11 16:27:39 +01:00
if ( ( SB_TEE = = Settings - > sserial_mode ) & & serial_bridge_buffer ) {
2022-06-07 09:03:12 +01:00
va_list arg ;
va_start ( arg , formatP ) ;
char * data = ext_vsnprintf_malloc_P ( formatP , arg ) ;
va_end ( arg ) ;
if ( data = = nullptr ) { return ; }
2022-11-12 14:03:42 +00:00
// SerialBridgeSerial->printf(data); // This resolves "MqttClientMask":"DVES_%06X" into "DVES_000002"
SerialBridgeSerial - > print ( data ) ; // This does not resolve "DVES_%06X"
2022-06-07 09:03:12 +01:00
free ( data ) ;
2022-06-06 16:48:40 +01:00
}
2022-06-06 17:08:02 +01:00
# endif // USE_SERIAL_BRIDGE_TEE
2022-06-06 16:48:40 +01:00
}
2021-12-25 11:58:24 +00:00
/********************************************************************************************/
void SerialBridgeInput ( void ) {
2018-03-20 13:31:11 +00:00
while ( SerialBridgeSerial - > available ( ) ) {
yield ( ) ;
2019-02-05 13:13:53 +00:00
uint8_t serial_in_byte = SerialBridgeSerial - > read ( ) ;
2020-05-26 11:35:21 +01:00
2022-06-06 17:08:02 +01:00
# ifdef USE_SERIAL_BRIDGE_TEE
2024-06-11 16:27:39 +01:00
if ( SB_TEE = = Settings - > sserial_mode ) { // CMND_SSERIALSEND9 - Enable logging tee to serialbridge
2022-06-06 16:48:40 +01:00
static bool serial_bridge_overrun = false ;
if ( isprint ( serial_in_byte ) ) { // Any char between 32 and 127
2024-06-11 16:27:39 +01:00
if ( SBridge . in_byte_counter < SERIAL_BRIDGE_BUFSIZE - 1 ) { // Add char to string if it still fits
serial_bridge_buffer [ SBridge . in_byte_counter + + ] = serial_in_byte ;
2022-06-06 16:48:40 +01:00
} else {
serial_bridge_overrun = true ; // Signal overrun but continue reading input to flush until '\n' (EOL)
}
}
else if ( serial_in_byte = = ' \n ' ) {
2024-06-11 16:27:39 +01:00
serial_bridge_buffer [ SBridge . in_byte_counter ] = 0 ; // Serial data completed
2022-06-06 16:48:40 +01:00
TasmotaGlobal . seriallog_level = ( Settings - > seriallog_level < LOG_LEVEL_INFO ) ? ( uint8_t ) LOG_LEVEL_INFO : Settings - > seriallog_level ;
if ( serial_bridge_overrun ) {
AddLog ( LOG_LEVEL_INFO , PSTR ( D_LOG_COMMAND " SSerial buffer overrun " ) ) ;
} else {
AddLog ( LOG_LEVEL_INFO , PSTR ( D_LOG_COMMAND " %s " ) , serial_bridge_buffer ) ;
2022-06-07 09:35:51 +01:00
ExecuteCommand ( serial_bridge_buffer , SRC_SSERIAL ) ;
2022-06-06 16:48:40 +01:00
}
2024-06-11 16:27:39 +01:00
SBridge . in_byte_counter = 0 ;
2022-06-06 16:48:40 +01:00
serial_bridge_overrun = false ;
SerialBridgeSerial - > flush ( ) ;
return ;
}
} else {
2022-06-06 17:08:02 +01:00
# endif // USE_SERIAL_BRIDGE_TEE
2024-06-11 16:27:39 +01:00
SBridge . raw = ( Settings - > sserial_mode > SB_TEE ) ? true : ( 254 = = Settings - > serial_delimiter ) ; // SerialDelimiter
if ( ( serial_in_byte > 127 ) & & ! SBridge . raw ) { // Discard binary data above 127 if no raw reception allowed
SBridge . in_byte_counter = 0 ;
2022-06-06 16:48:40 +01:00
SerialBridgeSerial - > flush ( ) ;
return ;
2018-03-20 13:31:11 +00:00
}
2024-06-11 16:27:39 +01:00
if ( serial_in_byte | | SBridge . raw ) { // Any char between 1 and 127 or any char (0 - 255)
2022-06-06 16:48:40 +01:00
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
2024-06-11 16:27:39 +01:00
! SBridge . raw ; // In raw mode (CMND_SERIALSEND3) there is never a delimiter
2022-06-06 16:48:40 +01:00
2024-06-11 16:27:39 +01:00
if ( ( SBridge . in_byte_counter < SERIAL_BRIDGE_BUFSIZE - 1 ) & & // Add char to string if it still fits and ...
2022-06-06 16:48:40 +01:00
! in_byte_is_delimiter ) { // Char is not a delimiter
2024-06-11 16:27:39 +01:00
serial_bridge_buffer [ SBridge . in_byte_counter + + ] = serial_in_byte ;
2022-06-06 16:48:40 +01:00
}
2020-05-23 16:30:48 +01:00
2024-06-11 16:27:39 +01:00
if ( ( SBridge . in_byte_counter > = SERIAL_BRIDGE_BUFSIZE - 1 ) | | // Send message when buffer is full or ...
2022-06-06 16:48:40 +01:00
in_byte_is_delimiter ) { // Char is delimiter
2024-06-11 16:27:39 +01:00
SBridge . polling_window = 0 ; // Publish now
2022-06-06 16:48:40 +01:00
break ;
}
}
2024-06-11 16:27:39 +01:00
SBridge . polling_window = millis ( ) ; // Wait for more data
2022-06-06 17:08:02 +01:00
# ifdef USE_SERIAL_BRIDGE_TEE
2018-03-20 13:31:11 +00:00
}
2022-06-06 17:08:02 +01:00
# endif // USE_SERIAL_BRIDGE_TEE
}
# ifdef USE_SERIAL_BRIDGE_TEE
2024-08-23 10:22:26 +01:00
if ( SB_TEE = = Settings - > sserial_mode ) { // CMND_SSERIALSEND9 - Enable logging tee to serialbridge
2022-06-06 17:08:02 +01:00
return ;
2018-03-20 13:31:11 +00:00
}
2022-06-06 17:08:02 +01:00
# endif // USE_SERIAL_BRIDGE_TEE
2018-03-20 13:31:11 +00:00
2024-06-11 16:27:39 +01:00
if ( SBridge . in_byte_counter & & ( millis ( ) > ( SBridge . polling_window + SERIAL_POLLING ) ) ) {
serial_bridge_buffer [ SBridge . in_byte_counter ] = 0 ; // Serial data completed
if ( SB_NONE = = Settings - > sserial_mode ) {
bool assume_json = ( ! SBridge . raw & & ( serial_bridge_buffer [ 0 ] = = ' { ' ) ) ;
TasmotaGlobal . serial_skip + + ; // SetOption35 Skip number of serial messages received (default 0)
if ( TasmotaGlobal . serial_skip > Settings - > param [ P_SERIAL_SKIP ] ) { // Handle intermediate changes to SetOption35
TasmotaGlobal . serial_skip = 0 ;
Response_P ( PSTR ( " { \" " D_JSON_SSERIALRECEIVED " \" : " ) ) ;
if ( assume_json ) {
ResponseAppend_P ( serial_bridge_buffer ) ;
} else {
ResponseAppend_P ( PSTR ( " \" " ) ) ;
if ( SBridge . raw ) {
ResponseAppend_P ( PSTR ( " %*_H " ) , SBridge . in_byte_counter , serial_bridge_buffer ) ;
} else {
ResponseAppend_P ( EscapeJSONString ( serial_bridge_buffer ) . c_str ( ) ) ;
}
ResponseAppend_P ( PSTR ( " \" " ) ) ;
}
ResponseJsonEnd ( ) ;
2024-06-14 10:23:03 +01:00
if ( Settings - > flag6 . mqtt_disable_publish ) { // SetOption147 - If it is activated, Tasmota will not publish SSerialReceived MQTT messages, but it will proccess event trigger rules
2024-06-11 16:27:39 +01:00
XdrvRulesProcess ( 0 ) ;
2022-11-20 11:52:24 +00:00
} else {
2024-06-11 16:27:39 +01:00
MqttPublishPrefixTopicRulesProcess_P ( RESULT_OR_TELE , PSTR ( D_JSON_SSERIALRECEIVED ) ) ;
2022-11-20 11:52:24 +00:00
}
2020-05-24 16:15:06 +01:00
}
2024-06-11 16:27:39 +01:00
}
2022-06-06 17:08:02 +01:00
2024-06-11 16:27:39 +01:00
if ( Settings - > sserial_mode > SB_TEE ) {
AddLog ( LOG_LEVEL_DEBUG_MORE , PSTR ( " SBR: Rcvd '%*_H' " ) , SBridge . in_byte_counter , serial_bridge_buffer ) ;
}
# ifdef USE_SERIAL_BRIDGE_WTS01
// Sonoff WTS01 9600bps, 8N1 datagram every second
// 0 1 2 3 4 5 6 7 8
// 55 01 01 04 01 11 16 12 95
// header T Td Ck - T = Temperature, Td = Temperature decimal, Ck = Checksum
if ( SB_WTS01 = = Settings - > sserial_mode ) {
if ( 9 = = SBridge . in_byte_counter ) {
uint32_t * header = ( uint32_t * ) serial_bridge_buffer ;
if ( 0x04010155 = = * header ) {
2024-10-14 14:28:33 +01:00
/*
14 : 43 : 26.718 WTS : buf6 0x01 , buf7 0x5d , temp 1 , dec 93 1.93
14 : 43 : 33.175 WTS : buf6 0x01 , buf7 0x12 , temp 1 , dec 18 1.18
14 : 43 : 34.252 WTS : buf6 0x01 , buf7 0x06 , temp 1 , dec 6 1.06
14 : 43 : 35.328 WTS : buf6 0x00 , buf7 0x5d , temp 0 , dec 93 0.93
14 : 43 : 42.862 WTS : buf6 0x00 , buf7 0x0c , temp 0 , dec 12 0.12
14 : 43 : 43.938 WTS : buf6 0x00 , buf7 0x00 , temp 0 , dec 0 0.00
14 : 43 : 45.015 WTS : buf6 0x80 , buf7 0x0c , temp 128 , dec 12 - 0.12
14 : 43 : 53.624 WTS : buf6 0x80 , buf7 0x5d , temp 128 , dec 93 - 0.93
14 : 43 : 54.700 WTS : buf6 0x81 , buf7 0x06 , temp 129 , dec 6 - 1.06
*/
uint8_t temp = serial_bridge_buffer [ 6 ] ;
int sign = 1 ;
if ( temp > 127 ) {
temp - = 128 ;
sign = - 1 ;
}
SBridge . temperature = sign * ( ( float ) temp + ( ( float ) serial_bridge_buffer [ 7 ] / 100.0f ) ) ;
2024-06-11 16:27:39 +01:00
}
2022-11-20 11:52:24 +00:00
}
2022-11-10 15:02:00 +00:00
}
2024-06-11 16:27:39 +01:00
# endif // USE_SERIAL_BRIDGE_WTS01
2022-11-20 11:52:24 +00:00
2024-06-11 16:27:39 +01:00
SBridge . in_byte_counter = 0 ;
2018-03-20 13:31:11 +00:00
}
}
/********************************************************************************************/
2022-06-06 16:48:40 +01:00
void SerialBridgeInit ( void ) {
2024-06-11 11:41:19 +01:00
if ( PinUsed ( GPIO_SBR_RX ) | | PinUsed ( GPIO_SBR_TX ) ) {
2024-08-23 10:22:26 +01:00
SerialBridgeSerial = new TasmotaSerial ( Pin ( GPIO_SBR_RX ) ,
Pin ( GPIO_SBR_TX ) ,
HARDWARE_FALLBACK ,
0 , // Software receive mode (FALLING edge)
MIN_INPUT_BUFFER_SIZE , // 256
Settings - > flag3 . sb_receive_invert ) ; // SetOption69 - (Serial) Invert Serial receive on SerialBridge
2021-12-25 11:58:24 +00:00
if ( SetSSerialBegin ( ) ) {
2019-02-09 15:08:09 +00:00
if ( SerialBridgeSerial - > hardwareSerial ( ) ) {
ClaimSerial ( ) ;
2020-10-30 11:29:48 +00:00
serial_bridge_buffer = TasmotaGlobal . serial_in_buffer ; // Use idle serial buffer to save RAM
2019-02-09 15:08:09 +00:00
} else {
2022-11-18 15:21:54 +00:00
serial_bridge_buffer = ( char * ) ( malloc ( SERIAL_BRIDGE_BUFSIZE ) ) ;
2018-11-27 11:09:36 +00:00
}
2022-11-11 15:10:39 +00:00
# ifdef ESP32
AddLog ( LOG_LEVEL_DEBUG , PSTR ( " SBR: Serial UART%d " ) , SerialBridgeSerial - > getUart ( ) ) ;
# endif
2023-12-28 16:53:21 +00:00
SerialBridgeSerial - > flush ( ) ;
SerialBridgePrintf ( " \r \n " ) ;
2018-03-20 13:31:11 +00:00
}
}
}
/*********************************************************************************************\
* Commands
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2022-06-06 16:48:40 +01:00
void CmndSSerialSend ( void ) {
2024-06-11 16:27:39 +01:00
if ( Settings - > sserial_mode > SB_DUMP ) { return ; } // Not supported in receive only mode
2022-12-04 14:09:39 +00:00
if ( XdrvMailbox . index > 9 ) { XdrvMailbox . index - = 10 ; }
2020-07-21 11:42:18 +01:00
if ( ( XdrvMailbox . index > 0 ) & & ( XdrvMailbox . index < = 6 ) ) {
2024-06-11 16:27:39 +01:00
SBridge . raw = ( XdrvMailbox . index > 3 ) ;
2019-02-09 15:08:09 +00:00
if ( XdrvMailbox . data_len > 0 ) {
2018-03-20 13:31:11 +00:00
if ( 1 = = XdrvMailbox . index ) {
2019-02-09 15:08:09 +00:00
SerialBridgeSerial - > write ( XdrvMailbox . data , XdrvMailbox . data_len ) ; // "Hello Tiger"
SerialBridgeSerial - > write ( " \n " ) ; // "\n"
2018-03-20 13:31:11 +00:00
}
2019-02-09 15:08:09 +00:00
else if ( ( 2 = = XdrvMailbox . index ) | | ( 4 = = XdrvMailbox . index ) ) {
SerialBridgeSerial - > write ( XdrvMailbox . data , XdrvMailbox . data_len ) ; // "Hello Tiger" or "A0"
2018-03-20 13:31:11 +00:00
}
2019-02-09 15:08:09 +00:00
else if ( 3 = = XdrvMailbox . index ) { // "Hello\f"
2018-03-20 13:31:11 +00:00
SerialBridgeSerial - > write ( Unescape ( XdrvMailbox . data , & XdrvMailbox . data_len ) , XdrvMailbox . data_len ) ;
}
2019-02-09 15:08:09 +00:00
else if ( 5 = = XdrvMailbox . index ) {
2019-01-17 16:48:34 +00:00
char * p ;
char stemp [ 3 ] ;
uint8_t code ;
char * codes = RemoveSpace ( XdrvMailbox . data ) ;
int size = strlen ( XdrvMailbox . data ) ;
2019-10-15 07:27:32 +01:00
while ( size > 1 ) {
2019-03-08 18:24:02 +00:00
strlcpy ( stemp , codes , sizeof ( stemp ) ) ;
2019-01-17 16:48:34 +00:00
code = strtol ( stemp , & p , 16 ) ;
2019-02-09 15:08:09 +00:00
SerialBridgeSerial - > write ( code ) ; // "AA004566" as hex values
2019-01-17 16:48:34 +00:00
size - = 2 ;
codes + = 2 ;
}
}
2020-07-21 11:42:18 +01:00
else if ( 6 = = XdrvMailbox . index ) {
char * p ;
uint8_t code ;
char * values = XdrvMailbox . data ;
for ( char * str = strtok_r ( values , " , " , & p ) ; str ; str = strtok_r ( nullptr , " , " , & p ) ) {
code = ( uint8_t ) atoi ( str ) ;
SerialBridgeSerial - > write ( code ) ; // "72,101,108,108"
}
}
2019-08-03 12:01:34 +01:00
ResponseCmndDone ( ) ;
2018-03-20 13:31:11 +00:00
}
}
2019-08-01 16:33:44 +01:00
}
2018-11-27 11:09:36 +00:00
2021-12-25 11:58:24 +00:00
void CmndSBaudrate ( void ) {
2019-08-28 11:02:27 +01:00
if ( XdrvMailbox . payload > = 300 ) {
XdrvMailbox . payload / = 300 ; // Make it a valid baudrate
2021-06-11 17:14:12 +01:00
Settings - > sbaudrate = XdrvMailbox . payload ;
2021-12-25 11:58:24 +00:00
SetSSerialBegin ( ) ;
2019-08-01 16:33:44 +01:00
}
2021-06-11 17:14:12 +01:00
ResponseCmndNumber ( Settings - > sbaudrate * 300 ) ;
2018-03-20 13:31:11 +00:00
}
2022-11-18 12:00:59 +00:00
void CmndSSerialBuffer ( void ) {
// Allow non-pesistent serial receive buffer size change
if ( SerialBridgeSerial - > hardwareSerial ( ) ) {
// between MIN_INPUT_BUFFER_SIZE and MAX_INPUT_BUFFER_SIZE characters
CmndSerialBuffer ( ) ;
} else {
2022-11-18 15:21:54 +00:00
// ESP8266 (software serial): between MIN_INPUT_BUFFER_SIZE and SERIAL_BRIDGE_BUFSIZE characters
2022-11-18 12:00:59 +00:00
// ESP32 (hardware serial only): between MIN_INPUT_BUFFER_SIZE and MAX_INPUT_BUFFER_SIZE characters
if ( XdrvMailbox . data_len > 0 ) {
size_t size = XdrvMailbox . payload ;
2022-11-18 15:21:54 +00:00
if ( XdrvMailbox . payload < MIN_INPUT_BUFFER_SIZE ) {
size = MIN_INPUT_BUFFER_SIZE ; // 256 / 256
2022-11-18 12:00:59 +00:00
}
2022-11-18 15:21:54 +00:00
else if ( XdrvMailbox . payload > SERIAL_BRIDGE_BUFSIZE ) {
size = SERIAL_BRIDGE_BUFSIZE ; // 256 / 800
2022-11-18 12:00:59 +00:00
}
SerialBridgeSerial - > setRxBufferSize ( size ) ;
}
ResponseCmndNumber ( SerialBridgeSerial - > getRxBufferSize ( ) ) ;
}
}
2021-12-25 11:58:24 +00:00
void CmndSSerialConfig ( void ) {
// See TasmotaSerialConfig for possible options
// SSerialConfig 0..23 where 3 equals 8N1
// SSerialConfig 8N1
if ( XdrvMailbox . data_len > 0 ) {
if ( XdrvMailbox . data_len < 3 ) { // Use 0..23 as serial config option
if ( ( XdrvMailbox . payload > = TS_SERIAL_5N1 ) & & ( XdrvMailbox . payload < = TS_SERIAL_8O2 ) ) {
SetSSerialConfig ( XdrvMailbox . payload ) ;
}
}
else if ( ( XdrvMailbox . payload > = 5 ) & & ( XdrvMailbox . payload < = 8 ) ) {
int8_t serial_config = ParseSerialConfig ( XdrvMailbox . data ) ;
if ( serial_config > = 0 ) {
SetSSerialConfig ( serial_config ) ;
}
}
}
ResponseCmndChar ( GetSerialConfig ( Settings - > sserial_config ) . c_str ( ) ) ;
}
2024-06-11 16:27:39 +01:00
void CmndSSerialMode ( void ) {
// SSerialMode 0 - Default mode (Tee off, 115200bps, 8N1)
// SSerialMode 1 - Toggle console tee
// SSerialMode 2 - Dump hex data to log level 4 for analysis
// SSerialMode 3 - Sonoff WTS01 decode
if ( XdrvMailbox . payload > = 0 ) {
switch ( XdrvMailbox . payload ) {
case SB_NONE :
Settings - > sserial_mode = XdrvMailbox . payload ;
// Settings->serial_delimiter = 255;
Settings - > sbaudrate = 115200 / 300 ; // 115200bps
SetSSerialConfig ( 3 ) ; // 8N1
break ;
# ifdef USE_SERIAL_BRIDGE_TEE
case SB_TEE :
Settings - > sserial_mode = XdrvMailbox . payload ;
break ;
# endif // USE_SERIAL_BRIDGE_TEE
case SB_DUMP :
Settings - > sserial_mode = XdrvMailbox . payload ;
break ;
# ifdef USE_SERIAL_BRIDGE_WTS01
case SB_WTS01 :
Settings - > sserial_mode = XdrvMailbox . payload ;
2024-08-23 10:22:26 +01:00
Settings - > flag3 . sb_receive_invert = 0 ; // SetOption69 - (Serial) Invert Serial receive on SerialBridge
2024-06-11 16:27:39 +01:00
Settings - > sbaudrate = 9600 / 300 ; // 9600bps
SetSSerialConfig ( 3 ) ; // 8N1
break ;
# endif // USE_SERIAL_BRIDGE_WTS01
default :
return ; // Not supported
}
}
ResponseCmndNumber ( Settings - > sserial_mode ) ;
}
/*********************************************************************************************\
* Presentation
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void SerialBridgeShow ( bool json ) {
# ifdef USE_SERIAL_BRIDGE_WTS01
if ( SB_WTS01 = = Settings - > sserial_mode ) {
float temperature = ConvertTemp ( SBridge . temperature ) ;
if ( json ) {
ResponseAppend_P ( PSTR ( " , \" WTS01 \" :{ \" " D_JSON_TEMPERATURE " \" :%*_f} " ) , Settings - > flag2 . temperature_resolution , & temperature ) ;
# ifdef USE_DOMOTICZ
if ( 0 = = TasmotaGlobal . tele_period ) { DomoticzFloatSensor ( DZ_TEMP , temperature ) ; }
# endif // USE_DOMOTICZ
# ifdef USE_KNX
if ( 0 = = TasmotaGlobal . tele_period ) { KnxSensor ( KNX_TEMPERATURE , temperature ) ; }
# endif // USE_KNX
# ifdef USE_WEBSERVER
} else {
WSContentSend_Temp ( " WTS01 " , temperature ) ;
# endif // USE_WEBSERVER
}
}
# endif // USE_SERIAL_BRIDGE_WTS01
}
2018-03-20 13:31:11 +00:00
/*********************************************************************************************\
* Interface
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2022-11-11 09:44:56 +00:00
bool Xdrv08 ( uint32_t function ) {
2019-01-28 13:08:33 +00:00
bool result = false ;
2018-03-20 13:31:11 +00:00
2022-06-06 16:48:40 +01:00
if ( FUNC_PRE_INIT = = function ) {
SerialBridgeInit ( ) ;
}
else if ( serial_bridge_buffer ) {
2018-03-20 13:31:11 +00:00
switch ( function ) {
case FUNC_LOOP :
2022-11-11 08:57:00 +00:00
case FUNC_SLEEP_LOOP :
2022-06-06 16:48:40 +01:00
SerialBridgeInput ( ) ;
2019-03-30 12:03:45 +00:00
break ;
2024-06-11 16:27:39 +01:00
case FUNC_JSON_APPEND :
SerialBridgeShow ( 1 ) ;
break ;
# ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR :
SerialBridgeShow ( 0 ) ;
break ;
# endif // USE_WEBSERVER
2018-03-20 13:31:11 +00:00
case FUNC_COMMAND :
2019-08-01 16:33:44 +01:00
result = DecodeCommand ( kSerialBridgeCommands , SerialBridgeCommand ) ;
2018-03-20 13:31:11 +00:00
break ;
2023-12-27 21:03:56 +00:00
case FUNC_ACTIVE :
result = true ;
break ;
2018-03-20 13:31:11 +00:00
}
}
return result ;
}
# endif // USE_SERIAL_BRIDGE