FastLED 3.10.8
Loading...
Searching...
No Matches

◆ setState()

void fl::WLED::setState ( const fl::json & wledState)

Set WLED state from JSON object.

Parameters
wledStateJSON object containing "on" (bool) and/or "bri" (0-255) fields

Extracts WLED control fields and updates internal state:

  • "on": boolean on/off state (optional, keeps existing value if missing)
  • "bri": brightness 0-255 (optional, keeps existing value if missing)

Example: fl::json state = fl::json::parse(R"({"on":true,"bri":128})"); remote.setState(state);

Definition at line 29 of file wled.cpp.hpp.

29 {
30 if (!wledState.has_value()) {
31 FL_WARN("WLED: setState called with invalid JSON");
32 return;
33 }
34
35 // Extract "on" field (bool) - optional, keep existing if missing
36 if (wledState.contains("on") && wledState["on"].is_bool()) {
37 bool newOn = wledState["on"] | mWledOn;
38 if (newOn != mWledOn) {
39 mWledOn = newOn;
40 FL_DBG("WLED: on=" << ((mWledOn ? "true" : "false")));
41 }
42 }
43
44 // Extract "bri" field (0-255) - optional, keep existing if missing
45 if (wledState.contains("bri")) {
46 if (wledState["bri"].is_int()) {
47 i64 briInt = wledState["bri"] | static_cast<i64>(mWledBri);
48 // Clamp to valid range 0-255
49 if (briInt < 0) {
50 FL_WARN("WLED: brightness " << briInt << " out of range, clamping to 0");
51 briInt = 0;
52 } else if (briInt > 255) {
53 FL_WARN("WLED: brightness " << briInt << " out of range, clamping to 255");
54 briInt = 255;
55 }
56 u8 newBri = static_cast<u8>(briInt);
57 if (newBri != mWledBri) {
58 mWledBri = newBri;
59 FL_DBG("WLED: bri=" << (static_cast<int>(mWledBri)));
60 }
61 } else {
62 FL_WARN("WLED: 'bri' field has invalid type (expected int)");
63 }
64 }
65
66 // Extract "transition" field (0-65535) - optional, keep existing if missing
67 if (wledState.contains("transition")) {
68 if (wledState["transition"].is_int()) {
69 i64 transInt = wledState["transition"] | static_cast<i64>(mTransition);
70 // Clamp to valid range 0-65535
71 if (transInt < 0) {
72 FL_WARN("WLED: transition " << transInt << " out of range, clamping to 0");
73 transInt = 0;
74 } else if (transInt > 65535) {
75 FL_WARN("WLED: transition " << transInt << " out of range, clamping to 65535");
76 transInt = 65535;
77 }
78 u16 newTransition = static_cast<u16>(transInt);
79 if (newTransition != mTransition) {
80 mTransition = newTransition;
81 FL_DBG("WLED: transition=" << mTransition);
82 }
83 } else {
84 FL_WARN("WLED: 'transition' field has invalid type (expected int)");
85 }
86 }
87
88 // Extract "ps" field (preset ID: -1 to 250) - optional, keep existing if missing
89 if (wledState.contains("ps")) {
90 if (wledState["ps"].is_int()) {
91 i64 psInt = wledState["ps"] | static_cast<i64>(mPreset);
92 // Clamp to valid range -1 to 250
93 if (psInt < -1) {
94 FL_WARN("WLED: preset " << psInt << " out of range, clamping to -1");
95 psInt = -1;
96 } else if (psInt > 250) {
97 FL_WARN("WLED: preset " << psInt << " out of range, clamping to 250");
98 psInt = 250;
99 }
100 i16 newPreset = static_cast<i16>(psInt);
101 if (newPreset != mPreset) {
102 mPreset = newPreset;
103 FL_DBG("WLED: ps=" << mPreset);
104 }
105 } else {
106 FL_WARN("WLED: 'ps' field has invalid type (expected int)");
107 }
108 }
109
110 // Extract "pl" field (playlist ID: -1 to 250) - optional, keep existing if missing
111 if (wledState.contains("pl")) {
112 if (wledState["pl"].is_int()) {
113 i64 plInt = wledState["pl"] | static_cast<i64>(mPlaylist);
114 // Clamp to valid range -1 to 250
115 if (plInt < -1) {
116 FL_WARN("WLED: playlist " << plInt << " out of range, clamping to -1");
117 plInt = -1;
118 } else if (plInt > 250) {
119 FL_WARN("WLED: playlist " << plInt << " out of range, clamping to 250");
120 plInt = 250;
121 }
122 i16 newPlaylist = static_cast<i16>(plInt);
123 if (newPlaylist != mPlaylist) {
124 mPlaylist = newPlaylist;
125 FL_DBG("WLED: pl=" << mPlaylist);
126 }
127 } else {
128 FL_WARN("WLED: 'pl' field has invalid type (expected int)");
129 }
130 }
131
132 // Extract "lor" field (live override: 0-2) - optional, keep existing if missing
133 if (wledState.contains("lor")) {
134 if (wledState["lor"].is_int()) {
135 i64 lorInt = wledState["lor"] | static_cast<i64>(mLiveOverride);
136 // Clamp to valid range 0-2
137 if (lorInt < 0) {
138 FL_WARN("WLED: live override " << lorInt << " out of range, clamping to 0");
139 lorInt = 0;
140 } else if (lorInt > 2) {
141 FL_WARN("WLED: live override " << lorInt << " out of range, clamping to 2");
142 lorInt = 2;
143 }
144 u8 newLiveOverride = static_cast<u8>(lorInt);
145 if (newLiveOverride != mLiveOverride) {
146 mLiveOverride = newLiveOverride;
147 FL_DBG("WLED: lor=" << (static_cast<int>(mLiveOverride)));
148 }
149 } else {
150 FL_WARN("WLED: 'lor' field has invalid type (expected int)");
151 }
152 }
153
154 // Extract "mainseg" field (main segment: 0-255) - optional, keep existing if missing
155 if (wledState.contains("mainseg")) {
156 if (wledState["mainseg"].is_int()) {
157 i64 mainsegInt = wledState["mainseg"] | static_cast<i64>(mMainSegment);
158 // Clamp to valid range 0-255
159 if (mainsegInt < 0) {
160 FL_WARN("WLED: main segment " << mainsegInt << " out of range, clamping to 0");
161 mainsegInt = 0;
162 } else if (mainsegInt > 255) {
163 FL_WARN("WLED: main segment " << mainsegInt << " out of range, clamping to 255");
164 mainsegInt = 255;
165 }
166 u8 newMainSegment = static_cast<u8>(mainsegInt);
167 if (newMainSegment != mMainSegment) {
168 mMainSegment = newMainSegment;
169 FL_DBG("WLED: mainseg=" << (static_cast<int>(mMainSegment)));
170 }
171 } else {
172 FL_WARN("WLED: 'mainseg' field has invalid type (expected int)");
173 }
174 }
175
176 // Extract "nl" field (nightlight object) - optional
177 if (wledState.contains("nl")) {
178 if (wledState["nl"].is_object()) {
179 const fl::json& nl = wledState["nl"];
180
181 // Extract "on" field (bool)
182 if (nl.contains("on") && nl["on"].is_bool()) {
183 bool newNlOn = nl["on"] | mNightlightOn;
184 if (newNlOn != mNightlightOn) {
185 mNightlightOn = newNlOn;
186 FL_DBG("WLED: nl.on=" << ((mNightlightOn ? "true" : "false")));
187 }
188 }
189
190 // Extract "dur" field (1-255 minutes)
191 if (nl.contains("dur")) {
192 if (nl["dur"].is_int()) {
193 i64 durInt = nl["dur"] | static_cast<i64>(mNightlightDuration);
194 // Clamp to valid range 1-255
195 if (durInt < 1) {
196 FL_WARN("WLED: nl.dur " << durInt << " out of range, clamping to 1");
197 durInt = 1;
198 } else if (durInt > 255) {
199 FL_WARN("WLED: nl.dur " << durInt << " out of range, clamping to 255");
200 durInt = 255;
201 }
202 u8 newDur = static_cast<u8>(durInt);
203 if (newDur != mNightlightDuration) {
204 mNightlightDuration = newDur;
205 FL_DBG("WLED: nl.dur=" << (static_cast<int>(mNightlightDuration)));
206 }
207 } else {
208 FL_WARN("WLED: 'nl.dur' field has invalid type (expected int)");
209 }
210 }
211
212 // Extract "mode" field (0-3)
213 if (nl.contains("mode")) {
214 if (nl["mode"].is_int()) {
215 i64 modeInt = nl["mode"] | static_cast<i64>(mNightlightMode);
216 // Clamp to valid range 0-3
217 if (modeInt < 0) {
218 FL_WARN("WLED: nl.mode " << modeInt << " out of range, clamping to 0");
219 modeInt = 0;
220 } else if (modeInt > 3) {
221 FL_WARN("WLED: nl.mode " << modeInt << " out of range, clamping to 3");
222 modeInt = 3;
223 }
224 u8 newMode = static_cast<u8>(modeInt);
225 if (newMode != mNightlightMode) {
226 mNightlightMode = newMode;
227 FL_DBG("WLED: nl.mode=" << (static_cast<int>(mNightlightMode)));
228 }
229 } else {
230 FL_WARN("WLED: 'nl.mode' field has invalid type (expected int)");
231 }
232 }
233
234 // Extract "tbri" field (0-255 target brightness)
235 if (nl.contains("tbri")) {
236 if (nl["tbri"].is_int()) {
237 i64 tbriInt = nl["tbri"] | static_cast<i64>(mNightlightTargetBrightness);
238 // Clamp to valid range 0-255
239 if (tbriInt < 0) {
240 FL_WARN("WLED: nl.tbri " << tbriInt << " out of range, clamping to 0");
241 tbriInt = 0;
242 } else if (tbriInt > 255) {
243 FL_WARN("WLED: nl.tbri " << tbriInt << " out of range, clamping to 255");
244 tbriInt = 255;
245 }
246 u8 newTbri = static_cast<u8>(tbriInt);
247 if (newTbri != mNightlightTargetBrightness) {
249 FL_DBG("WLED: nl.tbri=" << (static_cast<int>(mNightlightTargetBrightness)));
250 }
251 } else {
252 FL_WARN("WLED: 'nl.tbri' field has invalid type (expected int)");
253 }
254 }
255 } else {
256 FL_WARN("WLED: 'nl' field has invalid type (expected object)");
257 }
258 }
259
260 // Extract "udpn" field (UDP sync settings) - optional
261 if (wledState.contains("udpn")) {
262 if (wledState["udpn"].is_object()) {
263 const fl::json& udpn = wledState["udpn"];
264
265 // Extract "send" field (bool)
266 if (udpn.contains("send") && udpn["send"].is_bool()) {
267 bool newSend = udpn["send"] | mUdpSend;
268 if (newSend != mUdpSend) {
269 mUdpSend = newSend;
270 FL_DBG("WLED: udpn.send=" << ((mUdpSend ? "true" : "false")));
271 }
272 }
273
274 // Extract "recv" field (bool)
275 if (udpn.contains("recv") && udpn["recv"].is_bool()) {
276 bool newRecv = udpn["recv"] | mUdpReceive;
277 if (newRecv != mUdpReceive) {
278 mUdpReceive = newRecv;
279 FL_DBG("WLED: udpn.recv=" << ((mUdpReceive ? "true" : "false")));
280 }
281 }
282 } else {
283 FL_WARN("WLED: 'udpn' field has invalid type (expected object)");
284 }
285 }
286
287 // Extract "playlist" field (playlist configuration) - optional
288 if (wledState.contains("playlist")) {
289 if (wledState["playlist"].is_object()) {
290 const fl::json& pl = wledState["playlist"];
291
292 // Extract "ps" field (array of preset IDs)
293 if (pl.contains("ps") && pl["ps"].is_array()) {
294 mPlaylistPresets.clear();
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;
298 // Clamp to valid range -1 to 250
299 if (psInt < -1) psInt = -1;
300 if (psInt > 250) psInt = 250;
301 mPlaylistPresets.push_back(static_cast<i16>(psInt));
302 }
303 }
304 FL_DBG("WLED: playlist.ps count=" << mPlaylistPresets.size());
305 }
306
307 // Extract "dur" field (array of durations in seconds)
308 if (pl.contains("dur") && pl["dur"].is_array()) {
309 mPlaylistDurations.clear();
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;
315 mPlaylistDurations.push_back(static_cast<u16>(durInt));
316 }
317 }
318 }
319
320 // Extract "transition" field (array of transitions in ×100ms)
321 if (pl.contains("transition") && pl["transition"].is_array()) {
322 mPlaylistTransitions.clear();
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;
328 mPlaylistTransitions.push_back(static_cast<u16>(transInt));
329 }
330 }
331 }
332
333 // Extract "repeat" field
334 if (pl.contains("repeat") && pl["repeat"].is_int()) {
335 i64 repeatInt = pl["repeat"] | 0;
336 if (repeatInt < 0) repeatInt = 0;
337 if (repeatInt > 65535) repeatInt = 65535;
338 mPlaylistRepeat = static_cast<u16>(repeatInt);
339 FL_DBG("WLED: playlist.repeat=" << mPlaylistRepeat);
340 }
341
342 // Extract "end" field
343 if (pl.contains("end") && pl["end"].is_int()) {
344 i64 endInt = pl["end"] | -1;
345 if (endInt < -1) endInt = -1;
346 if (endInt > 250) endInt = 250;
347 mPlaylistEnd = static_cast<i16>(endInt);
348 FL_DBG("WLED: playlist.end=" << mPlaylistEnd);
349 }
350
351 // Extract "r" field (randomize)
352 if (pl.contains("r") && pl["r"].is_bool()) {
353 mPlaylistRandomize = pl["r"] | false;
354 FL_DBG("WLED: playlist.r=" << ((mPlaylistRandomize ? "true" : "false")));
355 }
356 } else {
357 FL_WARN("WLED: 'playlist' field has invalid type (expected object)");
358 }
359 }
360
361 // Extract "seg" field (segment array) - optional
362 if (wledState.contains("seg")) {
363 if (wledState["seg"].is_array()) {
364 for (size_t i = 0; i < wledState["seg"].size(); i++) {
365 const fl::json& segJson = wledState["seg"][i];
366 if (!segJson.is_object()) {
367 FL_WARN("WLED: segment at index " << i << " is not an object");
368 continue;
369 }
370
371 // Extract segment ID (required for updates)
372 u8 segId = 0;
373 if (segJson.contains("id") && segJson["id"].is_int()) {
374 i64 idInt = segJson["id"] | 0;
375 if (idInt < 0) idInt = 0;
376 if (idInt > 255) idInt = 255;
377 segId = static_cast<u8>(idInt);
378 } else {
379 // If no ID provided, use index
380 segId = static_cast<u8>(i);
381 }
382
383 // Find existing segment or create new one
384 WLEDSegment* seg = nullptr;
385 for (size_t j = 0; j < mSegments.size(); j++) {
386 if (mSegments[j].mId == segId) {
387 seg = &mSegments[j];
388 break;
389 }
390 }
391 if (!seg) {
392 // Create new segment
393 WLEDSegment newSeg;
394 newSeg.mId = segId;
395 mSegments.push_back(newSeg);
396 seg = &mSegments[mSegments.size() - 1];
397 }
398
399 // Parse segment fields using helper function
400 wled::parseSegmentFields(segJson, *seg);
401 }
402 } else {
403 FL_WARN("WLED: 'seg' field has invalid type (expected array)");
404 }
405 }
406}
fl::vector< u16 > mPlaylistDurations
Definition wled.h:448
bool mNightlightOn
Definition wled.h:441
fl::vector< u16 > mPlaylistTransitions
Definition wled.h:449
u8 mWledBri
Definition wled.h:433
i16 mPlaylistEnd
Definition wled.h:451
u8 mLiveOverride
Definition wled.h:437
u16 mTransition
Definition wled.h:434
u8 mNightlightTargetBrightness
Definition wled.h:444
u8 mNightlightDuration
Definition wled.h:442
bool mUdpSend
Definition wled.h:455
bool mUdpReceive
Definition wled.h:456
i16 mPreset
Definition wled.h:435
i16 mPlaylist
Definition wled.h:436
fl::vector< i16 > mPlaylistPresets
Definition wled.h:447
bool mWledOn
Definition wled.h:432
bool mPlaylistRandomize
Definition wled.h:452
u16 mPlaylistRepeat
Definition wled.h:450
fl::vector< WLEDSegment > mSegments
Definition wled.h:459
u8 mMainSegment
Definition wled.h:438
u8 mNightlightMode
Definition wled.h:443
bool is_object() const FL_NO_EXCEPT
Definition json.h:391
size_t size() const FL_NO_EXCEPT
Definition json.h:798
bool has_value() const FL_NO_EXCEPT
Definition json.h:819
bool contains(size_t idx) const FL_NO_EXCEPT
Definition json.h:790
#define FL_WARN(...)
Definition log.h:437
#define FL_DBG
Definition log.h:553
void parseSegmentFields(const fl::json &segJson, WLEDSegment &seg) FL_NO_EXCEPT
Parse all fields from a segment JSON object into a WLEDSegment.
unsigned char u8
Definition stdint.h:131
fl::i64 i64
Definition stdint.h:221

References fl::json::contains(), FL_DBG, fl::FL_NO_EXCEPT, FL_WARN, fl::json::is_array(), fl::json::is_bool(), fl::json::is_int(), fl::json::is_object(), fl::WLEDSegment::mId, mLiveOverride, mMainSegment, mNightlightDuration, mNightlightMode, mNightlightOn, mNightlightTargetBrightness, mPlaylist, mPlaylistDurations, mPlaylistEnd, mPlaylistPresets, mPlaylistRandomize, mPlaylistRepeat, mPlaylistTransitions, mPreset, mSegments, mTransition, mUdpReceive, mUdpSend, mWledBri, mWledOn, fl::wled::parseSegmentFields(), and fl::json::size().

+ Here is the call graph for this function: