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}