mirror of
https://github.com/home-assistant/core.git
synced 2025-07-31 17:18:23 +00:00
Add details to Husqvarna Automower restricted reason sensor (#147678)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
This commit is contained in:
parent
dda46e7e0b
commit
7f9be420d2
@ -8,6 +8,7 @@ from operator import attrgetter
|
|||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from aioautomower.model import (
|
from aioautomower.model import (
|
||||||
|
ExternalReasons,
|
||||||
InactiveReasons,
|
InactiveReasons,
|
||||||
MowerAttributes,
|
MowerAttributes,
|
||||||
MowerModes,
|
MowerModes,
|
||||||
@ -190,11 +191,37 @@ RESTRICTED_REASONS: list = [
|
|||||||
RestrictedReasons.PARK_OVERRIDE,
|
RestrictedReasons.PARK_OVERRIDE,
|
||||||
RestrictedReasons.SENSOR,
|
RestrictedReasons.SENSOR,
|
||||||
RestrictedReasons.WEEK_SCHEDULE,
|
RestrictedReasons.WEEK_SCHEDULE,
|
||||||
|
ExternalReasons.AMAZON_ALEXA,
|
||||||
|
ExternalReasons.DEVELOPER_PORTAL,
|
||||||
|
ExternalReasons.GARDENA_SMART_SYSTEM,
|
||||||
|
ExternalReasons.GOOGLE_ASSISTANT,
|
||||||
|
ExternalReasons.HOME_ASSISTANT,
|
||||||
|
ExternalReasons.IFTTT,
|
||||||
|
ExternalReasons.IFTTT_APPLETS,
|
||||||
|
ExternalReasons.IFTTT_CALENDAR_CONNECTION,
|
||||||
|
ExternalReasons.SMART_ROUTINE,
|
||||||
|
ExternalReasons.SMART_ROUTINE_FROST_GUARD,
|
||||||
|
ExternalReasons.SMART_ROUTINE_RAIN_GUARD,
|
||||||
|
ExternalReasons.SMART_ROUTINE_WILDLIFE_PROTECTION,
|
||||||
]
|
]
|
||||||
|
|
||||||
STATE_NO_WORK_AREA_ACTIVE = "no_work_area_active"
|
STATE_NO_WORK_AREA_ACTIVE = "no_work_area_active"
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _get_restricted_reason(data: MowerAttributes) -> str:
|
||||||
|
"""Return the restricted reason.
|
||||||
|
|
||||||
|
If there is an external reason, return that instead, if it's available.
|
||||||
|
"""
|
||||||
|
if (
|
||||||
|
data.planner.restricted_reason == RestrictedReasons.EXTERNAL
|
||||||
|
and data.planner.external_reason is not None
|
||||||
|
):
|
||||||
|
return data.planner.external_reason
|
||||||
|
return data.planner.restricted_reason
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _get_work_area_names(data: MowerAttributes) -> list[str]:
|
def _get_work_area_names(data: MowerAttributes) -> list[str]:
|
||||||
"""Return a list with all work area names."""
|
"""Return a list with all work area names."""
|
||||||
@ -400,7 +427,7 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = (
|
|||||||
translation_key="restricted_reason",
|
translation_key="restricted_reason",
|
||||||
device_class=SensorDeviceClass.ENUM,
|
device_class=SensorDeviceClass.ENUM,
|
||||||
option_fn=lambda data: RESTRICTED_REASONS,
|
option_fn=lambda data: RESTRICTED_REASONS,
|
||||||
value_fn=attrgetter("planner.restricted_reason"),
|
value_fn=_get_restricted_reason,
|
||||||
),
|
),
|
||||||
AutomowerSensorEntityDescription(
|
AutomowerSensorEntityDescription(
|
||||||
key="inactive_reason",
|
key="inactive_reason",
|
||||||
|
@ -242,16 +242,28 @@
|
|||||||
"restricted_reason": {
|
"restricted_reason": {
|
||||||
"name": "Restricted reason",
|
"name": "Restricted reason",
|
||||||
"state": {
|
"state": {
|
||||||
"none": "No restrictions",
|
"all_work_areas_completed": "All work areas completed",
|
||||||
"week_schedule": "Week schedule",
|
"amazon_alexa": "Amazon Alexa",
|
||||||
"park_override": "Park override",
|
|
||||||
"sensor": "Weather timer",
|
|
||||||
"daily_limit": "Daily limit",
|
"daily_limit": "Daily limit",
|
||||||
|
"developer_portal": "Developer Portal",
|
||||||
|
"external": "External",
|
||||||
"fota": "Firmware Over-the-Air update running",
|
"fota": "Firmware Over-the-Air update running",
|
||||||
"frost": "Frost",
|
"frost": "Frost",
|
||||||
"all_work_areas_completed": "All work areas completed",
|
"gardena_smart_system": "Gardena Smart System",
|
||||||
"external": "External",
|
"google_assistant": "Google Assistant",
|
||||||
"not_applicable": "Not applicable"
|
"home_assistant": "Home Assistant",
|
||||||
|
"ifttt_applets": "IFTTT applets",
|
||||||
|
"ifttt_calendar_connection": "IFTTT calendar connection",
|
||||||
|
"ifttt": "IFTTT",
|
||||||
|
"none": "No restrictions",
|
||||||
|
"not_applicable": "Not applicable",
|
||||||
|
"park_override": "Park override",
|
||||||
|
"sensor": "Weather timer",
|
||||||
|
"smart_routine_frost_guard": "Frost guard",
|
||||||
|
"smart_routine_rain_guard": "Rain guard",
|
||||||
|
"smart_routine_wildlife_protection": "Wildlife protection",
|
||||||
|
"smart_routine": "Generic smart routine",
|
||||||
|
"week_schedule": "Week schedule"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"total_charging_time": {
|
"total_charging_time": {
|
||||||
|
@ -978,6 +978,18 @@
|
|||||||
<RestrictedReasons.PARK_OVERRIDE: 'park_override'>,
|
<RestrictedReasons.PARK_OVERRIDE: 'park_override'>,
|
||||||
<RestrictedReasons.SENSOR: 'sensor'>,
|
<RestrictedReasons.SENSOR: 'sensor'>,
|
||||||
<RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>,
|
<RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>,
|
||||||
|
<ExternalReasons.AMAZON_ALEXA: 'amazon_alexa'>,
|
||||||
|
<ExternalReasons.DEVELOPER_PORTAL: 'developer_portal'>,
|
||||||
|
<ExternalReasons.GARDENA_SMART_SYSTEM: 'gardena_smart_system'>,
|
||||||
|
<ExternalReasons.GOOGLE_ASSISTANT: 'google_assistant'>,
|
||||||
|
<ExternalReasons.HOME_ASSISTANT: 'home_assistant'>,
|
||||||
|
<ExternalReasons.IFTTT: 'ifttt'>,
|
||||||
|
<ExternalReasons.IFTTT_APPLETS: 'ifttt_applets'>,
|
||||||
|
<ExternalReasons.IFTTT_CALENDAR_CONNECTION: 'ifttt_calendar_connection'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE: 'smart_routine'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_FROST_GUARD: 'smart_routine_frost_guard'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_RAIN_GUARD: 'smart_routine_rain_guard'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_WILDLIFE_PROTECTION: 'smart_routine_wildlife_protection'>,
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
'config_entry_id': <ANY>,
|
'config_entry_id': <ANY>,
|
||||||
@ -1025,6 +1037,18 @@
|
|||||||
<RestrictedReasons.PARK_OVERRIDE: 'park_override'>,
|
<RestrictedReasons.PARK_OVERRIDE: 'park_override'>,
|
||||||
<RestrictedReasons.SENSOR: 'sensor'>,
|
<RestrictedReasons.SENSOR: 'sensor'>,
|
||||||
<RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>,
|
<RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>,
|
||||||
|
<ExternalReasons.AMAZON_ALEXA: 'amazon_alexa'>,
|
||||||
|
<ExternalReasons.DEVELOPER_PORTAL: 'developer_portal'>,
|
||||||
|
<ExternalReasons.GARDENA_SMART_SYSTEM: 'gardena_smart_system'>,
|
||||||
|
<ExternalReasons.GOOGLE_ASSISTANT: 'google_assistant'>,
|
||||||
|
<ExternalReasons.HOME_ASSISTANT: 'home_assistant'>,
|
||||||
|
<ExternalReasons.IFTTT: 'ifttt'>,
|
||||||
|
<ExternalReasons.IFTTT_APPLETS: 'ifttt_applets'>,
|
||||||
|
<ExternalReasons.IFTTT_CALENDAR_CONNECTION: 'ifttt_calendar_connection'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE: 'smart_routine'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_FROST_GUARD: 'smart_routine_frost_guard'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_RAIN_GUARD: 'smart_routine_rain_guard'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_WILDLIFE_PROTECTION: 'smart_routine_wildlife_protection'>,
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
'context': <ANY>,
|
'context': <ANY>,
|
||||||
@ -1953,6 +1977,18 @@
|
|||||||
<RestrictedReasons.PARK_OVERRIDE: 'park_override'>,
|
<RestrictedReasons.PARK_OVERRIDE: 'park_override'>,
|
||||||
<RestrictedReasons.SENSOR: 'sensor'>,
|
<RestrictedReasons.SENSOR: 'sensor'>,
|
||||||
<RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>,
|
<RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>,
|
||||||
|
<ExternalReasons.AMAZON_ALEXA: 'amazon_alexa'>,
|
||||||
|
<ExternalReasons.DEVELOPER_PORTAL: 'developer_portal'>,
|
||||||
|
<ExternalReasons.GARDENA_SMART_SYSTEM: 'gardena_smart_system'>,
|
||||||
|
<ExternalReasons.GOOGLE_ASSISTANT: 'google_assistant'>,
|
||||||
|
<ExternalReasons.HOME_ASSISTANT: 'home_assistant'>,
|
||||||
|
<ExternalReasons.IFTTT: 'ifttt'>,
|
||||||
|
<ExternalReasons.IFTTT_APPLETS: 'ifttt_applets'>,
|
||||||
|
<ExternalReasons.IFTTT_CALENDAR_CONNECTION: 'ifttt_calendar_connection'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE: 'smart_routine'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_FROST_GUARD: 'smart_routine_frost_guard'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_RAIN_GUARD: 'smart_routine_rain_guard'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_WILDLIFE_PROTECTION: 'smart_routine_wildlife_protection'>,
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
'config_entry_id': <ANY>,
|
'config_entry_id': <ANY>,
|
||||||
@ -2000,6 +2036,18 @@
|
|||||||
<RestrictedReasons.PARK_OVERRIDE: 'park_override'>,
|
<RestrictedReasons.PARK_OVERRIDE: 'park_override'>,
|
||||||
<RestrictedReasons.SENSOR: 'sensor'>,
|
<RestrictedReasons.SENSOR: 'sensor'>,
|
||||||
<RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>,
|
<RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>,
|
||||||
|
<ExternalReasons.AMAZON_ALEXA: 'amazon_alexa'>,
|
||||||
|
<ExternalReasons.DEVELOPER_PORTAL: 'developer_portal'>,
|
||||||
|
<ExternalReasons.GARDENA_SMART_SYSTEM: 'gardena_smart_system'>,
|
||||||
|
<ExternalReasons.GOOGLE_ASSISTANT: 'google_assistant'>,
|
||||||
|
<ExternalReasons.HOME_ASSISTANT: 'home_assistant'>,
|
||||||
|
<ExternalReasons.IFTTT: 'ifttt'>,
|
||||||
|
<ExternalReasons.IFTTT_APPLETS: 'ifttt_applets'>,
|
||||||
|
<ExternalReasons.IFTTT_CALENDAR_CONNECTION: 'ifttt_calendar_connection'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE: 'smart_routine'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_FROST_GUARD: 'smart_routine_frost_guard'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_RAIN_GUARD: 'smart_routine_rain_guard'>,
|
||||||
|
<ExternalReasons.SMART_ROUTINE_WILDLIFE_PROTECTION: 'smart_routine_wildlife_protection'>,
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
'context': <ANY>,
|
'context': <ANY>,
|
||||||
|
@ -4,7 +4,13 @@ import datetime
|
|||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
import zoneinfo
|
import zoneinfo
|
||||||
|
|
||||||
from aioautomower.model import MowerAttributes, MowerModes, MowerStates
|
from aioautomower.model import (
|
||||||
|
ExternalReasons,
|
||||||
|
MowerAttributes,
|
||||||
|
MowerModes,
|
||||||
|
MowerStates,
|
||||||
|
RestrictedReasons,
|
||||||
|
)
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
import pytest
|
||||||
from syrupy.assertion import SnapshotAssertion
|
from syrupy.assertion import SnapshotAssertion
|
||||||
@ -123,6 +129,41 @@ async def test_work_area_sensor(
|
|||||||
assert state.state == "no_work_area_active"
|
assert state.state == "no_work_area_active"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_restricted_reason_sensor(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_automower_client: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
values: dict[str, MowerAttributes],
|
||||||
|
) -> None:
|
||||||
|
"""Test the work area sensor."""
|
||||||
|
sensor = "sensor.test_mower_1_restricted_reason"
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
state = hass.states.get(sensor)
|
||||||
|
assert state is not None
|
||||||
|
assert state.state == RestrictedReasons.WEEK_SCHEDULE
|
||||||
|
|
||||||
|
values[TEST_MOWER_ID].planner.restricted_reason = RestrictedReasons.EXTERNAL
|
||||||
|
values[TEST_MOWER_ID].planner.external_reason = None
|
||||||
|
mock_automower_client.get_status.return_value = values
|
||||||
|
freezer.tick(SCAN_INTERVAL)
|
||||||
|
async_fire_time_changed(hass)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(sensor)
|
||||||
|
assert state.state == RestrictedReasons.EXTERNAL
|
||||||
|
|
||||||
|
values[TEST_MOWER_ID].planner.restricted_reason = RestrictedReasons.EXTERNAL
|
||||||
|
values[
|
||||||
|
TEST_MOWER_ID
|
||||||
|
].planner.external_reason = ExternalReasons.SMART_ROUTINE_WILDLIFE_PROTECTION
|
||||||
|
mock_automower_client.get_status.return_value = values
|
||||||
|
freezer.tick(SCAN_INTERVAL)
|
||||||
|
async_fire_time_changed(hass)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get(sensor)
|
||||||
|
assert state.state == ExternalReasons.SMART_ROUTINE_WILDLIFE_PROTECTION
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("sensor_to_test"),
|
("sensor_to_test"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user