aquarium_control/utilities/
signal_handler_channels.rs

1/* Copyright 2025 Uwe Martin
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
7THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8*/
9use crate::launch::channels::{AquaChannelError, AquaReceiver, AquaSender};
10use crate::utilities::channel_content::InternalCommand;
11use std::fmt;
12
13pub struct SignalHandlerChannels {
14    // --- Channels for each module ---
15    pub tx_signal_handler_to_messaging_opt: Option<AquaSender<InternalCommand>>,
16
17    pub rx_signal_handler_from_messaging_opt: Option<AquaReceiver<bool>>,
18
19    pub tx_signal_handler_to_refill: AquaSender<InternalCommand>,
20
21    pub rx_signal_handler_from_refill: AquaReceiver<bool>,
22
23    pub tx_signal_handler_to_tank_level_switch: AquaSender<InternalCommand>,
24
25    pub rx_signal_handler_from_tank_level_switch: AquaReceiver<bool>,
26
27    pub tx_signal_handler_to_heating: AquaSender<InternalCommand>,
28
29    pub rx_signal_handler_from_heating: AquaReceiver<bool>,
30
31    pub tx_signal_handler_to_relay_manager: AquaSender<InternalCommand>,
32
33    pub rx_signal_handler_from_relay_manager: AquaReceiver<bool>,
34
35    pub tx_signal_handler_to_atlas_scientific: AquaSender<InternalCommand>,
36
37    pub rx_signal_handler_from_atlas_scientific: AquaReceiver<bool>,
38
39    pub tx_signal_handler_to_sensor_manager: AquaSender<InternalCommand>,
40
41    pub rx_signal_handler_from_sensor_manager: AquaReceiver<bool>,
42
43    pub tx_signal_handler_to_data_logger: AquaSender<InternalCommand>,
44
45    pub rx_signal_handler_from_data_logger: AquaReceiver<bool>,
46
47    pub tx_signal_handler_to_balling: AquaSender<InternalCommand>,
48
49    pub rx_signal_handler_from_balling: AquaReceiver<bool>,
50
51    pub tx_signal_handler_to_ventilation: AquaSender<InternalCommand>,
52
53    pub rx_signal_handler_from_ventilation: AquaReceiver<bool>,
54
55    pub tx_signal_handler_to_monitors: AquaSender<InternalCommand>,
56
57    pub rx_signal_handler_from_monitors: AquaReceiver<bool>,
58
59    pub tx_signal_handler_to_feed: AquaSender<InternalCommand>,
60
61    pub rx_signal_handler_from_feed: AquaReceiver<bool>,
62
63    pub tx_signal_handler_to_schedule_check: AquaSender<InternalCommand>,
64
65    pub rx_signal_handler_from_schedule_check: AquaReceiver<bool>,
66
67    pub tx_signal_handler_to_tcp_opt: Option<AquaSender<InternalCommand>>,
68
69    pub rx_signal_handler_from_tcp_opt: Option<AquaReceiver<bool>>,
70
71    pub tx_signal_handler_to_watchdog: AquaSender<InternalCommand>,
72
73    pub rx_signal_handler_from_watchdog: AquaReceiver<bool>,
74
75    pub tx_signal_handler_to_memory: AquaSender<InternalCommand>,
76
77    // Hardware-specific channels
78    pub tx_signal_handler_to_dht: AquaSender<InternalCommand>,
79
80    pub tx_signal_handler_to_i2c_interface: AquaSender<InternalCommand>,
81
82    pub tx_signal_handler_to_ds18b20: AquaSender<InternalCommand>,
83}
84
85impl SignalHandlerChannels {
86    // --- Optional Modules ---
87    #[allow(unused)]
88    pub fn send_to_messaging(
89        &mut self,
90        command: InternalCommand,
91    ) -> Option<Result<(), AquaChannelError>> {
92        self.tx_signal_handler_to_messaging_opt
93            .as_mut()
94            .map(|mut tx| tx.send(command))
95    }
96
97    #[allow(unused)]
98    pub fn receive_from_messaging(&mut self) -> Option<Result<bool, AquaChannelError>> {
99        self.rx_signal_handler_from_messaging_opt
100            .as_mut()
101            .map(|rx| rx.recv())
102    }
103
104    #[allow(unused)]
105    pub fn send_to_tcp(
106        &mut self,
107        command: InternalCommand,
108    ) -> Option<Result<(), AquaChannelError>> {
109        self.tx_signal_handler_to_tcp_opt
110            .as_mut()
111            .map(|mut tx| tx.send(command))
112    }
113
114    #[allow(unused)]
115    pub fn receive_from_tcp(&mut self) -> Option<Result<bool, AquaChannelError>> {
116        self.rx_signal_handler_from_tcp_opt
117            .as_mut()
118            .map(|rx| rx.recv())
119    }
120
121    #[allow(unused)]
122    pub fn send_to_refill(&mut self, command: InternalCommand) -> Result<(), AquaChannelError> {
123        self.tx_signal_handler_to_refill.send(command)
124    }
125
126    #[allow(unused)]
127    pub fn receive_from_refill(&mut self) -> Result<bool, AquaChannelError> {
128        self.rx_signal_handler_from_refill.recv()
129    }
130
131    #[allow(unused)]
132    pub fn send_to_tank_level_switch(
133        &mut self,
134        command: InternalCommand,
135    ) -> Result<(), AquaChannelError> {
136        self.tx_signal_handler_to_tank_level_switch.send(command)
137    }
138
139    #[allow(unused)]
140    pub fn receive_from_tank_level_switch(&mut self) -> Result<bool, AquaChannelError> {
141        self.rx_signal_handler_from_tank_level_switch.recv()
142    }
143
144    #[allow(unused)]
145    pub fn send_to_heating(&mut self, command: InternalCommand) -> Result<(), AquaChannelError> {
146        self.tx_signal_handler_to_heating.send(command)
147    }
148
149    #[allow(unused)]
150    pub fn receive_from_heating(&mut self) -> Result<bool, AquaChannelError> {
151        self.rx_signal_handler_from_heating.recv()
152    }
153
154    #[allow(unused)]
155    pub fn send_to_relay_manager(
156        &mut self,
157        command: InternalCommand,
158    ) -> Result<(), AquaChannelError> {
159        self.tx_signal_handler_to_relay_manager.send(command)
160    }
161
162    #[allow(unused)]
163    pub fn receive_from_relay_manager(&mut self) -> Result<bool, AquaChannelError> {
164        self.rx_signal_handler_from_relay_manager.recv()
165    }
166
167    #[allow(unused)]
168    pub fn send_to_atlas_scientific(
169        &mut self,
170        command: InternalCommand,
171    ) -> Result<(), AquaChannelError> {
172        self.tx_signal_handler_to_atlas_scientific.send(command)
173    }
174
175    #[allow(unused)]
176    pub fn receive_from_atlas_scientific(&mut self) -> Result<bool, AquaChannelError> {
177        self.rx_signal_handler_from_atlas_scientific.recv()
178    }
179
180    #[allow(unused)]
181    pub fn send_to_sensor_manager(
182        &mut self,
183        command: InternalCommand,
184    ) -> Result<(), AquaChannelError> {
185        self.tx_signal_handler_to_sensor_manager.send(command)
186    }
187
188    #[allow(unused)]
189    pub fn receive_from_sensor_manager(&mut self) -> Result<bool, AquaChannelError> {
190        self.rx_signal_handler_from_sensor_manager.recv()
191    }
192
193    #[allow(unused)]
194    pub fn send_to_data_logger(
195        &mut self,
196        command: InternalCommand,
197    ) -> Result<(), AquaChannelError> {
198        self.tx_signal_handler_to_data_logger.send(command)
199    }
200
201    #[allow(unused)]
202    pub fn receive_from_data_logger(&mut self) -> Result<bool, AquaChannelError> {
203        self.rx_signal_handler_from_data_logger.recv()
204    }
205
206    #[allow(unused)]
207    pub fn send_to_balling(&mut self, command: InternalCommand) -> Result<(), AquaChannelError> {
208        self.tx_signal_handler_to_balling.send(command)
209    }
210
211    #[allow(unused)]
212    pub fn receive_from_balling(&mut self) -> Result<bool, AquaChannelError> {
213        self.rx_signal_handler_from_balling.recv()
214    }
215
216    #[allow(unused)]
217    pub fn send_to_ventilation(
218        &mut self,
219        command: InternalCommand,
220    ) -> Result<(), AquaChannelError> {
221        self.tx_signal_handler_to_ventilation.send(command)
222    }
223
224    #[allow(unused)]
225    pub fn receive_from_ventilation(&mut self) -> Result<bool, AquaChannelError> {
226        self.rx_signal_handler_from_ventilation.recv()
227    }
228
229    #[allow(unused)]
230    pub fn send_to_monitors(&mut self, command: InternalCommand) -> Result<(), AquaChannelError> {
231        self.tx_signal_handler_to_monitors.send(command)
232    }
233
234    #[allow(unused)]
235    pub fn receive_from_monitors(&mut self) -> Result<bool, AquaChannelError> {
236        self.rx_signal_handler_from_monitors.recv()
237    }
238
239    #[allow(unused)]
240    pub fn send_to_feed(&mut self, command: InternalCommand) -> Result<(), AquaChannelError> {
241        self.tx_signal_handler_to_feed.send(command)
242    }
243
244    #[allow(unused)]
245    pub fn receive_from_feed(&mut self) -> Result<bool, AquaChannelError> {
246        self.rx_signal_handler_from_feed.recv()
247    }
248
249    #[allow(unused)]
250    pub fn send_to_schedule_check(
251        &mut self,
252        command: InternalCommand,
253    ) -> Result<(), AquaChannelError> {
254        self.tx_signal_handler_to_schedule_check.send(command)
255    }
256
257    #[allow(unused)]
258    pub fn receive_from_schedule_check(&mut self) -> Result<bool, AquaChannelError> {
259        self.rx_signal_handler_from_schedule_check.recv()
260    }
261
262    #[allow(unused)]
263    pub fn send_to_watchdog(&mut self, command: InternalCommand) -> Result<(), AquaChannelError> {
264        self.tx_signal_handler_to_watchdog.send(command)
265    }
266
267    #[allow(unused)]
268    pub fn receive_from_watchdog(&mut self) -> Result<bool, AquaChannelError> {
269        self.rx_signal_handler_from_watchdog.recv()
270    }
271
272    #[allow(unused)]
273    pub fn send_to_memory(&mut self, command: InternalCommand) -> Result<(), AquaChannelError> {
274        self.tx_signal_handler_to_memory.send(command)
275    }
276
277    // --- Hardware-Specific Modules (Send only) ---
278    #[allow(unused)]
279    pub fn send_to_dht(&mut self, command: InternalCommand) -> Result<(), AquaChannelError> {
280        self.tx_signal_handler_to_dht.send(command)
281    }
282
283    #[allow(unused)]
284    pub fn send_to_i2c_interface(
285        &mut self,
286        command: InternalCommand,
287    ) -> Result<(), AquaChannelError> {
288        self.tx_signal_handler_to_i2c_interface.send(command)
289    }
290
291    #[allow(unused)]
292    pub fn send_to_ds18b20(&mut self, command: InternalCommand) -> Result<(), AquaChannelError> {
293        self.tx_signal_handler_to_ds18b20.send(command)
294    }
295}
296
297#[cfg(feature = "debug_channels")]
298impl fmt::Display for SignalHandlerChannels {
299    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300        writeln!(f, "=== Signal Handler Channel Status ===")?;
301        writeln!(
302            f,
303            "tx_signal_handler_to_messaging_opt: {}",
304            self.tx_signal_handler_to_messaging_opt
305                .as_ref()
306                .unwrap()
307                .count
308        )?;
309        writeln!(
310            f,
311            "rx_signal_handler_from_messaging_opt: {}",
312            self.rx_signal_handler_from_messaging_opt
313                .as_ref()
314                .unwrap()
315                .count
316        )?;
317        writeln!(
318            f,
319            "tx_signal_handler_to_refill: {}",
320            self.tx_signal_handler_to_refill.count
321        )?;
322        writeln!(
323            f,
324            "rx_signal_handler_from_refill: {}",
325            self.rx_signal_handler_from_refill.count
326        )?;
327        writeln!(
328            f,
329            "tx_signal_handler_to_tank_level_switch: {}",
330            self.tx_signal_handler_to_tank_level_switch.count
331        )?;
332        writeln!(
333            f,
334            "rx_signal_handler_from_tank_level_switch: {}",
335            self.rx_signal_handler_from_tank_level_switch.count
336        )?;
337        writeln!(
338            f,
339            "tx_signal_handler_to_heating: {}",
340            self.tx_signal_handler_to_heating.count
341        )?;
342        writeln!(
343            f,
344            "rx_signal_handler_from_heating: {}",
345            self.rx_signal_handler_from_heating.count
346        )?;
347        writeln!(
348            f,
349            "tx_signal_handler_to_relay_manager: {}",
350            self.tx_signal_handler_to_relay_manager.count
351        )?;
352        writeln!(
353            f,
354            "rx_signal_handler_from_relay_manager: {}",
355            self.rx_signal_handler_from_relay_manager.count
356        )?;
357        writeln!(
358            f,
359            "tx_signal_handler_to_atlas_scientific: {}",
360            self.tx_signal_handler_to_atlas_scientific.count
361        )?;
362        writeln!(
363            f,
364            "rx_signal_handler_from_atlas_scientific: {}",
365            self.rx_signal_handler_from_atlas_scientific.count
366        )?;
367        writeln!(
368            f,
369            "tx_signal_handler_to_sensor_manager: {}",
370            self.tx_signal_handler_to_sensor_manager.count
371        )?;
372        writeln!(
373            f,
374            "rx_signal_handler_from_sensor_manager: {}",
375            self.rx_signal_handler_from_sensor_manager.count
376        )?;
377        writeln!(
378            f,
379            "tx_signal_handler_to_data_logger: {}",
380            self.tx_signal_handler_to_data_logger.count
381        )?;
382        writeln!(
383            f,
384            "rx_signal_handler_from_data_logger: {}",
385            self.rx_signal_handler_from_data_logger.count
386        )?;
387        writeln!(
388            f,
389            "tx_signal_handler_to_balling: {}",
390            self.tx_signal_handler_to_balling.count
391        )?;
392        writeln!(
393            f,
394            "rx_signal_handler_from_balling: {}",
395            self.rx_signal_handler_from_balling.count
396        )?;
397        writeln!(
398            f,
399            "tx_signal_handler_to_ventilation: {}",
400            self.tx_signal_handler_to_ventilation.count
401        )?;
402        writeln!(
403            f,
404            "rx_signal_handler_from_ventilation: {}",
405            self.rx_signal_handler_from_ventilation.count
406        )?;
407        writeln!(
408            f,
409            "tx_signal_handler_to_monitors: {}",
410            self.tx_signal_handler_to_monitors.count
411        )?;
412        writeln!(
413            f,
414            "rx_signal_handler_from_monitors: {}",
415            self.rx_signal_handler_from_monitors.count
416        )?;
417        writeln!(
418            f,
419            "tx_signal_handler_to_feed: {}",
420            self.tx_signal_handler_to_feed.count
421        )?;
422        writeln!(
423            f,
424            "rx_signal_handler_from_feed: {}",
425            self.rx_signal_handler_from_feed.count
426        )?;
427        writeln!(
428            f,
429            "tx_signal_handler_to_schedule_check: {}",
430            self.tx_signal_handler_to_schedule_check.count
431        )?;
432        writeln!(
433            f,
434            "rx_signal_handler_from_schedule_check: {}",
435            self.rx_signal_handler_from_schedule_check.count
436        )?;
437        writeln!(
438            f,
439            "tx_signal_handler_to_tcp_opt: {}",
440            self.tx_signal_handler_to_tcp_opt.as_ref().unwrap().count
441        )?;
442        writeln!(
443            f,
444            "rx_signal_handler_from_tcp_opt: {}",
445            self.rx_signal_handler_from_tcp_opt.as_ref().unwrap().count
446        )?;
447        writeln!(
448            f,
449            "tx_signal_handler_to_watchdog: {}",
450            self.tx_signal_handler_to_watchdog.count
451        )?;
452        writeln!(
453            f,
454            "rx_signal_handler_from_watchdog: {}",
455            self.rx_signal_handler_from_watchdog.count
456        )?;
457
458        writeln!(
459            f,
460            "tx_signal_handler_to_dht: {}",
461            self.tx_signal_handler_to_dht.count
462        )?;
463        writeln!(
464            f,
465            "tx_signal_handler_to_i2c_interface: {}",
466            self.tx_signal_handler_to_i2c_interface.count
467        )?;
468        writeln!(
469            f,
470            "tx_signal_handler_to_ds18b20: {}",
471            self.tx_signal_handler_to_ds18b20.count
472        )?;
473
474        Ok(())
475    }
476}
477
478#[cfg(not(feature = "debug_channels"))]
479impl fmt::Display for SignalHandlerChannels {
480    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
481        write!(
482            f,
483            "Channel counters are not active. Use --features \"debug_channels\" to enable them."
484        )
485    }
486}