14 [
this](
const fl::json& response) { stubResponseSink(response); }
18 FL_ERROR(
"WLED::stubRequestSource: Not implemented - provide a real RequestSource callback");
24 FL_ERROR(
"WLED::stubResponseSink: Not implemented - provide a real ResponseSink callback");
30 if (!wledState.has_value()) {
31 FL_WARN(
"WLED: setState called with invalid JSON");
36 if (wledState.contains(
"on") && wledState[
"on"].is_bool()) {
37 bool newOn = wledState[
"on"] |
mWledOn;
45 if (wledState.contains(
"bri")) {
46 if (wledState[
"bri"].is_int()) {
50 FL_WARN(
"WLED: brightness " << briInt <<
" out of range, clamping to 0");
52 }
else if (briInt > 255) {
53 FL_WARN(
"WLED: brightness " << briInt <<
" out of range, clamping to 255");
56 u8 newBri =
static_cast<u8>(briInt);
62 FL_WARN(
"WLED: 'bri' field has invalid type (expected int)");
67 if (wledState.contains(
"transition")) {
68 if (wledState[
"transition"].is_int()) {
72 FL_WARN(
"WLED: transition " << transInt <<
" out of range, clamping to 0");
74 }
else if (transInt > 65535) {
75 FL_WARN(
"WLED: transition " << transInt <<
" out of range, clamping to 65535");
78 u16 newTransition =
static_cast<u16
>(transInt);
84 FL_WARN(
"WLED: 'transition' field has invalid type (expected int)");
89 if (wledState.contains(
"ps")) {
90 if (wledState[
"ps"].is_int()) {
94 FL_WARN(
"WLED: preset " << psInt <<
" out of range, clamping to -1");
96 }
else if (psInt > 250) {
97 FL_WARN(
"WLED: preset " << psInt <<
" out of range, clamping to 250");
100 i16 newPreset =
static_cast<i16
>(psInt);
106 FL_WARN(
"WLED: 'ps' field has invalid type (expected int)");
111 if (wledState.contains(
"pl")) {
112 if (wledState[
"pl"].is_int()) {
116 FL_WARN(
"WLED: playlist " << plInt <<
" out of range, clamping to -1");
118 }
else if (plInt > 250) {
119 FL_WARN(
"WLED: playlist " << plInt <<
" out of range, clamping to 250");
122 i16 newPlaylist =
static_cast<i16
>(plInt);
128 FL_WARN(
"WLED: 'pl' field has invalid type (expected int)");
133 if (wledState.contains(
"lor")) {
134 if (wledState[
"lor"].is_int()) {
138 FL_WARN(
"WLED: live override " << lorInt <<
" out of range, clamping to 0");
140 }
else if (lorInt > 2) {
141 FL_WARN(
"WLED: live override " << lorInt <<
" out of range, clamping to 2");
144 u8 newLiveOverride =
static_cast<u8>(lorInt);
150 FL_WARN(
"WLED: 'lor' field has invalid type (expected int)");
155 if (wledState.contains(
"mainseg")) {
156 if (wledState[
"mainseg"].is_int()) {
159 if (mainsegInt < 0) {
160 FL_WARN(
"WLED: main segment " << mainsegInt <<
" out of range, clamping to 0");
162 }
else if (mainsegInt > 255) {
163 FL_WARN(
"WLED: main segment " << mainsegInt <<
" out of range, clamping to 255");
166 u8 newMainSegment =
static_cast<u8>(mainsegInt);
172 FL_WARN(
"WLED: 'mainseg' field has invalid type (expected int)");
177 if (wledState.contains(
"nl")) {
178 if (wledState[
"nl"].is_object()) {
179 const fl::json& nl = wledState[
"nl"];
192 if (nl[
"dur"].is_int()) {
196 FL_WARN(
"WLED: nl.dur " << durInt <<
" out of range, clamping to 1");
198 }
else if (durInt > 255) {
199 FL_WARN(
"WLED: nl.dur " << durInt <<
" out of range, clamping to 255");
202 u8 newDur =
static_cast<u8>(durInt);
208 FL_WARN(
"WLED: 'nl.dur' field has invalid type (expected int)");
214 if (nl[
"mode"].is_int()) {
218 FL_WARN(
"WLED: nl.mode " << modeInt <<
" out of range, clamping to 0");
220 }
else if (modeInt > 3) {
221 FL_WARN(
"WLED: nl.mode " << modeInt <<
" out of range, clamping to 3");
224 u8 newMode =
static_cast<u8>(modeInt);
230 FL_WARN(
"WLED: 'nl.mode' field has invalid type (expected int)");
236 if (nl[
"tbri"].is_int()) {
240 FL_WARN(
"WLED: nl.tbri " << tbriInt <<
" out of range, clamping to 0");
242 }
else if (tbriInt > 255) {
243 FL_WARN(
"WLED: nl.tbri " << tbriInt <<
" out of range, clamping to 255");
246 u8 newTbri =
static_cast<u8>(tbriInt);
252 FL_WARN(
"WLED: 'nl.tbri' field has invalid type (expected int)");
256 FL_WARN(
"WLED: 'nl' field has invalid type (expected object)");
261 if (wledState.contains(
"udpn")) {
262 if (wledState[
"udpn"].is_object()) {
263 const fl::json& udpn = wledState[
"udpn"];
267 bool newSend = udpn[
"send"] |
mUdpSend;
283 FL_WARN(
"WLED: 'udpn' field has invalid type (expected object)");
288 if (wledState.contains(
"playlist")) {
289 if (wledState[
"playlist"].is_object()) {
290 const fl::json& pl = wledState[
"playlist"];
295 for (
size_t i = 0; i < pl[
"ps"].
size(); i++) {
296 if (pl[
"ps"][i].is_int()) {
297 i64 psInt = pl[
"ps"][i] | -1;
299 if (psInt < -1) psInt = -1;
300 if (psInt > 250) psInt = 250;
310 for (
size_t i = 0; i < pl[
"dur"].
size(); i++) {
311 if (pl[
"dur"][i].is_int()) {
312 i64 durInt = pl[
"dur"][i] | 0;
313 if (durInt < 0) durInt = 0;
314 if (durInt > 65535) durInt = 65535;
323 for (
size_t i = 0; i < pl[
"transition"].
size(); i++) {
324 if (pl[
"transition"][i].is_int()) {
325 i64 transInt = pl[
"transition"][i] | 0;
326 if (transInt < 0) transInt = 0;
327 if (transInt > 65535) transInt = 65535;
335 i64 repeatInt = pl[
"repeat"] | 0;
336 if (repeatInt < 0) repeatInt = 0;
337 if (repeatInt > 65535) repeatInt = 65535;
344 i64 endInt = pl[
"end"] | -1;
345 if (endInt < -1) endInt = -1;
346 if (endInt > 250) endInt = 250;
357 FL_WARN(
"WLED: 'playlist' field has invalid type (expected object)");
362 if (wledState.contains(
"seg")) {
364 for (
size_t i = 0; i < wledState[
"seg"].size(); i++) {
365 const fl::json& segJson = wledState[
"seg"][i];
367 FL_WARN(
"WLED: segment at index " << i <<
" is not an object");
374 i64 idInt = segJson[
"id"] | 0;
375 if (idInt < 0) idInt = 0;
376 if (idInt > 255) idInt = 255;
377 segId =
static_cast<u8>(idInt);
380 segId =
static_cast<u8>(i);
385 for (
size_t j = 0; j <
mSegments.size(); j++) {
403 FL_WARN(
"WLED: 'seg' field has invalid type (expected array)");
430 state.set(
"udpn", udpn);
443 segJson.
set(
"id",
static_cast<i64>(seg.mId));
444 segJson.
set(
"start",
static_cast<i64>(seg.mStart));
445 segJson.
set(
"stop",
static_cast<i64>(seg.mStop));
446 segJson.
set(
"len",
static_cast<i64>(seg.mLen));
447 segJson.
set(
"grp",
static_cast<i64>(seg.mGrp));
448 segJson.
set(
"spc",
static_cast<i64>(seg.mSpc));
449 segJson.
set(
"of",
static_cast<i64>(seg.mOf));
450 segJson.
set(
"on", seg.mOn);
451 segJson.
set(
"bri",
static_cast<i64>(seg.mBri));
452 segJson.
set(
"cct",
static_cast<i64>(seg.mCct));
455 segJson.
set(
"fx",
static_cast<i64>(seg.mFx));
456 segJson.
set(
"sx",
static_cast<i64>(seg.mSx));
457 segJson.
set(
"ix",
static_cast<i64>(seg.mIx));
458 segJson.
set(
"pal",
static_cast<i64>(seg.mPal));
459 segJson.
set(
"c1",
static_cast<i64>(seg.mC1));
460 segJson.
set(
"c2",
static_cast<i64>(seg.mC2));
461 segJson.
set(
"c3",
static_cast<i64>(seg.mC3));
464 segJson.
set(
"sel", seg.mSel);
465 segJson.
set(
"rev", seg.mRev);
466 segJson.
set(
"mi", seg.mMi);
467 segJson.
set(
"o1", seg.mO1);
468 segJson.
set(
"o2", seg.mO2);
469 segJson.
set(
"o3", seg.mO3);
470 segJson.
set(
"si",
static_cast<i64>(seg.mSi));
471 segJson.
set(
"m12",
static_cast<i64>(seg.mM12));
472 segJson.
set(
"rpt", seg.mRpt);
474 if (!seg.mName.empty()) {
475 segJson.
set(
"n", seg.mName);
479 if (!seg.mColors.empty()) {
481 for (
const auto&
color : seg.mColors) {
482 if (
color.size() >= 3) {
484 for (
size_t i = 0; i <
color.size(); i++) {
490 segJson.
set(
"col", colors);
494 if (!seg.mIndividualLeds.empty()) {
496 for (
const auto& led : seg.mIndividualLeds) {
497 if (led.size() >= 3) {
507 state.set(
"seg", segments);
522 playlist.
set(
"ps",
ps);
531 playlist.
set(
"dur", dur);
540 playlist.
set(
"transition", trans);
Remote(RequestSource source, ResponseSink sink) FL_NO_EXCEPT
Construct with I/O callbacks.
fl::vector< u16 > mPlaylistDurations
fl::json getState() const FL_NO_EXCEPT
Get current WLED state as JSON object.
fl::vector< u16 > mPlaylistTransitions
const WLEDSegment * findSegmentById(u8 id) const FL_NO_EXCEPT
Find segment by ID.
bool hasPlaylistConfig() const FL_NO_EXCEPT
Check if playlist is active.
fl::optional< fl::json > stubRequestSource() FL_NO_EXCEPT
Stub request source callback.
u8 mNightlightTargetBrightness
fl::json getPlaylistConfig() const FL_NO_EXCEPT
Get playlist configuration.
void setState(const fl::json &wledState) FL_NO_EXCEPT
Set WLED state from JSON object.
WLED() FL_NO_EXCEPT
Construct WLED with default stub I/O callbacks.
fl::vector< i16 > mPlaylistPresets
fl::vector< WLEDSegment > mSegments
void stubResponseSink(const fl::json &response) FL_NO_EXCEPT
Stub response sink callback.
const char * c_str() const FL_NO_EXCEPT
bool is_object() const FL_NO_EXCEPT
size_t size() const FL_NO_EXCEPT
void set(const fl::string &key, const json &value) FL_NO_EXCEPT
bool is_int() const FL_NO_EXCEPT
bool is_array() const FL_NO_EXCEPT
void push_back(const json &value) FL_NO_EXCEPT
bool contains(size_t idx) const FL_NO_EXCEPT
bool is_bool() const FL_NO_EXCEPT
static json object() FL_NO_EXCEPT
static json array() FL_NO_EXCEPT
fl::UISlider transition("Transition", 0.0f, 0.0f, 1.0f, 0.01f)
Centralized logging categories for FastLED hardware interfaces and subsystems.
fl::string rgbToHex(u8 r, u8 g, u8 b) FL_NO_EXCEPT
Convert RGB components to hex string.
void parseSegmentFields(const fl::json &segJson, WLEDSegment &seg) FL_NO_EXCEPT
Parse all fields from a segment JSON object into a WLEDSegment.
u8 u8 fract8 blur_amount FL_NO_EXCEPT
constexpr nullopt_t nullopt
Base definition for an LED controller.
WLED segment configuration.