embassy_ha/
entity_binary_sensor.rs

1use crate::{BinarySensorState, BinaryState, Entity, EntityCommonConfig, EntityConfig, constants};
2
3#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
4pub enum BinarySensorClass {
5    #[default]
6    Generic,
7    Battery,
8    BatteryCharging,
9    Connectivity,
10    Door,
11    GarageDoor,
12    Motion,
13    Occupancy,
14    Opening,
15    Plug,
16    Power,
17    Presence,
18    Problem,
19    Smoke,
20    Window,
21}
22
23#[derive(Debug, Default)]
24pub struct BinarySensorConfig {
25    pub common: EntityCommonConfig,
26    pub class: BinarySensorClass,
27}
28
29impl BinarySensorConfig {
30    pub(crate) fn populate(&self, config: &mut EntityConfig) {
31        self.common.populate(config);
32        config.domain = constants::HA_DOMAIN_BINARY_SENSOR;
33        config.device_class = match self.class {
34            BinarySensorClass::Generic => None,
35            BinarySensorClass::Battery => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_BATTERY),
36            BinarySensorClass::BatteryCharging => {
37                Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_BATTERY_CHARGING)
38            }
39            BinarySensorClass::Connectivity => {
40                Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_CONNECTIVITY)
41            }
42            BinarySensorClass::Door => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_DOOR),
43            BinarySensorClass::GarageDoor => {
44                Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_GARAGE_DOOR)
45            }
46            BinarySensorClass::Motion => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_MOTION),
47            BinarySensorClass::Occupancy => {
48                Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_OCCUPANCY)
49            }
50            BinarySensorClass::Opening => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_OPENING),
51            BinarySensorClass::Plug => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_PLUG),
52            BinarySensorClass::Power => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_POWER),
53            BinarySensorClass::Presence => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_PRESENCE),
54            BinarySensorClass::Problem => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_PROBLEM),
55            BinarySensorClass::Smoke => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_SMOKE),
56            BinarySensorClass::Window => Some(constants::HA_DEVICE_CLASS_BINARY_SENSOR_WINDOW),
57        };
58    }
59}
60
61pub struct BinarySensor<'a>(Entity<'a>);
62
63impl<'a> BinarySensor<'a> {
64    pub(crate) fn new(entity: Entity<'a>) -> Self {
65        Self(entity)
66    }
67
68    pub fn set(&mut self, state: BinaryState) {
69        let publish = self.0.with_data(|data| {
70            let storage = data.storage.as_binary_sensor_mut();
71            let publish = match &storage.state {
72                Some(s) => s.value != state,
73                None => true,
74            };
75            storage.state = Some(BinarySensorState {
76                value: state,
77                timestamp: embassy_time::Instant::now(),
78            });
79            publish
80        });
81        if publish {
82            self.0.queue_publish();
83        }
84    }
85
86    pub fn value(&self) -> Option<BinaryState> {
87        self.0.with_data(|data| {
88            let storage = data.storage.as_binary_sensor_mut();
89            storage.state.as_ref().map(|s| s.value)
90        })
91    }
92
93    pub fn toggle(&mut self) -> BinaryState {
94        let new_state = self.value().unwrap_or(BinaryState::Off).flip();
95        self.set(new_state);
96        new_state
97    }
98}