Browse Source

Update support for basic RF receivers, using RFBridge web interface to learn codes (#594)

rfm69
Xose Pérez 6 years ago
parent
commit
59553cad2c
6 changed files with 2789 additions and 2693 deletions
  1. +4
    -2
      code/espurna/config/general.h
  2. BIN
      code/espurna/data/index.html.gz
  3. +144
    -53
      code/espurna/rf.ino
  4. +2634
    -2632
      code/espurna/static/index.html.gz.h
  5. +6
    -5
      code/html/index.html
  6. +1
    -1
      code/platformio.ini

+ 4
- 2
code/espurna/config/general.h View File

@ -849,6 +849,7 @@ PROGMEM const char* const custom_reset_string[] = {
// -----------------------------------------------------------------------------
// RFBRIDGE
// This module is not compatible with RF_SUPPORT=1
// -----------------------------------------------------------------------------
#define RF_SEND_TIMES 4 // How many times to send the message
@ -1010,6 +1011,7 @@ PROGMEM const char* const custom_reset_string[] = {
// Custom RF module
// Check http://tinkerman.cat/adding-rf-to-a-non-rf-itead-sonoff/
// Enable support by passing RF_SUPPORT=1 build flag
// This module is not compatible with RFBRIDGE
//--------------------------------------------------------------------------------
#ifndef RF_SUPPORT
@ -1020,5 +1022,5 @@ PROGMEM const char* const custom_reset_string[] = {
#define RF_PIN 14
#endif
#define RF_CHANNEL 31
#define RF_DEVICE 1
#define RF_DEBOUNCE 500
#define RF_LEARN_TIMEOUT 60000

BIN
code/espurna/data/index.html.gz View File


+ 144
- 53
code/espurna/rf.ino View File

@ -8,90 +8,181 @@ Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
#if RF_SUPPORT
#include <RemoteReceiver.h>
#include <RCSwitch.h>
unsigned long rfCode = 0;
unsigned long rfCodeON = 0;
unsigned long rfCodeOFF = 0;
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
// -----------------------------------------------------------------------------
void _rfWebSocketOnSend(JsonObject& root) {
root["rfVisible"] = 1;
root["rfChannel"] = getSetting("rfChannel", RF_CHANNEL);
root["rfDevice"] = getSetting("rfDevice", RF_DEVICE);
unsigned long _rfRetrieve(unsigned char id, bool status) {
String code = getSetting(status ? "rfbON" : "rfbOFF", id, "0");
return strtoul(code.c_str(), 0, 16);
}
void _rfBuildCodes() {
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);
}
unsigned long code = 0;
void _rfLearn(unsigned char id, bool status) {
_rf_learn_start = millis();
_rf_learn_id = id;
_rf_learn_status = status;
_rf_learn_active = true;
}
// channel
unsigned int channel = getSetting("rfChannel", RF_CHANNEL).toInt();
for (byte i = 0; i < 5; i++) {
code *= 3;
if (channel & 1) code += 1;
channel >>= 1;
}
void _rfForget(unsigned char id, bool status) {
// device
unsigned int device = getSetting("rfDevice", RF_DEVICE).toInt();
for (byte i = 0; i < 5; i++) {
code *= 3;
if (device != i) code += 2;
}
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);
// status
code *= 9;
rfCodeOFF = code + 2;
rfCodeON = code + 6;
for (unsigned char i=0; i<relayCount(); i++) {
DEBUG_MSG_P(PSTR("[RF] Code ON : %lu\n"), rfCodeON);
DEBUG_MSG_P(PSTR("[RF] Code OFF: %lu\n"), rfCodeOFF);
unsigned long code_on = _rfRetrieve(i, true);
unsigned long code_off = _rfRetrieve(i, false);
if (code == code_on) {
DEBUG_MSG_P(PSTR("[RF] Match ON code for relay %d\n"), i);
value = 1;
found = true;
}
if (code == code_off) {
DEBUG_MSG_P(PSTR("[RF] Match OFF code for relay %d\n"), i);
if (found) value = 2;
found = true;
}
if (found) {
relayID = i;
return true;
}
}
return false;
}
// -----------------------------------------------------------------------------
// WEB
// -----------------------------------------------------------------------------
void rfLoop() {
if (rfCode == 0) return;
DEBUG_MSG_P(PSTR("[RF] Received code: %lu\n"), rfCode);
if (rfCode == rfCodeON) relayStatus(0, true);
if (rfCode == rfCodeOFF) relayStatus(0, false);
rfCode = 0;
void _rfWebSocketOnSend(JsonObject& root) {
char buffer[20];
root["rfbVisible"] = 1;
root["rfbCount"] = relayCount();
JsonArray& rfb = root.createNestedArray("rfb");
for (byte id=0; id<relayCount(); id++) {
for (byte status=0; status<2; status++) {
JsonObject& node = rfb.createNestedObject();
snprintf_P(buffer, sizeof(buffer), PSTR("%X"), _rfRetrieve(id, status == 1));
node["id"] = id;
node["status"] = status;
node["data"] = String(buffer);
}
}
}
void rfCallback(unsigned long code, unsigned int period) {
rfCode = code;
void _rfWebSocketOnAction(uint32_t client_id, const char * action, JsonObject& data) {
if (strcmp(action, "rfblearn") == 0) _rfLearn(data["id"], data["status"]);
if (strcmp(action, "rfbforget") == 0) _rfForget(data["id"], data["status"]);
if (strcmp(action, "rfbsend") == 0) _rfStore(data["id"], data["status"], data["data"].as<long>());
}
void rfSetup() {
// -----------------------------------------------------------------------------
pinMode(RF_PIN, INPUT_PULLUP);
_rfBuildCodes();
RemoteReceiver::init(RF_PIN, 3, rfCallback);
RemoteReceiver::disable();
DEBUG_MSG_P(PSTR("[RF] Disabled\n"));
void rfLoop() {
wifiRegister([](justwifi_messages_t code, char * parameter) {
static unsigned long last = 0;
if (code == MESSAGE_CONNECTED || code == MESSAGE_ACCESSPOINT_CREATED) {
RemoteReceiver::enable();
DEBUG_MSG_P(PSTR("[RF] Enabled\n"));
}
if (_rfModem->available()) {
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);
}
}
}
}
if (code == MESSAGE_DISCONNECTED)
RemoteReceiver::disable();
DEBUG_MSG_P(PSTR("[RF] Disabled\n"));
}
});
_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);
wsOnAfterParseRegister(_rfBuildCodes);
wsOnActionRegister(_rfWebSocketOnAction);
#endif
// Register loop


+ 2634
- 2632
code/espurna/static/index.html.gz.h
File diff suppressed because it is too large
View File


+ 6
- 5
code/html/index.html View File

@ -127,7 +127,7 @@
</li>
<li class="pure-menu-item module module-rfb">
<a href="#" class="pure-menu-link" data="panel-rfb">RFBRIDGE</a>
<a href="#" class="pure-menu-link" data="panel-rfb">RF</a>
</li>
<li class="pure-menu-item">
@ -1015,11 +1015,12 @@
<div class="panel" id="panel-rfb">
<div class="header">
<h1>RFBRIDGE</h1>
<h1>RADIO FREQUENCY</h1>
<h2>
Sonoff 433 RF Bridge Configuration<br /><br />
To learn a new code click <strong>LEARN</strong>, the Sonoff RFBridge will beep, then press a button on the remote, the RFBridge will then double beep and the new code should show up. If the device double beeps but the code does not update it has not been properly learnt. Keep trying.<br /><br />
Modify or create new codes manually (18 characters) and then click <strong>SAVE</strong> to store them in the device memory. If your controlled device uses the same code to switch ON and OFF, learn the code with the ON button and copy paste it to the OFF input box, then click SAVE on the last one to store the value.<br /><br />
Sonoff 433 RF Bridge &amp; RF Link Configuration<br /><br />
This page allows you to configure the RF codes for the Sonoff RFBridge 433 and also for a basic RF receiver.<br /><br />
To learn a new code click <strong>LEARN</strong> (the Sonoff RFBridge will beep) then press a button on the remote, the new code should show up (and the RFBridge will double beep). If the device double beeps but the code does not update it has not been properly learnt. Keep trying.<br /><br />
Modify or create new codes manually and then click <strong>SAVE</strong> to store them in the device memory. If your controlled device uses the same code to switch ON and OFF, learn the code with the ON button and copy paste it to the OFF input box, then click SAVE on the last one to store the value.<br /><br />
Delete any code clicking the <strong>FORGET</strong> button.
<span class="module module-rfbraw"><br /><br />You can also specify 116-chars long RAW codes. Raw codes require a <a target="_blank" href="https://github.com/rhx/RF-Bridge-EFM8BB1">specific firmware for for the EFM8BB1</a>.</span>
</h2>


+ 1
- 1
code/platformio.ini View File

@ -30,7 +30,7 @@ lib_deps =
OneWire
PMS Library
PubSubClient
https://github.com/xoseperez/RemoteSwitch-arduino-library.git
rc-switch
https://github.com/xoseperez/Time
lib_ignore =
extra_scripts = extra_scripts.py


Loading…
Cancel
Save