aranet_core/traits.rs
1//! Trait abstractions for Aranet device operations.
2//!
3//! This module provides the [`AranetDevice`] trait that abstracts over
4//! real Bluetooth devices and mock devices for testing.
5
6use async_trait::async_trait;
7
8use aranet_types::{CurrentReading, DeviceInfo, DeviceType, HistoryRecord};
9
10use crate::error::Result;
11use crate::history::{HistoryInfo, HistoryOptions};
12use crate::settings::{CalibrationData, MeasurementInterval};
13
14/// Trait abstracting Aranet device operations.
15///
16/// This trait enables writing code that works with both real Bluetooth devices
17/// and mock devices for testing. Implement this trait for any type that can
18/// provide Aranet sensor data.
19///
20/// # Example
21///
22/// ```ignore
23/// use aranet_core::{AranetDevice, Result};
24///
25/// async fn print_reading<D: AranetDevice>(device: &D) -> Result<()> {
26/// let reading = device.read_current().await?;
27/// println!("CO2: {} ppm", reading.co2);
28/// Ok(())
29/// }
30/// ```
31#[async_trait]
32pub trait AranetDevice: Send + Sync {
33 // --- Connection Management ---
34
35 /// Check if the device is connected.
36 async fn is_connected(&self) -> bool;
37
38 /// Connect to the device.
39 ///
40 /// For devices that are already connected, this should be a no-op.
41 /// For devices that support reconnection, this should attempt to reconnect.
42 ///
43 /// The default implementation returns `Ok(())` for backwards compatibility.
44 async fn connect(&self) -> Result<()> {
45 Ok(())
46 }
47
48 /// Disconnect from the device.
49 async fn disconnect(&self) -> Result<()>;
50
51 // --- Device Identity ---
52
53 /// Get the device name, if available.
54 fn name(&self) -> Option<&str>;
55
56 /// Get the device address or identifier.
57 ///
58 /// On Linux/Windows this is typically the MAC address.
59 /// On macOS this is a UUID since MAC addresses are not exposed.
60 fn address(&self) -> &str;
61
62 /// Get the detected device type, if available.
63 fn device_type(&self) -> Option<DeviceType>;
64
65 // --- Current Readings ---
66
67 /// Read the current sensor values.
68 async fn read_current(&self) -> Result<CurrentReading>;
69
70 /// Read device information (model, serial, firmware version, etc.).
71 async fn read_device_info(&self) -> Result<DeviceInfo>;
72
73 /// Read the current RSSI (signal strength) in dBm.
74 ///
75 /// More negative values indicate weaker signals.
76 /// Typical values range from -30 (strong) to -90 (weak).
77 async fn read_rssi(&self) -> Result<i16>;
78
79 // --- Battery ---
80
81 /// Read the battery level (0-100).
82 async fn read_battery(&self) -> Result<u8>;
83
84 // --- History ---
85
86 /// Get information about stored history.
87 async fn get_history_info(&self) -> Result<HistoryInfo>;
88
89 /// Download all historical readings.
90 async fn download_history(&self) -> Result<Vec<HistoryRecord>>;
91
92 /// Download historical readings with custom options.
93 async fn download_history_with_options(
94 &self,
95 options: HistoryOptions,
96 ) -> Result<Vec<HistoryRecord>>;
97
98 // --- Settings ---
99
100 /// Get the current measurement interval.
101 async fn get_interval(&self) -> Result<MeasurementInterval>;
102
103 /// Set the measurement interval.
104 async fn set_interval(&self, interval: MeasurementInterval) -> Result<()>;
105
106 /// Read calibration data from the device.
107 async fn get_calibration(&self) -> Result<CalibrationData>;
108}