mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
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
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 = [
|
PLATFORMS = [
|
||||||
Platform.BINARY_SENSOR,
|
Platform.BINARY_SENSOR,
|
||||||
|
Platform.BUTTON,
|
||||||
Platform.CAMERA,
|
Platform.CAMERA,
|
||||||
Platform.LIGHT,
|
Platform.LIGHT,
|
||||||
Platform.SENSOR,
|
Platform.SENSOR,
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
"voice_volume": {
|
"voice_volume": {
|
||||||
"default": "mdi:account-voice"
|
"default": "mdi:account-voice"
|
||||||
},
|
},
|
||||||
|
"open_door": {
|
||||||
|
"default": "mdi:door-closed-lock"
|
||||||
|
},
|
||||||
"wifi_signal_category": {
|
"wifi_signal_category": {
|
||||||
"default": "mdi:wifi"
|
"default": "mdi:wifi"
|
||||||
},
|
},
|
||||||
|
@ -37,6 +37,11 @@
|
|||||||
"name": "Ding"
|
"name": "Ding"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"button": {
|
||||||
|
"open_door": {
|
||||||
|
"name": "Open door"
|
||||||
|
}
|
||||||
|
},
|
||||||
"light": {
|
"light": {
|
||||||
"light": {
|
"light": {
|
||||||
"name": "[%key:component::light::title%]"
|
"name": "[%key:component::light::title%]"
|
||||||
|
@ -131,4 +131,15 @@ def requests_mock_fixture():
|
|||||||
),
|
),
|
||||||
text="ok",
|
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
|
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…
x
Reference in New Issue
Block a user