Add per-segment light capability info (#2552)
* Add per-segment light capability info * Fix duplication * Change to more lightweight seglc array * Added segment capabilities. * Differs and capabilities refactoring * Add back selection differs option Co-authored-by: Blaz Kristan <blaz@kristan-sp.si>
This commit is contained in:
parent
53abe36b83
commit
7138e891be
28
wled00/FX.h
28
wled00/FX.h
@ -334,28 +334,8 @@ class WS2812FX {
|
|||||||
vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||||
return vLength;
|
return vLength;
|
||||||
}
|
}
|
||||||
uint8_t differs(Segment& b) {
|
uint8_t differs(Segment& b);
|
||||||
uint8_t d = 0;
|
uint8_t getLightCapabilities();
|
||||||
if (start != b.start) d |= SEG_DIFFERS_BOUNDS;
|
|
||||||
if (stop != b.stop) d |= SEG_DIFFERS_BOUNDS;
|
|
||||||
if (offset != b.offset) d |= SEG_DIFFERS_GSO;
|
|
||||||
if (grouping != b.grouping) d |= SEG_DIFFERS_GSO;
|
|
||||||
if (spacing != b.spacing) d |= SEG_DIFFERS_GSO;
|
|
||||||
if (opacity != b.opacity) d |= SEG_DIFFERS_BRI;
|
|
||||||
if (mode != b.mode) d |= SEG_DIFFERS_FX;
|
|
||||||
if (speed != b.speed) d |= SEG_DIFFERS_FX;
|
|
||||||
if (intensity != b.intensity) d |= SEG_DIFFERS_FX;
|
|
||||||
if (palette != b.palette) d |= SEG_DIFFERS_FX;
|
|
||||||
|
|
||||||
if ((options & 0b00101110) != (b.options & 0b00101110)) d |= SEG_DIFFERS_OPT;
|
|
||||||
if ((options & 0x01) != (b.options & 0x01)) d |= SEG_DIFFERS_SEL;
|
|
||||||
for (uint8_t i = 0; i < NUM_COLORS; i++)
|
|
||||||
{
|
|
||||||
if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
} segment;
|
} segment;
|
||||||
|
|
||||||
// segment runtime parameters
|
// segment runtime parameters
|
||||||
@ -653,7 +633,7 @@ class WS2812FX {
|
|||||||
setMainSegmentId(uint8_t n),
|
setMainSegmentId(uint8_t n),
|
||||||
restartRuntime(),
|
restartRuntime(),
|
||||||
resetSegments(),
|
resetSegments(),
|
||||||
makeAutoSegments(),
|
makeAutoSegments(bool forceReset = false),
|
||||||
fixInvalidSegments(),
|
fixInvalidSegments(),
|
||||||
setPixelColor(uint16_t n, uint32_t c),
|
setPixelColor(uint16_t n, uint32_t c),
|
||||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||||
@ -665,6 +645,7 @@ class WS2812FX {
|
|||||||
gammaCorrectBri = false,
|
gammaCorrectBri = false,
|
||||||
gammaCorrectCol = true,
|
gammaCorrectCol = true,
|
||||||
checkSegmentAlignment(void),
|
checkSegmentAlignment(void),
|
||||||
|
hasRGBWBus(void),
|
||||||
hasCCTBus(void),
|
hasCCTBus(void),
|
||||||
// return true if the strip is being sent pixel updates
|
// return true if the strip is being sent pixel updates
|
||||||
isUpdating(void);
|
isUpdating(void);
|
||||||
@ -680,6 +661,7 @@ class WS2812FX {
|
|||||||
getMaxSegments(void),
|
getMaxSegments(void),
|
||||||
getActiveSegmentsNum(void),
|
getActiveSegmentsNum(void),
|
||||||
getMainSegmentId(void),
|
getMainSegmentId(void),
|
||||||
|
getLastActiveSegmentId(void),
|
||||||
getTargetFps(void),
|
getTargetFps(void),
|
||||||
setPixelSegment(uint8_t n),
|
setPixelSegment(uint8_t n),
|
||||||
gamma8(uint8_t),
|
gamma8(uint8_t),
|
||||||
|
@ -460,6 +460,13 @@ uint8_t WS2812FX::getMainSegmentId(void) {
|
|||||||
return _mainSegment;
|
return _mainSegment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::getLastActiveSegmentId(void) {
|
||||||
|
for (uint8_t i = MAX_NUM_SEGMENTS -1; i > 0; i--) {
|
||||||
|
if (_segments[i].isActive()) return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t WS2812FX::getActiveSegmentsNum(void) {
|
uint8_t WS2812FX::getActiveSegmentsNum(void) {
|
||||||
uint8_t c = 0;
|
uint8_t c = 0;
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
@ -520,6 +527,77 @@ uint16_t WS2812FX::getLengthPhysical(void) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::Segment::differs(Segment& b) {
|
||||||
|
uint8_t d = 0;
|
||||||
|
if (start != b.start) d |= SEG_DIFFERS_BOUNDS;
|
||||||
|
if (stop != b.stop) d |= SEG_DIFFERS_BOUNDS;
|
||||||
|
if (offset != b.offset) d |= SEG_DIFFERS_GSO;
|
||||||
|
if (grouping != b.grouping) d |= SEG_DIFFERS_GSO;
|
||||||
|
if (spacing != b.spacing) d |= SEG_DIFFERS_GSO;
|
||||||
|
if (opacity != b.opacity) d |= SEG_DIFFERS_BRI;
|
||||||
|
if (mode != b.mode) d |= SEG_DIFFERS_FX;
|
||||||
|
if (speed != b.speed) d |= SEG_DIFFERS_FX;
|
||||||
|
if (intensity != b.intensity) d |= SEG_DIFFERS_FX;
|
||||||
|
if (palette != b.palette) d |= SEG_DIFFERS_FX;
|
||||||
|
|
||||||
|
if ((options & 0b00101110) != (b.options & 0b00101110)) d |= SEG_DIFFERS_OPT;
|
||||||
|
if ((options & 0x01) != (b.options & 0x01)) d |= SEG_DIFFERS_SEL;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < NUM_COLORS; i++)
|
||||||
|
{
|
||||||
|
if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::Segment::getLightCapabilities() {
|
||||||
|
if (!isActive()) return 0;
|
||||||
|
uint8_t capabilities = 0;
|
||||||
|
uint8_t awm = Bus::getAutoWhiteMode();
|
||||||
|
bool whiteSlider = (awm == RGBW_MODE_DUAL || awm == RGBW_MODE_MANUAL_ONLY);
|
||||||
|
|
||||||
|
for (uint8_t b = 0; b < busses.getNumBusses(); b++) {
|
||||||
|
Bus *bus = busses.getBus(b);
|
||||||
|
if (bus == nullptr || bus->getLength()==0) break;
|
||||||
|
if (bus->getStart() >= stop) continue;
|
||||||
|
if (bus->getStart() + bus->getLength() <= start) continue;
|
||||||
|
|
||||||
|
uint8_t type = bus->getType();
|
||||||
|
if (!whiteSlider || (type != TYPE_ANALOG_1CH && (cctFromRgb || type != TYPE_ANALOG_2CH)))
|
||||||
|
{
|
||||||
|
capabilities |= 0x01; //segment supports RGB (full color)
|
||||||
|
}
|
||||||
|
if (bus->isRgbw() && whiteSlider) capabilities |= 0x02; //segment supports white channel
|
||||||
|
if (!cctFromRgb) {
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_ANALOG_5CH:
|
||||||
|
case TYPE_ANALOG_2CH:
|
||||||
|
capabilities |= 0x04; //segment supports white CCT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (correctWB && type != TYPE_ANALOG_1CH) capabilities |= 0x04; //white balance correction (uses CCT slider)
|
||||||
|
}
|
||||||
|
return capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
//used for JSON API info.leds.rgbw. Little practical use, deprecate with info.leds.rgbw.
|
||||||
|
//returns if there is an RGBW bus (supports RGB and White, not only white)
|
||||||
|
//not influenced by auto-white mode, also true if white slider does not affect output white channel
|
||||||
|
bool WS2812FX::hasRGBWBus(void) {
|
||||||
|
for (uint8_t b = 0; b < busses.getNumBusses(); b++) {
|
||||||
|
Bus *bus = busses.getBus(b);
|
||||||
|
if (bus == nullptr || bus->getLength()==0) break;
|
||||||
|
switch (bus->getType()) {
|
||||||
|
case TYPE_SK6812_RGBW:
|
||||||
|
case TYPE_TM1814:
|
||||||
|
case TYPE_ANALOG_4CH:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool WS2812FX::hasCCTBus(void) {
|
bool WS2812FX::hasCCTBus(void) {
|
||||||
if (cctFromRgb && !correctWB) return false;
|
if (cctFromRgb && !correctWB) return false;
|
||||||
for (uint8_t b = 0; b < busses.getNumBusses(); b++) {
|
for (uint8_t b = 0; b < busses.getNumBusses(); b++) {
|
||||||
@ -604,7 +682,7 @@ void WS2812FX::resetSegments() {
|
|||||||
_segment_runtimes[0].markForReset();
|
_segment_runtimes[0].markForReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::makeAutoSegments() {
|
void WS2812FX::makeAutoSegments(bool forceReset) {
|
||||||
if (autoSegments) { //make one segment per bus
|
if (autoSegments) { //make one segment per bus
|
||||||
uint16_t segStarts[MAX_NUM_SEGMENTS] = {0};
|
uint16_t segStarts[MAX_NUM_SEGMENTS] = {0};
|
||||||
uint16_t segStops [MAX_NUM_SEGMENTS] = {0};
|
uint16_t segStops [MAX_NUM_SEGMENTS] = {0};
|
||||||
@ -630,9 +708,15 @@ void WS2812FX::makeAutoSegments() {
|
|||||||
setSegment(i, segStarts[i], segStops[i]);
|
setSegment(i, segStarts[i], segStops[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//expand the main seg to the entire length, but only if there are no other segments
|
//expand the main seg to the entire length, but only if there are no other segments, or reset is forced
|
||||||
uint8_t mainSeg = getMainSegmentId();
|
uint8_t mainSeg = getMainSegmentId();
|
||||||
|
|
||||||
|
if (forceReset) {
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) {
|
||||||
|
setSegment(i, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (getActiveSegmentsNum() < 2) {
|
if (getActiveSegmentsNum() < 2) {
|
||||||
setSegment(mainSeg, 0, _length);
|
setSegment(mainSeg, 0, _length);
|
||||||
}
|
}
|
||||||
|
@ -306,7 +306,7 @@
|
|||||||
|
|
||||||
// Size of buffer for API JSON object (increase for more segments)
|
// Size of buffer for API JSON object (increase for more segments)
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define JSON_BUFFER_SIZE 9216
|
#define JSON_BUFFER_SIZE 10240
|
||||||
#else
|
#else
|
||||||
#define JSON_BUFFER_SIZE 20480
|
#define JSON_BUFFER_SIZE 20480
|
||||||
#endif
|
#endif
|
||||||
|
@ -508,9 +508,9 @@ void serializeInfo(JsonObject root)
|
|||||||
|
|
||||||
JsonObject leds = root.createNestedObject("leds");
|
JsonObject leds = root.createNestedObject("leds");
|
||||||
leds[F("count")] = strip.getLengthTotal();
|
leds[F("count")] = strip.getLengthTotal();
|
||||||
leds[F("rgbw")] = strip.hasWhiteChannel();
|
leds[F("rgbw")] = strip.hasRGBWBus(); //deprecated, use info.leds.lc
|
||||||
leds[F("wv")] = false;
|
leds[F("wv")] = false; //deprecated, use info.leds.lc
|
||||||
leds["cct"] = correctWB || strip.hasCCTBus();
|
leds["cct"] = correctWB || strip.hasCCTBus(); //deprecated, use info.leds.lc
|
||||||
switch (Bus::getAutoWhiteMode()) {
|
switch (Bus::getAutoWhiteMode()) {
|
||||||
case RGBW_MODE_MANUAL_ONLY:
|
case RGBW_MODE_MANUAL_ONLY:
|
||||||
case RGBW_MODE_DUAL:
|
case RGBW_MODE_DUAL:
|
||||||
@ -524,6 +524,17 @@ void serializeInfo(JsonObject root)
|
|||||||
leds[F("maxseg")] = strip.getMaxSegments();
|
leds[F("maxseg")] = strip.getMaxSegments();
|
||||||
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
|
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
|
||||||
|
|
||||||
|
uint8_t totalLC = 0;
|
||||||
|
JsonArray lcarr = leds.createNestedArray(F("seglc"));
|
||||||
|
uint8_t nSegs = strip.getLastActiveSegmentId();
|
||||||
|
for (byte s = 0; s <= nSegs; s++) {
|
||||||
|
uint8_t lc = strip.getSegment(s).getLightCapabilities();
|
||||||
|
totalLC |= lc;
|
||||||
|
lcarr.add(lc);
|
||||||
|
}
|
||||||
|
|
||||||
|
leds["lc"] = totalLC;
|
||||||
|
|
||||||
root[F("str")] = syncToggleReceive;
|
root[F("str")] = syncToggleReceive;
|
||||||
|
|
||||||
root[F("name")] = serverDescription;
|
root[F("name")] = serverDescription;
|
||||||
|
Loading…
Reference in New Issue
Block a user