mirror of
https://github.com/home-assistant/core.git
synced 2026-02-15 07:36:16 +00:00
Add bedtime end time entity Nintendo parental controls (#160927)
This commit is contained in:
@@ -8,6 +8,9 @@ BEDTIME_ALARM_MIN = "16:00"
|
||||
BEDTIME_ALARM_MAX = "23:00"
|
||||
BEDTIME_ALARM_DISABLE = "00:00"
|
||||
|
||||
BEDTIME_END_TIME_MIN = "05:00"
|
||||
BEDTIME_END_TIME_MAX = "09:00"
|
||||
|
||||
APP_SETUP_URL = (
|
||||
"https://www.nintendo.com/my/support/switch/parentalcontrols/app/setup.html"
|
||||
)
|
||||
|
||||
@@ -65,6 +65,9 @@
|
||||
"time": {
|
||||
"bedtime_alarm": {
|
||||
"name": "Bedtime alarm"
|
||||
},
|
||||
"bedtime_end_time": {
|
||||
"name": "Bedtime end time"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -75,6 +78,9 @@
|
||||
"bedtime_alarm_out_of_range": {
|
||||
"message": "{value} not accepted. Bedtime Alarm must be between {bedtime_alarm_min} and {bedtime_alarm_max}. To disable, set to {bedtime_alarm_disable}."
|
||||
},
|
||||
"bedtime_end_time_out_of_range": {
|
||||
"message": "{value} not accepted. Bedtime End Time must be between {bedtime_end_time_min} and {bedtime_end_time_max}. To disable, set to {bedtime_alarm_disable}."
|
||||
},
|
||||
"config_entry_not_found": {
|
||||
"message": "Config entry not found."
|
||||
},
|
||||
|
||||
@@ -16,7 +16,14 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import BEDTIME_ALARM_DISABLE, BEDTIME_ALARM_MAX, BEDTIME_ALARM_MIN, DOMAIN
|
||||
from .const import (
|
||||
BEDTIME_ALARM_DISABLE,
|
||||
BEDTIME_ALARM_MAX,
|
||||
BEDTIME_ALARM_MIN,
|
||||
BEDTIME_END_TIME_MAX,
|
||||
BEDTIME_END_TIME_MIN,
|
||||
DOMAIN,
|
||||
)
|
||||
from .coordinator import NintendoParentalControlsConfigEntry, NintendoUpdateCoordinator
|
||||
from .entity import Device, NintendoDevice
|
||||
|
||||
@@ -30,6 +37,7 @@ class NintendoParentalControlsTime(StrEnum):
|
||||
"""Store keys for Nintendo Parental time."""
|
||||
|
||||
BEDTIME_ALARM = "bedtime_alarm"
|
||||
BEDTIME_END_TIME = "bedtime_end_time"
|
||||
|
||||
|
||||
@dataclass(kw_only=True, frozen=True)
|
||||
@@ -47,6 +55,12 @@ TIME_DESCRIPTIONS: tuple[NintendoParentalControlsTimeEntityDescription, ...] = (
|
||||
value_fn=lambda device: device.bedtime_alarm,
|
||||
set_value_fn=lambda device, value: device.set_bedtime_alarm(value=value),
|
||||
),
|
||||
NintendoParentalControlsTimeEntityDescription(
|
||||
key=NintendoParentalControlsTime.BEDTIME_END_TIME,
|
||||
translation_key=NintendoParentalControlsTime.BEDTIME_END_TIME,
|
||||
value_fn=lambda device: device.bedtime_end,
|
||||
set_value_fn=lambda device, value: device.set_bedtime_end_time(value=value),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -88,6 +102,20 @@ class NintendoParentalControlsTimeEntity(NintendoDevice, TimeEntity):
|
||||
try:
|
||||
await self.entity_description.set_value_fn(self._device, value)
|
||||
except BedtimeOutOfRangeError as exc:
|
||||
if (
|
||||
self.entity_description.key
|
||||
== NintendoParentalControlsTime.BEDTIME_END_TIME
|
||||
):
|
||||
raise ServiceValidationError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="bedtime_end_time_out_of_range",
|
||||
translation_placeholders={
|
||||
"value": value.strftime("%H:%M"),
|
||||
"bedtime_end_time_max": BEDTIME_END_TIME_MAX,
|
||||
"bedtime_end_time_min": BEDTIME_END_TIME_MIN,
|
||||
"bedtime_alarm_disable": BEDTIME_ALARM_DISABLE,
|
||||
},
|
||||
) from exc
|
||||
raise ServiceValidationError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="bedtime_alarm_out_of_range",
|
||||
|
||||
@@ -39,11 +39,13 @@ def mock_nintendo_device() -> Device:
|
||||
mock.limit_time = 120
|
||||
mock.today_playing_time = 110
|
||||
mock.today_time_remaining = 10
|
||||
mock.bedtime_end = time(hour=7)
|
||||
mock.bedtime_alarm = time(hour=19)
|
||||
mock.timer_mode = DeviceTimerMode.DAILY
|
||||
mock.extra_playing_time = 30
|
||||
mock.add_extra_time.return_value = None
|
||||
mock.set_bedtime_alarm.return_value = None
|
||||
mock.set_bedtime_end_time.return_value = None
|
||||
mock.update_max_daily_playtime.return_value = None
|
||||
mock.set_timer_mode.return_value = None
|
||||
mock.forced_termination_mode = True
|
||||
|
||||
@@ -48,3 +48,52 @@
|
||||
'state': '19:00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_time[time.home_assistant_test_bedtime_end_time-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'time',
|
||||
'entity_category': None,
|
||||
'entity_id': 'time.home_assistant_test_bedtime_end_time',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Bedtime end time',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Bedtime end time',
|
||||
'platform': 'nintendo_parental_controls',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': <NintendoParentalControlsTime.BEDTIME_END_TIME: 'bedtime_end_time'>,
|
||||
'unique_id': 'testdevid_bedtime_end_time',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_time[time.home_assistant_test_bedtime_end_time-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Home Assistant Test Bedtime end time',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'time.home_assistant_test_bedtime_end_time',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '07:00:00',
|
||||
})
|
||||
# ---
|
||||
|
||||
@@ -38,11 +38,25 @@ async def test_time(
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "new_value", "called_function_name"),
|
||||
[
|
||||
("time.home_assistant_test_bedtime_alarm", "20:00:00", "set_bedtime_alarm"),
|
||||
(
|
||||
"time.home_assistant_test_bedtime_end_time",
|
||||
"06:30:00",
|
||||
"set_bedtime_end_time",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_set_time(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_nintendo_client: AsyncMock,
|
||||
mock_nintendo_device: AsyncMock,
|
||||
entity_id: str,
|
||||
new_value: str,
|
||||
called_function_name: str,
|
||||
) -> None:
|
||||
"""Test time platform service validation errors."""
|
||||
with patch(
|
||||
@@ -53,21 +67,44 @@ async def test_set_time(
|
||||
await hass.services.async_call(
|
||||
TIME_DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
service_data={ATTR_TIME: "20:00:00"},
|
||||
target={ATTR_ENTITY_ID: "time.home_assistant_test_bedtime_alarm"},
|
||||
service_data={ATTR_TIME: new_value},
|
||||
target={ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(mock_nintendo_device.set_bedtime_alarm.mock_calls) == 1
|
||||
assert len(getattr(mock_nintendo_device, called_function_name).mock_calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "new_value", "translation_key", "called_function_name"),
|
||||
[
|
||||
(
|
||||
"time.home_assistant_test_bedtime_alarm",
|
||||
"03:00:00",
|
||||
"bedtime_alarm_out_of_range",
|
||||
"set_bedtime_alarm",
|
||||
),
|
||||
(
|
||||
"time.home_assistant_test_bedtime_end_time",
|
||||
"10:00:00",
|
||||
"bedtime_end_time_out_of_range",
|
||||
"set_bedtime_end_time",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_set_time_service_exceptions(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_nintendo_client: AsyncMock,
|
||||
mock_nintendo_device: AsyncMock,
|
||||
entity_id: str,
|
||||
new_value: str,
|
||||
translation_key: str,
|
||||
called_function_name: str,
|
||||
) -> None:
|
||||
"""Test time platform service validation errors."""
|
||||
mock_nintendo_device.set_bedtime_alarm.side_effect = BedtimeOutOfRangeError(None)
|
||||
getattr(
|
||||
mock_nintendo_device, called_function_name
|
||||
).side_effect = BedtimeOutOfRangeError(None)
|
||||
with patch(
|
||||
"homeassistant.components.nintendo_parental_controls._PLATFORMS",
|
||||
[Platform.TIME],
|
||||
@@ -77,9 +114,9 @@ async def test_set_time_service_exceptions(
|
||||
await hass.services.async_call(
|
||||
TIME_DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
service_data={ATTR_TIME: "01:00:00"},
|
||||
target={ATTR_ENTITY_ID: "time.home_assistant_test_bedtime_alarm"},
|
||||
service_data={ATTR_TIME: new_value},
|
||||
target={ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(mock_nintendo_device.set_bedtime_alarm.mock_calls) == 1
|
||||
assert err.value.translation_key == "bedtime_alarm_out_of_range"
|
||||
assert len(getattr(mock_nintendo_device, called_function_name).mock_calls) == 1
|
||||
assert err.value.translation_key == translation_key
|
||||
|
||||
Reference in New Issue
Block a user