From d03f8a73991d1ac427401bf64d653b526fa9adc2 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Thu, 13 Aug 2020 15:49:25 +0300 Subject: [PATCH] rfb: let API show learning status --- code/espurna/rfbridge.cpp | 117 ++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 54 deletions(-) diff --git a/code/espurna/rfbridge.cpp b/code/espurna/rfbridge.cpp index 13cd3c08..cc691b43 100644 --- a/code/espurna/rfbridge.cpp +++ b/code/espurna/rfbridge.cpp @@ -55,7 +55,13 @@ unsigned char _uartbuf[RF_MESSAGE_SIZE+3] = {0}; unsigned char _uartpos = 0; unsigned char _learnId = 0; -bool _learnStatus = true; +enum class RfbLearn { + Disabled, + On, + Off +}; + +RfbLearn _learnStatus = RfbLearn::Disabled; bool _rfbin = false; struct rfb_message_t { @@ -66,7 +72,6 @@ static std::queue _rfb_message_queue; #if RFB_DIRECT RCSwitch * _rfModem; - bool _learning = false; #endif bool _rfb_receive = false; @@ -118,7 +123,7 @@ bool _rfbWebSocketOnKeyCheck(const char * key, JsonVariant& value) { } void _rfbWebSocketOnData(JsonObject& root) { - _rfbWebSocketSendCodeArray(root, 0, relayCount()); + _rfbWebSocketSendCodeArray(root, 0, relayCount()); } #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")); - rfbStore(_learnId, _learnStatus, buffer); + rfbStore(_learnId, (_learnStatus == RfbLearn::On), buffer); // Websocket update #if WEB_SUPPORT @@ -213,7 +218,7 @@ void _rfbDecode() { unsigned char id; unsigned char status; bool matched = _rfbMatch(buffer, id, status, buffer); - + if (matched) { DEBUG_MSG_P(PSTR("[RF] Matched message '%s'\n"), buffer); _rfbin = true; @@ -320,7 +325,6 @@ void _rfbAckImpl() {} void _rfbLearnImpl() { DEBUG_MSG_P(PSTR("[RF] Entering LEARN mode\n")); - _learning = true; } void _rfbSendImpl(uint8_t * message) { @@ -351,10 +355,10 @@ void _rfbReceiveImpl() { if (!_rfb_receive) return; static long learn_start = 0; - if (!_learning && learn_start) { + if ((_learnStatus == RfbLearn::Disabled) && learn_start) { learn_start = 0; } - if (_learning) { + if (_learnStatus != RfbLearn::Disabled) { if (!learn_start) { DEBUG_MSG_P(PSTR("[RF] Arming learn timeout\n")); learn_start = millis(); @@ -364,7 +368,7 @@ void _rfbReceiveImpl() { memset(_uartbuf, 0, sizeof(_uartbuf)); _uartbuf[0] = RF_CODE_LEARN_KO; _rfbDecode(); - _learning = false; + _learnStatus = RfbLearn::Disabled; } } @@ -378,7 +382,7 @@ void _rfbReceiveImpl() { unsigned int timing = _rfModem->getReceivedDelay(); memset(_uartbuf, 0, sizeof(_uartbuf)); 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[1] = _rfModem->getReceivedProtocol(); msgbuf[2] = timing >> 8; @@ -389,7 +393,7 @@ void _rfbReceiveImpl() { msgbuf[7] = rf_code >> 8; msgbuf[8] = rf_code >> 0; _rfbDecode(); - _learning = false; + _learnStatus = RfbLearn::Disabled; } } _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 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) { - // Match topic String t = mqttMagnitude((char *) topic); - // Check if should go into learn mode 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; - } if (t.equals(MQTT_TOPIC_RFOUT)) { _rfbParseCode(payload); + return; } #if !RFB_DIRECT if (t.equals(MQTT_TOPIC_RFRAW)) { _rfbParseRaw(payload); + return; } #endif @@ -553,39 +580,21 @@ void _rfbApiSetup() { apiRegister({ MQTT_TOPIC_RFLEARN, Api::Type::Basic, ApiUnusedArg, - apiOk, // just a stub, nothing to return [](const Api&, ApiBuffer& buffer) { - // The payload must be the relayID plus the mode (0 or 1) - char* sep = strchr(buffer.data, ','); - if (NULL == sep) { - return; - } - - char relay[3] {0, 0, 0}; - if ((sep - buffer) > 2) { - return; - } - - std::copy(buffer.data, 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'); - _rfbLearnImpl(); + 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' + ); } + }, + [](const Api&, ApiBuffer& buffer) { + _rfbLearnFromPayload(buffer.data); } }); - #if not RFB_DIRECT + #if !RFB_DIRECT apiRegister({ MQTT_TOPIC_RFRAW, Api::Type::Basic, ApiUnusedArg, apiOk, // just a stub, nothing to return @@ -609,7 +618,7 @@ void _rfbInitCommands() { terminalError(F("Wrong arguments")); return; } - + // 1st argument is relayID int id = ctx.argv[1].toInt(); if (id >= relayCount()) { @@ -630,7 +639,7 @@ void _rfbInitCommands() { terminalError(F("Wrong arguments")); return; } - + // 1st argument is relayID int id = ctx.argv[1].toInt(); if (id >= relayCount()) { @@ -706,7 +715,7 @@ void rfbStatus(unsigned char id, bool status) { void rfbLearn(unsigned char id, bool status) { _learnId = id; - _learnStatus = status; + _learnStatus = status ? RfbLearn::On : RfbLearn::Off; _rfbLearnImpl(); }