mirror of
https://github.com/home-assistant/core.git
synced 2026-10-07 06:50:41 -04:00
bosch_shc: add Shutter Contact II bypass timeout number (#183638)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com> Co-authored-by: Erwin Douna <e.douna@gmail.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
Erwin Douna
parent
9341a09dfd
commit
659eba7659
@@ -4,7 +4,7 @@ from collections.abc import Callable, Coroutine
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Any, override
|
||||
|
||||
from boschshcpy import SHCMicromoduleRelay
|
||||
from boschshcpy import SHCMicromoduleRelay, SHCShutterContact2
|
||||
from boschshcpy.device import SHCDevice
|
||||
|
||||
from homeassistant.components.number import (
|
||||
@@ -66,6 +66,21 @@ NUMBER_TYPES: dict[str, SHCNumberEntityDescription] = {
|
||||
value_fn=_impulse_length_value_fn,
|
||||
set_value_fn=_impulse_length_set_value_fn,
|
||||
),
|
||||
"bypass_timeout": SHCNumberEntityDescription[SHCShutterContact2](
|
||||
key="bypass_timeout",
|
||||
translation_key="bypass_timeout",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
device_class=NumberDeviceClass.DURATION,
|
||||
native_unit_of_measurement=UnitOfTime.MINUTES,
|
||||
native_min_value=1.0,
|
||||
native_max_value=15.0,
|
||||
native_step=1.0,
|
||||
mode=NumberMode.BOX,
|
||||
value_fn=lambda device: float(device.bypass_timeout),
|
||||
set_value_fn=lambda device, value: device.async_set_bypass_timeout(
|
||||
round(value)
|
||||
),
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +116,17 @@ async def async_setup_entry(
|
||||
)
|
||||
)
|
||||
|
||||
entities.extend(
|
||||
SHCNumber(
|
||||
hass=hass,
|
||||
device=device,
|
||||
parent_id=shc_info.unique_id,
|
||||
entry_id=config_entry.entry_id,
|
||||
description=NUMBER_TYPES["bypass_timeout"],
|
||||
)
|
||||
for device in session.device_helper.shutter_contacts2
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
}
|
||||
},
|
||||
"number": {
|
||||
"bypass_timeout": {
|
||||
"name": "Break function timeout"
|
||||
},
|
||||
"impulse_length": {
|
||||
"name": "Pulse length"
|
||||
}
|
||||
|
||||
@@ -463,6 +463,7 @@ def shutter_contact2_device(
|
||||
name: str = "Shutter contact",
|
||||
bypass: BypassService.State = BypassService.State.BYPASS_INACTIVE,
|
||||
bypass_infinite: bool = False,
|
||||
bypass_timeout: int = 5,
|
||||
) -> SHCShutterContact2:
|
||||
"""Build a minimal device double for the shutter_contacts2 bucket."""
|
||||
device = create_autospec(SHCShutterContact2, instance=True, spec_set=True)
|
||||
@@ -477,6 +478,7 @@ def shutter_contact2_device(
|
||||
device.status = "AVAILABLE"
|
||||
device.bypass = bypass
|
||||
device.bypass_infinite = bypass_infinite
|
||||
device.bypass_timeout = bypass_timeout
|
||||
return device
|
||||
|
||||
|
||||
|
||||
@@ -12,11 +12,16 @@ from homeassistant.components.number import (
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .conftest import micromodule_relay_device, setup_integration
|
||||
from .conftest import (
|
||||
micromodule_relay_device,
|
||||
setup_integration,
|
||||
shutter_contact2_device,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
IMPULSE_LENGTH_ENTITY_ID = "number.relay_pulse_length"
|
||||
BYPASS_TIMEOUT_ENTITY_ID = "number.shutter_contact_break_function_timeout"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -99,3 +104,45 @@ async def test_micromodule_impulse_relay_impulse_length_partial_poll(
|
||||
state = hass.states.get(IMPULSE_LENGTH_ENTITY_ID)
|
||||
assert state is not None
|
||||
assert state.state == "unknown"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_buckets",
|
||||
[{"shutter_contacts2": [shutter_contact2_device(bypass_timeout=7)]}],
|
||||
indirect=True,
|
||||
)
|
||||
@pytest.mark.usefixtures("mock_session")
|
||||
async def test_shutter_contact2_bypass_timeout_value(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""The bypass timeout is reported in minutes."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
state = hass.states.get(BYPASS_TIMEOUT_ENTITY_ID)
|
||||
assert state is not None
|
||||
assert state.state == "7.0"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_buckets",
|
||||
[{"shutter_contacts2": [shutter_contact2_device()]}],
|
||||
indirect=True,
|
||||
)
|
||||
@pytest.mark.usefixtures("mock_session")
|
||||
async def test_shutter_contact2_bypass_timeout_set_value(
|
||||
hass: HomeAssistant,
|
||||
mock_session: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Setting a value writes the rounded minutes to the device."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
device = mock_session.device_helper.shutter_contacts2[0]
|
||||
|
||||
await hass.services.async_call(
|
||||
NUMBER_DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
{ATTR_ENTITY_ID: BYPASS_TIMEOUT_ENTITY_ID, ATTR_VALUE: 10.6},
|
||||
blocking=True,
|
||||
)
|
||||
device.async_set_bypass_timeout.assert_awaited_once_with(11)
|
||||
|
||||
Reference in New Issue
Block a user