Browse Source

rfb: rework both efm8bb1 & rcswitch implementations (#2335)

- build flags RF_... are renamed to RFB_...
- drop RFB_DIRECT boolean in favor of RFB_PROVIDER=..., adds RFB_PROVIDER_EFM8BB1 and RFB_PROVIDER_RCSWITCH
- rework rfbridge parser. drop serial buffering and combined processing of rcswitch / rfb data in favor of state-full parsing
- rework rcswitch integration, support variable length payload via bitlength and allow to output 64bit data via rc-switch fork from open-mqtt-gateway.
- apply bit-length comparison for the old rcswitch codes, bump cfg version to 5 to allow 1.14.1 config updates (broken on dev, since cfg setting was never updated on clean installations 😞)
- optional relay support for both, independent of mqtt
- rework settings scanning routine when trying to match rf payload with the relay ID, scan settings only once instead of relayCount()<sup>2</sup> times if we want to find something for relayCount()-1'th relay
- add broker callbacks list with proto id + stringified code. default rfbridge does not support more than one protocol, so send out ID 0 as default (which matches with what 0xa6 will show, supposedly as it does not work for me :?)
- send out  0xa6 and 0xb0 sniffer data from https://github.com/Portisch/RF-Bridge-EFM8BB1/ to the MQTT and internally via broker callback
- update receiver callback 'locking' to make sure specific relay ID is tracked instead of all at once
- update build tests and deprecation notices

Stock RFBridge & RCSwitch refactoring are closely related, so pulling all of this at once. We no longer use the same 'flow', using separate integration paths.

One sort-of breaking thing is the new internal _rfbMatch() change - we no longer update serialized 'buffer' string when matching in the receiver, thus we (very) likely send a different string to the MQTT when receiving the same device's code. This introduces non-trivial dependency on the output buffer though :/ And we don't always have relay support, so that would be another layer of preprocessor checks.
Instead, I am in favor of another option - special build / runtime setting to provide the same protocol + payload pair as new broker integration does. To simplify / make sure it is noticed, separate protocol and actual data with comma, colon (like IR) or space.
mcspr-patch-1
Max Prokhorov 4 years ago
committed by GitHub
parent
commit
82d5de0b64
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1024 additions and 494 deletions
  1. +2
    -2
      code/espurna/board.cpp
  2. +1
    -1
      code/espurna/config/arduino.h
  3. +0
    -5
      code/espurna/config/dependencies.h
  4. +40
    -0
      code/espurna/config/deprecated.h
  5. +25
    -24
      code/espurna/config/general.h
  6. +16
    -12
      code/espurna/config/hardware.h
  7. +3
    -0
      code/espurna/config/types.h
  8. +1
    -1
      code/espurna/config/version.h
  9. +1
    -1
      code/espurna/config/webui.h
  10. +1
    -1
      code/espurna/main.cpp
  11. +3
    -1
      code/espurna/migrate.cpp
  12. +896
    -420
      code/espurna/rfbridge.cpp
  13. +7
    -5
      code/espurna/rfbridge.h
  14. +1
    -1
      code/espurna/system.cpp
  15. +17
    -11
      code/espurna/utils.cpp
  16. +1
    -1
      code/espurna/utils.h
  17. +2
    -2
      code/platformio.ini
  18. +2
    -2
      code/test/build/nondefault.h
  19. +5
    -4
      code/test/build/rfbridge.h

+ 2
- 2
code/espurna/board.cpp View File

@ -84,8 +84,8 @@ PROGMEM const char espurna_modules[] =
#if RFM69_SUPPORT #if RFM69_SUPPORT
"RFM69 " "RFM69 "
#endif #endif
#if RF_SUPPORT
"RF "
#if RFB_SUPPORT
"RFB "
#endif #endif
#if RPN_RULES_SUPPORT #if RPN_RULES_SUPPORT
"RPN_RULES " "RPN_RULES "


+ 1
- 1
code/espurna/config/arduino.h View File

@ -207,7 +207,7 @@
//#define NTP_SUPPORT 0 //#define NTP_SUPPORT 0
//#define OTA_ARDUINOOTA_SUPPORT 1 //#define OTA_ARDUINOOTA_SUPPORT 1
//#define RFM69_SUPPORT 1 //#define RFM69_SUPPORT 1
//#define RF_SUPPORT 1
//#define RFB_SUPPORT 1
//#define RPN_RULES_SUPPORT 0 //#define RPN_RULES_SUPPORT 0
//#define SCHEDULER_SUPPORT 0 //#define SCHEDULER_SUPPORT 0
//#define SPIFFS_SUPPORT 1 //#define SPIFFS_SUPPORT 1


+ 0
- 5
code/espurna/config/dependencies.h View File

@ -49,11 +49,6 @@
#define MQTT_SUPPORT 1 #define MQTT_SUPPORT 1
#endif #endif
#if RF_SUPPORT
#undef RELAY_SUPPORT
#define RELAY_SUPPORT 1
#endif
#if LED_SUPPORT #if LED_SUPPORT
#undef BROKER_SUPPORT #undef BROKER_SUPPORT
#define BROKER_SUPPORT 1 // If LED is enabled enable BROKER to supply status changes #define BROKER_SUPPORT 1 // If LED is enabled enable BROKER to supply status changes


+ 40
- 0
code/espurna/config/deprecated.h View File

@ -108,3 +108,43 @@
#warning "WIFI_FALLBACK_APMODE is deprecated! Please use WIFI_AP_MODE instead" #warning "WIFI_FALLBACK_APMODE is deprecated! Please use WIFI_AP_MODE instead"
#define WIFI_AP_MODE ((1 == WIFI_FALLBACK_APMODE) ? WiFiApMode::Fallback : WiFiApMode::Disabled) #define WIFI_AP_MODE ((1 == WIFI_FALLBACK_APMODE) ? WiFiApMode::Fallback : WiFiApMode::Disabled)
#endif #endif
#ifdef RFB_DIRECT
#warning "RFB_DIRECT is deprecated! Please use RFB_PROVIDER=RFB_PROVIDER_..."
#undef RFB_PROVIDER
#if RFB_DIRECT
#define RFB_PROVIDER RFB_PROVIDER_RCSWITCH
#else
#define RFB_PROVIDER RFB_PROVIDER_EFM8BB1
#endif
#endif
#ifdef RF_LEARN_TIMEOUT
#warning "RF_LEARN_TIMEOUT is deprecated! Please use RFB_LEARN_TIMEOUT"
#undef RFB_LEARN_TIMEOUT
#define RFB_LEARN_TIMEOUT RF_LEARN_TIMEOUT
#endif
#ifdef RF_SEND_TIMES
#warning "RF_SEND_TIMES is deprecated! Please use RFB_SEND_TIMES"
#undef RFB_SEND_TIMES
#define RFB_SEND_TIMES RF_SEND_TIMES
#endif
#ifdef RF_SEND_DELAY
#warning "RF_SEND_DELAY is deprecated! Please use RFB_SEND_DELAY"
#undef RFB_SEND_DELAY
#define RFB_SEND_DELAY RF_SEND_DELAY
#endif
#ifdef RF_RECEIVE_DELAY
#warning "RF_RECEIVE_DELAY is deprecated! Please use RFB_RECEIVE_DELAY"
#undef RFB_RECEIVE_DELAY
#define RFB_RECEIVE_DELAY RF_RECEIVE_DELAY
#endif
#ifdef RF_SUPPORT
#warning "RF_SUPPORT is deprecated! Please use RFB_SUPPORT"
#undef RFB_SUPPORT
#define RFB_SUPPORT RF_SUPPORT
#endif

+ 25
- 24
code/espurna/config/general.h View File

@ -1621,40 +1621,26 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// MQTT RF BRIDGE
// RF BRIDGE
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#ifndef RF_SUPPORT
#define RF_SUPPORT 0
#ifndef RFB_SUPPORT
#define RFB_SUPPORT 0
#endif #endif
#ifndef RF_DEBOUNCE
#define RF_DEBOUNCE 500
#ifndef RFB_SEND_TIMES
#define RFB_SEND_TIMES 1 // How many times to send the message
#endif #endif
#ifndef RF_LEARN_TIMEOUT
#define RF_LEARN_TIMEOUT 60000
#endif
#ifndef RF_SEND_TIMES
#define RF_SEND_TIMES 4 // How many times to send the message
#endif
#ifndef RF_SEND_DELAY
#define RF_SEND_DELAY 500 // Interval between sendings in ms
#endif
#ifndef RF_RECEIVE_DELAY
#define RF_RECEIVE_DELAY 500 // Interval between recieving in ms (avoid debouncing)
#endif
// Enable RCSwitch support
// - RFB_PROVIDER_EFM8BB1
// Default option for the ITEAD_SONOFF_RFBRIDGE or any custom firmware implementing the protocol
// - RFB_PROVIDER_RCSWITCH
// Originally implemented for SONOFF BASIC // Originally implemented for SONOFF BASIC
// https://tinkerman.cat/adding-rf-to-a-non-rf-itead-sonoff/ // https://tinkerman.cat/adding-rf-to-a-non-rf-itead-sonoff/
// Also possible to use with SONOFF RF BRIDGE, thanks to @wildwiz // Also possible to use with SONOFF RF BRIDGE, thanks to @wildwiz
// https://github.com/xoseperez/espurna/wiki/Hardware-Itead-Sonoff-RF-Bridge---Direct-Hack // https://github.com/xoseperez/espurna/wiki/Hardware-Itead-Sonoff-RF-Bridge---Direct-Hack
#ifndef RFB_DIRECT
#define RFB_DIRECT 0
#ifndef RFB_PROVIDER
#define RFB_PROVIDER RFB_PROVIDER_RCSWITCH
#endif #endif
#ifndef RFB_RX_PIN #ifndef RFB_RX_PIN
@ -1665,6 +1651,21 @@
#define RFB_TX_PIN GPIO_NONE #define RFB_TX_PIN GPIO_NONE
#endif #endif
#ifndef RFB_LEARN_TIMEOUT
#define RFB_LEARN_TIMEOUT 15000
#endif
#ifndef RFB_SEND_DELAY
#define RFB_SEND_DELAY 500 // Interval between sendings in ms
#endif
#ifndef RFB_RECEIVE_DELAY
#define RFB_RECEIVE_DELAY 500 // Interval between recieving in ms (avoid bouncing)
#endif
#ifndef RFB_TRANSMIT_TIMES
#define RFB_TRANSMIT_TIMES 5 // How many times RCSwitch will repeat the message
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// IR Bridge // IR Bridge


+ 16
- 12
code/espurna/config/hardware.h View File

@ -789,20 +789,24 @@
#define LED1_PIN 13 #define LED1_PIN 13
#define LED1_PIN_INVERSE 1 #define LED1_PIN_INVERSE 1
#define RF_SUPPORT 1
// Only used when RFB_DIRECT=1
#define RFB_RX_PIN 4
#define RFB_TX_PIN 5
#define RFB_SUPPORT 1
// When using un-modified harware, ESPurna communicates with the secondary // When using un-modified harware, ESPurna communicates with the secondary
// MCU EFM8BB1 via UART at 19200 bps so we need to change the speed of // MCU EFM8BB1 via UART at 19200 bps so we need to change the speed of
// the port and remove UART noise on serial line // the port and remove UART noise on serial line
#if not RFB_DIRECT
#ifndef RFB_PROVIDER
#define RFB_PROVIDER RFB_PROVIDER_EFM8BB1
#endif
#if RFB_PROVIDER == RFB_PROVIDER_EFM8BB1
#define SERIAL_BAUDRATE 19200 #define SERIAL_BAUDRATE 19200
#define DEBUG_SERIAL_SUPPORT 0 #define DEBUG_SERIAL_SUPPORT 0
#endif #endif
// Only used when RFB_PROVIDER is RCSWITCH
#define RFB_RX_PIN 4
#define RFB_TX_PIN 5
#elif defined(ITEAD_SONOFF_B1) #elif defined(ITEAD_SONOFF_B1)
// Info // Info
@ -1373,9 +1377,9 @@
#define LIGHT_CH4_PIN 13 // WHITE #define LIGHT_CH4_PIN 13 // WHITE
// RF // RF
#define RF_SUPPORT 1
#define RFB_DIRECT 1
#define RFB_RX_PIN 4
#define RFB_SUPPORT 1
#define RFB_PROVIDER RFB_PROVIDER_RCSWITCH
#define RFB_RX_PIN 4
#elif defined(MAGICHOME_ZJ_WFMN_C_11) #elif defined(MAGICHOME_ZJ_WFMN_C_11)
@ -2683,9 +2687,9 @@
#endif #endif
#define DALLAS_PIN 2 #define DALLAS_PIN 2
#define RF_SUPPORT 1
#define RFB_DIRECT 1
#define RFB_RX_PIN 14
#define RFB_SUPPORT 1
#define RFB_PROVIDER RFB_PROVIDER_RCSWITCH
#define RFB_RX_PIN 14
#ifndef DIGITAL_SUPPORT #ifndef DIGITAL_SUPPORT
#define DIGITAL_SUPPORT 1 #define DIGITAL_SUPPORT 1


+ 3
- 0
code/espurna/config/types.h View File

@ -103,6 +103,9 @@
#define RELAY_PROVIDER_STM 4 #define RELAY_PROVIDER_STM 4
#define RELAY_PROVIDER_MCP23S08 5 #define RELAY_PROVIDER_MCP23S08 5
#define RFB_PROVIDER_RCSWITCH 0
#define RFB_PROVIDER_EFM8BB1 1
#define RELAY_GROUP_SYNC_NORMAL 0 #define RELAY_GROUP_SYNC_NORMAL 0
#define RELAY_GROUP_SYNC_INVERSE 1 #define RELAY_GROUP_SYNC_INVERSE 1
#define RELAY_GROUP_SYNC_RECEIVEONLY 2 #define RELAY_GROUP_SYNC_RECEIVEONLY 2


+ 1
- 1
code/espurna/config/version.h View File

@ -8,4 +8,4 @@
#define APP_VERSION "1.15.0-dev" #define APP_VERSION "1.15.0-dev"
#define APP_AUTHOR "xose.perez@gmail.com" #define APP_AUTHOR "xose.perez@gmail.com"
#define APP_WEBSITE "http://tinkerman.cat" #define APP_WEBSITE "http://tinkerman.cat"
#define CFG_VERSION 4
#define CFG_VERSION 5

+ 1
- 1
code/espurna/config/webui.h View File

@ -32,7 +32,7 @@
#endif #endif
#endif #endif
#if RF_SUPPORT == 1
#if RFB_SUPPORT == 1
#ifndef WEBUI_IMAGE #ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_RFBRIDGE #define WEBUI_IMAGE WEBUI_IMAGE_RFBRIDGE
#else #else


+ 1
- 1
code/espurna/main.cpp View File

@ -244,7 +244,7 @@ void setup() {
#if I2C_SUPPORT #if I2C_SUPPORT
i2cSetup(); i2cSetup();
#endif #endif
#if RF_SUPPORT
#if RFB_SUPPORT
rfbSetup(); rfbSetup();
#endif #endif
#if ALEXA_SUPPORT #if ALEXA_SUPPORT


+ 3
- 1
code/espurna/migrate.cpp View File

@ -26,6 +26,7 @@ void _cmpMoveIndexDown(const char * key, int offset = 0) {
// 2: based on Embedis, with board definitions 1-based // 2: based on Embedis, with board definitions 1-based
// 3: based on Embedis, with board definitions 0-based // 3: based on Embedis, with board definitions 0-based
// 4: based on Embedis, no board definitions // 4: based on Embedis, no board definitions
// 5: based on Embedis, updated rfb codes format
int migrateVersion() { int migrateVersion() {
const static auto version = getSetting("cfg", CFG_VERSION); const static auto version = getSetting("cfg", CFG_VERSION);
@ -38,7 +39,8 @@ int migrateVersion() {
void migrate() { void migrate() {
// Update if not on the latest version
// We either get 0, when version did not change
// Or, the version we migrate from
const auto version = migrateVersion(); const auto version = migrateVersion();
setSetting("cfg", CFG_VERSION); setSetting("cfg", CFG_VERSION);


+ 896
- 420
code/espurna/rfbridge.cpp
File diff suppressed because it is too large
View File


+ 7
- 5
code/espurna/rfbridge.h View File

@ -6,13 +6,15 @@ Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
*/ */
#pragma once
#include "espurna.h" #include "espurna.h"
#if RF_SUPPORT
#if RFB_SUPPORT
#include "broker.h"
#if RFB_DIRECT
#include <RCSwitch.h>
#endif
BrokerDeclare(RfbridgeBroker, void(unsigned char protocol, const char* code));
void rfbStatus(unsigned char id, bool status); void rfbStatus(unsigned char id, bool status);
void rfbLearn(unsigned char id, bool status); void rfbLearn(unsigned char id, bool status);
@ -23,4 +25,4 @@ void rfbStore(unsigned char id, bool status, const char * code);
void rfbForget(unsigned char id, bool status); void rfbForget(unsigned char id, bool status);
void rfbSetup(); void rfbSetup();
#endif // RF_SUPPORT == 1
#endif // RFB_SUPPORT == 1

+ 1
- 1
code/espurna/system.cpp View File

@ -251,7 +251,7 @@ void _systemSetupSpecificHardware() {
// These devices use the hardware UART // These devices use the hardware UART
// to communicate to secondary microcontrollers // to communicate to secondary microcontrollers
#if (RF_SUPPORT && !RFB_DIRECT) || (RELAY_PROVIDER == RELAY_PROVIDER_DUAL) || (RELAY_PROVIDER == RELAY_PROVIDER_STM)
#if (RFB_SUPPORT && (RFB_PROVIDER == RFB_PROVIDER_EFM8BB1)) || (RELAY_PROVIDER == RELAY_PROVIDER_DUAL) || (RELAY_PROVIDER == RELAY_PROVIDER_STM)
Serial.begin(SERIAL_BAUDRATE); Serial.begin(SERIAL_BAUDRATE);
#endif #endif


+ 17
- 11
code/espurna/utils.cpp View File

@ -792,7 +792,7 @@ char* strnstr(const char* buffer, const char* token, size_t n) {
} }
// From a byte array to an hexa char array ("A220EE...", double the size) // From a byte array to an hexa char array ("A220EE...", double the size)
size_t hexEncode(uint8_t * in, size_t in_size, char * out, size_t out_size) {
size_t hexEncode(const uint8_t * in, size_t in_size, char * out, size_t out_size) {
if ((2 * in_size + 1) > (out_size)) return 0; if ((2 * in_size + 1) > (out_size)) return 0;
static const char base16[] = "0123456789ABCDEF"; static const char base16[] = "0123456789ABCDEF";
@ -812,10 +812,9 @@ size_t hexEncode(uint8_t * in, size_t in_size, char * out, size_t out_size) {
// From an hexa char array ("A220EE...") to a byte array (half the size) // From an hexa char array ("A220EE...") to a byte array (half the size)
size_t hexDecode(const char* in, size_t in_size, uint8_t* out, size_t out_size) { size_t hexDecode(const char* in, size_t in_size, uint8_t* out, size_t out_size) {
if (out_size < (in_size / 2)) return 0;
size_t index = 0;
size_t out_index = 0;
if ((in_size & 1) || (out_size < (in_size / 2))) {
return 0;
}
auto char2byte = [](char ch) -> uint8_t { auto char2byte = [](char ch) -> uint8_t {
if ((ch >= '0') && (ch <= '9')) { if ((ch >= '0') && (ch <= '9')) {
@ -829,13 +828,20 @@ size_t hexDecode(const char* in, size_t in_size, uint8_t* out, size_t out_size)
} }
}; };
while (index < in_size) {
out[out_index] = char2byte(in[index]) << 4;
out[out_index] += char2byte(in[index + 1]);
size_t index = 0;
size_t out_index = 0;
index += 2;
out_index += 1;
while (index < in_size) {
const uint8_t lhs = char2byte(in[index]) << 4;
const uint8_t rhs = char2byte(in[index + 1]);
if (lhs || rhs) {
out[out_index++] = lhs | rhs;
index += 2;
continue;
}
out_index = 0;
break;
} }
return out_index ? (1 + out_index) : 0;
return out_index;
} }

+ 1
- 1
code/espurna/utils.h View File

@ -69,5 +69,5 @@ void nice_delay(unsigned long ms);
double roundTo(double num, unsigned char positions); double roundTo(double num, unsigned char positions);
size_t hexEncode(uint8_t* in, size_t in_size, char* out, size_t out_size);
size_t hexEncode(const uint8_t* in, size_t in_size, char* out, size_t out_size);
size_t hexDecode(const char* in, size_t in_size, uint8_t* out, size_t out_size); size_t hexDecode(const char* in, size_t in_size, uint8_t* out, size_t out_size);

+ 2
- 2
code/platformio.ini View File

@ -143,7 +143,7 @@ lib_deps =
OneWire OneWire
PZEM004T PZEM004T
PubSubClient PubSubClient
rc-switch
https://github.com/1technophile/rc-switch#11402652
https://github.com/LowPowerLab/RFM69#7008d57a https://github.com/LowPowerLab/RFM69#7008d57a
https://github.com/mcspr/rpnlib.git#0.24.1 https://github.com/mcspr/rpnlib.git#0.24.1
NewPing NewPing
@ -493,7 +493,7 @@ src_build_flags = -DITEAD_SONOFF_RFBRIDGE -DDISABLE_POSTMORTEM_STACKDUMP
[env:itead-sonoff-rfbridge-direct] [env:itead-sonoff-rfbridge-direct]
extends = env:esp8266-1m-base extends = env:esp8266-1m-base
src_build_flags = -DITEAD_SONOFF_RFBRIDGE -DRFB_DIRECT
src_build_flags = -DITEAD_SONOFF_RFBRIDGE -DRFB_PROVIDER=RFB_PROVIDER_RCSWITCH
[env:itead-slampher] [env:itead-slampher]
extends = env:esp8266-1m-base extends = env:esp8266-1m-base


+ 2
- 2
code/test/build/nondefault.h View File

@ -5,11 +5,11 @@
#define NETBIOS_SUPPORT 1 #define NETBIOS_SUPPORT 1
#define NOFUSS_SUPPORT 1 #define NOFUSS_SUPPORT 1
#define OTA_MQTT_SUPPORT 1 #define OTA_MQTT_SUPPORT 1
#define RFB_DIRECT 1
#define RFM69_SUPPORT 1 #define RFM69_SUPPORT 1
#define RF_SUPPORT 1
#define RPN_RULES_SUPPORT 1 #define RPN_RULES_SUPPORT 1
#define SSDP_SUPPORT 1 #define SSDP_SUPPORT 1
#define UART_MQTT_SUPPORT 1 #define UART_MQTT_SUPPORT 1
#define TERMINAL_WEB_API_SUPPORT 1 #define TERMINAL_WEB_API_SUPPORT 1
#define TERMINAL_MQTT_SUPPORT 1 #define TERMINAL_MQTT_SUPPORT 1
#define RFB_SUPPORT 1
#define RFB_PROVIDER RFB_PROVIDER_RCSWITCH

+ 5
- 4
code/test/build/rfbridge.h View File

@ -1,4 +1,5 @@
#define DUMMY_RELAY_COUNT 8
#define RF_SUPPORT 1
#define SERIAL_BAUDRATE 19200
#define DEBUG_SERIAL_SUPPORT 0
#define DUMMY_RELAY_COUNT 8
#define SERIAL_BAUDRATE 19200
#define DEBUG_SERIAL_SUPPORT 0
#define RFB_SUPPORT 1
#define RFB_PROVIDER RFB_PROVIDER_EFM8BB1

Loading…
Cancel
Save