mirror of
https://github.com/home-assistant/core.git
synced 2025-04-27 02:37:50 +00:00
Add button platform to Dremel 3D printer (#94517)
Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
parent
3e85a29b86
commit
cd26de73b4
@ -12,7 +12,7 @@ from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from .const import CAMERA_MODEL, DOMAIN
|
||||
from .coordinator import Dremel3DPrinterDataUpdateCoordinator
|
||||
|
||||
PLATFORMS = [Platform.BINARY_SENSOR, Platform.CAMERA, Platform.SENSOR]
|
||||
PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.CAMERA, Platform.SENSOR]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
|
78
homeassistant/components/dremel_3d_printer/button.py
Normal file
78
homeassistant/components/dremel_3d_printer/button.py
Normal file
@ -0,0 +1,78 @@
|
||||
"""Support for Dremel 3D Printer buttons."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
from dremel3dpy import Dremel3DPrinter
|
||||
|
||||
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DOMAIN
|
||||
from .entity import Dremel3DPrinterEntity
|
||||
|
||||
|
||||
@dataclass
|
||||
class Dremel3DPrinterButtonEntityMixin:
|
||||
"""Mixin for required keys."""
|
||||
|
||||
press_fn: Callable[[Dremel3DPrinter], None]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Dremel3DPrinterButtonEntityDescription(
|
||||
ButtonEntityDescription, Dremel3DPrinterButtonEntityMixin
|
||||
):
|
||||
"""Describes a Dremel 3D Printer button entity."""
|
||||
|
||||
|
||||
BUTTON_TYPES: tuple[Dremel3DPrinterButtonEntityDescription, ...] = (
|
||||
Dremel3DPrinterButtonEntityDescription(
|
||||
key="cancel_job",
|
||||
translation_key="cancel_job",
|
||||
press_fn=lambda api: api.stop_print(),
|
||||
),
|
||||
Dremel3DPrinterButtonEntityDescription(
|
||||
key="pause_job",
|
||||
translation_key="pause_job",
|
||||
press_fn=lambda api: api.pause_print(),
|
||||
),
|
||||
Dremel3DPrinterButtonEntityDescription(
|
||||
key="resume_job",
|
||||
translation_key="resume_job",
|
||||
press_fn=lambda api: api.resume_print(),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Dremel 3D Printer control buttons."""
|
||||
coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
async_add_entities(
|
||||
Dremel3DPrinterButtonEntity(coordinator, description)
|
||||
for description in BUTTON_TYPES
|
||||
)
|
||||
|
||||
|
||||
class Dremel3DPrinterButtonEntity(Dremel3DPrinterEntity, ButtonEntity):
|
||||
"""Represent a Dremel 3D Printer button."""
|
||||
|
||||
entity_description: Dremel3DPrinterButtonEntityDescription
|
||||
|
||||
def press(self) -> None:
|
||||
"""Handle the button press."""
|
||||
# api does not care about the current state
|
||||
try:
|
||||
self.entity_description.press_fn(self._api)
|
||||
except RuntimeError as ex:
|
||||
raise HomeAssistantError(
|
||||
"An error occurred while submitting command"
|
||||
) from ex
|
@ -16,6 +16,17 @@
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"button": {
|
||||
"cancel_job": {
|
||||
"name": "Cancel job"
|
||||
},
|
||||
"pause_job": {
|
||||
"name": "Pause job"
|
||||
},
|
||||
"resume_job": {
|
||||
"name": "Resume job"
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
"job_phase": {
|
||||
"name": "Job phase"
|
||||
|
56
tests/components/dremel_3d_printer/test_button.py
Normal file
56
tests/components/dremel_3d_printer/test_button.py
Normal file
@ -0,0 +1,56 @@
|
||||
"""Button tests for the Dremel 3D Printer integration."""
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
|
||||
from homeassistant.components.dremel_3d_printer.const import DOMAIN
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("button", "function"),
|
||||
(
|
||||
("cancel", "stop"),
|
||||
("pause", "pause"),
|
||||
("resume", "resume"),
|
||||
),
|
||||
)
|
||||
async def test_buttons(
|
||||
hass: HomeAssistant,
|
||||
connection: None,
|
||||
config_entry: MockConfigEntry,
|
||||
entity_registry_enabled_by_default: AsyncMock,
|
||||
button: str,
|
||||
function: str,
|
||||
) -> None:
|
||||
"""Test button entities function."""
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
with patch(
|
||||
f"homeassistant.components.dremel_3d_printer.Dremel3DPrinter.{function}_print"
|
||||
) as mock:
|
||||
await hass.services.async_call(
|
||||
BUTTON_DOMAIN,
|
||||
SERVICE_PRESS,
|
||||
{ATTR_ENTITY_ID: [f"button.dremel_3d45_{button}_job"]},
|
||||
blocking=True,
|
||||
)
|
||||
assert mock.call_count == 1
|
||||
|
||||
with patch(
|
||||
f"homeassistant.components.dremel_3d_printer.Dremel3DPrinter.{function}_print",
|
||||
side_effect=RuntimeError,
|
||||
) as mock, pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
BUTTON_DOMAIN,
|
||||
SERVICE_PRESS,
|
||||
{ATTR_ENTITY_ID: [f"button.dremel_3d45_{button}_job"]},
|
||||
blocking=True,
|
||||
)
|
||||
assert mock.call_count == 1
|
Loading…
x
Reference in New Issue
Block a user