mirror of
https://github.com/wled/WLED.git
synced 2025-07-25 11:46:34 +00:00
Merge pull request #4595 from wled/cherry-pick-mulifix
Cherry pick mulifix
This commit is contained in:
commit
ecfe6e625d
@ -95,9 +95,9 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
fastled_col.red = col[0];
|
||||
fastled_col.green = col[1];
|
||||
fastled_col.blue = col[2];
|
||||
fastled_col.red = colPri[0];
|
||||
fastled_col.green = colPri[1];
|
||||
fastled_col.blue = colPri[2];
|
||||
prim_hsv = rgb2hsv_approximate(fastled_col);
|
||||
new_val = (int16_t)prim_hsv.h + fadeAmount;
|
||||
if (new_val > 255)
|
||||
@ -106,9 +106,9 @@ public:
|
||||
new_val += 255; // roll-over if smaller than 0
|
||||
prim_hsv.h = (byte)new_val;
|
||||
hsv2rgb_rainbow(prim_hsv, fastled_col);
|
||||
col[0] = fastled_col.red;
|
||||
col[1] = fastled_col.green;
|
||||
col[2] = fastled_col.blue;
|
||||
colPri[0] = fastled_col.red;
|
||||
colPri[1] = fastled_col.green;
|
||||
colPri[2] = fastled_col.blue;
|
||||
}
|
||||
}
|
||||
else if (Enc_B == LOW)
|
||||
@ -120,9 +120,9 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
fastled_col.red = col[0];
|
||||
fastled_col.green = col[1];
|
||||
fastled_col.blue = col[2];
|
||||
fastled_col.red = colPri[0];
|
||||
fastled_col.green = colPri[1];
|
||||
fastled_col.blue = colPri[2];
|
||||
prim_hsv = rgb2hsv_approximate(fastled_col);
|
||||
new_val = (int16_t)prim_hsv.h - fadeAmount;
|
||||
if (new_val > 255)
|
||||
@ -131,9 +131,9 @@ public:
|
||||
new_val += 255; // roll-over if smaller than 0
|
||||
prim_hsv.h = (byte)new_val;
|
||||
hsv2rgb_rainbow(prim_hsv, fastled_col);
|
||||
col[0] = fastled_col.red;
|
||||
col[1] = fastled_col.green;
|
||||
col[2] = fastled_col.blue;
|
||||
colPri[0] = fastled_col.red;
|
||||
colPri[1] = fastled_col.green;
|
||||
colPri[2] = fastled_col.blue;
|
||||
}
|
||||
}
|
||||
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
|
||||
|
@ -518,7 +518,7 @@ void RotaryEncoderUIUsermod::setup()
|
||||
|
||||
loopTime = millis();
|
||||
|
||||
currentCCT = (approximateKelvinFromRGB(RGBW32(col[0], col[1], col[2], col[3])) - 1900) >> 5;
|
||||
currentCCT = (approximateKelvinFromRGB(RGBW32(colPri[0], colPri[1], colPri[2], colPri[3])) - 1900) >> 5;
|
||||
|
||||
if (!initDone) sortModesAndPalettes();
|
||||
|
||||
@ -920,17 +920,17 @@ void RotaryEncoderUIUsermod::changeHue(bool increase){
|
||||
display->updateRedrawTime();
|
||||
#endif
|
||||
currentHue1 = max(min((increase ? currentHue1+fadeAmount : currentHue1-fadeAmount), 255), 0);
|
||||
colorHStoRGB(currentHue1*256, currentSat1, col);
|
||||
colorHStoRGB(currentHue1*256, currentSat1, colPri);
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (unsigned i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
seg.colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
|
||||
seg.colors[0] = RGBW32(colPri[0], colPri[1], colPri[2], colPri[3]);
|
||||
}
|
||||
} else {
|
||||
Segment& seg = strip.getSegment(strip.getMainSegmentId());
|
||||
seg.colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
|
||||
seg.colors[0] = RGBW32(colPri[0], colPri[1], colPri[2], colPri[3]);
|
||||
}
|
||||
lampUdated();
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
@ -950,16 +950,16 @@ void RotaryEncoderUIUsermod::changeSat(bool increase){
|
||||
display->updateRedrawTime();
|
||||
#endif
|
||||
currentSat1 = max(min((increase ? currentSat1+fadeAmount : currentSat1-fadeAmount), 255), 0);
|
||||
colorHStoRGB(currentHue1*256, currentSat1, col);
|
||||
colorHStoRGB(currentHue1*256, currentSat1, colPri);
|
||||
if (applyToAll) {
|
||||
for (unsigned i=0; i<strip.getSegmentsNum(); i++) {
|
||||
Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive()) continue;
|
||||
seg.colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
|
||||
seg.colors[0] = RGBW32(colPri[0], colPri[1], colPri[2], colPri[3]);
|
||||
}
|
||||
} else {
|
||||
Segment& seg = strip.getSegment(strip.getMainSegmentId());
|
||||
seg.colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
|
||||
seg.colors[0] = RGBW32(colPri[0], colPri[1], colPri[2], colPri[3]);
|
||||
}
|
||||
lampUdated();
|
||||
#ifdef USERMOD_FOUR_LINE_DISPLAY
|
||||
|
@ -543,7 +543,7 @@ typedef struct Segment {
|
||||
static void handleRandomPalette();
|
||||
inline static const CRGBPalette16 &getCurrentPalette() { return Segment::_currentPalette; }
|
||||
|
||||
void setGeometry(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
|
||||
void setGeometry(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1, uint8_t m12 = 0);
|
||||
Segment &setColor(uint8_t slot, uint32_t c);
|
||||
Segment &setCCT(uint16_t k);
|
||||
Segment &setOpacity(uint8_t o);
|
||||
|
@ -458,19 +458,24 @@ void Segment::handleRandomPalette() {
|
||||
}
|
||||
|
||||
// segId is given when called from network callback, changes are queued if that segment is currently in its effect function
|
||||
void Segment::setGeometry(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) {
|
||||
void Segment::setGeometry(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y, uint8_t m12) {
|
||||
// return if neither bounds nor grouping have changed
|
||||
bool boundsUnchanged = (start == i1 && stop == i2);
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (Segment::maxHeight>1) boundsUnchanged &= (startY == i1Y && stopY == i2Y); // 2D
|
||||
#endif
|
||||
|
||||
m12 = constrain(m12, 0, 7);
|
||||
if (stop && (spc > 0 || m12 != map1D2D)) fill(BLACK);
|
||||
if (m12 != map1D2D) map1D2D = m12;
|
||||
/*
|
||||
if (boundsUnchanged
|
||||
&& (!grp || (grouping == grp && spacing == spc))
|
||||
&& (ofs == UINT16_MAX || ofs == offset)) return;
|
||||
|
||||
&& (m12 == map1D2D)
|
||||
) return;
|
||||
*/
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
|
||||
if (stop) fill(BLACK); // turn old segment range off (clears pixels if changing spacing)
|
||||
if (grp) { // prevent assignment of 0
|
||||
grouping = grp;
|
||||
spacing = spc;
|
||||
@ -480,10 +485,7 @@ void Segment::setGeometry(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, ui
|
||||
}
|
||||
if (ofs < UINT16_MAX) offset = ofs;
|
||||
|
||||
DEBUG_PRINT(F("setUp segment: ")); DEBUG_PRINT(i1);
|
||||
DEBUG_PRINT(','); DEBUG_PRINT(i2);
|
||||
DEBUG_PRINT(F(" -> ")); DEBUG_PRINT(i1Y);
|
||||
DEBUG_PRINT(','); DEBUG_PRINTLN(i2Y);
|
||||
DEBUG_PRINTF_P(PSTR("Segment geometry: %d,%d -> %d,%d\n"), (int)i1, (int)i2, (int)i1Y, (int)i2Y);
|
||||
markForReset();
|
||||
if (boundsUnchanged) return;
|
||||
|
||||
@ -1063,36 +1065,25 @@ void Segment::fade_out(uint8_t rate) {
|
||||
const int cols = is2D() ? virtualWidth() : virtualLength();
|
||||
const int rows = virtualHeight(); // will be 1 for 1D
|
||||
|
||||
rate = (255-rate) >> 1;
|
||||
float mappedRate = 1.0f / (float(rate) + 1.1f);
|
||||
|
||||
uint32_t color = colors[1]; // SEGCOLOR(1); // target color
|
||||
int w2 = W(color);
|
||||
int r2 = R(color);
|
||||
int g2 = G(color);
|
||||
int b2 = B(color);
|
||||
rate = (256-rate) >> 1;
|
||||
const int mappedRate = 256 / (rate + 1);
|
||||
|
||||
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
||||
color = is2D() ? getPixelColorXY(x, y) : getPixelColor(x);
|
||||
uint32_t color = is2D() ? getPixelColorXY(x, y) : getPixelColor(x);
|
||||
if (color == colors[1]) continue; // already at target color
|
||||
int w1 = W(color);
|
||||
int r1 = R(color);
|
||||
int g1 = G(color);
|
||||
int b1 = B(color);
|
||||
|
||||
int wdelta = (w2 - w1) * mappedRate;
|
||||
int rdelta = (r2 - r1) * mappedRate;
|
||||
int gdelta = (g2 - g1) * mappedRate;
|
||||
int bdelta = (b2 - b1) * mappedRate;
|
||||
|
||||
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
|
||||
wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1;
|
||||
rdelta += (r2 == r1) ? 0 : (r2 > r1) ? 1 : -1;
|
||||
gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1;
|
||||
bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1;
|
||||
|
||||
if (is2D()) setPixelColorXY(x, y, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
|
||||
else setPixelColor(x, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
|
||||
for (int i = 0; i < 32; i += 8) {
|
||||
uint8_t c2 = (colors[1]>>i); // get background channel
|
||||
uint8_t c1 = (color>>i); // get foreground channel
|
||||
// we can't use bitshift since we are using int
|
||||
int delta = (c2 - c1) * mappedRate / 256;
|
||||
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
|
||||
if (delta == 0) delta += (c2 == c1) ? 0 : (c2 > c1) ? 1 : -1;
|
||||
// stuff new value back into color
|
||||
color &= ~(0xFF<<i);
|
||||
color |= ((c1 + delta) & 0xFF) << i;
|
||||
}
|
||||
if (is2D()) setPixelColorXY(x, y, color);
|
||||
else setPixelColor(x, color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1366,7 +1357,7 @@ void WS2812FX::service() {
|
||||
_segment_index = 0;
|
||||
|
||||
for (segment &seg : _segments) {
|
||||
if (_suspend) return; // immediately stop processing segments if suspend requested during service()
|
||||
if (_suspend) break; // immediately stop processing segments if suspend requested during service()
|
||||
|
||||
// process transition (mode changes in the middle of transition)
|
||||
seg.handleTransition();
|
||||
@ -1431,8 +1422,8 @@ void WS2812FX::service() {
|
||||
if (doShow) {
|
||||
yield();
|
||||
Segment::handleRandomPalette(); // slowly transition random palette; move it into for loop when each segment has individual random palette
|
||||
show();
|
||||
_lastServiceShow = nowUp; // update timestamp, for precise FPS control
|
||||
if (!_suspend) show();
|
||||
}
|
||||
#ifdef WLED_DEBUG
|
||||
if ((_targetFps != FPS_UNLIMITED) && (millis() - nowUp > _frametime)) DEBUG_PRINTF_P(PSTR("Slow strip %u/%d.\n"), (unsigned)(millis()-nowUp), (int)_frametime);
|
||||
|
@ -40,7 +40,7 @@ void longPressAction(uint8_t b)
|
||||
{
|
||||
if (!macroLongPress[b]) {
|
||||
switch (b) {
|
||||
case 0: setRandomColor(col); colorUpdated(CALL_MODE_BUTTON); break;
|
||||
case 0: setRandomColor(colPri); colorUpdated(CALL_MODE_BUTTON); break;
|
||||
case 1:
|
||||
if(buttonBriDirection) {
|
||||
if (bri == 255) break; // avoid unnecessary updates to brightness
|
||||
@ -230,7 +230,7 @@ void handleAnalog(uint8_t b)
|
||||
effectPalette = constrain(effectPalette, 0, strip.getPaletteCount()-1); // map is allowed to "overshoot", so we need to contrain the result
|
||||
} else if (macroDoublePress[b] == 200) {
|
||||
// primary color, hue, full saturation
|
||||
colorHStoRGB(aRead*256,255,col);
|
||||
colorHStoRGB(aRead*256,255,colPri);
|
||||
} else {
|
||||
// otherwise use "double press" for segment selection
|
||||
Segment& seg = strip.getSegment(macroDoublePress[b]);
|
||||
|
@ -773,8 +773,8 @@ function populateSegments(s)
|
||||
}
|
||||
|
||||
let segp = `<div id="segp${i}" class="sbs">`+
|
||||
`<i class="icons slider-icon pwr ${inst.on ? "act":""}" id="seg${i}pwr" onclick="setSegPwr(${i})"></i>`+
|
||||
`<div class="sliderwrap il">`+
|
||||
`<i class="icons slider-icon pwr ${inst.on ? "act":""}" id="seg${i}pwr" title="Power" onclick="setSegPwr(${i})"></i>`+
|
||||
`<div class="sliderwrap il" title="Opacity/Brightness">`+
|
||||
`<input id="seg${i}bri" class="noslide" onchange="setSegBri(${i})" oninput="updateTrail(this)" max="255" min="1" type="range" value="${inst.bri}" />`+
|
||||
`<div class="sliderdisplay"></div>`+
|
||||
`</div>`+
|
||||
@ -810,7 +810,7 @@ function populateSegments(s)
|
||||
cn += `<div class="seg lstI ${i==s.mainseg && !simplifiedUI ? 'selected' : ''} ${exp ? "expanded":""}" id="seg${i}" data-set="${inst.set}">`+
|
||||
`<label class="check schkl ${smpl}">`+
|
||||
`<input type="checkbox" id="seg${i}sel" onchange="selSeg(${i})" ${inst.sel ? "checked":""}>`+
|
||||
`<span class="checkmark"></span>`+
|
||||
`<span class="checkmark" title="Select"></span>`+
|
||||
`</label>`+
|
||||
`<div class="segname ${smpl}" onclick="selSegEx(${i})">`+
|
||||
`<i class="icons e-icon frz" id="seg${i}frz" title="(un)Freeze" onclick="event.preventDefault();tglFreeze(${i});">&#x${inst.frz ? (li.live && li.liveseg==i?'e410':'e0e8') : 'e325'};</i>`+
|
||||
@ -1659,13 +1659,17 @@ function setEffectParameters(idx)
|
||||
paOnOff[0] = paOnOff[0].substring(0,dPos);
|
||||
}
|
||||
if (paOnOff.length>0 && paOnOff[0] != "!") text = paOnOff[0];
|
||||
gId("adPal").classList.remove("hide");
|
||||
if (lastinfo.cpalcount>0) gId("rmPal").classList.remove("hide");
|
||||
} else {
|
||||
// disable palette list
|
||||
text += ' not used';
|
||||
palw.style.display = "none";
|
||||
gId("adPal").classList.add("hide");
|
||||
gId("rmPal").classList.add("hide");
|
||||
// Close palette dialog if not available
|
||||
if (gId("palw").lastElementChild.tagName == "DIALOG") {
|
||||
gId("palw").lastElementChild.close();
|
||||
if (palw.lastElementChild.tagName == "DIALOG") {
|
||||
palw.lastElementChild.close();
|
||||
}
|
||||
}
|
||||
pall.innerHTML = icon + text;
|
||||
@ -1879,7 +1883,7 @@ function makeSeg()
|
||||
function resetUtil(off=false)
|
||||
{
|
||||
gId('segutil').innerHTML = `<div class="seg btn btn-s${off?' off':''}" style="padding:0;margin-bottom:12px;">`
|
||||
+ '<label class="check schkl"><input type="checkbox" id="selall" onchange="selSegAll(this)"><span class="checkmark"></span></label>'
|
||||
+ '<label class="check schkl"><input type="checkbox" id="selall" onchange="selSegAll(this)"><span class="checkmark" title="Select all"></span></label>'
|
||||
+ `<div class="segname" ${off?'':'onclick="makeSeg()"'}><i class="icons btn-icon"></i>Add segment</div>`
|
||||
+ '<div class="pop hide" onclick="event.stopPropagation();">'
|
||||
+ `<i class="icons g-icon" title="Select group" onclick="this.nextElementSibling.classList.toggle('hide');"></i>`
|
||||
@ -2649,28 +2653,28 @@ function fromRgb()
|
||||
var g = gId('sliderG').value;
|
||||
var b = gId('sliderB').value;
|
||||
setPicker(`rgb(${r},${g},${b})`);
|
||||
let cd = gId('csl').children; // color slots
|
||||
cd[csel].dataset.r = r;
|
||||
cd[csel].dataset.g = g;
|
||||
cd[csel].dataset.b = b;
|
||||
setCSL(cd[csel]);
|
||||
let cd = gId('csl').children[csel]; // color slots
|
||||
cd.dataset.r = r;
|
||||
cd.dataset.g = g;
|
||||
cd.dataset.b = b;
|
||||
setCSL(cd);
|
||||
}
|
||||
|
||||
function fromW()
|
||||
{
|
||||
let w = gId('sliderW');
|
||||
let cd = gId('csl').children; // color slots
|
||||
cd[csel].dataset.w = w.value;
|
||||
setCSL(cd[csel]);
|
||||
let cd = gId('csl').children[csel]; // color slots
|
||||
cd.dataset.w = w.value;
|
||||
setCSL(cd);
|
||||
updateTrail(w);
|
||||
}
|
||||
|
||||
// sr 0: from RGB sliders, 1: from picker, 2: from hex
|
||||
function setColor(sr)
|
||||
{
|
||||
var cd = gId('csl').children; // color slots
|
||||
let cdd = cd[csel].dataset;
|
||||
let w = 0, r,g,b;
|
||||
var cd = gId('csl').children[csel]; // color slots
|
||||
let cdd = cd.dataset;
|
||||
let w = parseInt(cdd.w), r = parseInt(cdd.r), g = parseInt(cdd.g), b = parseInt(cdd.b);
|
||||
if (sr == 1 && isRgbBlack(cdd)) cpick.color.setChannel('hsv', 'v', 100);
|
||||
if (sr != 2 && hasWhite) w = parseInt(gId('sliderW').value);
|
||||
var col = cpick.color.rgb;
|
||||
@ -2678,7 +2682,7 @@ function setColor(sr)
|
||||
cdd.g = g = hasRGB ? col.g : w;
|
||||
cdd.b = b = hasRGB ? col.b : w;
|
||||
cdd.w = w;
|
||||
setCSL(cd[csel]);
|
||||
setCSL(cd);
|
||||
var obj = {"seg": {"col": [[],[],[]]}};
|
||||
obj.seg.col[csel] = [r, g, b, w];
|
||||
requestJson(obj);
|
||||
|
@ -24,6 +24,7 @@
|
||||
function is16b(t) { return !!(gT(t).c & 0x10); } // is digital 16 bit type
|
||||
function mustR(t) { return !!(gT(t).c & 0x20); } // Off refresh is mandatory
|
||||
function numPins(t){ return Math.max(gT(t).t.length, 1); } // type length determines number of GPIO pins
|
||||
function chrID(x) { return String.fromCharCode((x<10?48:55)+x); }
|
||||
function S() {
|
||||
getLoc();
|
||||
loadJS(getURL('/settings/s.js?p=2'), false, ()=>{
|
||||
@ -138,7 +139,7 @@
|
||||
gId("ppldis").style.display = ppl ? 'inline' : 'none';
|
||||
// set PPL minimum value and clear actual PPL limit if ABL is disabled
|
||||
d.Sf.querySelectorAll("#mLC input[name^=MA]").forEach((i,x)=>{
|
||||
var n = String.fromCharCode((x<10?48:55)+x);
|
||||
var n = chrID(x);
|
||||
gId("PSU"+n).style.display = ppl ? "inline" : "none";
|
||||
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
||||
const c = parseInt(d.Sf["LC"+n].value); //get LED count
|
||||
@ -169,7 +170,7 @@
|
||||
// select appropriate LED current
|
||||
d.Sf.querySelectorAll("#mLC select[name^=LAsel]").forEach((sel,x)=>{
|
||||
sel.value = 0; // set custom
|
||||
var n = String.fromCharCode((x<10?48:55)+x);
|
||||
var n = chrID(x);
|
||||
if (en)
|
||||
switch (parseInt(d.Sf["LA"+n].value)) {
|
||||
case 0: break; // disable ABL
|
||||
@ -399,7 +400,7 @@
|
||||
}
|
||||
function lastEnd(i) {
|
||||
if (i-- < 1) return 0;
|
||||
var s = String.fromCharCode((i<10?48:55)+i);
|
||||
var s = chrID(i);
|
||||
v = parseInt(d.getElementsByName("LS"+s)[0].value) + parseInt(d.getElementsByName("LC"+s)[0].value);
|
||||
var t = parseInt(d.getElementsByName("LT"+s)[0].value);
|
||||
if (isPWM(t)) v = 1; //PWM busses
|
||||
@ -422,7 +423,7 @@
|
||||
});
|
||||
|
||||
if ((n==1 && i>=maxB+maxV) || (n==-1 && i==0)) return;
|
||||
var s = String.fromCharCode((i<10?48:55)+i);
|
||||
var s = chrID(i);
|
||||
|
||||
if (n==1) {
|
||||
// npm run build has trouble minimizing spaces inside string
|
||||
@ -506,7 +507,7 @@ mA/LED: <select name="LAsel${s}" onchange="enLA(this,'${s}');UI();">
|
||||
function addCOM(start=0,len=1,co=0) {
|
||||
var i = gEBCN("com_entry").length;
|
||||
if (i >= maxCO) return;
|
||||
var s = String.fromCharCode((i<10?48:55)+i);
|
||||
var s = chrID(i);
|
||||
var b = `<div class="com_entry">
|
||||
<hr class="sml">
|
||||
${i+1}: Start: <input type="number" name="XS${s}" id="xs${s}" class="l starts" min="0" max="65535" value="${start}" oninput="UI();" required="">
|
||||
@ -560,7 +561,7 @@ Swap: <select id="xw${s}" name="XW${s}">
|
||||
|
||||
function addBtn(i,p,t) {
|
||||
var c = gId("btns").innerHTML;
|
||||
var s = String.fromCharCode((i<10?48:55)+i);
|
||||
var s = chrID(i);
|
||||
c += `Button ${i} GPIO: <input type="number" name="BT${s}" onchange="UI()" class="xs" value="${p}">`;
|
||||
c += ` <select name="BE${s}">`
|
||||
c += `<option value="0" ${t==0?"selected":""}>Disabled</option>`;
|
||||
@ -584,8 +585,10 @@ Swap: <select id="xw${s}" name="XW${s}">
|
||||
function checkSi() { //on load, checks whether there are custom start fields
|
||||
var cs = false;
|
||||
for (var i=1; i < gEBCN("iST").length; i++) {
|
||||
var v = parseInt(gId("ls"+(i-1)).value) + parseInt(gN("LC"+(i-1)).value);
|
||||
if (v != parseInt(gId("ls"+i).value)) {cs = true; startsDirty[i] = true;}
|
||||
var s = chrID(i);
|
||||
var p = chrID(i-1); // cover edge case 'A' previous char being '9'
|
||||
var v = parseInt(gId("ls"+p).value) + parseInt(gN("LC"+p).value);
|
||||
if (v != parseInt(gId("ls"+s).value)) {cs = true; startsDirty[i] = true;}
|
||||
}
|
||||
if (gId("ls0") && parseInt(gId("ls0").value) != 0) {cs = true; startsDirty[0] = true;}
|
||||
gId("si").checked = cs;
|
||||
@ -617,7 +620,7 @@ Swap: <select id="xw${s}" name="XW${s}">
|
||||
var c = JSON.parse(lines);
|
||||
if (c.hw) {
|
||||
if (c.hw.led) {
|
||||
for (var i=0; i<10; i++) addLEDs(-1);
|
||||
for (var i=0; i<oMaxB+maxV; i++) addLEDs(-1);
|
||||
var l = c.hw.led;
|
||||
l.ins.forEach((v,i,a)=>{
|
||||
addLEDs(1);
|
||||
|
@ -195,9 +195,9 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len)
|
||||
{
|
||||
switch(hueColormode)
|
||||
{
|
||||
case 1: if (hueX != hueXLast || hueY != hueYLast) colorXYtoRGB(hueX,hueY,col); hueXLast = hueX; hueYLast = hueY; break;
|
||||
case 2: if (hueHue != hueHueLast || hueSat != hueSatLast) colorHStoRGB(hueHue,hueSat,col); hueHueLast = hueHue; hueSatLast = hueSat; break;
|
||||
case 3: if (hueCt != hueCtLast) colorCTtoRGB(hueCt,col); hueCtLast = hueCt; break;
|
||||
case 1: if (hueX != hueXLast || hueY != hueYLast) colorXYtoRGB(hueX,hueY,colPri); hueXLast = hueX; hueYLast = hueY; break;
|
||||
case 2: if (hueHue != hueHueLast || hueSat != hueSatLast) colorHStoRGB(hueHue,hueSat,colPri); hueHueLast = hueHue; hueSatLast = hueSat; break;
|
||||
case 3: if (hueCt != hueCtLast) colorCTtoRGB(hueCt,colPri); hueCtLast = hueCt; break;
|
||||
}
|
||||
}
|
||||
hueReceived = true;
|
||||
|
102
wled00/json.cpp
102
wled00/json.cpp
@ -91,19 +91,20 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t grp = elem["grp"] | seg.grouping;
|
||||
uint16_t spc = elem[F("spc")] | seg.spacing;
|
||||
uint16_t of = seg.offset;
|
||||
uint8_t soundSim = elem["si"] | seg.soundSim;
|
||||
uint8_t map1D2D = elem["m12"] | seg.map1D2D;
|
||||
|
||||
if ((spc>0 && spc!=seg.spacing) || seg.map1D2D!=map1D2D) seg.fill(BLACK); // clear spacing gaps
|
||||
|
||||
seg.map1D2D = constrain(map1D2D, 0, 7);
|
||||
seg.soundSim = constrain(soundSim, 0, 3);
|
||||
|
||||
uint8_t set = elem[F("set")] | seg.set;
|
||||
seg.set = constrain(set, 0, 3);
|
||||
uint16_t grp = elem["grp"] | seg.grouping;
|
||||
uint16_t spc = elem[F("spc")] | seg.spacing;
|
||||
uint16_t of = seg.offset;
|
||||
uint8_t soundSim = elem["si"] | seg.soundSim;
|
||||
uint8_t map1D2D = elem["m12"] | seg.map1D2D;
|
||||
uint8_t set = elem[F("set")] | seg.set;
|
||||
bool selected = getBoolVal(elem["sel"], seg.selected);
|
||||
bool reverse = getBoolVal(elem["rev"], seg.reverse);
|
||||
bool mirror = getBoolVal(elem["mi"] , seg.mirror);
|
||||
#ifndef WLED_DISABLE_2D
|
||||
bool reverse_y = getBoolVal(elem["rY"] , seg.reverse_y);
|
||||
bool mirror_y = getBoolVal(elem["mY"] , seg.mirror_y);
|
||||
bool transpose = getBoolVal(elem[F("tp")], seg.transpose);
|
||||
#endif
|
||||
|
||||
int len = 1;
|
||||
if (stop > start) len = stop - start;
|
||||
@ -117,7 +118,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
if (stop > start && of > len -1) of = len -1;
|
||||
|
||||
// update segment (delete if necessary)
|
||||
seg.setGeometry(start, stop, grp, spc, of, startY, stopY); // strip needs to be suspended for this to work without issues
|
||||
seg.setGeometry(start, stop, grp, spc, of, startY, stopY, map1D2D); // strip needs to be suspended for this to work without issues
|
||||
|
||||
if (newSeg) seg.refreshLightCapabilities(); // fix for #3403
|
||||
|
||||
@ -206,20 +207,16 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
}
|
||||
#endif
|
||||
|
||||
//seg.map1D2D = constrain(map1D2D, 0, 7); // done in setGeometry()
|
||||
seg.set = constrain(set, 0, 3);
|
||||
seg.soundSim = constrain(soundSim, 0, 3);
|
||||
seg.selected = selected;
|
||||
seg.reverse = reverse;
|
||||
seg.mirror = mirror;
|
||||
#ifndef WLED_DISABLE_2D
|
||||
bool reverse = seg.reverse;
|
||||
bool mirror = seg.mirror;
|
||||
#endif
|
||||
seg.selected = getBoolVal(elem["sel"], seg.selected);
|
||||
seg.reverse = getBoolVal(elem["rev"], seg.reverse);
|
||||
seg.mirror = getBoolVal(elem["mi"] , seg.mirror);
|
||||
#ifndef WLED_DISABLE_2D
|
||||
bool reverse_y = seg.reverse_y;
|
||||
bool mirror_y = seg.mirror_y;
|
||||
seg.reverse_y = getBoolVal(elem["rY"] , seg.reverse_y);
|
||||
seg.mirror_y = getBoolVal(elem["mY"] , seg.mirror_y);
|
||||
seg.transpose = getBoolVal(elem[F("tp")], seg.transpose);
|
||||
if (seg.is2D() && seg.map1D2D == M12_pArc && (reverse != seg.reverse || reverse_y != seg.reverse_y || mirror != seg.mirror || mirror_y != seg.mirror_y)) seg.fill(BLACK); // clear entire segment (in case of Arc 1D to 2D expansion)
|
||||
seg.reverse_y = reverse_y;
|
||||
seg.mirror_y = mirror_y;
|
||||
seg.transpose = transpose;
|
||||
#endif
|
||||
|
||||
byte fx = seg.mode;
|
||||
@ -393,35 +390,38 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
|
||||
int it = 0;
|
||||
JsonVariant segVar = root["seg"];
|
||||
if (!segVar.isNull()) strip.suspend();
|
||||
if (segVar.is<JsonObject>())
|
||||
{
|
||||
int id = segVar["id"] | -1;
|
||||
//if "seg" is not an array and ID not specified, apply to all selected/checked segments
|
||||
if (id < 0) {
|
||||
//apply all selected segments
|
||||
//bool didSet = false;
|
||||
for (size_t s = 0; s < strip.getSegmentsNum(); s++) {
|
||||
Segment &sg = strip.getSegment(s);
|
||||
if (sg.isActive() && sg.isSelected()) {
|
||||
deserializeSegment(segVar, s, presetId);
|
||||
//didSet = true;
|
||||
if (!segVar.isNull()) {
|
||||
// we may be called during strip.service() so we must not modify segments while effects are executing
|
||||
strip.suspend();
|
||||
const unsigned long waitUntil = millis() + strip.getFrameTime();
|
||||
while (strip.isServicing() && millis() < waitUntil) delay(1); // wait until frame is over
|
||||
#ifdef WLED_DEBUG
|
||||
if (millis() >= waitUntil) DEBUG_PRINTLN(F("JSON: Waited for strip to finish servicing."));
|
||||
#endif
|
||||
if (segVar.is<JsonObject>()) {
|
||||
int id = segVar["id"] | -1;
|
||||
//if "seg" is not an array and ID not specified, apply to all selected/checked segments
|
||||
if (id < 0) {
|
||||
//apply all selected segments
|
||||
for (size_t s = 0; s < strip.getSegmentsNum(); s++) {
|
||||
Segment &sg = strip.getSegment(s);
|
||||
if (sg.isActive() && sg.isSelected()) {
|
||||
deserializeSegment(segVar, s, presetId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
deserializeSegment(segVar, id, presetId); //apply only the segment with the specified ID
|
||||
}
|
||||
//TODO: not sure if it is good idea to change first active but unselected segment
|
||||
//if (!didSet) deserializeSegment(segVar, strip.getMainSegmentId(), presetId);
|
||||
} else {
|
||||
deserializeSegment(segVar, id, presetId); //apply only the segment with the specified ID
|
||||
size_t deleted = 0;
|
||||
JsonArray segs = segVar.as<JsonArray>();
|
||||
for (JsonObject elem : segs) {
|
||||
if (deserializeSegment(elem, it++, presetId) && !elem["stop"].isNull() && elem["stop"]==0) deleted++;
|
||||
}
|
||||
if (strip.getSegmentsNum() > 3 && deleted >= strip.getSegmentsNum()/2U) strip.purgeSegments(); // batch deleting more than half segments
|
||||
}
|
||||
} else {
|
||||
size_t deleted = 0;
|
||||
JsonArray segs = segVar.as<JsonArray>();
|
||||
for (JsonObject elem : segs) {
|
||||
if (deserializeSegment(elem, it++, presetId) && !elem["stop"].isNull() && elem["stop"]==0) deleted++;
|
||||
}
|
||||
if (strip.getSegmentsNum() > 3 && deleted >= strip.getSegmentsNum()/2U) strip.purgeSegments(); // batch deleting more than half segments
|
||||
strip.resume();
|
||||
}
|
||||
strip.resume();
|
||||
|
||||
UsermodManager::readFromJsonState(root);
|
||||
|
||||
|
@ -9,10 +9,10 @@ void setValuesFromFirstSelectedSeg() { setValuesFromSegment(strip.getFirstSelect
|
||||
void setValuesFromSegment(uint8_t s)
|
||||
{
|
||||
Segment& seg = strip.getSegment(s);
|
||||
col[0] = R(seg.colors[0]);
|
||||
col[1] = G(seg.colors[0]);
|
||||
col[2] = B(seg.colors[0]);
|
||||
col[3] = W(seg.colors[0]);
|
||||
colPri[0] = R(seg.colors[0]);
|
||||
colPri[1] = G(seg.colors[0]);
|
||||
colPri[2] = B(seg.colors[0]);
|
||||
colPri[3] = W(seg.colors[0]);
|
||||
colSec[0] = R(seg.colors[1]);
|
||||
colSec[1] = G(seg.colors[1]);
|
||||
colSec[2] = B(seg.colors[1]);
|
||||
@ -39,7 +39,7 @@ void applyValuesToSelectedSegs()
|
||||
if (effectIntensity != selsegPrev.intensity) {seg.intensity = effectIntensity; stateChanged = true;}
|
||||
if (effectPalette != selsegPrev.palette) {seg.setPalette(effectPalette);}
|
||||
if (effectCurrent != selsegPrev.mode) {seg.setMode(effectCurrent);}
|
||||
uint32_t col0 = RGBW32( col[0], col[1], col[2], col[3]);
|
||||
uint32_t col0 = RGBW32(colPri[0], colPri[1], colPri[2], colPri[3]);
|
||||
uint32_t col1 = RGBW32(colSec[0], colSec[1], colSec[2], colSec[3]);
|
||||
if (col0 != selsegPrev.colors[0]) {seg.setColor(0, col0);}
|
||||
if (col1 != selsegPrev.colors[1]) {seg.setColor(1, col1);}
|
||||
@ -157,14 +157,14 @@ void updateInterfaces(uint8_t callMode)
|
||||
|
||||
sendDataWs();
|
||||
lastInterfaceUpdate = millis();
|
||||
interfaceUpdateCallMode = 0; //disable further updates
|
||||
interfaceUpdateCallMode = CALL_MODE_INIT; //disable further updates
|
||||
|
||||
if (callMode == CALL_MODE_WS_SEND) return;
|
||||
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
if (espalexaDevice != nullptr && callMode != CALL_MODE_ALEXA) {
|
||||
espalexaDevice->setValue(bri);
|
||||
espalexaDevice->setColor(col[0], col[1], col[2]);
|
||||
espalexaDevice->setColor(colPri[0], colPri[1], colPri[2]);
|
||||
}
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_MQTT
|
||||
@ -221,7 +221,7 @@ void handleNightlight()
|
||||
nightlightDelayMs = (unsigned)(nightlightDelayMins*60000);
|
||||
nightlightActiveOld = true;
|
||||
briNlT = bri;
|
||||
for (unsigned i=0; i<4; i++) colNlT[i] = col[i]; // remember starting color
|
||||
for (unsigned i=0; i<4; i++) colNlT[i] = colPri[i]; // remember starting color
|
||||
if (nightlightMode == NL_MODE_SUN)
|
||||
{
|
||||
//save current
|
||||
@ -246,7 +246,7 @@ void handleNightlight()
|
||||
bri = briNlT + ((nightlightTargetBri - briNlT)*nper);
|
||||
if (nightlightMode == NL_MODE_COLORFADE) // color fading only is enabled with "NF=2"
|
||||
{
|
||||
for (unsigned i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color
|
||||
for (unsigned i=0; i<4; i++) colPri[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color
|
||||
}
|
||||
colorUpdated(CALL_MODE_NO_NOTIFY);
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ static void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProp
|
||||
//Prefix is stripped from the topic at this point
|
||||
|
||||
if (strcmp_P(topic, PSTR("/col")) == 0) {
|
||||
colorFromDecOrHexString(col, payloadStr);
|
||||
colorFromDecOrHexString(colPri, payloadStr);
|
||||
colorUpdated(CALL_MODE_DIRECT_CHANGE);
|
||||
} else if (strcmp_P(topic, PSTR("/api")) == 0) {
|
||||
if (requestJSONBufferLock(15)) {
|
||||
@ -165,7 +165,7 @@ void publishMqtt()
|
||||
strcat_P(subuf, PSTR("/g"));
|
||||
mqtt->publish(subuf, 0, retainMqttMsg, s); // optionally retain message (#2263)
|
||||
|
||||
sprintf_P(s, PSTR("#%06X"), (col[3] << 24) | (col[0] << 16) | (col[1] << 8) | (col[2]));
|
||||
sprintf_P(s, PSTR("#%06X"), (colPri[3] << 24) | (colPri[0] << 16) | (colPri[1] << 8) | (colPri[2]));
|
||||
strlcpy(subuf, mqttDeviceTopic, 33);
|
||||
strcat_P(subuf, PSTR("/c"));
|
||||
mqtt->publish(subuf, 0, retainMqttMsg, s); // optionally retain message (#2263)
|
||||
|
@ -144,7 +144,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
|
||||
bool busesChanged = false;
|
||||
for (int s = 0; s < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; s++) {
|
||||
int offset = s < 10 ? 48 : 55;
|
||||
int offset = s < 10 ? '0' : 'A';
|
||||
char lp[4] = "L0"; lp[2] = offset+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
||||
char lc[4] = "LC"; lc[2] = offset+s; lc[3] = 0; //strip length
|
||||
char co[4] = "CO"; co[2] = offset+s; co[3] = 0; //strip color order
|
||||
@ -163,7 +163,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
lp[1] = offset+i;
|
||||
lp[1] = '0'+i;
|
||||
if (!request->hasArg(lp)) break;
|
||||
pins[i] = (request->arg(lp).length() > 0) ? request->arg(lp).toInt() : 255;
|
||||
}
|
||||
@ -218,7 +218,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
// we will not bother with pre-allocating ColorOrderMappings vector
|
||||
BusManager::getColorOrderMap().reset();
|
||||
for (int s = 0; s < WLED_MAX_COLOR_ORDER_MAPPINGS; s++) {
|
||||
int offset = s < 10 ? 48 : 55;
|
||||
int offset = s < 10 ? '0' : 'A';
|
||||
char xs[4] = "XS"; xs[2] = offset+s; xs[3] = 0; //start LED
|
||||
char xc[4] = "XC"; xc[2] = offset+s; xc[3] = 0; //strip length
|
||||
char xo[4] = "XO"; xo[2] = offset+s; xo[3] = 0; //color order
|
||||
@ -257,7 +257,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
disablePullUp = (bool)request->hasArg(F("IP"));
|
||||
touchThreshold = request->arg(F("TT")).toInt();
|
||||
for (int i = 0; i < WLED_MAX_BUTTONS; i++) {
|
||||
int offset = i < 10 ? 48 : 55;
|
||||
int offset = i < 10 ? '0' : 'A';
|
||||
char bt[4] = "BT"; bt[2] = offset+i; bt[3] = 0; // button pin (use A,B,C,... if WLED_MAX_BUTTONS>10)
|
||||
char be[4] = "BE"; be[2] = offset+i; be[3] = 0; // button type (use A,B,C,... if WLED_MAX_BUTTONS>10)
|
||||
int hw_btn_pin = request->arg(bt).toInt();
|
||||
@ -1185,7 +1185,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
}
|
||||
// you can add more if you need
|
||||
|
||||
// global col[], effectCurrent, ... are updated in stateChanged()
|
||||
// global colPri[], effectCurrent, ... are updated in stateChanged()
|
||||
if (!apply) return true; // when called by JSON API, do not call colorUpdated() here
|
||||
|
||||
pos = req.indexOf(F("&NN")); //do not send UDP notifications this time
|
||||
|
@ -459,7 +459,7 @@ void WLED::setup()
|
||||
#endif
|
||||
|
||||
// fill in unique mdns default
|
||||
if (strcmp(cmDNS, "x") == 0) sprintf_P(cmDNS, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
|
||||
if (strcmp(cmDNS, DEFAULT_MDNS_NAME) == 0) sprintf_P(cmDNS, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
|
||||
#ifndef WLED_DISABLE_MQTT
|
||||
if (mqttDeviceTopic[0] == 0) sprintf_P(mqttDeviceTopic, PSTR("wled/%*s"), 6, escapedMac.c_str() + 6);
|
||||
if (mqttClientID[0] == 0) sprintf_P(mqttClientID, PSTR("WLED-%*s"), 6, escapedMac.c_str() + 6);
|
||||
@ -540,11 +540,12 @@ void WLED::beginStrip()
|
||||
} else {
|
||||
// fix for #3196
|
||||
if (bootPreset > 0) {
|
||||
bool oldTransition = fadeTransition; // workaround if transitions are enabled
|
||||
fadeTransition = false; // ignore transitions temporarily
|
||||
strip.setColor(0, BLACK); // set all segments black
|
||||
fadeTransition = oldTransition; // restore transitions
|
||||
col[0] = col[1] = col[2] = col[3] = 0; // needed for colorUpdated()
|
||||
// set all segments black (no transition)
|
||||
for (unsigned i = 0; i < strip.getSegmentsNum(); i++) {
|
||||
Segment &seg = strip.getSegment(i);
|
||||
if (seg.isActive()) seg.colors[0] = BLACK;
|
||||
}
|
||||
colPri[0] = colPri[1] = colPri[2] = colPri[3] = 0; // needed for colorUpdated()
|
||||
}
|
||||
briLast = briS; bri = 0;
|
||||
strip.fill(BLACK);
|
||||
|
@ -407,7 +407,7 @@ WLED_GLOBAL bool gammaCorrectCol _INIT(true); // use gamma correction on col
|
||||
WLED_GLOBAL bool gammaCorrectBri _INIT(false); // use gamma correction on brightness
|
||||
WLED_GLOBAL float gammaCorrectVal _INIT(2.8f); // gamma correction value
|
||||
|
||||
WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color.
|
||||
WLED_GLOBAL byte colPri[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. colPri[] should be updated if you want to change the color.
|
||||
WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color
|
||||
|
||||
WLED_GLOBAL byte nightlightTargetBri _INIT(0); // brightness after nightlight is over
|
||||
|
@ -11,7 +11,7 @@ void XML_response(Print& dest)
|
||||
dest.printf_P(PSTR("<?xml version=\"1.0\" ?><vs><ac>%d</ac>"), (nightlightActive && nightlightMode > NL_MODE_SET) ? briT : bri);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
dest.printf_P(PSTR("<cl>%d</cl>"), col[i]);
|
||||
dest.printf_P(PSTR("<cl>%d</cl>"), colPri[i]);
|
||||
}
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
@ -20,7 +20,7 @@ void XML_response(Print& dest)
|
||||
dest.printf_P(PSTR("<ns>%d</ns><nr>%d</nr><nl>%d</nl><nf>%d</nf><nd>%d</nd><nt>%d</nt><fx>%d</fx><sx>%d</sx><ix>%d</ix><fp>%d</fp><wv>%d</wv><ws>%d</ws><ps>%d</ps><cy>%d</cy><ds>%s%s</ds><ss>%d</ss></vs>"),
|
||||
notifyDirect, receiveGroups!=0, nightlightActive, nightlightMode > NL_MODE_SET, nightlightDelayMins,
|
||||
nightlightTargetBri, effectCurrent, effectSpeed, effectIntensity, effectPalette,
|
||||
strip.hasWhiteChannel() ? col[3] : -1, colSec[3], currentPreset, currentPlaylist >= 0,
|
||||
strip.hasWhiteChannel() ? colPri[3] : -1, colSec[3], currentPreset, currentPlaylist >= 0,
|
||||
serverDescription, realtimeMode ? PSTR(" (live)") : "",
|
||||
strip.getFirstSelectedSegId()
|
||||
);
|
||||
@ -293,9 +293,9 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
|
||||
unsigned sumMa = 0;
|
||||
for (int s = 0; s < BusManager::getNumBusses(); s++) {
|
||||
Bus* bus = BusManager::getBus(s);
|
||||
if (bus == nullptr) continue;
|
||||
int offset = s < 10 ? 48 : 55;
|
||||
const Bus* bus = BusManager::getBus(s);
|
||||
if (!bus || !bus->isOk()) break; // should not happen but for safety
|
||||
int offset = s < 10 ? '0' : 'A';
|
||||
char lp[4] = "L0"; lp[2] = offset+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
||||
char lc[4] = "LC"; lc[2] = offset+s; lc[3] = 0; //strip length
|
||||
char co[4] = "CO"; co[2] = offset+s; co[3] = 0; //strip color order
|
||||
@ -313,7 +313,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
|
||||
uint8_t pins[5];
|
||||
int nPins = bus->getPins(pins);
|
||||
for (int i = 0; i < nPins; i++) {
|
||||
lp[1] = offset+i;
|
||||
lp[1] = '0'+i;
|
||||
if (PinManager::isPinOk(pins[i]) || bus->isVirtual()) printSetFormValue(settingsScript,lp,pins[i]);
|
||||
}
|
||||
printSetFormValue(settingsScript,lc,bus->getLength());
|
||||
|
Loading…
x
Reference in New Issue
Block a user