93 lines
2.2 KiB
Rust
93 lines
2.2 KiB
Rust
use async_trait::async_trait;
|
|
use rumqttc::Publish;
|
|
use serde::Deserialize;
|
|
use tracing::{debug, trace, warn};
|
|
|
|
use crate::{
|
|
config::MqttDeviceConfig,
|
|
devices::Device,
|
|
event::{self, Event, EventChannel},
|
|
messages::BrightnessMessage,
|
|
traits::OnMqtt,
|
|
};
|
|
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
pub struct LightSensorConfig {
|
|
#[serde(flatten)]
|
|
pub mqtt: MqttDeviceConfig,
|
|
pub min: isize,
|
|
pub max: isize,
|
|
}
|
|
|
|
pub const DEFAULT: bool = false;
|
|
|
|
#[derive(Debug)]
|
|
pub struct LightSensor {
|
|
tx: event::Sender,
|
|
mqtt: MqttDeviceConfig,
|
|
min: isize,
|
|
max: isize,
|
|
is_dark: bool,
|
|
}
|
|
|
|
impl LightSensor {
|
|
pub fn new(config: LightSensorConfig, event_channel: &EventChannel) -> Self {
|
|
Self {
|
|
tx: event_channel.get_tx(),
|
|
mqtt: config.mqtt,
|
|
min: config.min,
|
|
max: config.max,
|
|
is_dark: DEFAULT,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Device for LightSensor {
|
|
fn get_id(&self) -> &str {
|
|
"light_sensor"
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl OnMqtt for LightSensor {
|
|
fn topics(&self) -> Vec<&str> {
|
|
vec![&self.mqtt.topic]
|
|
}
|
|
|
|
async fn on_mqtt(&mut self, message: Publish) {
|
|
let illuminance = match BrightnessMessage::try_from(message) {
|
|
Ok(state) => state.illuminance(),
|
|
Err(err) => {
|
|
warn!("Failed to parse message: {err}");
|
|
return;
|
|
}
|
|
};
|
|
|
|
debug!("Illuminance: {illuminance}");
|
|
let is_dark = if illuminance <= self.min {
|
|
trace!("It is dark");
|
|
true
|
|
} else if illuminance >= self.max {
|
|
trace!("It is light");
|
|
false
|
|
} else {
|
|
trace!(
|
|
"In between min ({}) and max ({}) value, keeping current state: {}",
|
|
self.min,
|
|
self.max,
|
|
self.is_dark
|
|
);
|
|
self.is_dark
|
|
};
|
|
|
|
if is_dark != self.is_dark {
|
|
debug!("Dark state has changed: {is_dark}");
|
|
self.is_dark = is_dark;
|
|
|
|
if self.tx.send(Event::Darkness(is_dark)).await.is_err() {
|
|
warn!("There are no receivers on the event channel");
|
|
}
|
|
}
|
|
}
|
|
}
|