2017-02-14 13:27:08 +00:00
/*
2019-10-27 10:13:24 +00:00
xdrv_05_irremote . ino - infra red support for Tasmota
2018-11-20 13:10:32 +00:00
2021-01-01 12:44:04 +00:00
Copyright ( C ) 2021 Heiko Krupp , Lazar Obradovic and Theo Arends
2018-11-20 13:10:32 +00:00
2017-05-13 12:02:10 +01: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 .
2018-11-20 13:10:32 +00:00
2017-05-13 12:02:10 +01:00
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 .
2018-11-20 13:10:32 +00:00
2017-05-13 12:02:10 +01:00
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2017-02-14 13:27:08 +00:00
*/
2020-10-01 22:10:17 +01:00
/*
Below is the Pyhton3 code to decompress IR comact format .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
import re
def ir_expand ( ir_compact ) :
count = ir_compact . count ( ' , ' ) # number of occurence of comma
if count > 1 :
return " Unsupported format "
if count = = 1 :
ir_compact = input . split ( ' , ' ) [ 1 ] # if 1 comma , skip the frequency
arr = re . findall ( " ( \ d+|[A-Za-z]) " , ir_compact )
comp_table = [ ] # compression history table
arr2 = [ ] # output
for elt in arr :
if len ( elt ) = = 1 :
c = ord ( elt . upper ( ) ) - ord ( ' A ' )
if c > = len ( arr ) : return " Error index undefined "
arr2 . append ( comp_table [ c ] )
else :
comp_table . append ( elt )
arr2 . append ( elt )
out = " , " . join ( arr2 )
return out
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2019-08-28 21:01:01 +01:00
# if defined(USE_IR_REMOTE) && !defined(USE_IR_REMOTE_FULL)
2017-02-14 13:27:08 +00:00
/*********************************************************************************************\
2017-10-06 16:28:00 +01:00
* IR Remote send and receive using IRremoteESP8266 library
2017-02-14 13:27:08 +00:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-11-07 09:30:03 +00:00
# define XDRV_05 5
2017-10-08 15:51:05 +01:00
# include <IRremoteESP8266.h>
2020-10-01 22:10:17 +01:00
# include <IRutils.h>
2017-11-19 17:02:03 +00:00
2020-12-26 18:45:06 +00:00
// Receiving IR while sending at the same time (i.e. receiving your own signal) was dsiabled in #10041
// At the demand of @pilaGit, you can `#define IR_RCV_WHILE_SENDING 1` to bring back this behavior
# ifndef IR_RCV_WHILE_SENDING
# define IR_RCV_WHILE_SENDING 0
# endif
2020-10-30 22:22:49 +00:00
enum IrErrors { IE_NO_ERROR , IE_INVALID_RAWDATA , IE_INVALID_JSON , IE_SYNTAX_IRSEND , IE_PROTO_UNSUPPORTED } ;
2019-03-31 12:06:42 +01:00
2019-11-12 21:41:09 +00:00
const char kIrRemoteCommands [ ] PROGMEM = " | " D_CMND_IRSEND ;
2019-08-02 13:23:41 +01:00
2019-11-24 11:24:35 +00:00
// Keep below IrRemoteCommand lines exactly as below as otherwise Arduino IDE prototyping will fail (#6982)
void ( * const IrRemoteCommand [ ] ) ( void ) PROGMEM = {
& CmndIrSend } ;
2018-11-22 16:58:07 +00:00
2022-05-31 13:08:33 +01:00
// 20220531 renamed as newer arduino core now also has this function
char * ir_ulltoa ( unsigned long long value , char * str , int radix )
2021-01-24 15:35:36 +00:00
{
char digits [ 64 ] ;
char * dst = str ;
int i = 0 ;
// if (radix < 2 || radix > 36) { radix = 10; }
do {
int n = value % radix ;
digits [ i + + ] = ( n < 10 ) ? ( char ) n + ' 0 ' : ( char ) n - 10 + ' A ' ;
value / = radix ;
} while ( value ! = 0 ) ;
while ( i > 0 ) { * dst + + = digits [ - - i ] ; }
* dst = 0 ;
return str ;
}
char * Uint64toHex ( uint64_t value , char * str , uint16_t bits )
{
2022-05-31 13:08:33 +01:00
ir_ulltoa ( value , str , 16 ) ; // Get 64bit value
2021-01-24 15:35:36 +00:00
int fill = 8 ;
if ( ( bits > 3 ) & & ( bits < 65 ) ) {
fill = bits / 4 ; // Max 16
if ( bits % 4 ) { fill + + ; }
}
int len = strlen ( str ) ;
fill - = len ;
if ( fill > 0 ) {
memmove ( str + fill , str , len + 1 ) ;
memset ( str , ' 0 ' , fill ) ;
}
return str ;
}
2020-10-01 22:10:17 +01:00
/*********************************************************************************************\
* Class used to make a compact IR Raw format .
2020-10-30 11:29:48 +00:00
*
2020-10-01 22:10:17 +01:00
* We round timings to the closest 10 ms value ,
* and store up to last 26 values with seen .
* A value already seen is encoded with a letter indicating the position in the table .
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
class IRRawTable {
public :
IRRawTable ( ) : timings ( ) { } // zero initialize the array
int32_t getTimingForLetter ( uint8_t l ) const {
l = toupper ( l ) ;
if ( ( l < ' A ' ) | | ( l > ' Z ' ) ) { return - 1 ; }
return timings [ l - ' A ' ] ;
}
uint8_t findOrAdd ( uint16_t t ) {
if ( 0 = = t ) { return 0 ; }
for ( uint32_t i = 0 ; i < 26 ; i + + ) {
if ( timings [ i ] = = t ) { return i + ' A ' ; }
if ( timings [ i ] = = 0 ) { timings [ i ] = t ; break ; } // add new value
}
return 0 ; // not found
}
void add ( uint16_t t ) {
if ( 0 = = t ) { return ; }
for ( uint32_t i = 0 ; i < 26 ; i + + ) {
if ( timings [ i ] = = 0 ) { timings [ i ] = t ; break ; } // add new value
}
}
protected :
uint16_t timings [ 26 ] ;
} ;
2017-11-19 17:02:03 +00:00
// Based on IRremoteESP8266.h enum decode_type_t
2019-11-24 11:24:35 +00:00
static const uint8_t MAX_STANDARD_IR = NEC ; // this is the last code mapped to decode_type_t
2019-11-12 21:41:09 +00:00
const char kIrRemoteProtocols [ ] PROGMEM = " UNKNOWN|RC5|RC6|NEC " ;
2017-11-19 17:02:03 +00:00
2017-10-08 15:51:05 +01:00
/*********************************************************************************************\
* IR Send
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-11-19 17:02:03 +00:00
# include <IRsend.h>
2019-03-26 17:26:50 +00:00
IRsend * irsend = nullptr ;
2017-02-14 13:27:08 +00:00
2017-10-18 17:22:34 +01:00
void IrSendInit ( void )
2017-02-14 13:27:08 +00:00
{
2020-12-29 09:35:44 +00:00
irsend = new IRsend ( Pin ( GPIO_IRSEND ) , IR_SEND_INVERTED , IR_SEND_USE_MODULATION ) ; // an IR led is at GPIO_IRSEND
2017-02-14 13:27:08 +00:00
irsend - > begin ( ) ;
}
2017-10-06 16:28:00 +01:00
# ifdef USE_IR_RECEIVE
2017-10-08 15:51:05 +01:00
/*********************************************************************************************\
* IR Receive
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-03-31 10:59:04 +01:00
const bool IR_RCV_SAVE_BUFFER = false ; // false = do not use buffer, true = use buffer for decoding
2021-03-22 03:50:26 +00:00
# ifndef IR_TIME_AVOID_DUPLICATE
2021-03-22 04:25:33 +00:00
# define IR_TIME_AVOID_DUPLICATE 50 // Milliseconds
2021-03-22 03:50:26 +00:00
# endif // IR_TIME_AVOID_DUPLICATE
2017-10-06 16:28:00 +01:00
2018-11-21 15:36:10 +00:00
# include <IRrecv.h>
2017-10-25 13:27:30 +01:00
2019-03-26 17:26:50 +00:00
IRrecv * irrecv = nullptr ;
2018-11-21 15:36:10 +00:00
2017-10-06 16:28:00 +01:00
unsigned long ir_lasttime = 0 ;
2019-11-20 19:53:12 +00:00
void IrReceiveUpdateThreshold ( void )
2019-05-27 10:56:14 +01:00
{
2019-07-08 11:24:31 +01:00
if ( irrecv ! = nullptr ) {
2021-06-11 17:14:12 +01:00
if ( Settings - > param [ P_IR_UNKNOW_THRESHOLD ] < 6 ) { Settings - > param [ P_IR_UNKNOW_THRESHOLD ] = 6 ; }
irrecv - > setUnknownThreshold ( Settings - > param [ P_IR_UNKNOW_THRESHOLD ] ) ;
2019-07-08 11:24:31 +01:00
}
2019-05-27 10:56:14 +01:00
}
2022-01-21 15:24:32 +00:00
void IrReceiveUpdateTolerance ( void )
{
if ( irrecv ! = nullptr ) {
2022-01-21 16:56:19 +00:00
if ( Settings - > param [ P_IR_TOLERANCE ] = = 0 ) { Settings - > param [ P_IR_TOLERANCE ] = IR_RCV_TOLERANCE ; }
2022-01-21 15:24:32 +00:00
if ( Settings - > param [ P_IR_TOLERANCE ] > 100 ) { Settings - > param [ P_IR_TOLERANCE ] = 100 ; }
irrecv - > setTolerance ( Settings - > param [ P_IR_TOLERANCE ] ) ;
}
}
2017-10-18 17:22:34 +01:00
void IrReceiveInit ( void )
2017-10-06 16:28:00 +01:00
{
2018-11-21 15:36:10 +00:00
// an IR led is at GPIO_IRRECV
2020-04-26 16:33:27 +01:00
irrecv = new IRrecv ( Pin ( GPIO_IRRECV ) , IR_RCV_BUFFER_SIZE , IR_RCV_TIMEOUT , IR_RCV_SAVE_BUFFER ) ;
2021-06-11 17:14:12 +01:00
irrecv - > setUnknownThreshold ( Settings - > param [ P_IR_UNKNOW_THRESHOLD ] ) ;
2022-02-07 12:51:02 +00:00
IrReceiveUpdateTolerance ( ) ;
2017-10-08 15:51:05 +01:00
irrecv - > enableIRIn ( ) ; // Start the receiver
2021-01-23 16:24:54 +00:00
// AddLog(LOG_LEVEL_DEBUG, PSTR("IrReceive initialized"));
2017-10-06 16:28:00 +01:00
}
2018-11-14 13:32:09 +00:00
void IrReceiveCheck ( void )
2017-10-08 15:51:05 +01:00
{
2019-11-24 11:24:35 +00:00
char sirtype [ 8 ] ; // Max is UNKNOWN
2017-10-08 15:51:05 +01:00
int8_t iridx = 0 ;
2017-02-14 13:27:08 +00:00
2017-10-08 15:51:05 +01:00
decode_results results ;
2017-03-29 17:42:05 +01:00
2017-10-08 15:51:05 +01:00
if ( irrecv - > decode ( & results ) ) {
2019-08-28 15:13:19 +01:00
char hvalue [ 65 ] ; // Max 256 bits
2019-09-10 19:45:27 +01:00
iridx = results . decode_type ;
2019-11-24 11:24:35 +00:00
if ( ( iridx < 0 ) | | ( iridx > MAX_STANDARD_IR ) ) { iridx = 0 ; } // UNKNOWN
2019-09-10 19:45:27 +01:00
if ( iridx ) {
if ( results . bits > 64 ) {
// This emulates IRutils resultToHexidecimal and may needs a larger IR_RCV_BUFFER_SIZE
uint32_t digits2 = results . bits / 8 ;
if ( results . bits % 8 ) { digits2 + + ; }
ToHex_P ( ( unsigned char * ) results . state , digits2 , hvalue , sizeof ( hvalue ) ) ; // Get n-bit value as hex 56341200
} else {
2019-09-15 10:10:59 +01:00
Uint64toHex ( results . value , hvalue , results . bits ) ; // Get 64bit value as hex 00123456
2019-09-10 19:45:27 +01:00
}
2019-08-28 15:13:19 +01:00
} else {
2019-09-15 10:10:59 +01:00
Uint64toHex ( results . value , hvalue , 32 ) ; // UNKNOWN is always 32 bits hash
2019-08-28 15:13:19 +01:00
}
2017-02-17 16:18:41 +00:00
2021-01-23 15:26:23 +00:00
AddLog ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_IRR " RawLen %d, Overflow %d, Bits %d, Value 0x%s, Decode %d " ) ,
2020-12-02 21:09:30 +00:00
results . rawlen , results . overflow , results . bits , hvalue , results . decode_type ) ;
2017-03-29 17:42:05 +01:00
2017-10-08 15:51:05 +01:00
unsigned long now = millis ( ) ;
2018-11-21 15:36:10 +00:00
// if ((now - ir_lasttime > IR_TIME_AVOID_DUPLICATE) && (UNKNOWN != results.decode_type) && (results.bits > 0)) {
2020-12-02 21:09:30 +00:00
if ( now - ir_lasttime > IR_TIME_AVOID_DUPLICATE ) {
2017-10-08 15:51:05 +01:00
ir_lasttime = now ;
2017-03-29 17:42:05 +01:00
2019-04-01 14:15:16 +01:00
char svalue [ 64 ] ;
2021-06-11 17:14:12 +01:00
if ( Settings - > flag . ir_receive_decimal ) { // SetOption29 - IR receive data format
2022-05-31 13:08:33 +01:00
ir_ulltoa ( results . value , svalue , 10 ) ;
2018-06-25 11:33:23 +01:00
} else {
2019-08-28 15:13:19 +01:00
snprintf_P ( svalue , sizeof ( svalue ) , PSTR ( " \" 0x%s \" " ) , hvalue ) ;
2018-06-25 11:33:23 +01:00
}
2019-09-10 19:45:27 +01:00
ResponseTime_P ( PSTR ( " , \" " D_JSON_IRRECEIVED " \" :{ \" " D_JSON_IR_PROTOCOL " \" : \" %s \" , \" " D_JSON_IR_BITS " \" :%d " ) ,
GetTextIndexed ( sirtype , sizeof ( sirtype ) , iridx , kIrRemoteProtocols ) , results . bits ) ;
if ( iridx ) {
ResponseAppend_P ( PSTR ( " , \" " D_JSON_IR_DATA " \" :%s " ) , svalue ) ;
} else {
ResponseAppend_P ( PSTR ( " , \" " D_JSON_IR_HASH " \" :%s " ) , svalue ) ;
}
2018-06-25 11:33:23 +01:00
2020-10-01 22:10:17 +01:00
IRRawTable raw_table ;
bool prev_number = false ; // was the previous value a number, meaning we may need a comma prefix
bool ir_high = true ; // alternate high/low
// Add raw data in a compact format
2021-06-11 17:14:12 +01:00
if ( Settings - > flag3 . receive_raw ) { // SetOption58 - Add IR Raw data to JSON message
2020-10-01 22:10:17 +01:00
ResponseAppend_P ( PSTR ( " , \" " D_JSON_IR_RAWDATA " \" : \" " ) ) ;
size_t rawlen = results . rawlen ;
uint32_t i ;
2020-10-30 11:29:48 +00:00
2020-10-01 22:10:17 +01:00
for ( i = 1 ; i < rawlen ; i + + ) {
// round to closest 10ms
uint32_t raw_val_millis = results . rawbuf [ i ] * kRawTick ;
uint16_t raw_dms = ( raw_val_millis * 2 + 5 ) / 10 ; // in 5 micro sec steps
// look if the data is already seen
uint8_t letter = raw_table . findOrAdd ( raw_dms ) ;
if ( letter ) {
if ( ! ir_high ) { letter = tolower ( letter ) ; }
ResponseAppend_P ( PSTR ( " %c " ) , letter ) ;
prev_number = false ;
} else {
// number
ResponseAppend_P ( PSTR ( " %c%d " ) , ir_high ? ' + ' : ' - ' , ( uint32_t ) raw_dms * 5 ) ;
prev_number = true ;
2018-11-21 15:36:10 +00:00
}
2020-10-01 22:10:17 +01:00
ir_high = ! ir_high ;
2021-05-23 17:22:29 +01:00
if ( ResponseLength ( ) + 40 > ResponseSize ( ) ) { break ; } // Quit if char string becomes too long
2018-11-21 15:36:10 +00:00
}
2020-10-01 22:10:17 +01:00
uint16_t extended_length = getCorrectedRawLength ( & results ) ;
ResponseAppend_P ( PSTR ( " \" , \" " D_JSON_IR_RAWDATA " Info \" :[%d,%d,%d] " ) , extended_length , i - 1 , results . overflow ) ;
2018-11-21 15:36:10 +00:00
}
2019-09-12 13:19:44 +01:00
ResponseJsonEndEnd ( ) ;
2024-06-14 10:23:03 +01:00
if ( Settings - > flag6 . mqtt_disable_publish ) { // SetOption147 - If it is activated, Tasmota will not publish IRReceived MQTT messages, but it will proccess event trigger rules
XdrvRulesProcess ( 0 ) ;
} else {
MqttPublishPrefixTopicRulesProcess_P ( RESULT_OR_TELE , PSTR ( D_JSON_IRRECEIVED ) ) ;
}
2018-11-21 15:36:10 +00:00
2017-10-08 15:51:05 +01:00
# ifdef USE_DOMOTICZ
2019-10-13 21:16:13 +01:00
if ( iridx ) {
2018-11-21 15:36:10 +00:00
unsigned long value = results . value | ( iridx < < 28 ) ; // [Protocol:4, Data:28]
DomoticzSensor ( DZ_COUNT , value ) ; // Send data as Domoticz Counter value
}
2019-10-13 21:16:13 +01:00
# endif // USE_DOMOTICZ
2017-04-25 17:24:42 +01:00
}
2017-10-08 15:51:05 +01:00
irrecv - > resume ( ) ;
2017-03-29 17:42:05 +01:00
}
2017-02-14 13:27:08 +00:00
}
2017-10-08 15:51:05 +01:00
# endif // USE_IR_RECEIVE
2017-03-29 17:42:05 +01:00
2017-10-08 15:51:05 +01:00
/*********************************************************************************************\
* Commands
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-08-02 13:23:41 +01:00
uint32_t IrRemoteCmndIrSendJson ( void )
{
// IRsend { "protocol": "RC5", "bits": 12, "data":"0xC86" }
// IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
2020-09-21 20:49:32 +01:00
RemoveSpace ( XdrvMailbox . data ) ; // TODO is this really needed?
2020-09-23 18:38:24 +01:00
JsonParser parser ( XdrvMailbox . data ) ;
JsonParserObject root = parser . getRootObject ( ) ;
2020-09-21 20:49:32 +01:00
if ( ! root ) { return IE_INVALID_JSON ; }
// IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
// IRsend { "protocol": "NEC", "bits": 32, "data":"0x02FDFE80", "repeat": 2 }
2020-09-21 21:21:05 +01:00
const char * protocol = root . getStr ( PSTR ( D_JSON_IR_PROTOCOL ) , " " ) ;
uint16_t bits = root . getUInt ( PSTR ( D_JSON_IR_BITS ) , 0 ) ;
uint64_t data = root . getULong ( PSTR ( D_JSON_IR_DATA ) , 0 ) ;
uint16_t repeat = root . getUInt ( PSTR ( D_JSON_IR_REPEAT ) , 0 ) ;
2020-10-30 11:29:48 +00:00
2019-08-04 11:37:01 +01:00
// check if the IRSend<x> is great than repeat
if ( XdrvMailbox . index > repeat + 1 ) {
repeat = XdrvMailbox . index - 1 ;
}
2019-08-02 13:23:41 +01:00
if ( ! ( protocol & & bits ) ) {
return IE_SYNTAX_IRSEND ;
}
char protocol_text [ 20 ] ;
int protocol_code = GetCommandCode ( protocol_text , sizeof ( protocol_text ) , protocol , kIrRemoteProtocols ) ;
2021-01-24 15:35:36 +00:00
// char dvalue[64];
// char hvalue[20];
// AddLog(LOG_LEVEL_DEBUG, PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %s (0x%s), repeat %d, protocol_code %d"),
// protocol_text, protocol, bits, ulltoa(data, dvalue, 10), Uint64toHex(data, hvalue, bits), repeat, protocol_code);
2019-08-02 13:23:41 +01:00
2020-12-20 16:22:48 +00:00
# ifdef USE_IR_RECEIVE
2022-08-08 13:11:57 +01:00
if ( ! IR_RCV_WHILE_SENDING & & ( irrecv ! = nullptr ) ) { irrecv - > pause ( ) ; }
2020-12-20 16:22:48 +00:00
# endif // USE_IR_RECEIVE
2019-08-02 13:23:41 +01:00
switch ( protocol_code ) { // Equals IRremoteESP8266.h enum decode_type_t
2019-07-21 15:03:20 +01:00
# ifdef USE_IR_SEND_RC5
2019-08-02 13:23:41 +01:00
case RC5 :
irsend - > sendRC5 ( data , bits , repeat ) ; break ;
2019-07-21 15:03:20 +01:00
# endif
# ifdef USE_IR_SEND_RC6
2019-08-02 13:23:41 +01:00
case RC6 :
irsend - > sendRC6 ( data , bits , repeat ) ; break ;
2019-07-21 15:03:20 +01:00
# endif
# ifdef USE_IR_SEND_NEC
2019-08-02 13:23:41 +01:00
case NEC :
irsend - > sendNEC ( data , ( bits > NEC_BITS ) ? NEC_BITS : bits , repeat ) ; break ;
2019-07-21 15:03:20 +01:00
# endif
2019-08-02 13:23:41 +01:00
default :
2020-12-20 16:22:48 +00:00
# ifdef USE_IR_RECEIVE
2022-08-08 13:11:57 +01:00
if ( ! IR_RCV_WHILE_SENDING & & ( irrecv ! = nullptr ) ) { irrecv - > resume ( ) ; }
2020-12-20 16:22:48 +00:00
# endif // USE_IR_RECEIVE
2020-10-30 22:22:49 +00:00
return IE_PROTO_UNSUPPORTED ;
2017-10-08 15:51:05 +01:00
}
2020-12-20 16:22:48 +00:00
# ifdef USE_IR_RECEIVE
2022-08-08 13:11:57 +01:00
if ( ! IR_RCV_WHILE_SENDING & & ( irrecv ! = nullptr ) ) { irrecv - > resume ( ) ; }
2020-12-20 16:22:48 +00:00
# endif // USE_IR_RECEIVE
2019-08-02 13:23:41 +01:00
return IE_NO_ERROR ;
}
void CmndIrSend ( void )
{
uint8_t error = IE_SYNTAX_IRSEND ;
if ( XdrvMailbox . data_len ) {
2020-11-04 10:20:17 +00:00
if ( strchr ( XdrvMailbox . data , ' { ' ) = = nullptr ) {
2019-11-12 21:41:09 +00:00
error = IE_INVALID_JSON ;
2019-08-02 13:23:41 +01:00
} else {
error = IrRemoteCmndIrSendJson ( ) ;
2017-10-08 15:51:05 +01:00
}
2017-10-06 16:28:00 +01:00
}
2019-08-02 13:23:41 +01:00
IrRemoteCmndResponse ( error ) ;
}
2018-05-17 10:55:40 +01:00
2019-08-02 13:23:41 +01:00
void IrRemoteCmndResponse ( uint32_t error )
{
2019-03-31 12:06:42 +01:00
switch ( error ) {
case IE_INVALID_RAWDATA :
2020-03-16 17:55:58 +00:00
ResponseCmndChar_P ( PSTR ( D_JSON_INVALID_RAWDATA ) ) ;
2019-03-31 12:06:42 +01:00
break ;
case IE_INVALID_JSON :
2020-03-16 17:55:58 +00:00
ResponseCmndChar_P ( PSTR ( D_JSON_INVALID_JSON ) ) ;
2019-03-31 12:06:42 +01:00
break ;
2020-10-30 22:22:49 +00:00
case IE_PROTO_UNSUPPORTED :
ResponseCmndChar ( D_JSON_PROTOCOL_NOT_SUPPORTED ) ;
break ;
2019-03-31 12:06:42 +01:00
case IE_SYNTAX_IRSEND :
Response_P ( PSTR ( " { \" " D_CMND_IRSEND " \" : \" " D_JSON_NO " " D_JSON_IR_PROTOCOL " , " D_JSON_IR_BITS " " D_JSON_OR " " D_JSON_IR_DATA " \" } " ) ) ;
break ;
2019-08-02 13:23:41 +01:00
default : // IE_NO_ERROR
2019-08-03 12:01:34 +01:00
ResponseCmndDone ( ) ;
2019-03-31 12:06:42 +01:00
}
2017-10-06 16:28:00 +01:00
}
2018-01-05 11:26:19 +00:00
/*********************************************************************************************\
* Interface
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2022-11-11 09:44:56 +00:00
bool Xdrv05 ( uint32_t function )
2018-01-05 11:26:19 +00:00
{
2019-01-28 13:08:33 +00:00
bool result = false ;
2018-01-05 11:26:19 +00:00
2020-04-27 11:54:07 +01:00
if ( PinUsed ( GPIO_IRSEND ) | | PinUsed ( GPIO_IRRECV ) ) {
2018-01-05 11:26:19 +00:00
switch ( function ) {
2018-06-04 17:10:38 +01:00
case FUNC_PRE_INIT :
2020-04-27 11:54:07 +01:00
if ( PinUsed ( GPIO_IRSEND ) ) {
2018-01-05 11:26:19 +00:00
IrSendInit ( ) ;
}
# ifdef USE_IR_RECEIVE
2020-04-27 11:54:07 +01:00
if ( PinUsed ( GPIO_IRRECV ) ) {
2018-01-05 11:26:19 +00:00
IrReceiveInit ( ) ;
}
# endif // USE_IR_RECEIVE
break ;
case FUNC_EVERY_50_MSECOND :
# ifdef USE_IR_RECEIVE
2020-04-27 11:54:07 +01:00
if ( PinUsed ( GPIO_IRRECV ) ) {
2018-01-05 11:26:19 +00:00
IrReceiveCheck ( ) ; // check if there's anything on IR side
}
# endif // USE_IR_RECEIVE
break ;
case FUNC_COMMAND :
2020-04-27 11:54:07 +01:00
if ( PinUsed ( GPIO_IRSEND ) ) {
2019-08-02 13:23:41 +01:00
result = DecodeCommand ( kIrRemoteCommands , IrRemoteCommand ) ;
2018-01-05 11:26:19 +00:00
}
break ;
2023-12-27 21:03:56 +00:00
case FUNC_ACTIVE :
result = true ;
break ;
2018-01-05 11:26:19 +00:00
}
}
return result ;
}
2019-08-28 21:01:01 +01:00
# endif // defined(USE_IR_REMOTE) && !defined(USE_IR_REMOTE_FULL)