diff --git a/CODEOWNERS b/CODEOWNERS index 5a34fab49a9..f5a81e04a6e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -214,8 +214,8 @@ homeassistant/components/digital_ocean/* @fabaff homeassistant/components/discogs/* @thibmaek homeassistant/components/dlna_dmr/* @StevenLooman @chishm tests/components/dlna_dmr/* @StevenLooman @chishm -homeassistant/components/doorbird/* @oblogic7 @bdraco -tests/components/doorbird/* @oblogic7 @bdraco +homeassistant/components/doorbird/* @oblogic7 @bdraco @flacjacket +tests/components/doorbird/* @oblogic7 @bdraco @flacjacket homeassistant/components/dsmr/* @Robbie1221 @frenck tests/components/dsmr/* @Robbie1221 @frenck homeassistant/components/dsmr_reader/* @depl0y diff --git a/homeassistant/components/doorbird/button.py b/homeassistant/components/doorbird/button.py new file mode 100644 index 00000000000..b823c81c6d0 --- /dev/null +++ b/homeassistant/components/doorbird/button.py @@ -0,0 +1,94 @@ +"""Support for powering relays in a DoorBird video doorbell.""" + +from collections.abc import Callable +from dataclasses import dataclass + +from doorbirdpy import DoorBird + +from homeassistant.components.button import ButtonEntity, ButtonEntityDescription +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN, DOOR_STATION, DOOR_STATION_INFO +from .entity import DoorBirdEntity + +IR_RELAY = "__ir_light__" + + +@dataclass +class DoorbirdButtonEntityDescriptionMixin: + """Mixin to describe a Doorbird Button entity.""" + + press_action: Callable[[DoorBird, str], None] + + +@dataclass +class DoorbirdButtonEntityDescription( + ButtonEntityDescription, DoorbirdButtonEntityDescriptionMixin +): + """Class to describe a Doorbird Button entity.""" + + +RELAY_ENTITY_DESCRIPTION = DoorbirdButtonEntityDescription( + key="relay", + press_action=lambda device, relay: device.energize_relay(relay), + icon="mdi:dip-switch", +) +IR_ENTITY_DESCRIPTION = DoorbirdButtonEntityDescription( + key="ir", + press_action=lambda device, _: device.turn_light_on(), + icon="mdi:lightbulb", +) + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up the DoorBird button platform.""" + config_entry_id = config_entry.entry_id + + data = hass.data[DOMAIN][config_entry_id] + doorstation = data[DOOR_STATION] + doorstation_info = data[DOOR_STATION_INFO] + + relays = doorstation_info["RELAYS"] + + entities = [ + DoorBirdButton(doorstation, doorstation_info, relay, RELAY_ENTITY_DESCRIPTION) + for relay in relays + ] + entities.append( + DoorBirdButton(doorstation, doorstation_info, IR_RELAY, IR_ENTITY_DESCRIPTION) + ) + + async_add_entities(entities) + + +class DoorBirdButton(DoorBirdEntity, ButtonEntity): + """A relay in a DoorBird device.""" + + def __init__( + self, + doorstation: DoorBird, + doorstation_info, + relay: str, + entity_description: DoorbirdButtonEntityDescription, + ) -> None: + """Initialize a relay in a DoorBird device.""" + super().__init__(doorstation, doorstation_info) + self._doorstation = doorstation + self._relay = relay + self.entity_description = entity_description + + if self._relay == IR_RELAY: + self._attr_name = f"{self._doorstation.name} IR" + else: + self._attr_name = f"{self._doorstation.name} Relay {self._relay}" + self._attr_unique_id = f"{self._mac_addr}_{self._relay}" + + def press(self) -> None: + """Power the relay.""" + self.entity_description.press_action(self._doorstation.device, self._relay) diff --git a/homeassistant/components/doorbird/const.py b/homeassistant/components/doorbird/const.py index 46c37e5b050..767366af734 100644 --- a/homeassistant/components/doorbird/const.py +++ b/homeassistant/components/doorbird/const.py @@ -2,7 +2,7 @@ from homeassistant.const import Platform DOMAIN = "doorbird" -PLATFORMS = [Platform.SWITCH, Platform.CAMERA] +PLATFORMS = [Platform.BUTTON, Platform.CAMERA] DOOR_STATION = "door_station" DOOR_STATION_INFO = "door_station_info" DOOR_STATION_EVENT_ENTITY_IDS = "door_station_event_entity_ids" diff --git a/homeassistant/components/doorbird/manifest.json b/homeassistant/components/doorbird/manifest.json index b379dab7e98..08c77f048a0 100644 --- a/homeassistant/components/doorbird/manifest.json +++ b/homeassistant/components/doorbird/manifest.json @@ -10,7 +10,7 @@ "properties": {"macaddress": "1ccae3*"} } ], - "codeowners": ["@oblogic7", "@bdraco"], + "codeowners": ["@oblogic7", "@bdraco", "@flacjacket"], "config_flow": true, "iot_class": "local_push" } diff --git a/homeassistant/components/doorbird/switch.py b/homeassistant/components/doorbird/switch.py deleted file mode 100644 index 6d5db220e77..00000000000 --- a/homeassistant/components/doorbird/switch.py +++ /dev/null @@ -1,112 +0,0 @@ -"""Support for powering relays in a DoorBird video doorbell.""" -import datetime - -from homeassistant.components.switch import SwitchEntity -from homeassistant.config_entries import ConfigEntry -from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_point_in_utc_time -import homeassistant.util.dt as dt_util - -from .const import DOMAIN, DOOR_STATION, DOOR_STATION_INFO -from .entity import DoorBirdEntity - -IR_RELAY = "__ir_light__" - - -async def async_setup_entry( - hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, -) -> None: - """Set up the DoorBird switch platform.""" - entities = [] - config_entry_id = config_entry.entry_id - - data = hass.data[DOMAIN][config_entry_id] - doorstation = data[DOOR_STATION] - doorstation_info = data[DOOR_STATION_INFO] - - relays = doorstation_info["RELAYS"] - relays.append(IR_RELAY) - - for relay in relays: - switch = DoorBirdSwitch(doorstation, doorstation_info, relay) - entities.append(switch) - - async_add_entities(entities) - - -class DoorBirdSwitch(DoorBirdEntity, SwitchEntity): - """A relay in a DoorBird device.""" - - def __init__(self, doorstation, doorstation_info, relay): - """Initialize a relay in a DoorBird device.""" - super().__init__(doorstation, doorstation_info) - self._doorstation = doorstation - self._relay = relay - self._state = False - - if relay == IR_RELAY: - self._time = datetime.timedelta(minutes=5) - else: - self._time = datetime.timedelta(seconds=5) - self._unique_id = f"{self._mac_addr}_{self._relay}" - self._reset_sub = None - - @property - def unique_id(self): - """Switch unique id.""" - return self._unique_id - - @property - def name(self): - """Return the name of the switch.""" - if self._relay == IR_RELAY: - return f"{self._doorstation.name} IR" - - return f"{self._doorstation.name} Relay {self._relay}" - - @property - def icon(self): - """Return the icon to display.""" - return "mdi:lightbulb" if self._relay == IR_RELAY else "mdi:dip-switch" - - @property - def should_poll(self): - """No need to poll.""" - return False - - @property - def is_on(self): - """Get the assumed state of the relay.""" - return self._state - - async def async_turn_on(self, **kwargs): - """Power the relay.""" - if self._reset_sub is not None: - self._reset_sub() - self._reset_sub = None - self._reset_sub = async_track_point_in_utc_time( - self.hass, self._async_turn_off, dt_util.utcnow() + self._time - ) - await self.hass.async_add_executor_job(self._turn_on) - self.async_write_ha_state() - - def _turn_on(self): - """Power the relay.""" - if self._relay == IR_RELAY: - self._state = self._doorstation.device.turn_light_on() - else: - self._state = self._doorstation.device.energize_relay(self._relay) - - async def async_turn_off(self, **kwargs): - """Turn off the relays is not needed. They are time-based.""" - raise NotImplementedError("DoorBird relays cannot be manually turned off.") - - @callback - def _async_turn_off(self, *_): - """Wait for the correct amount of assumed time to pass.""" - self._state = False - self._reset_sub = None - self.async_write_ha_state()