Add JSON override for ESP-NOW remote.
This commit is contained in:
parent
25831bfb60
commit
3255382132
@ -348,6 +348,7 @@
|
|||||||
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached
|
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached
|
||||||
#define ERR_FS_PLOAD 12 // It was attempted to load a preset that does not exist
|
#define ERR_FS_PLOAD 12 // It was attempted to load a preset that does not exist
|
||||||
#define ERR_FS_IRLOAD 13 // It was attempted to load an IR JSON cmd, but the "ir.json" file does not exist
|
#define ERR_FS_IRLOAD 13 // It was attempted to load an IR JSON cmd, but the "ir.json" file does not exist
|
||||||
|
#define ERR_FS_RMLOAD 14 // It was attempted to load an remote JSON cmd, but the "remote.json" file does not exist
|
||||||
#define ERR_FS_GENERAL 19 // A general unspecified filesystem error occured
|
#define ERR_FS_GENERAL 19 // A general unspecified filesystem error occured
|
||||||
#define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented)
|
#define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented)
|
||||||
#define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented)
|
#define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented)
|
||||||
|
@ -18,17 +18,17 @@
|
|||||||
// product spec. That remote is used as the baseline for behavior and availability
|
// product spec. That remote is used as the baseline for behavior and availability
|
||||||
// since it's broadly commercially available and works out of the box as a drop-in
|
// since it's broadly commercially available and works out of the box as a drop-in
|
||||||
typedef struct WizMoteMessageStructure {
|
typedef struct WizMoteMessageStructure {
|
||||||
uint8_t program; // 0x91 for ON button, 0x81 for all others
|
uint8_t program; // 0x91 for ON button, 0x81 for all others
|
||||||
uint8_t seq[4]; // Incremetal sequence number 32 bit unsigned integer LSB first
|
uint8_t seq[4]; // Incremetal sequence number 32 bit unsigned integer LSB first
|
||||||
uint8_t byte5 = 32; // Unknown
|
uint8_t byte5; // Unknown (seen 0x20)
|
||||||
uint8_t button; // Identifies which button is being pressed
|
uint8_t button; // Identifies which button is being pressed
|
||||||
uint8_t byte8 = 1; // Unknown, but always 0x01
|
uint8_t byte8; // Unknown, but always 0x01
|
||||||
uint8_t byte9 = 100; // Unnkown, but always 0x64
|
uint8_t byte9; // Unnkown, but always 0x64
|
||||||
|
|
||||||
uint8_t byte10; // Unknown, maybe checksum
|
uint8_t byte10; // Unknown, maybe checksum
|
||||||
uint8_t byte11; // Unknown, maybe checksum
|
uint8_t byte11; // Unknown, maybe checksum
|
||||||
uint8_t byte12; // Unknown, maybe checksum
|
uint8_t byte12; // Unknown, maybe checksum
|
||||||
uint8_t byte13; // Unknown, maybe checksum
|
uint8_t byte13; // Unknown, maybe checksum
|
||||||
} message_structure_t;
|
} message_structure_t;
|
||||||
|
|
||||||
static uint32_t last_seq = UINT32_MAX;
|
static uint32_t last_seq = UINT32_MAX;
|
||||||
@ -38,29 +38,30 @@ static int brightnessBeforeNightMode = NIGHT_MODE_DEACTIVATED;
|
|||||||
static const byte brightnessSteps[] = {
|
static const byte brightnessSteps[] = {
|
||||||
6, 9, 14, 22, 33, 50, 75, 113, 170, 255
|
6, 9, 14, 22, 33, 50, 75, 113, 170, 255
|
||||||
};
|
};
|
||||||
static const size_t numBrightnessSteps = sizeof(brightnessSteps) / sizeof(uint8_t);
|
static const size_t numBrightnessSteps = sizeof(brightnessSteps) / sizeof(byte);
|
||||||
|
|
||||||
static bool nightModeActive() {
|
inline bool nightModeActive() {
|
||||||
return brightnessBeforeNightMode != NIGHT_MODE_DEACTIVATED;
|
return brightnessBeforeNightMode != NIGHT_MODE_DEACTIVATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activateNightMode() {
|
static void activateNightMode() {
|
||||||
|
if (nightModeActive()) return;
|
||||||
brightnessBeforeNightMode = bri;
|
brightnessBeforeNightMode = bri;
|
||||||
bri = NIGHT_MODE_BRIGHTNESS;
|
bri = NIGHT_MODE_BRIGHTNESS;
|
||||||
|
stateUpdated(CALL_MODE_BUTTON);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool resetNightMode() {
|
static bool resetNightMode() {
|
||||||
if (!nightModeActive()) {
|
if (!nightModeActive()) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bri = brightnessBeforeNightMode;
|
bri = brightnessBeforeNightMode;
|
||||||
brightnessBeforeNightMode = NIGHT_MODE_DEACTIVATED;
|
brightnessBeforeNightMode = NIGHT_MODE_DEACTIVATED;
|
||||||
|
stateUpdated(CALL_MODE_BUTTON);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment `bri` to the next `brightnessSteps` value
|
// increment `bri` to the next `brightnessSteps` value
|
||||||
static void brightnessUp() {
|
static void brightnessUp() {
|
||||||
if (nightModeActive()) { return; }
|
if (nightModeActive()) return;
|
||||||
// dumb incremental search is efficient enough for so few items
|
// dumb incremental search is efficient enough for so few items
|
||||||
for (uint8_t index = 0; index < numBrightnessSteps; ++index) {
|
for (uint8_t index = 0; index < numBrightnessSteps; ++index) {
|
||||||
if (brightnessSteps[index] > bri) {
|
if (brightnessSteps[index] > bri) {
|
||||||
@ -68,11 +69,12 @@ static void brightnessUp() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stateUpdated(CALL_MODE_BUTTON);
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrement `bri` to the next `brightnessSteps` value
|
// decrement `bri` to the next `brightnessSteps` value
|
||||||
static void brightnessDown() {
|
static void brightnessDown() {
|
||||||
if (nightModeActive()) { return; }
|
if (nightModeActive()) return;
|
||||||
// dumb incremental search is efficient enough for so few items
|
// dumb incremental search is efficient enough for so few items
|
||||||
for (int index = numBrightnessSteps - 1; index >= 0; --index) {
|
for (int index = numBrightnessSteps - 1; index >= 0; --index) {
|
||||||
if (brightnessSteps[index] < bri) {
|
if (brightnessSteps[index] < bri) {
|
||||||
@ -80,30 +82,94 @@ static void brightnessDown() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stateUpdated(CALL_MODE_BUTTON);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setOn() {
|
static void setOn() {
|
||||||
if (resetNightMode()) {
|
resetNightMode();
|
||||||
stateUpdated(CALL_MODE_BUTTON);
|
|
||||||
}
|
|
||||||
if (!bri) {
|
if (!bri) {
|
||||||
toggleOnOff();
|
toggleOnOff();
|
||||||
|
stateUpdated(CALL_MODE_BUTTON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setOff() {
|
static void setOff() {
|
||||||
if (resetNightMode()) {
|
resetNightMode();
|
||||||
stateUpdated(CALL_MODE_BUTTON);
|
|
||||||
}
|
|
||||||
if (bri) {
|
if (bri) {
|
||||||
toggleOnOff();
|
toggleOnOff();
|
||||||
|
stateUpdated(CALL_MODE_BUTTON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void presetWithFallback(uint8_t presetID, uint8_t effectID, uint8_t paletteID) {
|
inline void presetWithFallback(uint8_t presetID, uint8_t effectID, uint8_t paletteID) {
|
||||||
|
resetNightMode();
|
||||||
applyPresetWithFallback(presetID, CALL_MODE_BUTTON_PRESET, effectID, paletteID);
|
applyPresetWithFallback(presetID, CALL_MODE_BUTTON_PRESET, effectID, paletteID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this function follows the same principle as decodeIRJson()
|
||||||
|
static bool remoteJson(int button)
|
||||||
|
{
|
||||||
|
char objKey[10];
|
||||||
|
bool parsed = false;
|
||||||
|
|
||||||
|
if (!requestJSONBufferLock(22)) return false;
|
||||||
|
|
||||||
|
sprintf_P(objKey, PSTR("\"%d\":"), button);
|
||||||
|
|
||||||
|
// attempt to read command from remote.json
|
||||||
|
readObjectFromFile("/remote.json", objKey, &doc);
|
||||||
|
JsonObject fdo = doc.as<JsonObject>();
|
||||||
|
if (fdo.isNull()) {
|
||||||
|
// the received button does not exist
|
||||||
|
if (!WLED_FS.exists("/remote.json")) errorFlag = ERR_FS_RMLOAD; //warn if file itself doesn't 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>()
|
||||||
|
{
|
||||||
|
if (cmdStr.startsWith("!")) {
|
||||||
|
// call limited set of C functions
|
||||||
|
if (cmdStr.startsWith(F("!incBri"))) {
|
||||||
|
brightnessUp();
|
||||||
|
parsed = true;
|
||||||
|
} else if (cmdStr.startsWith(F("!decBri"))) {
|
||||||
|
brightnessDown();
|
||||||
|
parsed = true;
|
||||||
|
} else if (cmdStr.startsWith(F("!presetF"))) { //!presetFallback
|
||||||
|
uint8_t p1 = fdo["PL"] | 1;
|
||||||
|
uint8_t p2 = fdo["FX"] | random8(strip.getModeCount() -1);
|
||||||
|
uint8_t p3 = fdo["FP"] | 0;
|
||||||
|
presetWithFallback(p1, p2, p3);
|
||||||
|
parsed = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// HTTP API command
|
||||||
|
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
||||||
|
//if (cmdStr.indexOf("~") || fdo["rpt"]) lastValidCode = code; // repeatable action
|
||||||
|
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 (TODO: currently will not handle irApplyToAllSelected correctly)
|
||||||
|
deserializeState(jsonCmdObj, CALL_MODE_BUTTON);
|
||||||
|
parsed = true;
|
||||||
|
}
|
||||||
|
releaseJSONBufferLock();
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
// Callback function that will be executed when data is received
|
// Callback function that will be executed when data is received
|
||||||
void handleRemote(uint8_t *incomingData, size_t len) {
|
void handleRemote(uint8_t *incomingData, size_t len) {
|
||||||
message_structure_t *incoming = reinterpret_cast<message_structure_t *>(incomingData);
|
message_structure_t *incoming = reinterpret_cast<message_structure_t *>(incomingData);
|
||||||
@ -125,24 +191,26 @@ void handleRemote(uint8_t *incomingData, size_t len) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_PRINT(F("Incoming ESP Now Packet["));
|
DEBUG_PRINT(F("Incoming ESP Now Packet ["));
|
||||||
DEBUG_PRINT(cur_seq);
|
DEBUG_PRINT(cur_seq);
|
||||||
DEBUG_PRINT(F("] from sender["));
|
DEBUG_PRINT(F("] from sender ["));
|
||||||
DEBUG_PRINT(last_signal_src);
|
DEBUG_PRINT(last_signal_src);
|
||||||
DEBUG_PRINT(F("] button: "));
|
DEBUG_PRINT(F("] button: "));
|
||||||
DEBUG_PRINTLN(incoming->button);
|
DEBUG_PRINTLN(incoming->button);
|
||||||
switch (incoming->button) {
|
|
||||||
case WIZMOTE_BUTTON_ON : setOn(); stateUpdated(CALL_MODE_BUTTON); break;
|
if (!remoteJson(incoming->button))
|
||||||
case WIZMOTE_BUTTON_OFF : setOff(); stateUpdated(CALL_MODE_BUTTON); break;
|
switch (incoming->button) {
|
||||||
case WIZMOTE_BUTTON_ONE : presetWithFallback(1, FX_MODE_STATIC, 0); resetNightMode(); break;
|
case WIZMOTE_BUTTON_ON : setOn(); break;
|
||||||
case WIZMOTE_BUTTON_TWO : presetWithFallback(2, FX_MODE_BREATH, 0); resetNightMode(); break;
|
case WIZMOTE_BUTTON_OFF : setOff(); break;
|
||||||
case WIZMOTE_BUTTON_THREE : presetWithFallback(3, FX_MODE_FIRE_FLICKER, 0); resetNightMode(); break;
|
case WIZMOTE_BUTTON_ONE : presetWithFallback(1, FX_MODE_STATIC, 0); break;
|
||||||
case WIZMOTE_BUTTON_FOUR : presetWithFallback(4, FX_MODE_RAINBOW, 0); resetNightMode(); break;
|
case WIZMOTE_BUTTON_TWO : presetWithFallback(2, FX_MODE_BREATH, 0); break;
|
||||||
case WIZMOTE_BUTTON_NIGHT : activateNightMode(); stateUpdated(CALL_MODE_BUTTON); break;
|
case WIZMOTE_BUTTON_THREE : presetWithFallback(3, FX_MODE_FIRE_FLICKER, 0); break;
|
||||||
case WIZMOTE_BUTTON_BRIGHT_UP : brightnessUp(); stateUpdated(CALL_MODE_BUTTON); break;
|
case WIZMOTE_BUTTON_FOUR : presetWithFallback(4, FX_MODE_RAINBOW, 0); break;
|
||||||
case WIZMOTE_BUTTON_BRIGHT_DOWN : brightnessDown(); stateUpdated(CALL_MODE_BUTTON); break;
|
case WIZMOTE_BUTTON_NIGHT : activateNightMode(); break;
|
||||||
default: break;
|
case WIZMOTE_BUTTON_BRIGHT_UP : brightnessUp(); break;
|
||||||
}
|
case WIZMOTE_BUTTON_BRIGHT_DOWN : brightnessDown(); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
last_seq = cur_seq;
|
last_seq = cur_seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user