Browse Source

Merged in rhexel/espurna/master (pull request #43)

Conflicts:
	code/espurna/data/index.html.gz
	code/espurna/static/index.html.gz.h
i18n
Xose Pérez 6 years ago
parent
commit
cc873a8471
6 changed files with 3300 additions and 3209 deletions
  1. +4
    -0
      code/espurna/config/general.h
  2. BIN
      code/espurna/data/index.html.gz
  3. +124
    -47
      code/espurna/rfbridge.ino
  4. +3165
    -3160
      code/espurna/static/index.html.gz.h
  5. +5
    -1
      code/html/custom.js
  6. +2
    -1
      code/html/index.html

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

@ -518,6 +518,7 @@ PROGMEM const char* const custom_reset_string[] = {
#define MQTT_TOPIC_RFOUT "rfout"
#define MQTT_TOPIC_RFIN "rfin"
#define MQTT_TOPIC_RFLEARN "rflearn"
#define MQTT_TOPIC_RFRAW "rfraw"
// Light module
#define MQTT_TOPIC_CHANNEL "channel"
@ -747,6 +748,9 @@ PROGMEM const char* const custom_reset_string[] = {
#define RF_SEND_DELAY 500 // Interval between sendings in ms
#define RF_RECEIVE_DELAY 500 // Interval between recieving in ms (avoid debouncing)
#define RF_RAW_SUPPORT 0 // RF raw codes require a specific firmware for the EFM8BB1
// https://github.com/rhx/RF-Bridge-EFM8BB1
// -----------------------------------------------------------------------------
// IR
// -----------------------------------------------------------------------------


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


+ 124
- 47
code/espurna/rfbridge.ino View File

@ -15,15 +15,23 @@ Copyright (C) 2017-2018 by Xose Pérez <xose dot perez at gmail dot com>
// DEFINITIONS
// -----------------------------------------------------------------------------
#define RF_MESSAGE_SIZE 9
#define RF_CODE_START 0xAA
#define RF_CODE_ACK 0xA0
#define RF_CODE_LEARN 0xA1
#define RF_CODE_LEARN_KO 0xA2
#define RF_CODE_LEARN_OK 0xA3
#define RF_CODE_RFIN 0xA4
#define RF_CODE_RFOUT 0xA5
#define RF_CODE_STOP 0x55
#define RF_MESSAGE_SIZE 9
#define RF_MAX_MESSAGE_SIZE (112+4)
#define RF_CODE_START 0xAA
#define RF_CODE_ACK 0xA0
#define RF_CODE_LEARN 0xA1
#define RF_CODE_LEARN_KO 0xA2
#define RF_CODE_LEARN_OK 0xA3
#define RF_CODE_RFIN 0xA4
#define RF_CODE_RFOUT 0xA5
#define RF_CODE_SNIFFING_ON 0xA6
#define RF_CODE_SNIFFING_OFF 0xA7
#define RF_CODE_RFOUT_NEW 0xA8
#define RF_CODE_LEARN_NEW 0xA9
#define RF_CODE_LEARN_KO_NEW 0xAA
#define RF_CODE_LEARN_OK_NEW 0xAB
#define RF_CODE_RFOUT_BUCKET 0xB0
#define RF_CODE_STOP 0x55
// -----------------------------------------------------------------------------
// GLOBALS TO THE MODULE
@ -46,9 +54,38 @@ Ticker _rfbTicker;
// PRIVATES
// -----------------------------------------------------------------------------
/*
From an hexa char array ("A220EE...") to a byte array (half the size)
*/
static int _rfbToArray(const char * in, byte * out, int length = RF_MESSAGE_SIZE * 2) {
int n = strlen(in);
if (n > RF_MAX_MESSAGE_SIZE*2 || (length > 0 && n != length)) return 0;
char tmp[3] = {0,0,0};
n /= 2;
for (unsigned char p = 0; p<n; p++) {
memcpy(tmp, &in[p*2], 2);
out[p] = strtol(tmp, NULL, 16);
}
return n;
}
/*
From a byte array to an hexa char array ("A220EE...", double the size)
*/
static bool _rfbToChar(byte * in, char * out, int n = RF_MESSAGE_SIZE) {
for (unsigned char p = 0; p<n; p++) {
sprintf_P(&out[p*2], PSTR("%02X"), in[p]);
}
return true;
}
void _rfbWebSocketOnSend(JsonObject& root) {
root["rfbVisible"] = 1;
root["rfbCount"] = relayCount();
#if RF_RAW_SUPPORT
root["rfbrawVisible"] = 1;
#endif
JsonArray& rfb = root.createNestedArray("rfb");
for (byte id=0; id<relayCount(); id++) {
for (byte status=0; status<2; status++) {
@ -94,13 +131,17 @@ void _rfbLearn() {
}
void _rfbSendRaw(const byte *message, const unsigned char n = RF_MESSAGE_SIZE) {
for (unsigned char j=0; j<n; j++) {
Serial.write(message[j]);
}
}
void _rfbSend(byte * message) {
Serial.println();
Serial.write(RF_CODE_START);
Serial.write(RF_CODE_RFOUT);
for (unsigned char j=0; j<RF_MESSAGE_SIZE; j++) {
Serial.write(message[j]);
}
_rfbSendRaw(message);
Serial.write(RF_CODE_STOP);
Serial.flush();
Serial.println();
@ -145,6 +186,17 @@ void _rfbSend(byte * code, int times) {
}
#if RF_RAW_SUPPORT
void _rfbSendRawOnce(byte *code, int length) {
char buffer[length*2];
_rfbToChar(code, buffer, length);
DEBUG_MSG_P(PSTR("[RFBRIDGE] Sending RAW MESSAGE '%s'\n"), buffer);
_rfbSendRaw(code, length);
}
#endif // RF_RAW_SUPPORT
bool _rfbMatch(char * code, unsigned char& relayID, unsigned char& value) {
if (strlen(code) != 18) return false;
@ -279,29 +331,6 @@ bool _rfbSameOnOff(unsigned char id) {
return _rfbCompare(rfbRetrieve(id, true).c_str(), rfbRetrieve(id, false).c_str());
}
/*
From an hexa char array ("A220EE...") to a byte array (half the size)
*/
bool _rfbToArray(const char * in, byte * out) {
if (strlen(in) != RF_MESSAGE_SIZE * 2) return false;
char tmp[3] = {0};
for (unsigned char p = 0; p<RF_MESSAGE_SIZE; p++) {
memcpy(tmp, &in[p*2], 2);
out[p] = strtol(tmp, NULL, 16);
}
return true;
}
/*
From a byte array to an hexa char array ("A220EE...", double the size)
*/
bool _rfbToChar(byte * in, char * out) {
for (unsigned char p = 0; p<RF_MESSAGE_SIZE; p++) {
sprintf_P(&out[p*2], PSTR("%02X"), in[p]);
}
return true;
}
#if MQTT_SUPPORT
void _rfbMqttCallback(unsigned int type, const char * topic, const char * payload) {
@ -310,6 +339,9 @@ void _rfbMqttCallback(unsigned int type, const char * topic, const char * payloa
snprintf_P(buffer, sizeof(buffer), PSTR("%s/+"), MQTT_TOPIC_RFLEARN);
mqttSubscribe(buffer);
mqttSubscribe(MQTT_TOPIC_RFOUT);
#if RF_RAW_SUPPORT
mqttSubscribe(MQTT_TOPIC_RFRAW);
#endif
}
if (type == MQTT_MESSAGE_EVENT) {
@ -330,11 +362,17 @@ void _rfbMqttCallback(unsigned int type, const char * topic, const char * payloa
}
if (t.equals(MQTT_TOPIC_RFOUT)) {
bool isRFOut = t.equals(MQTT_TOPIC_RFOUT);
#if RF_RAW_SUPPORT
bool isRFRaw = !isRFOut && t.equals(MQTT_TOPIC_RFRAW);
#else
bool isRFRaw = false;
#endif
if (isRFOut || isRFRaw) {
// The payload may be a code in HEX format ([0-9A-Z]{18}) or
// the code comma the number of times to transmit it.
byte message[RF_MESSAGE_SIZE];
char * tok = strtok((char *) payload, ",");
// Check if a switch is linked to that message
@ -349,11 +387,28 @@ void _rfbMqttCallback(unsigned int type, const char * topic, const char * payloa
return;
}
if (_rfbToArray(tok, message)) {
tok = strtok(NULL, ",");
byte times = (tok != NULL) ? atoi(tok) : 1;
_rfbSend(message, times);
}
#if RF_RAW_SUPPORT
byte message[RF_MAX_MESSAGE_SIZE];
int len = _rfbToArray(tok, message, 0);
if ((len > 0) && (isRFRaw || len != RF_MESSAGE_SIZE)) {
_rfbSendRawOnce(message, len);
} else {
tok = strtok(NULL, ",");
byte times = (tok != NULL) ? atoi(tok) : 1;
_rfbSend(message, times);
}
#else // RF_RAW_SUPPORT
byte message[RF_MESSAGE_SIZE];
if (_rfbToArray(tok, message)) {
tok = strtok(NULL, ",");
byte times = (tok != NULL) ? atoi(tok) : 1;
_rfbSend(message, times);
}
#endif // RF_RAW_SUPPORT
}
@ -383,11 +438,33 @@ void rfbStatus(unsigned char id, bool status) {
String value = rfbRetrieve(id, status);
if (value.length() > 0) {
bool same = _rfbSameOnOff(id);
byte message[RF_MESSAGE_SIZE];
_rfbToArray(value.c_str(), message);
unsigned char times = RF_SEND_TIMES;
if (same) times = _rfbin ? 0 : 1;
_rfbSend(message, times);
#if RF_RAW_SUPPORT
byte message[RF_MAX_MESSAGE_SIZE];
int len = _rfbToArray(value.c_str(), message, 0);
if (len == RF_MESSAGE_SIZE && // probably a standard msg
(message[0] != RF_CODE_START || // raw would start with 0xAA
message[1] != RF_CODE_RFOUT_BUCKET || // followed by 0xB0,
message[2] + 4 != len || // needs a valid length,
message[len-1] != RF_CODE_STOP)) { // and finish with 0x55
unsigned char times = RF_SEND_TIMES;
if (same) times = _rfbin ? 0 : 1;
_rfbSend(message, times);
} else {
_rfbSendRawOnce(message, len); // send a raw message
}
#else // RF_RAW_SUPPORT
byte message[RF_MESSAGE_SIZE];
_rfbToArray(value.c_str(), message);
unsigned char times = RF_SEND_TIMES;
if (same) times = _rfbin ? 0 : 1;
_rfbSend(message, times);
#endif // RF_RAW_SUPPORT
}
}


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


+ 5
- 1
code/html/custom.js View File

@ -130,7 +130,7 @@ function getData(form) {
// Do not report these fields
if (name === "filename" || name === "rfbcode" ) {
return;
return;
}
// Grab the value
@ -843,6 +843,10 @@ function processData(data) {
return;
}
if (key === "rfbrawVisible") {
$("input[name='rfbcode']").attr("maxlength", 116);
}
if (key === "rfb") {
var nodes = data.rfb;
for (i in nodes) {


+ 2
- 1
code/html/index.html View File

@ -1000,8 +1000,9 @@
<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 (all codes must be 18 characters long) 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 />
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 />
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>
</div>


Loading…
Cancel
Save