mirror of
https://github.com/wled/WLED.git
synced 2025-07-19 16:56:35 +00:00
RF433 json usermod (#4234)
* RF433 remote usermod --------- Co-authored-by: Kilrah <kilrah@kilrah.xyz>
This commit is contained in:
parent
a4c3491f0c
commit
b9aeb19834
@ -529,3 +529,14 @@ monitor_filters = esp32_exception_decoder
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32.lib_deps}
|
${esp32.lib_deps}
|
||||||
TFT_eSPI @ 2.5.33 ;; this is the last version that compiles with the WLED default framework - newer versions require platform = espressif32 @ ^6.3.2
|
TFT_eSPI @ 2.5.33 ;; this is the last version that compiles with the WLED default framework - newer versions require platform = espressif32 @ ^6.3.2
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Usermod examples
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# 433MHz RF remote example for esp32dev
|
||||||
|
[env:esp32dev_usermod_RF433]
|
||||||
|
extends = env:esp32dev
|
||||||
|
build_flags = ${env:esp32dev.build_flags} -D USERMOD_RF433
|
||||||
|
lib_deps = ${env:esp32dev.lib_deps}
|
||||||
|
sui77/rc-switch @ 2.6.4
|
||||||
|
18
usermods/usermod_v2_RF433/readme.md
Normal file
18
usermods/usermod_v2_RF433/readme.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# RF433 remote usermod
|
||||||
|
|
||||||
|
Usermod for controlling WLED using a generic 433 / 315MHz remote and simple 3-pin receiver
|
||||||
|
See <https://github.com/sui77/rc-switch/> for compatibility details
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
- Create a `platformio_override.ini` file at the root of the wled source directory if not already present
|
||||||
|
- Copy the `433MHz RF remote example for esp32dev` section from `platformio_override.sample.ini` into it
|
||||||
|
- Duplicate/adjust for other boards
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
- Connect receiver to a free pin
|
||||||
|
- Set pin in Config->Usermods
|
||||||
|
- Info pane will show the last received button code
|
||||||
|
- Upload the remote433.json sample file in this folder to the ESP with the file editor at [http://\[wled-ip\]/edit](http://ip/edit)
|
||||||
|
- Edit as necessary, the key is the button number retrieved from the info pane, and the "cmd" can be either an [HTTP API](https://kno.wled.ge/interfaces/http-api/) or a [JSON API](https://kno.wled.ge/interfaces/json-api/) command.
|
34
usermods/usermod_v2_RF433/remote433.json
Normal file
34
usermods/usermod_v2_RF433/remote433.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"13985576": {
|
||||||
|
"cmnt": "Toggle Power using HTTP API",
|
||||||
|
"cmd": "T=2"
|
||||||
|
},
|
||||||
|
"3670817": {
|
||||||
|
"cmnt": "Force Power ON using HTTP API",
|
||||||
|
"cmd": "T=1"
|
||||||
|
},
|
||||||
|
"13985572": {
|
||||||
|
"cmnt": "Set brightness to 200 using JSON API",
|
||||||
|
"cmd": {"bri":200}
|
||||||
|
},
|
||||||
|
"3670818": {
|
||||||
|
"cmnt": "Run Preset 1 using JSON API",
|
||||||
|
"cmd": {"ps":1}
|
||||||
|
},
|
||||||
|
"13985570": {
|
||||||
|
"cmnt": "Increase brightness by 40 using HTTP API",
|
||||||
|
"cmd": "A=~40"
|
||||||
|
},
|
||||||
|
"13985569": {
|
||||||
|
"cmnt": "Decrease brightness by 40 using HTTP API",
|
||||||
|
"cmd": "A=~-40"
|
||||||
|
},
|
||||||
|
"7608836": {
|
||||||
|
"cmnt": "Start 1min timer using JSON API",
|
||||||
|
"cmd": {"nl":{"on":true,"dur":1,"mode":0}}
|
||||||
|
},
|
||||||
|
"7608840": {
|
||||||
|
"cmnt": "Select random effect on all segments using JSON API",
|
||||||
|
"cmd": {"seg":{"fx":"r"}}
|
||||||
|
}
|
||||||
|
}
|
183
usermods/usermod_v2_RF433/usermod_v2_RF433.h
Normal file
183
usermods/usermod_v2_RF433/usermod_v2_RF433.h
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wled.h"
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include <RCSwitch.h>
|
||||||
|
|
||||||
|
#define RF433_BUSWAIT_TIMEOUT 24
|
||||||
|
|
||||||
|
class RF433Usermod : public Usermod
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
RCSwitch mySwitch = RCSwitch();
|
||||||
|
unsigned long lastCommand = 0;
|
||||||
|
unsigned long lastTime = 0;
|
||||||
|
|
||||||
|
bool modEnabled = true;
|
||||||
|
int8_t receivePin = -1;
|
||||||
|
|
||||||
|
static const char _modName[];
|
||||||
|
static const char _modEnabled[];
|
||||||
|
static const char _receivePin[];
|
||||||
|
|
||||||
|
bool initDone = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
mySwitch.disableReceive();
|
||||||
|
if (modEnabled)
|
||||||
|
{
|
||||||
|
mySwitch.enableReceive(receivePin);
|
||||||
|
}
|
||||||
|
initDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* connected() is called every time the WiFi is (re)connected
|
||||||
|
* Use it to initialize network interfaces
|
||||||
|
*/
|
||||||
|
void connected()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
if (!modEnabled || strip.isUpdating())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mySwitch.available())
|
||||||
|
{
|
||||||
|
unsigned long receivedCommand = mySwitch.getReceivedValue();
|
||||||
|
mySwitch.resetAvailable();
|
||||||
|
|
||||||
|
// Discard duplicates, limit long press repeat
|
||||||
|
if (lastCommand == receivedCommand && millis() - lastTime < 800)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lastCommand = receivedCommand;
|
||||||
|
lastTime = millis();
|
||||||
|
|
||||||
|
DEBUG_PRINT(F("RF433 Receive: "));
|
||||||
|
DEBUG_PRINTLN(receivedCommand);
|
||||||
|
|
||||||
|
if(!remoteJson433(receivedCommand))
|
||||||
|
DEBUG_PRINTLN(F("RF433: unknown button"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add last received button to info pane
|
||||||
|
void addToJsonInfo(JsonObject &root)
|
||||||
|
{
|
||||||
|
if (!initDone)
|
||||||
|
return; // prevent crash on boot applyPreset()
|
||||||
|
JsonObject user = root["u"];
|
||||||
|
if (user.isNull())
|
||||||
|
user = root.createNestedObject("u");
|
||||||
|
|
||||||
|
JsonArray switchArr = user.createNestedArray("RF433 Last Received"); // name
|
||||||
|
switchArr.add(lastCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addToConfig(JsonObject &root)
|
||||||
|
{
|
||||||
|
JsonObject top = root.createNestedObject(FPSTR(_modName)); // usermodname
|
||||||
|
top[FPSTR(_modEnabled)] = modEnabled;
|
||||||
|
JsonArray pinArray = top.createNestedArray("pin");
|
||||||
|
pinArray.add(receivePin);
|
||||||
|
|
||||||
|
DEBUG_PRINTLN(F(" config saved."));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readFromConfig(JsonObject &root)
|
||||||
|
{
|
||||||
|
JsonObject top = root[FPSTR(_modName)];
|
||||||
|
if (top.isNull())
|
||||||
|
{
|
||||||
|
DEBUG_PRINT(FPSTR(_modName));
|
||||||
|
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
getJsonValue(top[FPSTR(_modEnabled)], modEnabled);
|
||||||
|
getJsonValue(top["pin"][0], receivePin);
|
||||||
|
|
||||||
|
DEBUG_PRINTLN(F("config (re)loaded."));
|
||||||
|
|
||||||
|
// Redo init on update
|
||||||
|
if(initDone)
|
||||||
|
setup();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||||
|
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||||
|
*/
|
||||||
|
uint16_t getId()
|
||||||
|
{
|
||||||
|
return USERMOD_ID_RF433;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function follows the same principle as decodeIRJson() / remoteJson()
|
||||||
|
bool remoteJson433(int button)
|
||||||
|
{
|
||||||
|
char objKey[14];
|
||||||
|
bool parsed = false;
|
||||||
|
|
||||||
|
if (!requestJSONBufferLock(22)) return false;
|
||||||
|
|
||||||
|
sprintf_P(objKey, PSTR("\"%d\":"), button);
|
||||||
|
|
||||||
|
unsigned long start = millis();
|
||||||
|
while (strip.isUpdating() && millis()-start < RF433_BUSWAIT_TIMEOUT) yield(); // wait for strip to finish updating, accessing FS during sendout causes glitches
|
||||||
|
|
||||||
|
// attempt to read command from remote.json
|
||||||
|
readObjectFromFile(PSTR("/remote433.json"), objKey, pDoc);
|
||||||
|
JsonObject fdo = pDoc->as<JsonObject>();
|
||||||
|
if (fdo.isNull()) {
|
||||||
|
// the received button does not exist
|
||||||
|
releaseJSONBufferLock();
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
String cmdStr = fdo["cmd"].as<String>();
|
||||||
|
JsonObject jsonCmdObj = fdo["cmd"]; //object
|
||||||
|
|
||||||
|
if (jsonCmdObj.isNull()) // we could also use: fdo["cmd"].is<String>()
|
||||||
|
{
|
||||||
|
// HTTP API command
|
||||||
|
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
||||||
|
if (!cmdStr.startsWith(apireq)) cmdStr = apireq + cmdStr; // if no "win&" prefix
|
||||||
|
if (!irApplyToAllSelected && cmdStr.indexOf(F("SS="))<0) {
|
||||||
|
char tmp[10];
|
||||||
|
sprintf_P(tmp, PSTR("&SS=%d"), strip.getMainSegmentId());
|
||||||
|
cmdStr += tmp;
|
||||||
|
}
|
||||||
|
fdo.clear(); // clear JSON buffer (it is no longer needed)
|
||||||
|
handleSet(nullptr, cmdStr, false); // no stateUpdated() call here
|
||||||
|
stateUpdated(CALL_MODE_BUTTON);
|
||||||
|
parsed = true;
|
||||||
|
} else {
|
||||||
|
// command is JSON object
|
||||||
|
if (jsonCmdObj[F("psave")].isNull())
|
||||||
|
deserializeState(jsonCmdObj, CALL_MODE_BUTTON_PRESET);
|
||||||
|
else {
|
||||||
|
uint8_t psave = jsonCmdObj[F("psave")].as<int>();
|
||||||
|
char pname[33];
|
||||||
|
sprintf_P(pname, PSTR("IR Preset %d"), psave);
|
||||||
|
fdo.clear();
|
||||||
|
if (psave > 0 && psave < 251) savePreset(psave, pname, fdo);
|
||||||
|
}
|
||||||
|
parsed = true;
|
||||||
|
}
|
||||||
|
releaseJSONBufferLock();
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const char RF433Usermod::_modName[] PROGMEM = "RF433 Remote";
|
||||||
|
const char RF433Usermod::_modEnabled[] PROGMEM = "Enabled";
|
||||||
|
const char RF433Usermod::_receivePin[] PROGMEM = "RX Pin";
|
||||||
|
|
@ -204,6 +204,7 @@
|
|||||||
#define USERMOD_ID_POV_DISPLAY 53 //Usermod "usermod_pov_display.h"
|
#define USERMOD_ID_POV_DISPLAY 53 //Usermod "usermod_pov_display.h"
|
||||||
#define USERMOD_ID_PIXELS_DICE_TRAY 54 //Usermod "pixels_dice_tray.h"
|
#define USERMOD_ID_PIXELS_DICE_TRAY 54 //Usermod "pixels_dice_tray.h"
|
||||||
#define USERMOD_ID_DEEP_SLEEP 55 //Usermod "usermod_deep_sleep.h"
|
#define USERMOD_ID_DEEP_SLEEP 55 //Usermod "usermod_deep_sleep.h"
|
||||||
|
#define USERMOD_ID_RF433 56 //Usermod "usermod_v2_RF433.h"
|
||||||
|
|
||||||
//Access point behavior
|
//Access point behavior
|
||||||
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
||||||
|
@ -242,11 +242,14 @@
|
|||||||
#include "../usermods/LD2410_v2/usermod_ld2410.h"
|
#include "../usermods/LD2410_v2/usermod_ld2410.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef USERMOD_DEEP_SLEEP
|
#ifdef USERMOD_DEEP_SLEEP
|
||||||
#include "../usermods/deep_sleep/usermod_deep_sleep.h"
|
#include "../usermods/deep_sleep/usermod_deep_sleep.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USERMOD_RF433
|
||||||
|
#include "../usermods/usermod_v2_RF433/usermod_v2_RF433.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void registerUsermods()
|
void registerUsermods()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -479,4 +482,8 @@ void registerUsermods()
|
|||||||
#ifdef USERMOD_DEEP_SLEEP
|
#ifdef USERMOD_DEEP_SLEEP
|
||||||
UsermodManager::add(new DeepSleepUsermod());
|
UsermodManager::add(new DeepSleepUsermod());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USERMOD_RF433
|
||||||
|
UsermodManager::add(new RF433Usermod());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user