12 [
this](
const fl::json& response) { stubResponseSink(response); }
16 FL_ERROR(
"WLED::stubRequestSource: Not implemented - provide a real RequestSource callback");
21 FL_ERROR(
"WLED::stubResponseSink: Not implemented - provide a real ResponseSink callback");
28 FL_WARN(
"WLED: setState called with invalid JSON");
34 bool newOn = wledState[
"on"] |
mWledOn;
43 if (wledState[
"bri"].is_int()) {
47 FL_WARN(
"WLED: brightness " << briInt <<
" out of range, clamping to 0");
49 }
else if (briInt > 255) {
50 FL_WARN(
"WLED: brightness " << briInt <<
" out of range, clamping to 255");
53 u8 newBri =
static_cast<u8>(briInt);
59 FL_WARN(
"WLED: 'bri' field has invalid type (expected int)");
64 if (wledState.
contains(
"transition")) {
65 if (wledState[
"transition"].is_int()) {
69 FL_WARN(
"WLED: transition " << transInt <<
" out of range, clamping to 0");
71 }
else if (transInt > 65535) {
72 FL_WARN(
"WLED: transition " << transInt <<
" out of range, clamping to 65535");
75 u16 newTransition =
static_cast<u16
>(transInt);
81 FL_WARN(
"WLED: 'transition' field has invalid type (expected int)");
87 if (wledState[
"ps"].is_int()) {
91 FL_WARN(
"WLED: preset " << psInt <<
" out of range, clamping to -1");
93 }
else if (psInt > 250) {
94 FL_WARN(
"WLED: preset " << psInt <<
" out of range, clamping to 250");
97 i16 newPreset =
static_cast<i16
>(psInt);
103 FL_WARN(
"WLED: 'ps' field has invalid type (expected int)");
109 if (wledState[
"pl"].is_int()) {
113 FL_WARN(
"WLED: playlist " << plInt <<
" out of range, clamping to -1");
115 }
else if (plInt > 250) {
116 FL_WARN(
"WLED: playlist " << plInt <<
" out of range, clamping to 250");
119 i16 newPlaylist =
static_cast<i16
>(plInt);
125 FL_WARN(
"WLED: 'pl' field has invalid type (expected int)");
131 if (wledState[
"lor"].is_int()) {
135 FL_WARN(
"WLED: live override " << lorInt <<
" out of range, clamping to 0");
137 }
else if (lorInt > 2) {
138 FL_WARN(
"WLED: live override " << lorInt <<
" out of range, clamping to 2");
141 u8 newLiveOverride =
static_cast<u8>(lorInt);
147 FL_WARN(
"WLED: 'lor' field has invalid type (expected int)");
152 if (wledState.
contains(
"mainseg")) {
153 if (wledState[
"mainseg"].is_int()) {
156 if (mainsegInt < 0) {
157 FL_WARN(
"WLED: main segment " << mainsegInt <<
" out of range, clamping to 0");
159 }
else if (mainsegInt > 255) {
160 FL_WARN(
"WLED: main segment " << mainsegInt <<
" out of range, clamping to 255");
163 u8 newMainSegment =
static_cast<u8>(mainsegInt);
169 FL_WARN(
"WLED: 'mainseg' field has invalid type (expected int)");
175 if (wledState[
"nl"].is_object()) {
176 const fl::json& nl = wledState[
"nl"];
189 if (nl[
"dur"].is_int()) {
193 FL_WARN(
"WLED: nl.dur " << durInt <<
" out of range, clamping to 1");
195 }
else if (durInt > 255) {
196 FL_WARN(
"WLED: nl.dur " << durInt <<
" out of range, clamping to 255");
199 u8 newDur =
static_cast<u8>(durInt);
205 FL_WARN(
"WLED: 'nl.dur' field has invalid type (expected int)");
211 if (nl[
"mode"].is_int()) {
215 FL_WARN(
"WLED: nl.mode " << modeInt <<
" out of range, clamping to 0");
217 }
else if (modeInt > 3) {
218 FL_WARN(
"WLED: nl.mode " << modeInt <<
" out of range, clamping to 3");
221 u8 newMode =
static_cast<u8>(modeInt);
227 FL_WARN(
"WLED: 'nl.mode' field has invalid type (expected int)");
233 if (nl[
"tbri"].is_int()) {
237 FL_WARN(
"WLED: nl.tbri " << tbriInt <<
" out of range, clamping to 0");
239 }
else if (tbriInt > 255) {
240 FL_WARN(
"WLED: nl.tbri " << tbriInt <<
" out of range, clamping to 255");
243 u8 newTbri =
static_cast<u8>(tbriInt);
249 FL_WARN(
"WLED: 'nl.tbri' field has invalid type (expected int)");
253 FL_WARN(
"WLED: 'nl' field has invalid type (expected object)");
259 if (wledState[
"udpn"].is_object()) {
260 const fl::json& udpn = wledState[
"udpn"];
264 bool newSend = udpn[
"send"] |
mUdpSend;
280 FL_WARN(
"WLED: 'udpn' field has invalid type (expected object)");
285 if (wledState.
contains(
"playlist")) {
286 if (wledState[
"playlist"].is_object()) {
287 const fl::json& pl = wledState[
"playlist"];
292 for (
size_t i = 0; i < pl[
"ps"].
size(); i++) {
293 if (pl[
"ps"][i].is_int()) {
294 i64 psInt = pl[
"ps"][i] | -1;
296 if (psInt < -1) psInt = -1;
297 if (psInt > 250) psInt = 250;
307 for (
size_t i = 0; i < pl[
"dur"].
size(); i++) {
308 if (pl[
"dur"][i].is_int()) {
309 i64 durInt = pl[
"dur"][i] | 0;
310 if (durInt < 0) durInt = 0;
311 if (durInt > 65535) durInt = 65535;
320 for (
size_t i = 0; i < pl[
"transition"].
size(); i++) {
321 if (pl[
"transition"][i].is_int()) {
322 i64 transInt = pl[
"transition"][i] | 0;
323 if (transInt < 0) transInt = 0;
324 if (transInt > 65535) transInt = 65535;
332 i64 repeatInt = pl[
"repeat"] | 0;
333 if (repeatInt < 0) repeatInt = 0;
334 if (repeatInt > 65535) repeatInt = 65535;
341 i64 endInt = pl[
"end"] | -1;
342 if (endInt < -1) endInt = -1;
343 if (endInt > 250) endInt = 250;
354 FL_WARN(
"WLED: 'playlist' field has invalid type (expected object)");
361 for (
size_t i = 0; i < wledState[
"seg"].
size(); i++) {
362 const fl::json& segJson = wledState[
"seg"][i];
364 FL_WARN(
"WLED: segment at index " << i <<
" is not an object");
371 i64 idInt = segJson[
"id"] | 0;
372 if (idInt < 0) idInt = 0;
373 if (idInt > 255) idInt = 255;
374 segId =
static_cast<u8>(idInt);
377 segId =
static_cast<u8>(i);
382 for (
size_t j = 0; j <
mSegments.size(); j++) {
400 FL_WARN(
"WLED: 'seg' field has invalid type (expected array)");
427 state.set(
"udpn", udpn);
440 segJson.
set(
"id",
static_cast<i64>(seg.mId));
441 segJson.
set(
"start",
static_cast<i64>(seg.mStart));
442 segJson.
set(
"stop",
static_cast<i64>(seg.mStop));
443 segJson.
set(
"len",
static_cast<i64>(seg.mLen));
444 segJson.
set(
"grp",
static_cast<i64>(seg.mGrp));
445 segJson.
set(
"spc",
static_cast<i64>(seg.mSpc));
446 segJson.
set(
"of",
static_cast<i64>(seg.mOf));
447 segJson.
set(
"on", seg.mOn);
448 segJson.
set(
"bri",
static_cast<i64>(seg.mBri));
449 segJson.
set(
"cct",
static_cast<i64>(seg.mCct));
452 segJson.
set(
"fx",
static_cast<i64>(seg.mFx));
453 segJson.
set(
"sx",
static_cast<i64>(seg.mSx));
454 segJson.
set(
"ix",
static_cast<i64>(seg.mIx));
455 segJson.
set(
"pal",
static_cast<i64>(seg.mPal));
456 segJson.
set(
"c1",
static_cast<i64>(seg.mC1));
457 segJson.
set(
"c2",
static_cast<i64>(seg.mC2));
458 segJson.
set(
"c3",
static_cast<i64>(seg.mC3));
461 segJson.
set(
"sel", seg.mSel);
462 segJson.
set(
"rev", seg.mRev);
463 segJson.
set(
"mi", seg.mMi);
464 segJson.
set(
"o1", seg.mO1);
465 segJson.
set(
"o2", seg.mO2);
466 segJson.
set(
"o3", seg.mO3);
467 segJson.
set(
"si",
static_cast<i64>(seg.mSi));
468 segJson.
set(
"m12",
static_cast<i64>(seg.mM12));
469 segJson.
set(
"rpt", seg.mRpt);
471 if (!seg.mName.empty()) {
472 segJson.
set(
"n", seg.mName);
476 if (!seg.mColors.empty()) {
478 for (
const auto& color : seg.mColors) {
479 if (color.size() >= 3) {
481 for (
size_t i = 0; i < color.size(); i++) {
487 segJson.
set(
"col", colors);
491 if (!seg.mIndividualLeds.empty()) {
493 for (
const auto& led : seg.mIndividualLeds) {
494 if (led.size() >= 3) {
504 state.set(
"seg", segments);
519 playlist.
set(
"ps",
ps);
528 playlist.
set(
"dur", dur);
537 playlist.
set(
"transition", trans);
Remote(RequestSource source, ResponseSink sink)
Construct with I/O callbacks.
fl::json getPlaylistConfig() const
Get playlist configuration.
fl::vector< u16 > mPlaylistDurations
void setState(const fl::json &wledState)
Set WLED state from JSON object.
fl::vector< u16 > mPlaylistTransitions
void stubResponseSink(const fl::json &response)
Stub response sink callback.
fl::optional< fl::json > stubRequestSource()
Stub request source callback.
u8 mNightlightTargetBrightness
fl::vector< i16 > mPlaylistPresets
WLED() FL_NOEXCEPT
Construct WLED with default stub I/O callbacks.
fl::vector< WLEDSegment > mSegments
fl::json getState() const
Get current WLED state as JSON object.
const WLEDSegment * findSegmentById(u8 id) const
Find segment by ID.
bool hasPlaylistConfig() const
Check if playlist is active.
const char * c_str() const FL_NOEXCEPT
void push_back(const json &value) FL_NOEXCEPT
bool is_array() const FL_NOEXCEPT
bool is_int() const FL_NOEXCEPT
bool has_value() const FL_NOEXCEPT
bool is_object() const FL_NOEXCEPT
size_t size() const FL_NOEXCEPT
bool is_bool() const FL_NOEXCEPT
bool contains(size_t idx) const FL_NOEXCEPT
void set(const fl::string &key, const json &value) FL_NOEXCEPT
static json object() FL_NOEXCEPT
static json array() FL_NOEXCEPT
fl::UISlider transition("Transition", 0.0f, 0.0f, 1.0f, 0.01f)
Centralized logging categories for FastLED hardware interfaces and subsystems.
void parseSegmentFields(const fl::json &segJson, WLEDSegment &seg)
Parse all fields from a segment JSON object into a WLEDSegment.
fl::string rgbToHex(u8 r, u8 g, u8 b)
Convert RGB components to hex string.
constexpr nullopt_t nullopt
Base definition for an LED controller.
WLED segment configuration.