Add Ring Intercom open door button (#113514)
* Add button * Make Ruff happy * Apply suggestions from code review Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Fix doc string * Format * Update tests/components/ring/test_button.py --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
a9fb34d9c2
commit
4107cd6ad8
6 changed files with 119 additions and 0 deletions
57
homeassistant/components/ring/button.py
Normal file
57
homeassistant/components/ring/button.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
"""Component providing support for Ring buttons."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
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, RING_DEVICES, RING_DEVICES_COORDINATOR
|
||||
from .coordinator import RingDataCoordinator
|
||||
from .entity import RingEntity, exception_wrap
|
||||
|
||||
BUTTON_DESCRIPTION = ButtonEntityDescription(
|
||||
key="open_door", translation_key="open_door"
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Create the buttons for the Ring devices."""
|
||||
devices = hass.data[DOMAIN][config_entry.entry_id][RING_DEVICES]
|
||||
devices_coordinator: RingDataCoordinator = hass.data[DOMAIN][config_entry.entry_id][
|
||||
RING_DEVICES_COORDINATOR
|
||||
]
|
||||
|
||||
async_add_entities(
|
||||
RingDoorButton(device, devices_coordinator, BUTTON_DESCRIPTION)
|
||||
for device in devices["other"]
|
||||
if device.has_capability("open")
|
||||
)
|
||||
|
||||
|
||||
class RingDoorButton(RingEntity, ButtonEntity):
|
||||
"""Creates a button to open the ring intercom door."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
device,
|
||||
coordinator,
|
||||
description: ButtonEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the button."""
|
||||
super().__init__(
|
||||
device,
|
||||
coordinator,
|
||||
)
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{device.id}-{description.key}"
|
||||
|
||||
@exception_wrap
|
||||
def press(self) -> None:
|
||||
"""Open the door."""
|
||||
self._device.open_door()
|
|
@ -16,6 +16,7 @@ DEFAULT_ENTITY_NAMESPACE = "ring"
|
|||
|
||||
PLATFORMS = [
|
||||
Platform.BINARY_SENSOR,
|
||||
Platform.BUTTON,
|
||||
Platform.CAMERA,
|
||||
Platform.LIGHT,
|
||||
Platform.SENSOR,
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
"voice_volume": {
|
||||
"default": "mdi:account-voice"
|
||||
},
|
||||
"open_door": {
|
||||
"default": "mdi:door-closed-lock"
|
||||
},
|
||||
"wifi_signal_category": {
|
||||
"default": "mdi:wifi"
|
||||
},
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
"name": "Ding"
|
||||
}
|
||||
},
|
||||
"button": {
|
||||
"open_door": {
|
||||
"name": "Open door"
|
||||
}
|
||||
},
|
||||
"light": {
|
||||
"light": {
|
||||
"name": "[%key:component::light::title%]"
|
||||
|
|
|
@ -131,4 +131,15 @@ def requests_mock_fixture():
|
|||
),
|
||||
text="ok",
|
||||
)
|
||||
# Mocks the open door command for intercom devices
|
||||
mock.put(
|
||||
"https://api.ring.com/commands/v1/devices/185036587/device_rpc",
|
||||
status_code=200,
|
||||
text="{}",
|
||||
)
|
||||
# Mocks the response for getting the history of the intercom
|
||||
mock.get(
|
||||
"https://api.ring.com/clients_api/doorbots/185036587/history",
|
||||
text=load_fixture("intercom_history.json", "ring"),
|
||||
)
|
||||
yield mock
|
||||
|
|
42
tests/components/ring/test_button.py
Normal file
42
tests/components/ring/test_button.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
"""The tests for the Ring button platform."""
|
||||
|
||||
import requests_mock
|
||||
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .common import setup_platform
|
||||
|
||||
|
||||
async def test_entity_registry(
|
||||
hass: HomeAssistant,
|
||||
requests_mock: requests_mock.Mocker,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Tests that the devices are registered in the entity registry."""
|
||||
await setup_platform(hass, Platform.BUTTON)
|
||||
|
||||
entry = entity_registry.async_get("button.ingress_open_door")
|
||||
assert entry.unique_id == "185036587-open_door"
|
||||
|
||||
|
||||
async def test_button_opens_door(
|
||||
hass: HomeAssistant, requests_mock: requests_mock.Mocker
|
||||
) -> None:
|
||||
"""Tests the door open button works correctly."""
|
||||
await setup_platform(hass, Platform.BUTTON)
|
||||
|
||||
# Mocks the response for opening door
|
||||
mock = requests_mock.put(
|
||||
"https://api.ring.com/commands/v1/devices/185036587/device_rpc",
|
||||
status_code=200,
|
||||
text="{}",
|
||||
)
|
||||
|
||||
await hass.services.async_call(
|
||||
"button", "press", {"entity_id": "button.ingress_open_door"}, blocking=True
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
assert mock.called_once
|
Loading…
Add table
Reference in a new issue