@ -55,7 +55,13 @@ unsigned char _uartbuf[RF_MESSAGE_SIZE+3] = {0};
unsigned char _uartpos = 0 ;
unsigned char _uartpos = 0 ;
unsigned char _learnId = 0 ;
unsigned char _learnId = 0 ;
bool _learnStatus = true ;
enum class RfbLearn {
Disabled ,
On ,
Off
} ;
RfbLearn _learnStatus = RfbLearn : : Disabled ;
bool _rfbin = false ;
bool _rfbin = false ;
struct rfb_message_t {
struct rfb_message_t {
@ -66,7 +72,6 @@ static std::queue<rfb_message_t> _rfb_message_queue;
# if RFB_DIRECT
# if RFB_DIRECT
RCSwitch * _rfModem ;
RCSwitch * _rfModem ;
bool _learning = false ;
# endif
# endif
bool _rfb_receive = false ;
bool _rfb_receive = false ;
@ -118,7 +123,7 @@ bool _rfbWebSocketOnKeyCheck(const char * key, JsonVariant& value) {
}
}
void _rfbWebSocketOnData ( JsonObject & root ) {
void _rfbWebSocketOnData ( JsonObject & root ) {
_rfbWebSocketSendCodeArray ( root , 0 , relayCount ( ) ) ;
_rfbWebSocketSendCodeArray ( root , 0 , relayCount ( ) ) ;
}
}
# endif // WEB_SUPPORT
# endif // WEB_SUPPORT
@ -190,10 +195,10 @@ void _rfbDecode() {
}
}
if ( action = = RF_CODE_LEARN_OK ) {
if ( ( action = = RF_CODE_LEARN_OK ) & & ( _learnStatus ! = RfbLearn : : Disabled ) ) {
DEBUG_MSG_P ( PSTR ( " [RF] Learn success \n " ) ) ;
DEBUG_MSG_P ( PSTR ( " [RF] Learn success \n " ) ) ;
rfbStore ( _learnId , _learnStatus , buffer ) ;
rfbStore ( _learnId , ( _learnStatus = = RfbLearn : : On ) , buffer ) ;
// Websocket update
// Websocket update
# if WEB_SUPPORT
# if WEB_SUPPORT
@ -213,7 +218,7 @@ void _rfbDecode() {
unsigned char id ;
unsigned char id ;
unsigned char status ;
unsigned char status ;
bool matched = _rfbMatch ( buffer , id , status , buffer ) ;
bool matched = _rfbMatch ( buffer , id , status , buffer ) ;
if ( matched ) {
if ( matched ) {
DEBUG_MSG_P ( PSTR ( " [RF] Matched message '%s' \n " ) , buffer ) ;
DEBUG_MSG_P ( PSTR ( " [RF] Matched message '%s' \n " ) , buffer ) ;
_rfbin = true ;
_rfbin = true ;
@ -320,7 +325,6 @@ void _rfbAckImpl() {}
void _rfbLearnImpl ( ) {
void _rfbLearnImpl ( ) {
DEBUG_MSG_P ( PSTR ( " [RF] Entering LEARN mode \n " ) ) ;
DEBUG_MSG_P ( PSTR ( " [RF] Entering LEARN mode \n " ) ) ;
_learning = true ;
}
}
void _rfbSendImpl ( uint8_t * message ) {
void _rfbSendImpl ( uint8_t * message ) {
@ -351,10 +355,10 @@ void _rfbReceiveImpl() {
if ( ! _rfb_receive ) return ;
if ( ! _rfb_receive ) return ;
static long learn_start = 0 ;
static long learn_start = 0 ;
if ( ! _learning & & learn_start ) {
if ( ( _learnStatus = = RfbLearn : : Disabled ) & & learn_start ) {
learn_start = 0 ;
learn_start = 0 ;
}
}
if ( _learning ) {
if ( _learnStatus ! = RfbLearn : : Disabled ) {
if ( ! learn_start ) {
if ( ! learn_start ) {
DEBUG_MSG_P ( PSTR ( " [RF] Arming learn timeout \n " ) ) ;
DEBUG_MSG_P ( PSTR ( " [RF] Arming learn timeout \n " ) ) ;
learn_start = millis ( ) ;
learn_start = millis ( ) ;
@ -364,7 +368,7 @@ void _rfbReceiveImpl() {
memset ( _uartbuf , 0 , sizeof ( _uartbuf ) ) ;
memset ( _uartbuf , 0 , sizeof ( _uartbuf ) ) ;
_uartbuf [ 0 ] = RF_CODE_LEARN_KO ;
_uartbuf [ 0 ] = RF_CODE_LEARN_KO ;
_rfbDecode ( ) ;
_rfbDecode ( ) ;
_learning = false ;
_learnStatus = RfbLearn : : Disabled ;
}
}
}
}
@ -378,7 +382,7 @@ void _rfbReceiveImpl() {
unsigned int timing = _rfModem - > getReceivedDelay ( ) ;
unsigned int timing = _rfModem - > getReceivedDelay ( ) ;
memset ( _uartbuf , 0 , sizeof ( _uartbuf ) ) ;
memset ( _uartbuf , 0 , sizeof ( _uartbuf ) ) ;
unsigned char * msgbuf = _uartbuf + 1 ;
unsigned char * msgbuf = _uartbuf + 1 ;
_uartbuf [ 0 ] = _learning ? RF_CODE_LEARN_OK : RF_CODE_RFIN ;
_uartbuf [ 0 ] = ( _learnStatus ! = RfbLearn : : Disabled ) ? RF_CODE_LEARN_OK : RF_CODE_RFIN ;
msgbuf [ 0 ] = 0xC0 ;
msgbuf [ 0 ] = 0xC0 ;
msgbuf [ 1 ] = _rfModem - > getReceivedProtocol ( ) ;
msgbuf [ 1 ] = _rfModem - > getReceivedProtocol ( ) ;
msgbuf [ 2 ] = timing > > 8 ;
msgbuf [ 2 ] = timing > > 8 ;
@ -389,7 +393,7 @@ void _rfbReceiveImpl() {
msgbuf [ 7 ] = rf_code > > 8 ;
msgbuf [ 7 ] = rf_code > > 8 ;
msgbuf [ 8 ] = rf_code > > 0 ;
msgbuf [ 8 ] = rf_code > > 0 ;
_rfbDecode ( ) ;
_rfbDecode ( ) ;
_learning = false ;
_learnStatus = RfbLearn : : Disabled ;
}
}
}
}
_rfModem - > resetAvailable ( ) ;
_rfModem - > resetAvailable ( ) ;
@ -482,6 +486,37 @@ void _rfbParseCode(char * code) {
}
}
void _rfbLearnFromPayload ( const char * payload ) {
// The payload must be the `relayID,mode` (where mode is either 0 or 1)
const char * sep = strchr ( payload , ' , ' ) ;
if ( NULL = = sep ) {
return ;
}
// ref. RelaysMax, we only have up to 2 digits
char relay [ 3 ] { 0 , 0 , 0 } ;
if ( ( sep - payload ) > 2 ) {
return ;
}
std : : copy ( payload , sep , relay ) ;
if ( ! isNumber ( relay ) ) {
return ;
}
_learnId = atoi ( relay ) ;
if ( _learnId > = relayCount ( ) ) {
DEBUG_MSG_P ( PSTR ( " [RF] Wrong learnID (%d) \n " ) , _learnId ) ;
return ;
}
+ + sep ;
if ( ( * sep = = ' 0 ' ) | | ( * sep = = ' 1 ' ) ) {
_learnStatus = ( * sep ! = ' 0 ' ) ? RfbLearn : : On : RfbLearn : : Off ;
_rfbLearnImpl ( ) ;
}
}
# if MQTT_SUPPORT
# if MQTT_SUPPORT
void _rfbMqttCallback ( unsigned int type , const char * topic , char * payload ) {
void _rfbMqttCallback ( unsigned int type , const char * topic , char * payload ) {
@ -504,30 +539,22 @@ void _rfbMqttCallback(unsigned int type, const char * topic, char * payload) {
if ( type = = MQTT_MESSAGE_EVENT ) {
if ( type = = MQTT_MESSAGE_EVENT ) {
// Match topic
String t = mqttMagnitude ( ( char * ) topic ) ;
String t = mqttMagnitude ( ( char * ) topic ) ;
// Check if should go into learn mode
if ( t . startsWith ( MQTT_TOPIC_RFLEARN ) ) {
if ( t . startsWith ( MQTT_TOPIC_RFLEARN ) ) {
_learnId = t . substring ( strlen ( MQTT_TOPIC_RFLEARN ) + 1 ) . toInt ( ) ;
if ( _learnId > = relayCount ( ) ) {
DEBUG_MSG_P ( PSTR ( " [RF] Wrong learnID (%d) \n " ) , _learnId ) ;
return ;
}
_learnStatus = ( char ) payload [ 0 ] ! = ' 0 ' ;
_rfbLearnImpl ( ) ;
_rfbLearnFromPayload ( payload ) ;
return ;
return ;
}
}
if ( t . equals ( MQTT_TOPIC_RFOUT ) ) {
if ( t . equals ( MQTT_TOPIC_RFOUT ) ) {
_rfbParseCode ( payload ) ;
_rfbParseCode ( payload ) ;
return ;
}
}
# if !RFB_DIRECT
# if !RFB_DIRECT
if ( t . equals ( MQTT_TOPIC_RFRAW ) ) {
if ( t . equals ( MQTT_TOPIC_RFRAW ) ) {
_rfbParseRaw ( payload ) ;
_rfbParseRaw ( payload ) ;
return ;
}
}
# endif
# endif
@ -539,47 +566,42 @@ void _rfbMqttCallback(unsigned int type, const char * topic, char * payload) {
# if API_SUPPORT
# if API_SUPPORT
void _rfbAPI Setup ( ) {
void _rfbApi Setup ( ) {
apiRegister ( MQTT_TOPIC_RFOUT ,
[ ] ( char * buffer , size_t len ) {
snprintf_P ( buffer , len , PSTR ( " OK " ) ) ;
} ,
[ ] ( const char * payload ) {
_rfbParseCode ( ( char * ) payload ) ;
apiReserve ( 3u ) ;
apiRegister ( {
MQTT_TOPIC_RFOUT , Api : : Type : : Basic , ApiUnusedArg ,
apiOk , // just a stub, nothing to return
[ ] ( const Api & , ApiBuffer & buffer ) {
_rfbParseCode ( buffer . data ) ;
}
}
) ;
} ) ;
apiRegister ( MQTT_TOPIC_RFLEARN ,
[ ] ( char * buffer , size_t len ) {
snprintf_P ( buffer , len , PSTR ( " OK " ) ) ;
} ,
[ ] ( const char * payload ) {
// The payload must be the relayID plus the mode (0 or 1)
char * tok = strtok ( ( char * ) payload , " , " ) ;
if ( NULL = = tok ) return ;
if ( ! isNumber ( tok ) ) return ;
_learnId = atoi ( tok ) ;
if ( _learnId > = relayCount ( ) ) {
DEBUG_MSG_P ( PSTR ( " [RF] Wrong learnID (%d) \n " ) , _learnId ) ;
return ;
apiRegister ( {
MQTT_TOPIC_RFLEARN , Api : : Type : : Basic , ApiUnusedArg ,
[ ] ( const Api & , ApiBuffer & buffer ) {
if ( _learnStatus = = RfbLearn : : Disabled ) {
snprintf_P ( buffer . data , buffer . size , PSTR ( " waiting " ) ) ;
} else {
snprintf_P ( buffer . data , buffer . size , PSTR ( " id:%u,status:%c " ) ,
_learnId , ( _learnStatus = = RfbLearn : : On ) ? ' y ' : ' n '
) ;
}
}
tok = strtok ( NULL , " , " ) ;
if ( NULL = = tok ) return ;
_learnStatus = ( char ) tok [ 0 ] ! = ' 0 ' ;
_rfbLearnImpl ( ) ;
} ,
[ ] ( const Api & , ApiBuffer & buffer ) {
_rfbLearnFromPayload ( buffer . data ) ;
}
}
) ;
} ) ;
# if !RFB_DIRECT
# if !RFB_DIRECT
apiRegister ( MQTT_TOPIC_RFRAW ,
[ ] ( char * buffer , size_t len ) {
snprintf_P ( buffer , len , PSTR ( " OK " ) ) ;
} ,
[ ] ( const char * payload ) {
_rfbParseRaw ( ( char * ) payload ) ;
apiRegister ( {
MQTT_TOPIC_RFRAW , Api : : Type : : Basic , ApiUnusedArg ,
apiOk , // just a stub, nothing to return
[ ] ( const Api & , ApiBuffer & buffer ) {
_rfbParseRaw ( buffer . data ) ;
}
}
) ;
} ) ;
# endif
# endif
}
}
@ -596,7 +618,7 @@ void _rfbInitCommands() {
terminalError ( F ( " Wrong arguments " ) ) ;
terminalError ( F ( " Wrong arguments " ) ) ;
return ;
return ;
}
}
// 1st argument is relayID
// 1st argument is relayID
int id = ctx . argv [ 1 ] . toInt ( ) ;
int id = ctx . argv [ 1 ] . toInt ( ) ;
if ( id > = relayCount ( ) ) {
if ( id > = relayCount ( ) ) {
@ -617,7 +639,7 @@ void _rfbInitCommands() {
terminalError ( F ( " Wrong arguments " ) ) ;
terminalError ( F ( " Wrong arguments " ) ) ;
return ;
return ;
}
}
// 1st argument is relayID
// 1st argument is relayID
int id = ctx . argv [ 1 ] . toInt ( ) ;
int id = ctx . argv [ 1 ] . toInt ( ) ;
if ( id > = relayCount ( ) ) {
if ( id > = relayCount ( ) ) {
@ -693,7 +715,7 @@ void rfbStatus(unsigned char id, bool status) {
void rfbLearn ( unsigned char id , bool status ) {
void rfbLearn ( unsigned char id , bool status ) {
_learnId = id ;
_learnId = id ;
_learnStatus = status ;
_learnStatus = status ? RfbLearn : : On : RfbLearn : : Off ;
_rfbLearnImpl ( ) ;
_rfbLearnImpl ( ) ;
}
}
@ -723,7 +745,7 @@ void rfbSetup() {
# endif
# endif
# if API_SUPPORT
# if API_SUPPORT
_rfbAPI Setup ( ) ;
_rfbApi Setup ( ) ;
# endif
# endif
# if WEB_SUPPORT
# if WEB_SUPPORT