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::{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 let wakeup_health_ck: Vec<_> = (0..24)
60 .flat_map(|hour| (0..60).map(move |min| NaiveTime::from_hms_opt(hour, min, 0).unwrap()))
61 .collect();
62 let wakeup_health_tw = vec![
63 NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
64 NaiveTime::from_hms_opt(6, 0, 0).unwrap(),
65 NaiveTime::from_hms_opt(12, 0, 0).unwrap(),
66 NaiveTime::from_hms_opt(18, 0, 0).unwrap(),
67 ];
68
69 let wakeup_camera = vec![
70 NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
71 NaiveTime::from_hms_opt(3, 0, 0).unwrap(),
72 NaiveTime::from_hms_opt(6, 0, 0).unwrap(),
73 NaiveTime::from_hms_opt(9, 0, 0).unwrap(),
74 NaiveTime::from_hms_opt(12, 0, 0).unwrap(),
75 NaiveTime::from_hms_opt(15, 0, 0).unwrap(),
76 NaiveTime::from_hms_opt(18, 0, 0).unwrap(),
77 NaiveTime::from_hms_opt(21, 0, 0).unwrap(),
78 ];
79
80 let wakeup_twiter: Vec<_> = (0..24)
81 .flat_map(|hour| {
82 (0..60)
83 .step_by(5)
84 .map(move |min| NaiveTime::from_hms_opt(hour, min, 0).unwrap())
85 })
86 .collect();
87
88 let wakeup_discord: Vec<_> = (0..24)
89 .flat_map(|hour| {
90 (0..60)
91 .step_by(10)
92 .map(move |min| NaiveTime::from_hms_opt(hour, min, 0).unwrap())
93 })
94 .collect();
95
96 let mut event_target_list: Vec<SysModArc<dyn SystemModule>> = vec![];
97
98 let sysinfo = Arc::new(TokioMutex::new(SystemInfo::new()));
99 let health = Arc::new(TokioMutex::new(Health::new(
100 wakeup_health_ck,
101 wakeup_health_tw,
102 )?));
103 let camera = Arc::new(TokioMutex::new(Camera::new(wakeup_camera)?));
104 let twitter = Arc::new(TokioMutex::new(Twitter::new(wakeup_twiter)?));
105 let discord = Arc::new(TokioMutex::new(Discord::new(wakeup_discord)?));
106 let line = Arc::new(TokioMutex::new(Line::new()?));
107 let openai = Arc::new(TokioMutex::new(OpenAi::new()?));
108 let http = Arc::new(TokioMutex::new(HttpServer::new()?));
109
110 event_target_list.push(sysinfo.clone());
111 event_target_list.push(health.clone());
112 event_target_list.push(camera.clone());
113 event_target_list.push(twitter.clone());
114 event_target_list.push(discord.clone());
115 event_target_list.push(line.clone());
116 event_target_list.push(openai.clone());
117 event_target_list.push(http.clone());
118
119 info!("OK: initialize system modules");
120 Ok(Self {
121 sysinfo,
122 health,
123 camera,
124 twitter,
125 discord,
126 line,
127 openai,
128 http,
129 event_target_list,
130 })
131 }
132
133 pub async fn on_start(&self, ctrl: &Control) {
134 info!("invoke on_start for system modules...");
135 for sysmod in self.event_target_list.iter() {
136 sysmod.lock().await.on_start(ctrl);
137 }
138 info!("OK: invoke on_start for system modules");
139 }
140}