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

◆ parseSegmentFields()

void fl::wled::parseSegmentFields ( const fl::json & segJson,
WLEDSegment & seg )

Parse all fields from a segment JSON object into a WLEDSegment.

Parameters
segJsonJSON object containing segment fields
segOutput: WLEDSegment to populate with parsed data

Parses all WLED segment properties including:

  • Position (start, stop, len)
  • State (on, brightness)
  • Colors (col array, individual LEDs)
  • Effects (fx, sx, ix, pal, c1, c2, c3)
  • Layout (grp, spc, of)
  • Flags (sel, rev, mi, o1, o2, o3, rpt)
  • Other (cct, si, m12, name)

Definition at line 68 of file json_helpers.cpp.hpp.

68 {
69 // Extract basic properties
70 if (segJson.contains("start") && segJson["start"].is_int()) {
71 i64 startInt = segJson["start"] | 0;
72 if (startInt < 0) startInt = 0;
73 if (startInt > 65535) startInt = 65535;
74 seg.mStart = static_cast<u16>(startInt);
75 }
76
77 if (segJson.contains("stop") && segJson["stop"].is_int()) {
78 i64 stopInt = segJson["stop"] | 0;
79 if (stopInt < 0) stopInt = 0;
80 if (stopInt > 65535) stopInt = 65535;
81 seg.mStop = static_cast<u16>(stopInt);
82 }
83
84 if (segJson.contains("len") && segJson["len"].is_int()) {
85 i64 lenInt = segJson["len"] | 0;
86 if (lenInt < 0) lenInt = 0;
87 if (lenInt > 65535) lenInt = 65535;
88 seg.mLen = static_cast<u16>(lenInt);
89 }
90
91 if (segJson.contains("grp") && segJson["grp"].is_int()) {
92 i64 grpInt = segJson["grp"] | 1;
93 if (grpInt < 1) grpInt = 1;
94 if (grpInt > 255) grpInt = 255;
95 seg.mGrp = static_cast<u8>(grpInt);
96 }
97
98 if (segJson.contains("spc") && segJson["spc"].is_int()) {
99 i64 spcInt = segJson["spc"] | 0;
100 if (spcInt < 0) spcInt = 0;
101 if (spcInt > 255) spcInt = 255;
102 seg.mSpc = static_cast<u8>(spcInt);
103 }
104
105 if (segJson.contains("of") && segJson["of"].is_int()) {
106 i64 ofInt = segJson["of"] | 0;
107 if (ofInt < 0) ofInt = 0;
108 if (ofInt > 65535) ofInt = 65535;
109 seg.mOf = static_cast<u16>(ofInt);
110 }
111
112 if (segJson.contains("on") && segJson["on"].is_bool()) {
113 seg.mOn = segJson["on"] | true;
114 }
115
116 if (segJson.contains("bri") && segJson["bri"].is_int()) {
117 i64 briInt = segJson["bri"] | 255;
118 if (briInt < 0) briInt = 0;
119 if (briInt > 255) briInt = 255;
120 seg.mBri = static_cast<u8>(briInt);
121 }
122
123 if (segJson.contains("cct") && segJson["cct"].is_int()) {
124 i64 cctInt = segJson["cct"] | 0;
125 if (cctInt < 0) cctInt = 0;
126 if (cctInt > 65535) cctInt = 65535;
127 seg.mCct = static_cast<u16>(cctInt);
128 }
129
130 // Effect properties
131 if (segJson.contains("fx") && segJson["fx"].is_int()) {
132 i64 fxInt = segJson["fx"] | 0;
133 if (fxInt < 0) fxInt = 0;
134 if (fxInt > 255) fxInt = 255;
135 seg.mFx = static_cast<u8>(fxInt);
136 }
137
138 if (segJson.contains("sx") && segJson["sx"].is_int()) {
139 i64 sxInt = segJson["sx"] | 128;
140 if (sxInt < 0) sxInt = 0;
141 if (sxInt > 255) sxInt = 255;
142 seg.mSx = static_cast<u8>(sxInt);
143 }
144
145 if (segJson.contains("ix") && segJson["ix"].is_int()) {
146 i64 ixInt = segJson["ix"] | 128;
147 if (ixInt < 0) ixInt = 0;
148 if (ixInt > 255) ixInt = 255;
149 seg.mIx = static_cast<u8>(ixInt);
150 }
151
152 if (segJson.contains("pal") && segJson["pal"].is_int()) {
153 i64 palInt = segJson["pal"] | 0;
154 if (palInt < 0) palInt = 0;
155 if (palInt > 255) palInt = 255;
156 seg.mPal = static_cast<u8>(palInt);
157 }
158
159 if (segJson.contains("c1") && segJson["c1"].is_int()) {
160 i64 c1Int = segJson["c1"] | 128;
161 if (c1Int < 0) c1Int = 0;
162 if (c1Int > 255) c1Int = 255;
163 seg.mC1 = static_cast<u8>(c1Int);
164 }
165
166 if (segJson.contains("c2") && segJson["c2"].is_int()) {
167 i64 c2Int = segJson["c2"] | 128;
168 if (c2Int < 0) c2Int = 0;
169 if (c2Int > 255) c2Int = 255;
170 seg.mC2 = static_cast<u8>(c2Int);
171 }
172
173 if (segJson.contains("c3") && segJson["c3"].is_int()) {
174 i64 c3Int = segJson["c3"] | 16;
175 if (c3Int < 0) c3Int = 0;
176 if (c3Int > 255) c3Int = 255;
177 seg.mC3 = static_cast<u8>(c3Int);
178 }
179
180 // Boolean flags
181 if (segJson.contains("sel") && segJson["sel"].is_bool()) {
182 seg.mSel = segJson["sel"] | false;
183 }
184
185 if (segJson.contains("rev") && segJson["rev"].is_bool()) {
186 seg.mRev = segJson["rev"] | false;
187 }
188
189 if (segJson.contains("mi") && segJson["mi"].is_bool()) {
190 seg.mMi = segJson["mi"] | false;
191 }
192
193 if (segJson.contains("o1") && segJson["o1"].is_bool()) {
194 seg.mO1 = segJson["o1"] | false;
195 }
196
197 if (segJson.contains("o2") && segJson["o2"].is_bool()) {
198 seg.mO2 = segJson["o2"] | false;
199 }
200
201 if (segJson.contains("o3") && segJson["o3"].is_bool()) {
202 seg.mO3 = segJson["o3"] | false;
203 }
204
205 if (segJson.contains("si") && segJson["si"].is_int()) {
206 i64 siInt = segJson["si"] | 0;
207 if (siInt < 0) siInt = 0;
208 if (siInt > 3) siInt = 3;
209 seg.mSi = static_cast<u8>(siInt);
210 }
211
212 if (segJson.contains("m12") && segJson["m12"].is_int()) {
213 i64 m12Int = segJson["m12"] | 0;
214 if (m12Int < 0) m12Int = 0;
215 if (m12Int > 3) m12Int = 3;
216 seg.mM12 = static_cast<u8>(m12Int);
217 }
218
219 if (segJson.contains("rpt") && segJson["rpt"].is_bool()) {
220 seg.mRpt = segJson["rpt"] | false;
221 }
222
223 if (segJson.contains("n") && segJson["n"].is_string()) {
224 seg.mName = segJson["n"] | fl::string("");
225 }
226
227 // Parse "col" field (color slots)
228 if (segJson.contains("col") && segJson["col"].is_array()) {
229 seg.mColors.clear();
230 for (size_t i = 0; i < segJson["col"].size(); i++) {
231 const fl::json& colJson = segJson["col"][i];
232
233 if (colJson.is_array()) {
234 // RGB(W) array format: [R,G,B] or [R,G,B,W]
235 fl::vector<u8> color;
236 for (size_t j = 0; j < colJson.size() && j < 4; j++) {
237 if (colJson[j].is_int()) {
238 i64 val = colJson[j] | 0;
239 if (val < 0) val = 0;
240 if (val > 255) val = 255;
241 color.push_back(static_cast<u8>(val));
242 }
243 }
244 if (color.size() >= 3) {
245 seg.mColors.push_back(color);
246 }
247 } else if (colJson.is_string()) {
248 // Hex string format: "RRGGBB" or "#RRGGBB"
249 fl::string hexStr = colJson | fl::string("");
250 u8 r, g, b;
251 if (parseHexColor(hexStr, r, g, b)) {
252 fl::vector<u8> color;
253 color.push_back(r);
254 color.push_back(g);
255 color.push_back(b);
256 seg.mColors.push_back(color);
257 } else {
258 FL_WARN("WLED: invalid hex color string: " << hexStr);
259 }
260 }
261 }
262 }
263
264 // Parse "i" field (individual LED control)
265 if (segJson.contains("i") && segJson["i"].is_array()) {
267
268 size_t ledIndex = 0;
269 for (size_t i = 0; i < segJson["i"].size(); i++) {
270 const fl::json& ledJson = segJson["i"][i];
271
272 if (!ledJson.is_string()) {
273 continue;
274 }
275
276 fl::string ledStr = ledJson | fl::string("");
277
278 // Check for indexed or range format: "RRGGBB|index" or "RRGGBB|start-end"
279 size_t pipePos = ledStr.find('|');
280
281 fl::string hexStr;
282 size_t startIdx = ledIndex;
283 size_t endIdx = ledIndex;
284
285 if (pipePos != fl::string::npos) {
286 // Has index/range specifier
287 hexStr = ledStr.substr(0, pipePos);
288 fl::string indexStr = ledStr.substr(pipePos + 1);
289
290 // Check for range: "start-end"
291 size_t dashPos = indexStr.find('-');
292 if (dashPos != fl::string::npos) {
293 // Range format
294 fl::string startStr = indexStr.substr(0, dashPos);
295 fl::string endStr = indexStr.substr(dashPos + 1);
296
297 // Parse start and end indices
298 char* endptr;
299 long startVal = fl::strtol(startStr.c_str(), &endptr, 10);
300 if (endptr == startStr.c_str() || startVal < 0) {
301 FL_WARN("WLED: invalid range start index: " << startStr);
302 continue;
303 }
304
305 long endVal = fl::strtol(endStr.c_str(), &endptr, 10);
306 if (endptr == endStr.c_str() || endVal < 0) {
307 FL_WARN("WLED: invalid range end index: " << endStr);
308 continue;
309 }
310
311 startIdx = static_cast<size_t>(startVal);
312 endIdx = static_cast<size_t>(endVal);
313 } else {
314 // Single index format
315 char* endptr;
316 long idxVal = fl::strtol(indexStr.c_str(), &endptr, 10);
317 if (endptr == indexStr.c_str() || idxVal < 0) {
318 FL_WARN("WLED: invalid LED index: " << indexStr);
319 continue;
320 }
321 startIdx = endIdx = static_cast<size_t>(idxVal);
322 }
323 } else {
324 // Sequential format (no index specifier)
325 hexStr = ledStr;
326 ledIndex++;
327 }
328
329 // Parse hex color
330 u8 r, g, b;
331 if (!parseHexColor(hexStr, r, g, b)) {
332 FL_WARN("WLED: invalid hex color in individual LED: " << hexStr);
333 continue;
334 }
335
336 // Ensure array is large enough
337 size_t maxIdx = (endIdx > startIdx) ? endIdx : startIdx;
338 if (seg.mIndividualLeds.size() <= maxIdx) {
339 seg.mIndividualLeds.resize(maxIdx + 1);
340 }
341
342 // Set LEDs in range
343 for (size_t idx = startIdx; idx <= endIdx; idx++) {
344 seg.mIndividualLeds[idx].clear();
345 seg.mIndividualLeds[idx].push_back(r);
346 seg.mIndividualLeds[idx].push_back(g);
347 seg.mIndividualLeds[idx].push_back(b);
348 }
349 }
350 }
351}
fl::size find(const char &value) const FL_NO_EXCEPT
const char * c_str() const FL_NO_EXCEPT
size_t size() const FL_NO_EXCEPT
Definition json.h:798
bool is_array() const FL_NO_EXCEPT
Definition json.h:389
bool contains(size_t idx) const FL_NO_EXCEPT
Definition json.h:790
bool is_string() const FL_NO_EXCEPT
Definition json.h:388
string substr(fl::size start, fl::size length) const FL_NO_EXCEPT
static constexpr fl::size npos
Definition string.h:204
fl::size size() const FL_NO_EXCEPT
void resize(fl::size n) FL_NO_EXCEPT
Definition vector.h:593
void clear() FL_NO_EXCEPT
Definition vector.h:634
void push_back(const T &value) FL_NO_EXCEPT
Definition vector.h:624
#define FL_WARN(...)
Definition log.h:437
bool parseHexColor(const fl::string &hexStr, u8 &r, u8 &g, u8 &b) FL_NO_EXCEPT
Parse hex color string to RGB components.
unsigned char u8
Definition stdint.h:131
InputGamut g
Definition rgbw.h:125
FASTLED_FORCE_INLINE long strtol(const char *str, char **endptr, int base) FL_NO_EXCEPT
Definition cstdlib.h:61
fl::vector< fl::vector< u8 > > mColors
Definition segment.h:24
fl::string mName
Definition segment.h:54
fl::vector< fl::vector< u8 > > mIndividualLeds
Definition segment.h:58
fl::i64 i64
Definition stdint.h:221

References fl::basic_string::c_str(), fl::basic_string::find(), fl::FL_NO_EXCEPT, FL_WARN, fl::g, fl::json::is_array(), fl::json::is_string(), fl::string::npos, parseHexColor(), fl::json::size(), fl::strtol(), and fl::string::substr().

Referenced by fl::WLED::setState().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: