/* RF MODULE Copyright (C) 2016-2018 by Xose PĂ©rez */ #if RF_SUPPORT #include RCSwitch * _rfModem; unsigned long _rf_learn_start = 0; unsigned char _rf_learn_id = 0; bool _rf_learn_status = true; bool _rf_learn_active = false; // ----------------------------------------------------------------------------- // RF // ----------------------------------------------------------------------------- unsigned long _rfRetrieve(unsigned char id, bool status) { String code = getSetting(status ? "rfbON" : "rfbOFF", id, "0"); return strtoul(code.c_str(), 0, 16); } void _rfStore(unsigned char id, bool status, unsigned long code) { DEBUG_MSG_P(PSTR("[RF] Storing %d-%s => %X\n"), id, status ? "ON" : "OFF", code); char buffer[20]; snprintf_P(buffer, sizeof(buffer), PSTR("%X"), code); setSetting(status ? "rfbON" : "rfbOFF", id, buffer); } void _rfLearn(unsigned char id, bool status) { _rf_learn_start = millis(); _rf_learn_id = id; _rf_learn_status = status; _rf_learn_active = true; } void _rfForget(unsigned char id, bool status) { delSetting(status ? "rfbON" : "rfbOFF", id); // Websocket update #if WEB_SUPPORT char wsb[100]; snprintf_P(wsb, sizeof(wsb), PSTR("{\"rfb\":[{\"id\": %d, \"status\": %d, \"data\": \"\"}]}"), id, status ? 1 : 0); wsSend(wsb); #endif } bool _rfMatch(unsigned long code, unsigned char& relayID, unsigned char& value) { bool found = false; DEBUG_MSG_P(PSTR("[RF] Trying to match code %X\n"), code); for (unsigned char i=0; iargc < 3) { DEBUG_MSG_P(PSTR("-ERROR: Wrong arguments\n")); return; } int id = String(e->argv[1]).toInt(); if (id >= relayCount()) { DEBUG_MSG_P(PSTR("-ERROR: Wrong relayID (%d)\n"), id); return; } int status = String(e->argv[2]).toInt(); _rfLearn(id, status == 1); DEBUG_MSG_P(PSTR("+OK\n")); }); settingsRegisterCommand(F("FORGET"), [](Embedis* e) { if (e->argc < 3) { DEBUG_MSG_P(PSTR("-ERROR: Wrong arguments\n")); return; } int id = String(e->argv[1]).toInt(); if (id >= relayCount()) { DEBUG_MSG_P(PSTR("-ERROR: Wrong relayID (%d)\n"), id); return; } int status = String(e->argv[2]).toInt(); _rfForget(id, status == 1); DEBUG_MSG_P(PSTR("+OK\n")); }); } #endif // TERMINAL_SUPPORT // ----------------------------------------------------------------------------- // WEB // ----------------------------------------------------------------------------- void _rfWebSocketOnSend(JsonObject& root) { char buffer[20]; root["rfbVisible"] = 1; root["rfbCount"] = relayCount(); JsonArray& rfb = root.createNestedArray("rfb"); for (byte id=0; idavailable()) { static unsigned long last = 0; if (millis() - last > RF_DEBOUNCE) { last = millis(); if (_rfModem->getReceivedValue() > 0) { unsigned long rf_code = _rfModem->getReceivedValue(); DEBUG_MSG_P(PSTR("[RF] Received code: %X\n"), rf_code); if (_rf_learn_active) { _rf_learn_active = false; _rfStore(_rf_learn_id, _rf_learn_status, rf_code); // Websocket update #if WEB_SUPPORT char wsb[100]; snprintf_P( wsb, sizeof(wsb), PSTR("{\"rfb\":[{\"id\": %d, \"status\": %d, \"data\": \"%X\"}]}"), _rf_learn_id, _rf_learn_status ? 1 : 0, rf_code); wsSend(wsb); #endif } else { unsigned char id; unsigned char value; if (_rfMatch(rf_code, id, value)) { if (2 == value) { relayToggle(id); } else { relayStatus(id, 1 == value); } } } } } _rfModem->resetAvailable(); } if (_rf_learn_active && (millis() - _rf_learn_start > RF_LEARN_TIMEOUT)) { _rf_learn_active = false; } } void rfSetup() { _rfModem = new RCSwitch(); _rfModem->enableReceive(RF_PIN); DEBUG_MSG_P(PSTR("[RF] RF receiver on GPIO %u\n"), RF_PIN); #if WEB_SUPPORT wsOnSendRegister(_rfWebSocketOnSend); wsOnActionRegister(_rfWebSocketOnAction); #endif #if TERMINAL_SUPPORT _rfInitCommands(); #endif // Register loop espurnaRegisterLoop(rfLoop); } #endif