embassy_ha/
entity_button.rs

1use crate::{Entity, EntityCommonConfig, EntityConfig, constants};
2
3#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
4pub enum ButtonClass {
5    #[default]
6    Generic,
7    Identify,
8    Restart,
9    Update,
10}
11
12#[derive(Debug, Default)]
13pub struct ButtonConfig {
14    pub common: EntityCommonConfig,
15    pub class: ButtonClass,
16}
17
18impl ButtonConfig {
19    pub(crate) fn populate(&self, config: &mut EntityConfig) {
20        self.common.populate(config);
21        config.domain = constants::HA_DOMAIN_BUTTON;
22        config.device_class = match self.class {
23            ButtonClass::Generic => None,
24            ButtonClass::Identify => Some(constants::HA_DEVICE_CLASS_BUTTON_IDENTIFY),
25            ButtonClass::Restart => Some(constants::HA_DEVICE_CLASS_BUTTON_RESTART),
26            ButtonClass::Update => Some(constants::HA_DEVICE_CLASS_BUTTON_UPDATE),
27        };
28    }
29}
30
31pub struct Button<'a>(Entity<'a>);
32
33impl<'a> Button<'a> {
34    pub(crate) fn new(entity: Entity<'a>) -> Self {
35        Self(entity)
36    }
37
38    pub async fn pressed(&mut self) {
39        loop {
40            self.0.wait_command().await;
41            let pressed = self.0.with_data(|data| {
42                let storage = data.storage.as_button_mut();
43                if !storage.consumed && storage.timestamp.is_some() {
44                    storage.consumed = true;
45                    true
46                } else {
47                    false
48                }
49            });
50
51            if pressed {
52                break;
53            }
54        }
55    }
56}