tangled
alpha
login
or
join now
sachy.dev
/
striker
0
fork
atom
Bevy+Ratutui powered Monitoring of Pico-Strike devices
0
fork
atom
overview
issues
pulls
pipelines
Organise into widgets
sachy.dev
1 week ago
cacc7dcc
ac77fa45
+100
-41
2 changed files
expand all
collapse all
unified
split
src
device.rs
views
monitoring.rs
+30
src/device.rs
···
14
prelude::Deref,
15
};
16
use rapidhash::RapidHashSet;
0
0
0
0
0
17
18
use crate::net::DiscoverResponse;
19
···
37
pub blip_size: usize,
38
pub max_duty: u16,
39
pub duty: u16,
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
40
}
41
42
fn on_remove_device(mut world: DeferredWorld, context: HookContext) {
···
14
prelude::Deref,
15
};
16
use rapidhash::RapidHashSet;
17
+
use ratatui::{
18
+
style::{Color, Stylize},
19
+
text::{Line, Span, Text, ToSpan},
20
+
widgets::{Block, Padding, Paragraph, Widget},
21
+
};
22
23
use crate::net::DiscoverResponse;
24
···
42
pub blip_size: usize,
43
pub max_duty: u16,
44
pub duty: u16,
45
+
}
46
+
47
+
impl Widget for DeviceDetector {
48
+
fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer)
49
+
where
50
+
Self: Sized,
51
+
{
52
+
let detector_lines = [
53
+
Line::from_iter([Span::raw("Threshold: "), self.blip_threshold.to_span()]),
54
+
Line::from_iter([Span::raw("Blip Size: "), self.blip_size.to_span()]),
55
+
Line::from_iter([Span::raw("Max Duty: "), self.max_duty.to_span()]),
56
+
Line::from_iter([Span::raw("Current Duty: "), self.duty.to_span()]),
57
+
];
58
+
59
+
let detector_info = Paragraph::new(Text::from_iter(detector_lines))
60
+
.block(
61
+
Block::bordered()
62
+
.title("Settings")
63
+
.padding(Padding::horizontal(1))
64
+
.border_style(Color::LightGreen),
65
+
)
66
+
.white();
67
+
68
+
detector_info.render(area, buf);
69
+
}
70
}
71
72
fn on_remove_device(mut world: DeferredWorld, context: HookContext) {
+70
-41
src/views/monitoring.rs
···
20
layout::{Constraint, HorizontalAlignment, Layout},
21
style::{Color, Stylize},
22
text::{Line, Span, Text, ToSpan},
23
-
widgets::{Axis, Block, Chart, Dataset, Padding, Paragraph},
24
};
25
use striker_proto::{Response, StrikerRequest, StrikerResponse, Update};
26
···
206
207
let timestamp = latest_signal.map(|(t, _, _)| t);
208
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
209
let lines = [
210
-
Line::from(device.to_span()),
211
-
Line::from_iter([Span::raw("Status: "), connected.connection_state.to_span()]),
0
0
0
212
]
213
.into_iter()
214
-
.chain(timestamp.map(|t| Line::from(t.0.to_span())))
215
.chain(
216
-
latest_level.map(|level| Line::from_iter([Span::raw("Level: "), level.0.to_span()])),
0
217
);
218
219
let info = Paragraph::new(Text::from_iter(lines))
220
.block(
221
Block::bordered()
222
-
.padding(Padding::horizontal(2))
223
.title("Device")
224
.title_alignment(HorizontalAlignment::Center)
225
.border_style(Color::LightGreen),
226
)
227
.white();
228
229
-
let (data, detected) = latest_signal
0
0
0
0
0
0
0
0
0
0
0
0
0
0
230
.map(|(_, samples, signals)| {
231
(
232
samples
···
298
)
299
.block(block);
300
301
-
let help = Paragraph::new("Keys: 'q'/ESC Quit, BACKSPACE Return to Device select")
302
-
.block(
303
-
Block::bordered()
304
-
.padding(Padding::horizontal(2))
305
-
.border_style(Color::LightGreen),
306
-
)
307
-
.white();
308
-
309
-
let detector = detector.copied().unwrap_or_default();
310
-
311
-
let detector_lines = [
312
-
Line::from_iter([Span::raw("Threshold: "), detector.blip_threshold.to_span()]),
313
-
Line::from_iter([Span::raw("Blip Size: "), detector.blip_size.to_span()]),
314
-
Line::from_iter([Span::raw("Max Duty: "), detector.max_duty.to_span()]),
315
-
Line::from_iter([Span::raw("Current Duty: "), detector.duty.to_span()]),
316
-
];
317
-
318
-
let detector_info = Paragraph::new(Text::from_iter(detector_lines))
319
-
.block(
320
-
Block::bordered()
321
-
.title("Settings")
322
-
.padding(Padding::horizontal(2))
323
-
.border_style(Color::LightGreen),
324
-
)
325
-
.white();
326
-
327
-
frame.render_widget(info, device_block);
328
-
frame.render_widget(chart2, chart_block);
329
-
frame.render_widget(chart, chart_block);
330
-
frame.render_widget(detector_info, detector_block);
331
-
frame.render_widget(help, bottom);
332
-
})?;
333
-
334
-
Ok(())
335
}
···
20
layout::{Constraint, HorizontalAlignment, Layout},
21
style::{Color, Stylize},
22
text::{Line, Span, Text, ToSpan},
23
+
widgets::{Axis, Block, Chart, Dataset, Padding, Paragraph, Widget},
24
};
25
use striker_proto::{Response, StrikerRequest, StrikerResponse, Update};
26
···
206
207
let timestamp = latest_signal.map(|(t, _, _)| t);
208
209
+
let info = DeviceInfo {
210
+
name: device,
211
+
connected: &connected,
212
+
timestamp,
213
+
level: latest_level,
214
+
};
215
+
216
+
let signal_chart = SignalChart {
217
+
signal: latest_signal,
218
+
};
219
+
220
+
let help = Paragraph::new("Keys: 'q'/ESC Quit, BACKSPACE Return to Device select")
221
+
.block(
222
+
Block::bordered()
223
+
.padding(Padding::horizontal(2))
224
+
.border_style(Color::LightGreen),
225
+
)
226
+
.white();
227
+
228
+
let detector = detector.copied().unwrap_or_default();
229
+
230
+
frame.render_widget(info, device_block);
231
+
frame.render_widget(signal_chart, chart_block);
232
+
frame.render_widget(detector, detector_block);
233
+
frame.render_widget(help, bottom);
234
+
})?;
235
+
236
+
Ok(())
237
+
}
238
+
239
+
struct DeviceInfo<'a> {
240
+
name: &'a Name,
241
+
connected: &'a ConnectedDevice,
242
+
timestamp: Option<&'a Timestamp>,
243
+
level: Option<&'a StormLevel>,
244
+
}
245
+
246
+
impl Widget for DeviceInfo<'_> {
247
+
fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer)
248
+
where
249
+
Self: Sized,
250
+
{
251
let lines = [
252
+
Line::from(self.name.to_span()),
253
+
Line::from_iter([
254
+
Span::raw("Status: "),
255
+
self.connected.connection_state.to_span(),
256
+
]),
257
]
258
.into_iter()
259
+
.chain(self.timestamp.map(|t| Line::from(t.0.to_span())))
260
.chain(
261
+
self.level
262
+
.map(|level| Line::from_iter([Span::raw("Level: "), level.0.to_span()])),
263
);
264
265
let info = Paragraph::new(Text::from_iter(lines))
266
.block(
267
Block::bordered()
268
+
.padding(Padding::horizontal(1))
269
.title("Device")
270
.title_alignment(HorizontalAlignment::Center)
271
.border_style(Color::LightGreen),
272
)
273
.white();
274
275
+
info.render(area, buf);
276
+
}
277
+
}
278
+
279
+
struct SignalChart<'a> {
280
+
signal: Option<(&'a Timestamp, &'a StormSignal, &'a SignalPeaks)>,
281
+
}
282
+
283
+
impl Widget for SignalChart<'_> {
284
+
fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer)
285
+
where
286
+
Self: Sized,
287
+
{
288
+
let (data, detected) = self
289
+
.signal
290
.map(|(_, samples, signals)| {
291
(
292
samples
···
358
)
359
.block(block);
360
361
+
chart2.render(area, buf);
362
+
chart.render(area, buf);
363
+
}
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
364
}