wled_json_api_library/structures/
info.rs

1use serde;
2use serde::{Serialize, Deserialize};
3use serde_repr::{Deserialize_repr, Serialize_repr};
4use crate::errors::WledJsonApiError;
5use crate::structures::none_function;
6
7
8#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct Info {
11    /// Version name.
12    #[serde(skip_serializing_if = "Option::is_none")]
13    #[serde(default = "none_function")]
14    pub ver: Option<String>,
15
16    /// Build ID (YYMMDDB, B = daily build index).
17    #[serde(skip_serializing_if = "Option::is_none")]
18    #[serde(default = "none_function")]
19    pub vid: Option<u32>,
20
21    /// Contains info about the LED setup.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    #[serde(default = "none_function")]
24    pub leds: Option<Leds>,
25
26    /// sync Toggle Receive
27    /// UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise
28    #[serde(skip_serializing_if = "Option::is_none")]
29    #[serde(default = "none_function")]
30    pub str: Option<bool>,
31
32    /// Friendly name of the light. Intended for display in lists and titles.
33    /// Name of module - default is WLED
34    #[serde(skip_serializing_if = "Option::is_none")]
35    #[serde(default = "none_function")]
36    pub name: Option<String>,
37
38    /// The UDP port for realtime packets and WLED broadcast.
39    /// WLED notifier default port
40    #[serde(skip_serializing_if = "Option::is_none")]
41    #[serde(default = "none_function")]
42    pub udpport: Option<u16>,
43
44    /// If true, the software is currently receiving realtime data via UDP or E1.31.
45    #[serde(skip_serializing_if = "Option::is_none")]
46    #[serde(default = "none_function")]
47    pub live: Option<bool>,
48
49    /// main segment id if its active, -1 otherwise
50    #[serde(skip_serializing_if = "Option::is_none")]
51    #[serde(default = "none_function")]
52    pub liveseg: Option<i16>,
53
54    /// Info about the realtime data source
55    /// WLED SOURCE (as of ~wled 14.0:
56    ///   switch (realtimeMode) {
57    ///     case REALTIME_MODE_INACTIVE: root["lm"] = ""; break;
58    ///     case REALTIME_MODE_GENERIC:  root["lm"] = ""; break;
59    ///     case REALTIME_MODE_UDP:      root["lm"] = F("UDP"); break;
60    ///     case REALTIME_MODE_HYPERION: root["lm"] = F("Hyperion"); break;
61    ///     case REALTIME_MODE_E131:     root["lm"] = F("E1.31"); break;
62    ///     case REALTIME_MODE_ADALIGHT: root["lm"] = F("USB Adalight/TPM2"); break;
63    ///     case REALTIME_MODE_ARTNET:   root["lm"] = F("Art-Net"); break;
64    ///     case REALTIME_MODE_TPM2NET:  root["lm"] = F("tpm2.net"); break;
65    ///     case REALTIME_MODE_DDP:      root["lm"] = F("DDP"); break;
66    ///   }
67    #[serde(skip_serializing_if = "Option::is_none")]
68    #[serde(default = "none_function")]
69    pub lm: Option<String>,
70
71    /// Realtime data source IP address
72    #[serde(skip_serializing_if = "Option::is_none")]
73    #[serde(default = "none_function")]
74    pub lip: Option<String>,
75
76    /// -1 to 8; Number of currently connected WebSockets clients. -1 indicates that WS is unsupported in this build.
77    #[serde(skip_serializing_if = "Option::is_none")]
78    #[serde(default = "none_function")]
79    pub ws: Option<i8>,
80
81    /// Number of effects included.
82    #[serde(skip_serializing_if = "Option::is_none")]
83    #[serde(default = "none_function")]
84    pub fxcount: Option<u8>,
85
86    /// Number of palettes configured.
87    /// will only return built-in palette count
88    #[serde(skip_serializing_if = "Option::is_none")]
89    #[serde(default = "none_function")]
90    pub palcount: Option<u16>,
91
92    /// custom palette count
93    #[serde(skip_serializing_if = "Option::is_none")]
94    #[serde(default = "none_function")]
95    pub cpalcount: Option<u16>,
96
97    /// available ledmaps
98    #[serde(skip_serializing_if = "Option::is_none")]
99    #[serde(default = "none_function")]
100    pub maps: Option<Vec<Map>>,
101
102    /// Info about wifi
103    #[serde(skip_serializing_if = "Option::is_none")]
104    #[serde(default = "none_function")]
105    pub wifi: Option<Wifi>,
106
107    /// Info about the embedded LittleFS filesystem (since 0.11.0)
108    #[serde(skip_serializing_if = "Option::is_none")]
109    #[serde(default = "none_function")]
110    pub fs: Option<Fs>,
111
112    /// -1 to 255; Number of other WLED devices discovered on the network. -1 if Node discovery disabled. (since 0.12.0)
113    #[serde(skip_serializing_if = "Option::is_none")]
114    #[serde(default = "none_function")]
115    pub ndc: Option<i16>,
116
117    /// only present on debug builds
118    /// (int) WiFi.getTxPower();
119    #[serde(skip_serializing_if = "Option::is_none")]
120    #[serde(default = "none_function")]
121    #[serde(rename = "txPower")]
122    pub tx_power: Option<u32>,
123
124    /// only present on debug builds
125    /// (bool) WiFi.getSleep();
126    #[serde(skip_serializing_if = "Option::is_none")]
127    #[serde(default = "none_function")]
128    pub sleep: Option<bool>,
129
130    /// Name of the platform.
131    #[serde(skip_serializing_if = "Option::is_none")]
132    #[serde(default = "none_function")]
133    pub arch: Option<String>,
134
135    /// Version of the underlying (Arduino core) SDK.
136    #[serde(skip_serializing_if = "Option::is_none")]
137    #[serde(default = "none_function")]
138    pub core: Option<String>,
139
140    /// only present on debug esp32 builds
141    /// (int)rtc_get_reset_reason(0);
142    #[serde(skip_serializing_if = "Option::is_none")]
143    #[serde(default = "none_function")]
144    #[serde(rename = "resetReason0")]
145    pub reset_reason_0: Option<u32>,
146
147    /// only present on debug esp32 builds
148    /// (int)rtc_get_reset_reason(1);
149    #[serde(skip_serializing_if = "Option::is_none")]
150    #[serde(default = "none_function")]
151    #[serde(rename = "resetReason1")]
152    pub reset_reason_1: Option<u32>,
153
154    /// only present on debug esp8266 builds
155    /// (int)rtc_get_reset_reason(0);
156    #[serde(skip_serializing_if = "Option::is_none")]
157    #[serde(default = "none_function")]
158    #[serde(rename = "resetReason")]
159    pub reset_reason: Option<u32>,
160
161    /// 0-2; Version of LwIP. 1 or 2 on ESP8266, 0 (does not apply) on ESP32. Deprecated, removal in 0.14.0
162    #[serde(skip_serializing_if = "Option::is_none")]
163    #[serde(default = "none_function")]
164    pub lwip: Option<u8>,
165
166    /// Bytes of heap memory (RAM) currently available. Problematic if <10k.
167    #[serde(skip_serializing_if = "Option::is_none")]
168    #[serde(default = "none_function")]
169    pub freeheap: Option<u32>,
170
171    /// ESP.getFreePsram(); only present when hardware supports psram
172    #[serde(skip_serializing_if = "Option::is_none")]
173    #[serde(default = "none_function")]
174    pub psram: Option<u64>,
175
176    /// Time since the last boot/reset in seconds.
177    #[serde(skip_serializing_if = "Option::is_none")]
178    #[serde(default = "none_function")]
179    pub uptime: Option<u32>,
180
181    /// The current time in human readable format
182    #[serde(skip_serializing_if = "Option::is_none")]
183    #[serde(default = "none_function")]
184    pub time: Option<String>,
185
186    /// Used for debugging purposes only. bit map of build info
187    ///     #ifdef WLED_DEBUG_HOST
188    ///         os |= 0x0100;
189    ///         if (!netDebugEnabled) os &= ~0x0080;
190    ///     #endif
191    /// 0x80: debug enabled
192    /// 0x40: disable alexa
193    /// 0x20: Depreceated, used to be Blynk support, may be repurposed
194    /// 0x10: usermod Chronixie
195    /// 0x08: disable filesystem build tag
196    /// 0x04: disable hue sync build tag
197    /// 0x02: enable AdaLight build tag
198    /// 0x01: disable OTA build tag
199    #[serde(skip_serializing_if = "Option::is_none")]
200    #[serde(default = "none_function")]
201    pub opt: Option<u16>,
202
203    /// The producer/vendor of the light. Always WLED for standard installations.
204    #[serde(skip_serializing_if = "Option::is_none")]
205    #[serde(default = "none_function")]
206    pub brand: Option<String>,
207
208    /// The product name. Always FOSS for standard installations.
209    #[serde(skip_serializing_if = "Option::is_none")]
210    #[serde(default = "none_function")]
211    pub product: Option<String>,
212
213    /// The origin of the build.
214    /// src if a release version is compiled from source,
215    /// bin for an official release image,
216    /// dev for a development build (regardless of src/bin origin)
217    /// and exp for experimental versions.
218    /// ogn if the image is flashed to hardware by the vendor.
219    /// Removed as of v0.10
220    #[serde(skip_serializing_if = "Option::is_none")]
221    #[serde(default = "none_function")]
222    pub btype: Option<String>,
223
224    /// The hexadecimal hardware MAC address of the light, lowercase and without colons.
225    #[serde(skip_serializing_if = "Option::is_none")]
226    #[serde(default = "none_function")]
227    pub mac: Option<String>,
228
229    /// The IP address of this instance. Empty string if not connected. (since 0.13.0)
230    /// format: sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
231    #[serde(skip_serializing_if = "Option::is_none")]
232    #[serde(default = "none_function")]
233    pub ip: Option<String>,
234}
235
236impl TryFrom<&str> for Info{
237    type Error = WledJsonApiError;
238    fn try_from(str_in: &str) -> Result<Info, WledJsonApiError> {
239        serde_json::from_str(str_in).map_err(|e| {WledJsonApiError::SerdeError(e)})
240    }
241}
242
243#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
244#[serde(rename_all = "camelCase")]
245pub struct Leds {
246    /// 1 to 1200; Total LED count.
247    /// will include virtual/nonexistent pixels in matrix
248    #[serde(skip_serializing_if = "Option::is_none")]
249    #[serde(default = "none_function")]
250    pub count: Option<u16>,
251
252    /// 0 to 65000; Current LED power usage in milliamps as determined by the ABL.
253    /// (0 if ABL is disabled.)<-maybe
254    #[serde(skip_serializing_if = "Option::is_none")]
255    #[serde(default = "none_function")]
256    pub pwr: Option<u16>,
257
258    /// Returns the refresh rate of the LED strip.
259    /// Useful for finding out whether a given setup is fast enough.
260    /// Only updates on show() or is set to 0 fps if last show is more than 2 secs ago,
261    /// so accuracy varies
262    #[serde(skip_serializing_if = "Option::is_none")]
263    #[serde(default = "none_function")]
264    pub fps: Option<u16>,
265
266    /// 0 to 65000; Maximum power budget in milliamps for the ABL. 0 if ABL is disabled.
267    #[serde(skip_serializing_if = "Option::is_none")]
268    #[serde(default = "none_function")]
269    pub maxpwr: Option<u16>,
270
271    /// Maximum number of segments supported by this version.
272    /// returns maximum number of supported segments (fixed value)
273    #[serde(skip_serializing_if = "Option::is_none")]
274    #[serde(default = "none_function")]
275    pub maxseg: Option<u8>,
276
277    /// Dimensions of matrix; not included in all builds
278    #[serde(skip_serializing_if = "Option::is_none")]
279    #[serde(default = "none_function")]
280    pub matrix: Option<MatrixDims>,
281
282    /// Per-segment virtual light capabilities
283    ///
284    /// !!! this is a bitmap using the masks found in ```SegmentLightCapability```
285    ///
286    /// !!! Not ```LightCapability```
287    #[serde(skip_serializing_if = "Option::is_none")]
288    #[serde(default = "none_function")]
289    pub seglc: Option<Vec<u8>>,
290
291    /// Logical AND of all active segment's virtual light capabilities
292    #[serde(skip_serializing_if = "Option::is_none")]
293    #[serde(default = "none_function")]
294    pub lc: Option<u8>,
295
296    /// true if LEDs are 4-channel (RGB + White). (deprecated, use info.leds.lc)
297    #[serde(skip_serializing_if = "Option::is_none")]
298    #[serde(default = "none_function")]
299    pub rgbw: Option<bool>,
300
301    /// WLED WIKI SAYS BOOL??? true if a white channel slider should be displayed. (available since 0.10.0, deprecated, use info.leds.lc)
302    #[serde(skip_serializing_if = "Option::is_none")]
303    #[serde(default = "none_function")]
304    pub wv: Option<u8>,
305
306    /// WLED WIKI SAYS BOOL??? true if the light supports color temperature control (available since 0.13.0, deprecated, use info.leds.lc)
307    #[serde(skip_serializing_if = "Option::is_none")]
308    #[serde(default = "none_function")]
309    pub cct: Option<u8>,
310
311    /// LED strip pin(s). Always one element. Removed as of v0.13
312    #[serde(skip_serializing_if = "Option::is_none")]
313    #[serde(default = "none_function")]
314    pub pin: Option<Vec<i8>>,
315
316    /// [i2c_sda pin, i2c_scl pin];
317    /// only in debug builds
318    #[serde(skip_serializing_if = "Option::is_none")]
319    #[serde(default = "none_function")]
320    pub i2c: Option<[i8; 2]>,
321
322    /// [spi_mosi pin, spi_sclk pin, spi_miso pin];
323    /// only in debug builds
324    #[serde(skip_serializing_if = "Option::is_none")]
325    #[serde(default = "none_function")]
326    pub spi: Option<[i8; 3]>,
327}
328
329#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
330#[serde(rename_all = "camelCase")]
331pub struct Map {
332    /// index of an avilable led map
333    #[serde(skip_serializing_if = "Option::is_none")]
334    #[serde(default = "none_function")]
335    pub id: Option<u8>,
336
337    /// Led map name. only included in builds for hardware with sufficient processing power
338    /// (currently just everything but the esp8266)
339    #[serde(skip_serializing_if = "Option::is_none")]
340    #[serde(default = "none_function")]
341    pub n: Option<String>,
342}
343
344#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
345#[serde(rename_all = "camelCase")]
346pub struct Wifi {
347    /// Return the current bssid / mac associated with the network if configured
348    #[serde(skip_serializing_if = "Option::is_none")]
349    #[serde(default = "none_function")]
350    pub bssid: Option<String>,
351
352    /// undocumented??? heres the WLED source as of WLED ~14.0:
353    /// int qrssi = WiFi.RSSI(); <- thats an i8
354    ///   wifi_info[F("rssi")] = qrssi; <- but thats a u32
355    ///   wifi_info[F("signal")] = getSignalQuality(qrssi);
356    /// I'm going to make RSSI an i64 to include both in case this gets fixed in the future.
357    /// blame me for 4 bytes
358    #[serde(skip_serializing_if = "Option::is_none")]
359    #[serde(default = "none_function")]
360    pub rssi: Option<i64>,
361
362    /// 0-100; Relative signal quality of the current connection.
363    /// use this over RSSI unless for some reason you feel cooler doing the conversion in your head
364    #[serde(skip_serializing_if = "Option::is_none")]
365    #[serde(default = "none_function")]
366    pub signal: Option<u8>,
367
368    /// 1 to 14; The current WiFi channel. WLED source uses i32 so i will too
369    #[serde(skip_serializing_if = "Option::is_none")]
370    #[serde(default = "none_function")]
371    pub channel: Option<i32>,
372}
373
374#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
375#[serde(rename_all = "camelCase")]
376pub struct Fs {
377    /// Estimate of used filesystem space in kilobytes
378    #[serde(skip_serializing_if = "Option::is_none")]
379    #[serde(default = "none_function")]
380    pub u: Option<u32>,
381
382    /// Total filesystem size in kilobytes
383    #[serde(skip_serializing_if = "Option::is_none")]
384    #[serde(default = "none_function")]
385    pub t: Option<u32>,
386
387    /// Unix timestamp for the last modification to the presets.json file.
388    /// Not accurate after boot or after using /edit
389    #[serde(skip_serializing_if = "Option::is_none")]
390    #[serde(default = "none_function")]
391    pub pmt: Option<u64>,
392}
393
394///these define matrix width & height (max. segment dimensions)
395#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
396#[serde(rename_all = "camelCase")]
397pub struct MatrixDims {
398    /// max width
399    #[serde(skip_serializing_if = "Option::is_none")]
400    #[serde(default = "none_function")]
401    pub w: Option<u16>,
402
403    /// max height
404    #[serde(skip_serializing_if = "Option::is_none")]
405    #[serde(default = "none_function")]
406    pub h: Option<u16>,
407}
408
409
410///     NOT TO BE CONFUSED WITH LightCapability.
411///     this is a bitmap of 3 basic capabilities
412///
413///     I know its confusing. Believe me.
414#[allow(non_camel_case_types)]
415#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug, Clone)]
416#[repr(u8)]
417pub enum SegmentLightCapability {
418    SEG_CAPABILITY_RGB = 0x01,
419    SEG_CAPABILITY_W = 0x02,
420    SEG_CAPABILITY_CCT = 0x04,
421}
422
423#[cfg(test)]
424mod tests {
425    use crate::structures::info::Info;
426
427    #[test]
428    fn it_works() {
429        let a: Info = Info::try_from(r#"{"ver":"0.14.0","vid":2310130,"leds":{"count":6,"pwr":0,"fps":5,"maxpwr":0,"maxseg":32,"seglc":[1],"lc":1,"rgbw":false,"wv":0,"cct":0},"str":false,"name":"WLED","udpport":21324,"live":false,"liveseg":-1,"lm":"","lip":"","ws":0,"fxcount":187,"palcount":71,"cpalcount":0,"maps":[{"id":0}],"wifi":{"bssid":"FC:EC:DA:A4:C4:77","rssi":-60,"signal":80,"channel":1},"fs":{"u":12,"t":983,"pmt":0},"ndc":0,"arch":"esp32","core":"v3.3.6-16-gcc5440f6a2","lwip":0,"freeheap":200300,"uptime":6,"time":"1970-1-1, 00:00:06","opt":79,"brand":"WLED","product":"FOSS","mac":"a842e38d9828","ip":"192.168.1.40"}"#).unwrap();
430        println!("{:?}", a);
431    }
432}