Skip to content

Commit bcd5f8b

Browse files
authored
rework WiFiRSSIMonitor to WiFiMonitor (#145)
* rework WiFiRSSIMonitor to WiFiMonitor * optimize facts publish * drop dead code
1 parent 6c41aa9 commit bcd5f8b

13 files changed

Lines changed: 555 additions & 265 deletions

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ set(LIB_SOURCE_FILES
115115
src/mavlink.c
116116
src/wfbcli.hpp
117117
src/wfbcli.cpp
118-
src/WiFiRSSIMonitor.hpp
119-
src/WiFiRSSIMonitor.cpp
118+
src/WiFiMonitor.hpp
119+
src/WiFiMonitor.cpp
120120
src/scheduling_helper.hpp
121121
src/gstrtpreceiver.cpp
122122
src/gstrtpreceiver.h)

README.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ Typical OSD config looks like:
175175
"x": 10,
176176
"y": 60,
177177
"icon_path": "device_thermostat.png",
178-
"template": "CPU: %.0fC, GPU: %.0fC",
178+
"template": "CPU: %.0f°C, GPU: %.0f°C",
179179
"facts": [
180180
{"name": "os_mon.temperature",
181181
"tags": {"name": "soc-thermal"},
@@ -222,7 +222,27 @@ lot of facts to which widgets can subscribe to:
222222
| `video.decoder_feed_time_ms` | uint | Time to feed the video packet to hardware decoder |
223223
| `gstreamer.received_bytes` | uint | Number of bytes received from gstreamer (published for each packet) |
224224
| `osd.custom_message` | str | The custom message passed via `--osd-custom-message` feature |
225-
| `os_mon.wifi.rssi` | uint | rssi as reported from /proc/net/rtl88x2eu/<interface>/trx_info_debug |
225+
| `os_mon.wifi.rssi` | int | rssi as reported from /proc/net/`<driver>`/`<interface>`/trx_info_debug |
226+
| `os_mon.wifi.temperature` | int | RF chip temperature, degrees C, from /proc/net/`<driver>`/`<interface>`/thermal_state |
227+
228+
The `os_mon.wifi.*` facts are only published in APFPV mode (in WFB mode the same data comes from
229+
wfb-ng as `wfbcli.*`). They are read from the proc interface of the Realtek drivers - every
230+
`/proc/net/rtl*` directory is scanned, so all card families (rtl88x2eu, rtl88x2cu, rtl88x2bu, ...)
231+
are covered; cards whose driver has no `thermal_state` simply publish no temperature.
232+
Both are tagged with `interface` (eg `wlx0013eff604e2`) and `adapter`, plus `type`
233+
(`rssi_a`/`rssi_b`/`rssi_percent`/`connected`) for the rssi and `rf_path` (`0`/`1`) for the
234+
temperature. `adapter` is the index of the card among all adapters found, counted from 0 in
235+
interface-name order - bind widgets to it (`{"adapter": "0", "type": "rssi_a"}`) rather than to the
236+
MAC-derived interface name, which differs per ground station. Note that the index of a card changes
237+
when other adapters are plugged in or removed. Temperature is sampled every 10 seconds, because
238+
reading it makes the driver trigger an ADC conversion on the RF chip.
239+
240+
An adapter that is not associated (no drone yet, drone powered off) publishes `connected` = 0 and
241+
`-1` for every rssi value, so a bar bound to it disappears instead of freezing at the last value it
242+
saw. `-1` is outside the 0..100 percentage range that `IconSelectorWidget` configs cover, so it
243+
hides by default; add a range for it (`{"range": [-1, 0], "icon_path": "no_signal.png"}`) to show an
244+
explicit "no signal" icon instead. If an adapter is unplugged entirely, its facts are dropped back
245+
to undefined, which hides the widget as well.
226246

227247
There are many facts based on Mavlink telemetry, see `mavlink.c`. All of them have tags "sysid" and
228248
"compid", but some have extra tags.
@@ -333,6 +353,10 @@ to display any fact (as long as datatype matches):
333353
* `{"type": "DebugWidget"}` - displays debug information (name, type, tags, value) about fact(s)
334354
* `{"type": "IconSelectorWidget"}` - display a icon based on a fact's value
335355

356+
Text is rendered with LVGL's built-in Montserrat font, which only covers ASCII plus the degree sign
357+
`°` (U+00B0) and a few symbols. Any other character comes out as an empty box - watch out for
358+
look-alikes such as `` (U+2070, superscript zero).
359+
336360
Specific widgets expect quite concrete facts as input:
337361

338362
* `DvrStatusWidget` - shows up when DVR is recording and is hidden when not.

config_osd.json

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,123 @@
131131
{"range": [-130, -91], "icon_path": "signal8.png"}
132132
]
133133
},
134+
{
135+
"type": "IconSelectorWidget",
136+
"name": "APFPV RSSI of adapter 1 antenna 1",
137+
"x": -250,
138+
"y": 0,
139+
"facts": [
140+
{
141+
"__comment": "APFPV counterpart of the six widgets above: same slots, but fed by the WiFi driver instead of wfb-ng. Only one of the two sets is ever published, the other stays hidden. RSSI is a percentage here, not dBm. `adapter` counts the cards from 0 in interface-name order, `type` picks the RF path",
142+
"name": "os_mon.wifi.rssi", "tags": {"adapter": "0", "type": "rssi_a"}
143+
}
144+
],
145+
"ranges_and_icons": [
146+
{"range": [70, 100], "icon_path": "signal1.png"},
147+
{"range": [60, 69], "icon_path": "signal2.png"},
148+
{"range": [50, 59], "icon_path": "signal3.png"},
149+
{"range": [40, 49], "icon_path": "signal4.png"},
150+
{"range": [30, 39], "icon_path": "signal5.png"},
151+
{"range": [20, 29], "icon_path": "signal6.png"},
152+
{"range": [10, 19], "icon_path": "signal7.png"},
153+
{"range": [1, 9], "icon_path": "signal8.png"}
154+
]
155+
},
156+
{
157+
"type": "IconSelectorWidget",
158+
"name": "APFPV RSSI of adapter 1 antenna 2",
159+
"x": -205,
160+
"y": 0,
161+
"facts": [
162+
{"name": "os_mon.wifi.rssi", "tags": {"adapter": "0", "type": "rssi_b"}}
163+
],
164+
"ranges_and_icons": [
165+
{"range": [70, 100], "icon_path": "signal1.png"},
166+
{"range": [60, 69], "icon_path": "signal2.png"},
167+
{"range": [50, 59], "icon_path": "signal3.png"},
168+
{"range": [40, 49], "icon_path": "signal4.png"},
169+
{"range": [30, 39], "icon_path": "signal5.png"},
170+
{"range": [20, 29], "icon_path": "signal6.png"},
171+
{"range": [10, 19], "icon_path": "signal7.png"},
172+
{"range": [1, 9], "icon_path": "signal8.png"}
173+
]
174+
},
175+
{
176+
"type": "IconSelectorWidget",
177+
"name": "APFPV RSSI of adapter 2 antenna 1",
178+
"x": -160,
179+
"y": 0,
180+
"facts": [
181+
{"name": "os_mon.wifi.rssi", "tags": {"adapter": "1", "type": "rssi_a"}}
182+
],
183+
"ranges_and_icons": [
184+
{"range": [70, 100], "icon_path": "signal1.png"},
185+
{"range": [60, 69], "icon_path": "signal2.png"},
186+
{"range": [50, 59], "icon_path": "signal3.png"},
187+
{"range": [40, 49], "icon_path": "signal4.png"},
188+
{"range": [30, 39], "icon_path": "signal5.png"},
189+
{"range": [20, 29], "icon_path": "signal6.png"},
190+
{"range": [10, 19], "icon_path": "signal7.png"},
191+
{"range": [1, 9], "icon_path": "signal8.png"}
192+
]
193+
},
194+
{
195+
"type": "IconSelectorWidget",
196+
"name": "APFPV RSSI of adapter 2 antenna 2",
197+
"x": -115,
198+
"y": 0,
199+
"facts": [
200+
{"name": "os_mon.wifi.rssi", "tags": {"adapter": "1", "type": "rssi_b"}}
201+
],
202+
"ranges_and_icons": [
203+
{"range": [70, 100], "icon_path": "signal1.png"},
204+
{"range": [60, 69], "icon_path": "signal2.png"},
205+
{"range": [50, 59], "icon_path": "signal3.png"},
206+
{"range": [40, 49], "icon_path": "signal4.png"},
207+
{"range": [30, 39], "icon_path": "signal5.png"},
208+
{"range": [20, 29], "icon_path": "signal6.png"},
209+
{"range": [10, 19], "icon_path": "signal7.png"},
210+
{"range": [1, 9], "icon_path": "signal8.png"}
211+
]
212+
},
213+
{
214+
"type": "IconSelectorWidget",
215+
"name": "APFPV RSSI of adapter 3 antenna 1",
216+
"x": -70,
217+
"y": 0,
218+
"facts": [
219+
{"name": "os_mon.wifi.rssi", "tags": {"adapter": "2", "type": "rssi_a"}}
220+
],
221+
"ranges_and_icons": [
222+
{"range": [70, 100], "icon_path": "signal1.png"},
223+
{"range": [60, 69], "icon_path": "signal2.png"},
224+
{"range": [50, 59], "icon_path": "signal3.png"},
225+
{"range": [40, 49], "icon_path": "signal4.png"},
226+
{"range": [30, 39], "icon_path": "signal5.png"},
227+
{"range": [20, 29], "icon_path": "signal6.png"},
228+
{"range": [10, 19], "icon_path": "signal7.png"},
229+
{"range": [1, 9], "icon_path": "signal8.png"}
230+
]
231+
},
232+
{
233+
"type": "IconSelectorWidget",
234+
"name": "APFPV RSSI of adapter 3 antenna 2",
235+
"x": -25,
236+
"y": 0,
237+
"facts": [
238+
{"name": "os_mon.wifi.rssi", "tags": {"adapter": "2", "type": "rssi_b"}}
239+
],
240+
"ranges_and_icons": [
241+
{"range": [70, 100], "icon_path": "signal1.png"},
242+
{"range": [60, 69], "icon_path": "signal2.png"},
243+
{"range": [50, 59], "icon_path": "signal3.png"},
244+
{"range": [40, 49], "icon_path": "signal4.png"},
245+
{"range": [30, 39], "icon_path": "signal5.png"},
246+
{"range": [20, 29], "icon_path": "signal6.png"},
247+
{"range": [10, 19], "icon_path": "signal7.png"},
248+
{"range": [1, 9], "icon_path": "signal8.png"}
249+
]
250+
},
134251
{
135252
"name": "Video FPS and resolution",
136253
"type": "VideoWidget",
@@ -212,6 +329,30 @@
212329
"critical": 2,
213330
"facts": [ { "name": "gstreamer.received_bytes" } ]
214331
},
332+
{
333+
"name": "APFPV WiFi RF temperature adapter 1",
334+
"type": "---IconTplTextWidget",
335+
"x": -250,
336+
"y": 155,
337+
"icon_path": "device_thermostat.png",
338+
"template": "RF %i°C / %i°C",
339+
"facts": [
340+
{"name": "os_mon.wifi.temperature", "tags": {"adapter": "0", "rf_path": "0"}},
341+
{"name": "os_mon.wifi.temperature", "tags": {"adapter": "0", "rf_path": "1"}}
342+
]
343+
},
344+
{
345+
"name": "APFPV WiFi RF temperature adapter 2",
346+
"type": "---IconTplTextWidget",
347+
"x": -250,
348+
"y": 185,
349+
"icon_path": "device_thermostat.png",
350+
"template": "RF %i°C / %i°C",
351+
"facts": [
352+
{"name": "os_mon.wifi.temperature", "tags": {"adapter": "1", "rf_path": "0"}},
353+
{"name": "os_mon.wifi.temperature", "tags": {"adapter": "1", "rf_path": "1"}}
354+
]
355+
},
215356
{
216357
"name": "MspDisplayPort",
217358
"type": "---MspDisplayPortWidget",

0 commit comments

Comments
 (0)