1pub mod camera;
4pub mod discord;
5pub mod health;
6pub mod http;
7pub mod line;
8pub mod openai;
9pub mod sysinfo;
10pub mod twitter;
11
12use self::{
13 camera::Camera, discord::Discord, health::Health, http::HttpServer, openai::OpenAi,
14 sysinfo::SystemInfo, twitter::Twitter,
15};
16use crate::{rpienv, sysmod::line::Line, taskserver::Control};
17use anyhow::Result;
18use chrono::NaiveTime;
19use log::info;
20use std::sync::Arc;
21use tokio::sync::Mutex as TokioMutex;
22
23pub trait SystemModule: Sync + Send {
25 fn on_start(&mut self, _ctrl: &Control) {}
28}
29
30type SysModArc<T> = Arc<TokioMutex<T>>;
33
34pub struct SystemModules {
42 pub sysinfo: SysModArc<sysinfo::SystemInfo>,
43 pub health: SysModArc<health::Health>,
44 pub camera: SysModArc<camera::Camera>,
45 pub twitter: SysModArc<twitter::Twitter>,
46 pub discord: SysModArc<discord::Discord>,
47 pub line: SysModArc<line::Line>,
48 pub openai: SysModArc<openai::OpenAi>,
49 pub http: SysModArc<http::HttpServer>,
50
51 event_target_list: Vec<SysModArc<dyn SystemModule>>,
53}
54
55impl SystemModules {
56 pub fn new() -> Result<SystemModules> {
57 info!("initialize system modules...");
58
59 info!("get Raspberry Pi info...");
60 let rpienv = rpienv::raspi_env();
61 info!("{}", rpienv);
62
63 let wakeup_health_ck: Vec<_> = (0..24)
64 .flat_map(|hour| (0..60).map(move |min| NaiveTime::from_hms_opt(hour, min, 0).unwrap()))
65 .collect();
66 let wakeup_health_tw = vec![
67 NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
68 NaiveTime::from_hms_opt(6, 0, 0).unwrap(),
69 NaiveTime::from_hms_opt(12, 0, 0).unwrap(),
70 NaiveTime::from_hms_opt(18, 0, 0).unwrap(),
71 ];
72
73 let wakeup_camera = vec![
74 NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
75 NaiveTime::from_hms_opt(3, 0, 0).unwrap(),
76 NaiveTime::from_hms_opt(6, 0, 0).unwrap(),
77 NaiveTime::from_hms_opt(9, 0, 0).unwrap(),
78 NaiveTime::from_hms_opt(12, 0, 0).unwrap(),
79 NaiveTime::from_hms_opt(15, 0, 0).unwrap(),
80 NaiveTime::from_hms_opt(18, 0, 0).unwrap(),
81 NaiveTime::from_hms_opt(21, 0, 0).unwrap(),
82 ];
83
84 let wakeup_twiter: Vec<_> = (0..24)
85 .flat_map(|hour| {
86 (0..60)
87 .step_by(5)
88 .map(move |min| NaiveTime::from_hms_opt(hour, min, 0).unwrap())
89 })
90 .collect();
91
92 let wakeup_discord: Vec<_> = (0..24)
93 .flat_map(|hour| {
94 (0..60)
95 .step_by(10)
96 .map(move |min| NaiveTime::from_hms_opt(hour, min, 0).unwrap())
97 })
98 .collect();
99
100 let mut event_target_list: Vec<SysModArc<dyn SystemModule>> = vec![];
101
102 let sysinfo = Arc::new(TokioMutex::new(SystemInfo::new()));
103 let health = Arc::new(TokioMutex::new(Health::new(
104 wakeup_health_ck,
105 wakeup_health_tw,
106 )?));
107 let camera = Arc::new(TokioMutex::new(Camera::new(wakeup_camera)?));
108 let twitter = Arc::new(TokioMutex::new(Twitter::new(wakeup_twiter)?));
109 let discord = Arc::new(TokioMutex::new(Discord::new(wakeup_discord)?));
110 let line = Arc::new(TokioMutex::new(Line::new()?));
111 let openai = Arc::new(TokioMutex::new(OpenAi::new()?));
112 let http = Arc::new(TokioMutex::new(HttpServer::new()?));
113
114 event_target_list.push(sysinfo.clone());
115 event_target_list.push(health.clone());
116 event_target_list.push(camera.clone());
117 event_target_list.push(twitter.clone());
118 event_target_list.push(discord.clone());
119 event_target_list.push(line.clone());
120 event_target_list.push(openai.clone());
121 event_target_list.push(http.clone());
122
123 info!("OK: initialize system modules");
124 Ok(Self {
125 sysinfo,
126 health,
127 camera,
128 twitter,
129 discord,
130 line,
131 openai,
132 http,
133 event_target_list,
134 })
135 }
136
137 pub async fn on_start(&self, ctrl: &Control) {
138 info!("invoke on_start for system modules...");
139 for sysmod in self.event_target_list.iter() {
140 sysmod.lock().await.on_start(ctrl);
141 }
142 info!("OK: invoke on_start for system modules");
143 }
144}