Merge remote-tracking branch 'origin/ac_main' into mdev
This commit is contained in:
348
wled00/FX.cpp
348
wled00/FX.cpp
File diff suppressed because it is too large
Load Diff
@@ -104,7 +104,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
CJSON(strip.matrix.bottomStart, matrix[F("pb")]);
|
||||
CJSON(strip.matrix.rightStart, matrix[F("pr")]);
|
||||
CJSON(strip.matrix.vertical, matrix[F("pv")]);
|
||||
CJSON(strip.matrix.serpentine, matrix[F("ps")]);
|
||||
CJSON(strip.matrix.serpentine, matrix["ps"]);
|
||||
|
||||
JsonArray panels = matrix[F("panels")];
|
||||
uint8_t s = 0;
|
||||
@@ -192,6 +192,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
|
||||
// read multiple button configuration
|
||||
JsonObject btn_obj = hw["btn"];
|
||||
int pull = -1; // trick for inverted setting
|
||||
CJSON(pull, btn_obj[F("pull")]);
|
||||
if (pull>=0) disablePullUp = pull;
|
||||
JsonArray hw_btn_ins = btn_obj[F("ins")];
|
||||
if (!hw_btn_ins.isNull()) {
|
||||
uint8_t s = 0;
|
||||
@@ -200,11 +203,15 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
int8_t pin = btn["pin"][0] | -1;
|
||||
if (pin > -1 && pinManager.allocatePin(pin, false, PinOwner::Button)) {
|
||||
btnPin[s] = pin;
|
||||
#ifdef ESP32
|
||||
pinMode(btnPin[s], buttonType[s]==BTN_TYPE_PUSH_ACT_HIGH ? INPUT_PULLDOWN : INPUT_PULLUP);
|
||||
#else
|
||||
pinMode(btnPin[s], INPUT_PULLUP);
|
||||
#endif
|
||||
if (disablePullUp) {
|
||||
pinMode(btnPin[s], INPUT);
|
||||
} else {
|
||||
#ifdef ESP32
|
||||
pinMode(btnPin[s], buttonType[s]==BTN_TYPE_PUSH_ACT_HIGH ? INPUT_PULLDOWN : INPUT_PULLUP);
|
||||
#else
|
||||
pinMode(btnPin[s], INPUT_PULLUP);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
btnPin[s] = -1;
|
||||
}
|
||||
@@ -687,7 +694,7 @@ void serializeConfig() {
|
||||
matrix[F("pb")] = strip.matrix.bottomStart;
|
||||
matrix[F("pr")] = strip.matrix.rightStart;
|
||||
matrix[F("pv")] = strip.matrix.vertical;
|
||||
matrix[F("ps")] = strip.matrix.serpentine;
|
||||
matrix["ps"] = strip.matrix.serpentine;
|
||||
|
||||
JsonArray panels = matrix.createNestedArray(F("panels"));
|
||||
for (uint8_t i=0; i<strip.hPanels*strip.vPanels; i++) {
|
||||
@@ -735,6 +742,7 @@ void serializeConfig() {
|
||||
// button(s)
|
||||
JsonObject hw_btn = hw.createNestedObject("btn");
|
||||
hw_btn["max"] = WLED_MAX_BUTTONS; // just information about max number of buttons (not actually used)
|
||||
hw_btn[F("pull")] = !disablePullUp;
|
||||
JsonArray hw_btn_ins = hw_btn.createNestedArray("ins");
|
||||
|
||||
// configuration for all buttons
|
||||
|
||||
@@ -98,10 +98,11 @@
|
||||
#define USERMOD_ID_PING_PONG_CLOCK 34 //Usermod "usermod_v2_ping_pong_clock.h"
|
||||
#define USERMOD_ID_ADS1115 35 //Usermod "usermod_ads1115.h"
|
||||
#define USERMOD_ID_SD_CARD 37 //Usermod "usermod_sd_card.h"
|
||||
#define USERMOD_ID_PWM_OUTPUTS 38 //Usermod "usermod_pwm_outputs.h
|
||||
//WLEDMM
|
||||
#define USERMOD_ID_CUSTOMEFFECTS 38 //Usermod "usermod_v2_customeffects.h"
|
||||
#define USERMOD_ID_WEATHER 39 //Usermod "usermod_v2_weather.h"
|
||||
#define USERMOD_ID_GAMES 40 //Usermod "usermod_v2_games.h"
|
||||
#define USERMOD_ID_CUSTOMEFFECTS 39 //Usermod "usermod_v2_customeffects.h"
|
||||
#define USERMOD_ID_WEATHER 40 //Usermod "usermod_v2_weather.h"
|
||||
#define USERMOD_ID_GAMES 41 //Usermod "usermod_v2_games.h"
|
||||
|
||||
//Access point behavior
|
||||
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
||||
|
||||
@@ -17,6 +17,7 @@ var d = document;
|
||||
var palettesData;
|
||||
var fxdata = [];
|
||||
var pJson = {}, eJson = {}, lJson = {};
|
||||
var plJson = {}; // array of playlists
|
||||
var pN = "", pI = 0, pNum = 0;
|
||||
var pmt = 1, pmtLS = 0, pmtLast = 0;
|
||||
var lastinfo = {};
|
||||
@@ -522,7 +523,7 @@ function loadFXData(callback = null)
|
||||
fxdata = json||[];
|
||||
// add default value for Solid
|
||||
fxdata.shift()
|
||||
fxdata.unshift(";!;0");
|
||||
fxdata.unshift(";!;");
|
||||
})
|
||||
.catch((e)=>{
|
||||
fxdata = [];
|
||||
@@ -871,18 +872,19 @@ function populateEffects()
|
||||
let fd = "";
|
||||
if (ef.name.indexOf("RSVD") < 0) {
|
||||
if (Array.isArray(fxdata) && fxdata.length>id) {
|
||||
if (fxdata[id].length==0) fd = ";;!;1d"
|
||||
if (fxdata[id].length==0) fd = ";;!;1"
|
||||
else fd = fxdata[id];
|
||||
let eP = (fd == '')?[]:fd.split(";"); // effect parameters
|
||||
let p = (eP.length<3 || eP[2]==='')?[]:eP[2].split(","); // palette data
|
||||
if (p.length>0 && (p[0] !== "" && !isNumeric(p[0]))) nm += "🎨"; // effects using palette
|
||||
let m = (eP.length<4 || eP[3]==='')?[]:eP[3].split(","); // metadata
|
||||
if (m.length>0) for (let r of m) {
|
||||
if (r.substring(0,2)=="1d") nm += "⋮"; // 1D effects
|
||||
if (r.substring(0,4)=="1.5d") nm += "⋮⋮"; // 1D effects + vStrips
|
||||
if (r.substring(0,2)=="2d") nm += "▦"; // 2D effects
|
||||
if (r.substring(0,2)=="vo") nm += "♪"; // volume effects
|
||||
if (r.substring(0,2)=="fr") nm += "♫"; // frequency effects
|
||||
let m = (eP.length<4 || eP[3]==='')?'1':eP[3]; // flags
|
||||
if (id == 0) m = ''; // solid has no flags
|
||||
if (m.length>0) {
|
||||
if (m.includes('1')) nm += "⋮"; // 1D effects
|
||||
if (m.includes("1.5d")) nm += "⋮"; // WLEDMM: vStrips
|
||||
if (m.includes('2')) nm += "▦"; // 2D effects
|
||||
if (m.includes('v')) nm += "♪"; // volume effects
|
||||
if (m.includes('f')) nm += "♫"; // frequency effects
|
||||
}
|
||||
}
|
||||
html += generateListItemHtml('fx',id,nm,'setFX','',fd);
|
||||
@@ -1722,15 +1724,6 @@ function resetUtil()
|
||||
+ '<div class="segname" onclick="makeSeg()"><i class="icons btn-icon"></i>Add segment</div></div>';
|
||||
}
|
||||
|
||||
var plJson = {"0":{
|
||||
"ps": [0],
|
||||
"dur": [100],
|
||||
"transition": [-1], // to be inited to default transition dur
|
||||
"repeat": 0,
|
||||
"r": false,
|
||||
"end": 0
|
||||
}};
|
||||
|
||||
function makePlSel(el, incPl=false) {
|
||||
var plSelContent = "";
|
||||
delete pJson["0"]; // remove filler preset
|
||||
@@ -1811,6 +1804,14 @@ function plR(p) {
|
||||
function makeP(i,pl) {
|
||||
var content = "";
|
||||
if (pl) {
|
||||
if (i===0) plJson[0] = {
|
||||
ps: [1],
|
||||
dur: [100],
|
||||
transition: [tr],
|
||||
repeat: 0,
|
||||
r: false,
|
||||
end: 0
|
||||
};
|
||||
var rep = plJson[i].repeat ? plJson[i].repeat : 0;
|
||||
content =
|
||||
`<div id="ple${i}" style="margin-top:10px;"></div><label class="check revchkl">Shuffle
|
||||
@@ -1933,7 +1934,6 @@ function makePlUtil()
|
||||
if (pNum < 2) {
|
||||
showToast("You need at least 2 presets to make a playlist!"); //return;
|
||||
}
|
||||
if (plJson[0].transition[0] < 0) plJson[0].transition[0] = tr;
|
||||
let p = gId('putil');
|
||||
p.classList.remove('staybot');
|
||||
p.classList.add('pres');
|
||||
|
||||
@@ -619,6 +619,7 @@ Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65
|
||||
</div>
|
||||
<hr class="sml">
|
||||
<div id="btns"></div>
|
||||
Disable internal pull-up/down: <input type="checkbox" name="IP"><br>
|
||||
Touch threshold: <input type="number" class="s" min="0" max="100" name="TT" required><br>
|
||||
<div id="irOnOff2">
|
||||
<em style="color:darkorange">This firmware build does not include IR Remote support. <br></em>
|
||||
|
||||
@@ -184,18 +184,13 @@
|
||||
}
|
||||
}
|
||||
// https://stackoverflow.com/questions/26440494/insert-text-after-this-input-element-with-javascript
|
||||
//WLEDMM Add pre and post texts
|
||||
function addInfo(name,el,txt, txt2="") {
|
||||
let obj = d.getElementsByName(name);
|
||||
if (!obj.length) return;
|
||||
if (typeof el === "string" && obj[0]) obj[0].placeholder = el;
|
||||
else if (obj[el]) {
|
||||
if (txt2!="") {
|
||||
obj[el].insertAdjacentHTML('beforebegin', txt + ' ');
|
||||
obj[el].insertAdjacentHTML('afterend', ' '+txt2);
|
||||
}
|
||||
else
|
||||
obj[el].insertAdjacentHTML('afterend', ' '+txt);
|
||||
if (txt!="") obj[el].insertAdjacentHTML('afterend', ' '+txt);
|
||||
if (txt2!="") obj[el].insertAdjacentHTML('beforebegin', txt2 + ' '); //add pre texts
|
||||
}
|
||||
}
|
||||
// load settings and insert values into DOM
|
||||
|
||||
1534
wled00/html_other.h
1534
wled00/html_other.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2278
wled00/html_simple.h
2278
wled00/html_simple.h
File diff suppressed because it is too large
Load Diff
3992
wled00/html_ui.h
3992
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@@ -456,6 +456,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
// if preset contains HTTP API call do not change presetCycCurr
|
||||
if (root["win"].isNull()) presetCycCurr = currentPreset;
|
||||
stateChanged = false; // cancel state change update (preset was set directly by applying values stored in UI JSON array)
|
||||
notify(callMode);
|
||||
} else if (root["win"].isNull() && getVal(root["ps"], &ps, 0, 0) && ps > 0 && ps < 251 && ps != currentPreset) {
|
||||
// b) preset ID only or preset that does not change state (use embedded cycling limits if they exist in getVal())
|
||||
presetCycCurr = ps;
|
||||
@@ -463,7 +464,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
root.remove("v"); // may be added in UI call
|
||||
root.remove("time"); // may be added in UI call
|
||||
root.remove("ps");
|
||||
root.remove("on"); // some exetrnal calls add "on" to "ps" call
|
||||
root.remove("on"); // some external calls add "on" to "ps" call
|
||||
if (root.size() == 0) {
|
||||
unloadPlaylist(); // we need to unload playlist
|
||||
applyPreset(ps, callMode); // async load (only preset ID was specified)
|
||||
|
||||
@@ -195,14 +195,14 @@ void handleTransitions()
|
||||
}
|
||||
if (tper - tperLast < 0.004) return;
|
||||
tperLast = tper;
|
||||
briT = briOld +((bri - briOld )*tper);
|
||||
briT = briOld + ((bri - briOld) * tper);
|
||||
|
||||
applyBri();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//legacy method, applies values from col, effectCurrent, ... to selected segments
|
||||
// legacy method, applies values from col, effectCurrent, ... to selected segments
|
||||
void colorUpdated(byte callMode){
|
||||
applyValuesToSelectedSegs();
|
||||
stateUpdated(callMode);
|
||||
@@ -213,8 +213,8 @@ void handleNightlight()
|
||||
{
|
||||
static unsigned long lastNlUpdate;
|
||||
unsigned long now = millis();
|
||||
if (now < 100 && lastNlUpdate > 0) lastNlUpdate = 0; //take care of millis() rollover
|
||||
if (now - lastNlUpdate < 100) return; //allow only 10 NL updates per second
|
||||
if (now < 100 && lastNlUpdate > 0) lastNlUpdate = 0; // take care of millis() rollover
|
||||
if (now - lastNlUpdate < 100) return; // allow only 10 NL updates per second
|
||||
lastNlUpdate = now;
|
||||
|
||||
if (nightlightActive)
|
||||
|
||||
@@ -307,7 +307,7 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
|
||||
#ifdef WLED_DEBUG
|
||||
DEBUG_PRINT(F("PIN ALLOC: Invalid pin attempted to be allocated: GPIO "));
|
||||
DEBUG_PRINT(gpio);
|
||||
DEBUG_PRINT(" as "); DEBUG_PRINT(mptArray[i].isOutput ? "output": "input"); // WLEDMM
|
||||
DEBUG_PRINT(" as "); DEBUG_PRINT(mptArray[i].isOutput ? "output": "input");
|
||||
DEBUG_PRINTLN(F(""));
|
||||
#else // WLEDMM
|
||||
USER_PRINTF("PIN ALLOC: invalid pin - cannot use GPIO%d for %s.\n", gpio, mptArray[i].isOutput ? "output": "input");
|
||||
@@ -350,7 +350,7 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
|
||||
continue;
|
||||
}
|
||||
if (gpio >= WLED_NUM_PINS)
|
||||
continue; // WLEDMM - invalid GPIO => avoid array bounds violation
|
||||
continue; // other unexpected GPIO => avoid array bounds violation
|
||||
|
||||
byte by = gpio >> 3;
|
||||
byte bi = gpio - 8*by;
|
||||
@@ -371,7 +371,7 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
|
||||
bool PinManagerClass::allocatePin(byte gpio, bool output, PinOwner tag)
|
||||
{
|
||||
// HW I2C & SPI pins have to be allocated using allocateMultiplePins variant since there is always SCL/SDA pair
|
||||
if (!isPinOk(gpio, output) || (gpio >= WLED_NUM_PINS) || tag==PinOwner::HW_I2C || tag==PinOwner::HW_SPI) { // WLEDMM bugfix - avoid array bounds violation
|
||||
if (!isPinOk(gpio, output) || (gpio >= WLED_NUM_PINS) || tag==PinOwner::HW_I2C || tag==PinOwner::HW_SPI) {
|
||||
#ifdef WLED_DEBUG
|
||||
if (gpio < 255) { // 255 (-1) is the "not defined GPIO"
|
||||
if (!isPinOk(gpio, output)) {
|
||||
@@ -495,6 +495,7 @@ bool PinManagerClass::isPinOk(byte gpio, bool output)
|
||||
}
|
||||
|
||||
PinOwner PinManagerClass::getPinOwner(byte gpio) {
|
||||
if (gpio >= WLED_NUM_PINS) return PinOwner::None; // catch error case, to avoid array out-of-bounds access
|
||||
if (!isPinOk(gpio, false)) return PinOwner::None;
|
||||
if (gpio >= WLED_NUM_PINS) return PinOwner::None; // WLEDMM: catch error cases
|
||||
return ownerTag[gpio];
|
||||
|
||||
@@ -58,7 +58,8 @@ enum struct PinOwner : uint8_t {
|
||||
UM_BME280 = USERMOD_ID_BME280, // 0x18 // Usermod "usermod_bme280.h -- Uses "standard" HW_I2C pins
|
||||
UM_BH1750 = USERMOD_ID_BH1750, // 0x19 // Usermod "usermod_bme280.h -- Uses "standard" HW_I2C pins
|
||||
UM_Audioreactive = USERMOD_ID_AUDIOREACTIVE, // 0x1E // Usermod "audio_reactive.h"
|
||||
UM_SdCard = USERMOD_ID_SD_CARD // 0x24 // Usermod "usermod_sd_card.h"
|
||||
UM_SdCard = USERMOD_ID_SD_CARD, // 0x24 // Usermod "usermod_sd_card.h"
|
||||
UM_PWM_OUTPUTS = USERMOD_ID_PWM_OUTPUTS // 0x21 // Usermod "usermod_pwm_outputs.h"
|
||||
};
|
||||
static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected");
|
||||
|
||||
|
||||
@@ -245,7 +245,8 @@ void handlePresets()
|
||||
#endif
|
||||
|
||||
releaseJSONBufferLock(); // will also clear fileDoc
|
||||
colorUpdated(tmpMode);
|
||||
if (changePreset) notify(tmpMode); // force UDP notification
|
||||
stateUpdated(tmpMode); // was colorUpdated() if anything breaks
|
||||
updateInterfaces(tmpMode);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
}
|
||||
rlyMde = (bool)request->hasArg(F("RM"));
|
||||
|
||||
disablePullUp = (bool)request->hasArg(F("IP"));
|
||||
for (uint8_t i=0; i<WLED_MAX_BUTTONS; i++) {
|
||||
char bt[4] = "BT"; bt[2] = (i<10?48:55)+i; bt[3] = 0; // button pin (use A,B,C,... if WLED_MAX_BUTTONS>10)
|
||||
char be[4] = "BE"; be[2] = (i<10?48:55)+i; be[3] = 0; // button type (use A,B,C,... if WLED_MAX_BUTTONS>10)
|
||||
|
||||
@@ -172,6 +172,11 @@
|
||||
#include "../usermods/sd_card/usermod_sd_card.h"
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_PWM_OUTPUTS
|
||||
#include "../usermods/pwm_outputs/usermod_pwm_outputs.h"
|
||||
#endif
|
||||
|
||||
|
||||
//WLEDMM Custom Effects
|
||||
#ifdef USERMOD_CUSTOMEFFECTS
|
||||
#include "../usermods/customeffects/usermod_v2_customeffects.h"
|
||||
@@ -339,6 +344,10 @@ void registerUsermods()
|
||||
#ifdef SD_ADAPTER
|
||||
usermods.add(new UsermodSdCard());
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_PWM_OUTPUTS
|
||||
usermods.add(new PwmOutputsUsermod());
|
||||
#endif
|
||||
|
||||
//WLEDMM Custom Effects
|
||||
#ifdef USERMOD_CUSTOMEFFECTS
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2212051
|
||||
#define VERSION 2212060
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@@ -517,6 +517,7 @@ WLED_GLOBAL bool buttonPressedBefore[WLED_MAX_BUTTONS] _INIT({false});
|
||||
WLED_GLOBAL bool buttonLongPressed[WLED_MAX_BUTTONS] _INIT({false});
|
||||
WLED_GLOBAL unsigned long buttonPressedTime[WLED_MAX_BUTTONS] _INIT({0});
|
||||
WLED_GLOBAL unsigned long buttonWaitTime[WLED_MAX_BUTTONS] _INIT({0});
|
||||
WLED_GLOBAL bool disablePullUp _INIT(false);
|
||||
WLED_GLOBAL byte touchThreshold _INIT(TOUCH_THRESHOLD);
|
||||
|
||||
// notifications
|
||||
|
||||
@@ -22,15 +22,15 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||
if (client->id() == wsLiveClientId) wsLiveClientId = 0;
|
||||
DEBUG_PRINTLN(F("WS client disconnected."));
|
||||
} else if(type == WS_EVT_DATA){
|
||||
//data packet
|
||||
// data packet
|
||||
AwsFrameInfo * info = (AwsFrameInfo*)arg;
|
||||
if(info->final && info->index == 0 && info->len == len){
|
||||
//the whole message is in a single frame and we got all of its data (max. 1450byte)
|
||||
// the whole message is in a single frame and we got all of its data (max. 1450 bytes)
|
||||
if(info->opcode == WS_TEXT)
|
||||
{
|
||||
if (len > 0 && len < 10 && data[0] == 'p') {
|
||||
//application layer ping/pong heartbeat.
|
||||
//client-side socket layer ping packets are unresponded (investigate)
|
||||
// application layer ping/pong heartbeat.
|
||||
// client-side socket layer ping packets are unresponded (investigate)
|
||||
client->text(F("pong"));
|
||||
return;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||
}
|
||||
releaseJSONBufferLock(); // will clean fileDoc
|
||||
|
||||
// force broadcast in 500ms after upadting client
|
||||
// force broadcast in 500ms after updating client
|
||||
if (verboseResponse) {
|
||||
sendDataWs(client);
|
||||
lastInterfaceUpdate = millis() - (INTERFACE_UPDATE_COOLDOWN -500);
|
||||
|
||||
@@ -458,6 +458,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
oappend(itoa(buttonType[i],nS,10));
|
||||
oappend(SET_F(");"));
|
||||
}
|
||||
sappend('c',SET_F("IP"),disablePullUp);
|
||||
sappend('v',SET_F("TT"),touchThreshold);
|
||||
sappend('v',SET_F("IR"),irPin);
|
||||
sappend('v',SET_F("IT"),irEnabled);
|
||||
|
||||
Reference in New Issue
Block a user