use async_trait::async_trait;
use anyhow::{Result, bail};
use chrono::Utc;
use super::{Sensor, SensorReading, SensorType, SensorStatus, CalibrationData};
pub struct MLX90640Sensor {
id: String,
status: SensorStatus,
sample_rate: f64,
sequence: u64,
#[cfg(feature = "serial")]
port: Option<Box<dyn serialport::SerialPort>>,
}
impl MLX90640Sensor {
pub fn new(id: &str, port_name: &str) -> Self {
Self {
id: id.to_string(),
status: SensorStatus::Disconnected,
sample_rate: 4.0, sequence: 0,
#[cfg(feature = "serial")]
port: None,
}
}
}
#[async_trait]
impl Sensor for MLX90640Sensor {
fn id(&self) -> &str { &self.id }
fn sensor_type(&self) -> SensorType { SensorType::ThermalArray }
fn status(&self) -> SensorStatus { self.status }
async fn connect(&mut self) -> Result<()> {
self.status = SensorStatus::Connected;
Ok(())
}
async fn disconnect(&mut self) -> Result<()> {
self.status = SensorStatus::Disconnected;
Ok(())
}
async fn calibrate(&mut self) -> Result<CalibrationData> {
self.status = SensorStatus::Active;
Ok(CalibrationData {
offset: vec![0.0; 768],
scale: vec![1.0; 768],
noise_floor: 0.5,
timestamp: Utc::now(),
temperature: Some(25.0),
notes: "MLX90640 factory calibration".to_string(),
signature: vec![],
})
}
async fn read(&mut self) -> Result<SensorReading> {
self.sequence += 1;
bail!("Hardware not connected - use simulator")
}
fn sample_rate(&self) -> f64 { self.sample_rate }
fn set_sample_rate(&mut self, rate: f64) -> Result<()> {
self.sample_rate = rate.min(64.0);
Ok(())
}
fn config(&self) -> serde_json::Value {
serde_json::json!({ "refresh_rate": self.sample_rate })
}
fn set_config(&mut self, config: serde_json::Value) -> Result<()> {
if let Some(rate) = config.get("refresh_rate").and_then(|v| v.as_f64()) {
self.sample_rate = rate.min(64.0);
}
Ok(())
}
}
pub struct AMG8833Sensor {
id: String,
status: SensorStatus,
sample_rate: f64,
sequence: u64,
}
impl AMG8833Sensor {
pub fn new(id: &str) -> Self {
Self {
id: id.to_string(),
status: SensorStatus::Disconnected,
sample_rate: 10.0, sequence: 0,
}
}
}
#[async_trait]
impl Sensor for AMG8833Sensor {
fn id(&self) -> &str { &self.id }
fn sensor_type(&self) -> SensorType { SensorType::ThermalArray }
fn status(&self) -> SensorStatus { self.status }
async fn connect(&mut self) -> Result<()> {
self.status = SensorStatus::Connected;
Ok(())
}
async fn disconnect(&mut self) -> Result<()> {
self.status = SensorStatus::Disconnected;
Ok(())
}
async fn calibrate(&mut self) -> Result<CalibrationData> {
self.status = SensorStatus::Active;
Ok(CalibrationData {
offset: vec![0.0; 64],
scale: vec![1.0; 64],
noise_floor: 0.25,
timestamp: Utc::now(),
temperature: Some(25.0),
notes: "AMG8833 calibration".to_string(),
signature: vec![],
})
}
async fn read(&mut self) -> Result<SensorReading> {
self.sequence += 1;
bail!("Hardware not connected - use simulator")
}
fn sample_rate(&self) -> f64 { self.sample_rate }
fn set_sample_rate(&mut self, rate: f64) -> Result<()> {
self.sample_rate = rate.min(10.0);
Ok(())
}
fn config(&self) -> serde_json::Value { serde_json::json!({}) }
fn set_config(&mut self, _config: serde_json::Value) -> Result<()> { Ok(()) }
}