From b580ca6e6f05efb207917c1239f72faff6bac4b9 Mon Sep 17 00:00:00 2001 From: G Johansson Date: Mon, 6 Nov 2023 10:17:48 +0100 Subject: [PATCH] Add Check date service for Workday (#97280) --- .../components/workday/binary_sensor.py | 27 ++++++++++++- .../components/workday/services.yaml | 9 +++++ homeassistant/components/workday/strings.json | 12 ++++++ .../components/workday/test_binary_sensor.py | 40 ++++++++++++++++++- 4 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 homeassistant/components/workday/services.yaml diff --git a/homeassistant/components/workday/binary_sensor.py b/homeassistant/components/workday/binary_sensor.py index ebd665f38e7a..2692c27d58ab 100644 --- a/homeassistant/components/workday/binary_sensor.py +++ b/homeassistant/components/workday/binary_sensor.py @@ -2,19 +2,25 @@ from __future__ import annotations from datetime import date, timedelta +from typing import Final from holidays import ( HolidayBase, __version__ as python_holidays_version, country_holidays, ) +import voluptuous as vol from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME -from homeassistant.core import HomeAssistant +from homeassistant.core import HomeAssistant, ServiceResponse, SupportsResponse +import homeassistant.helpers.config_validation as cv from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.entity_platform import ( + AddEntitiesCallback, + async_get_current_platform, +) from homeassistant.util import dt as dt_util from .const import ( @@ -30,6 +36,9 @@ from .const import ( LOGGER, ) +SERVICE_CHECK_DATE: Final = "check_date" +CHECK_DATE: Final = "check_date" + def validate_dates(holiday_list: list[str]) -> list[str]: """Validate and adds to list of dates to add or remove.""" @@ -109,6 +118,15 @@ async def async_setup_entry( _holiday_string = holiday_date.strftime("%Y-%m-%d") LOGGER.debug("%s %s", _holiday_string, name) + platform = async_get_current_platform() + platform.async_register_entity_service( + SERVICE_CHECK_DATE, + {vol.Required(CHECK_DATE): cv.date}, + "check_date", + None, + SupportsResponse.ONLY, + ) + async_add_entities( [ IsWorkdaySensor( @@ -192,3 +210,8 @@ class IsWorkdaySensor(BinarySensorEntity): if self.is_exclude(day_of_week, adjusted_date): self._attr_is_on = False + + async def check_date(self, check_date: date) -> ServiceResponse: + """Check if date is workday or not.""" + holiday_date = check_date in self._obj_holidays + return {"workday": not holiday_date} diff --git a/homeassistant/components/workday/services.yaml b/homeassistant/components/workday/services.yaml new file mode 100644 index 000000000000..00935cd7215d --- /dev/null +++ b/homeassistant/components/workday/services.yaml @@ -0,0 +1,9 @@ +check_date: + target: + entity: + integration: workday + fields: + check_date: + example: "2022-12-25" + selector: + date: diff --git a/homeassistant/components/workday/strings.json b/homeassistant/components/workday/strings.json index 733ea595ec73..a05ab1fc669e 100644 --- a/homeassistant/components/workday/strings.json +++ b/homeassistant/components/workday/strings.json @@ -146,5 +146,17 @@ } } } + }, + "services": { + "check_date": { + "name": "Check date", + "description": "Check if date is workday.", + "fields": { + "check_date": { + "name": "Date", + "description": "Date to check if workday." + } + } + } } } diff --git a/tests/components/workday/test_binary_sensor.py b/tests/components/workday/test_binary_sensor.py index eeeb765e4a8a..e955bd0de0d5 100644 --- a/tests/components/workday/test_binary_sensor.py +++ b/tests/components/workday/test_binary_sensor.py @@ -1,10 +1,12 @@ """Tests the Home Assistant workday binary sensor.""" -from datetime import datetime +from datetime import date, datetime from typing import Any from freezegun.api import FrozenDateTimeFactory import pytest +from homeassistant.components.workday.binary_sensor import SERVICE_CHECK_DATE +from homeassistant.components.workday.const import DOMAIN from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component from homeassistant.util.dt import UTC @@ -273,3 +275,39 @@ async def test_setup_date_range( state = hass.states.get("binary_sensor.workday_sensor") assert state.state == "on" + + +async def test_check_date_service( + hass: HomeAssistant, + freezer: FrozenDateTimeFactory, +) -> None: + """Test check date service with response data.""" + + freezer.move_to(datetime(2017, 1, 6, 12, tzinfo=UTC)) # Friday + await init_integration(hass, TEST_CONFIG_WITH_PROVINCE) + + hass.states.get("binary_sensor.workday_sensor") + + response = await hass.services.async_call( + DOMAIN, + SERVICE_CHECK_DATE, + { + "entity_id": "binary_sensor.workday_sensor", + "check_date": date(2022, 12, 25), # Christmas Day + }, + blocking=True, + return_response=True, + ) + assert response == {"binary_sensor.workday_sensor": {"workday": False}} + + response = await hass.services.async_call( + DOMAIN, + SERVICE_CHECK_DATE, + { + "entity_id": "binary_sensor.workday_sensor", + "check_date": date(2022, 12, 23), # Normal Friday + }, + blocking=True, + return_response=True, + ) + assert response == {"binary_sensor.workday_sensor": {"workday": True}}