@@ -21,6 +21,7 @@ use std::time::Duration;
21
21
22
22
use async_std:: sync:: Arc ;
23
23
use async_std:: task:: spawn_blocking;
24
+ use serde:: { Deserialize , Serialize } ;
24
25
25
26
use crate :: broker:: { BrokerBuilder , Topic } ;
26
27
use crate :: measurement:: Measurement ;
@@ -59,19 +60,43 @@ mod hw {
59
60
use hw:: { HwMon , SysClass } ;
60
61
61
62
const UPDATE_INTERVAL : Duration = Duration :: from_millis ( 500 ) ;
63
+ const TEMPERATURE_SOC_CRITICAL : f32 = 90.0 ;
64
+ const TEMPERATURE_SOC_HIGH : f32 = 70.0 ;
65
+
66
+ #[ derive( Serialize , Deserialize , PartialEq , Eq , Clone ) ]
67
+ pub enum Warning {
68
+ Okay ,
69
+ SocHigh ,
70
+ SocCritical ,
71
+ }
72
+
73
+ impl Warning {
74
+ fn from_temperatures ( soc : f32 ) -> Self {
75
+ if soc > TEMPERATURE_SOC_CRITICAL {
76
+ Self :: SocCritical
77
+ } else if soc > TEMPERATURE_SOC_HIGH {
78
+ Self :: SocHigh
79
+ } else {
80
+ Self :: Okay
81
+ }
82
+ }
83
+ }
62
84
63
85
pub struct Temperatures {
64
86
pub soc_temperature : Arc < Topic < Measurement > > ,
87
+ pub warning : Arc < Topic < Warning > > ,
65
88
run : Option < Arc < AtomicBool > > ,
66
89
}
67
90
68
91
impl Temperatures {
69
92
pub fn new ( bb : & mut BrokerBuilder ) -> Self {
70
93
let run = Arc :: new ( AtomicBool :: new ( true ) ) ;
71
94
let soc_temperature = bb. topic_ro ( "/v1/tac/temperatures/soc" , None ) ;
95
+ let warning = bb. topic_ro ( "/v1/tac/temperatures/warning" , None ) ;
72
96
73
97
let run_thread = run. clone ( ) ;
74
98
let soc_temperature_thread = soc_temperature. clone ( ) ;
99
+ let warning_thread = warning. clone ( ) ;
75
100
76
101
spawn_blocking ( move || {
77
102
while run_thread. load ( Ordering :: Relaxed ) {
@@ -82,7 +107,15 @@ impl Temperatures {
82
107
. input ( )
83
108
. unwrap ( ) ;
84
109
85
- let meas = Measurement :: now ( val as f32 / 1000.0 ) ;
110
+ let val = val as f32 / 1000.0 ;
111
+
112
+ // Provide a topic that only provides "is overheating"/"is okay"
113
+ // updates and not the 2Hz temperature feed.
114
+ // Subscribing to this topic is cheaper w.r.t. cpu/network use.
115
+ let warning = Warning :: from_temperatures ( val) ;
116
+ warning_thread. set_if_changed ( warning) ;
117
+
118
+ let meas = Measurement :: now ( val) ;
86
119
soc_temperature_thread. set ( meas) ;
87
120
88
121
sleep ( UPDATE_INTERVAL ) ;
@@ -91,6 +124,7 @@ impl Temperatures {
91
124
92
125
Self {
93
126
soc_temperature,
127
+ warning,
94
128
run : Some ( run) ,
95
129
}
96
130
}
0 commit comments