Skip to content

Commit 1c577de

Browse files
committed
screens: iobus_health: add an alert screen in case of an overloaded iobus
Signed-off-by: Leonard Göhrs <l.goehrs@pengutronix.de>
1 parent 58efd02 commit 1c577de

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

src/ui/screens.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use serde::{Deserialize, Serialize};
2929
mod dig_out;
3030
mod help;
3131
mod iobus;
32+
mod iobus_health;
3233
mod locator;
3334
mod power;
3435
mod reboot;
@@ -43,6 +44,7 @@ mod usb;
4344
use dig_out::DigOutScreen;
4445
use help::HelpScreen;
4546
use iobus::IoBusScreen;
47+
use iobus_health::IoBusHealthScreen;
4648
use locator::LocatorScreen;
4749
use power::PowerScreen;
4850
use reboot::RebootConfirmScreen;
@@ -75,6 +77,7 @@ pub enum NormalScreen {
7577
#[derive(Serialize, Deserialize, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Debug)]
7678
pub enum AlertScreen {
7779
ScreenSaver,
80+
IoBusHealth,
7881
Locator,
7982
RebootConfirm,
8083
UpdateAvailable,
@@ -185,6 +188,7 @@ pub(super) fn init(
185188
Box::new(UartScreen::new()),
186189
Box::new(UsbScreen::new()),
187190
Box::new(HelpScreen::new(alerts, &res.setup_mode.show_help)),
191+
Box::new(IoBusHealthScreen::new(alerts, &res.iobus.supply_fault)),
188192
Box::new(UpdateInstallationScreen::new(
189193
alerts,
190194
&res.rauc.operation,

src/ui/screens/iobus_health.rs

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// This file is part of tacd, the LXA TAC system daemon
2+
// Copyright (C) 2023 Pengutronix e.K.
3+
//
4+
// This program is free software; you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation; either version 2 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License along
15+
// with this program; if not, write to the Free Software Foundation, Inc.,
16+
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17+
18+
use async_std::prelude::*;
19+
use async_std::sync::Arc;
20+
use async_std::task::spawn;
21+
use async_trait::async_trait;
22+
use embedded_graphics::{
23+
mono_font::MonoTextStyle, pixelcolor::BinaryColor, prelude::*, text::Text,
24+
};
25+
26+
use super::widgets::*;
27+
use super::{
28+
row_anchor, ActivatableScreen, ActiveScreen, AlertList, AlertScreen, Alerter, Display,
29+
InputEvent, Screen, Ui,
30+
};
31+
use crate::broker::Topic;
32+
use crate::measurement::Measurement;
33+
34+
const SCREEN_TYPE: AlertScreen = AlertScreen::IoBusHealth;
35+
36+
pub struct IoBusHealthScreen;
37+
38+
struct Active {
39+
widgets: WidgetContainer,
40+
alerts: Arc<Topic<AlertList>>,
41+
}
42+
43+
impl IoBusHealthScreen {
44+
pub fn new(alerts: &Arc<Topic<AlertList>>, supply_fault: &Arc<Topic<bool>>) -> Self {
45+
let (mut supply_fault_events, _) = supply_fault.clone().subscribe_unbounded();
46+
let alerts = alerts.clone();
47+
48+
spawn(async move {
49+
while let Some(fault) = supply_fault_events.next().await {
50+
if fault {
51+
alerts.assert(SCREEN_TYPE);
52+
} else {
53+
alerts.deassert(SCREEN_TYPE);
54+
}
55+
}
56+
});
57+
58+
Self
59+
}
60+
}
61+
62+
impl ActivatableScreen for IoBusHealthScreen {
63+
fn my_type(&self) -> Screen {
64+
Screen::Alert(SCREEN_TYPE)
65+
}
66+
67+
fn activate(&mut self, ui: &Ui, display: Display) -> Box<dyn ActiveScreen> {
68+
let ui_text_style: MonoTextStyle<BinaryColor> =
69+
MonoTextStyle::new(&UI_TEXT_FONT, BinaryColor::On);
70+
71+
display.with_lock(|target| {
72+
Text::new(
73+
"IOBus supply overload",
74+
row_anchor(0) - (row_anchor(1) - row_anchor(0)),
75+
ui_text_style,
76+
)
77+
.draw(target)
78+
.unwrap();
79+
80+
Text::new(
81+
"The IOBus supply is\noverloaded by a short\nor too many devices.",
82+
row_anchor(1),
83+
ui_text_style,
84+
)
85+
.draw(target)
86+
.unwrap();
87+
88+
Text::new("> Dismiss", row_anchor(8), ui_text_style)
89+
.draw(target)
90+
.unwrap();
91+
});
92+
93+
let mut widgets = WidgetContainer::new(display);
94+
95+
widgets.push(|display| {
96+
DynamicWidget::text(
97+
ui.res.adc.iobus_volt.topic.clone(),
98+
display,
99+
row_anchor(5),
100+
Box::new(|meas: &Measurement| format!(" {:-6.2}V / 12V", meas.value)),
101+
)
102+
});
103+
104+
widgets.push(|display| {
105+
DynamicWidget::text(
106+
ui.res.adc.iobus_curr.topic.clone(),
107+
display,
108+
row_anchor(6),
109+
Box::new(|meas: &Measurement| format!(" {:-6.2}A / 0.2A", meas.value)),
110+
)
111+
});
112+
113+
let alerts = ui.alerts.clone();
114+
115+
Box::new(Active { widgets, alerts })
116+
}
117+
}
118+
119+
#[async_trait]
120+
impl ActiveScreen for Active {
121+
fn my_type(&self) -> Screen {
122+
Screen::Alert(SCREEN_TYPE)
123+
}
124+
125+
async fn deactivate(mut self: Box<Self>) -> Display {
126+
self.widgets.destroy().await
127+
}
128+
129+
fn input(&mut self, ev: InputEvent) {
130+
match ev {
131+
InputEvent::NextScreen | InputEvent::ToggleAction(_) => {}
132+
InputEvent::PerformAction(_) => {
133+
self.alerts.deassert(SCREEN_TYPE);
134+
}
135+
}
136+
}
137+
}

0 commit comments

Comments
 (0)