Compare commits

...

6 Commits

Author SHA1 Message Date
epenet
fb27425529 Adjust 2026-01-27 14:21:49 +00:00
epenet
1ff27ded66 async_register_service_actions 2026-01-27 12:43:41 +00:00
epenet
fe2bc93652 Tweak 2026-01-27 09:39:58 +00:00
epenet
90743743ba Adjust CODEOWNERS 2026-01-27 09:20:57 +00:00
epenet
44be1f9eb4 Migrate abode 2026-01-27 09:14:34 +00:00
epenet
27c4b27dbf Add service actions platform 2026-01-27 09:06:45 +00:00
14 changed files with 80 additions and 12 deletions

1
CODEOWNERS generated
View File

@@ -1460,6 +1460,7 @@ build.json @home-assistant/supervisor
/homeassistant/components/senz/ @milanmeu
/tests/components/senz/ @milanmeu
/homeassistant/components/serial/ @fabaff
/homeassistant/components/services/ @home-assistant/core
/homeassistant/components/seven_segments/ @fabaff
/homeassistant/components/seventeentrack/ @shaiu
/tests/components/seventeentrack/ @shaiu

View File

@@ -28,10 +28,8 @@ from homeassistant.const import (
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.typing import ConfigType
from .const import CONF_POLLING, DOMAIN, LOGGER
from .services import async_setup_services
ATTR_DEVICE_NAME = "device_name"
ATTR_DEVICE_TYPE = "device_type"
@@ -67,12 +65,6 @@ class AbodeSystem:
logout_listener: CALLBACK_TYPE | None = None
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Abode component."""
async_setup_services(hass)
return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Abode integration from a config entry."""
username = entry.data[CONF_USERNAME]

View File

@@ -6,7 +6,7 @@ from jaraco.abode.exceptions import Exception as AbodeException
import voluptuous as vol
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send
@@ -70,9 +70,8 @@ def _trigger_automation(call: ServiceCall) -> None:
dispatcher_send(call.hass, signal)
@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Home Assistant services."""
async def async_register_service_actions(hass: HomeAssistant) -> None:
"""Register service actions."""
hass.services.async_register(
DOMAIN, SERVICE_SETTINGS, _change_setting, schema=CHANGE_SETTING_SCHEMA

View File

@@ -0,0 +1,39 @@
"""The Service Actions integration."""
from __future__ import annotations
from typing import Protocol
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv, integration_platform
from homeassistant.helpers.typing import ConfigType
from .const import DOMAIN
__all__ = []
CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up Service Actions integration."""
await integration_platform.async_process_integration_platforms(
hass, DOMAIN, _register_service_actions_platform
)
return True
class ServiceActionsProtocol(Protocol):
"""Define the format that service actions platforms can have."""
async def async_register_service_actions(self, hass: HomeAssistant) -> None:
"""Register service actions for an integration."""
async def _register_service_actions_platform(
hass: HomeAssistant, integration_domain: str, platform: ServiceActionsProtocol
) -> None:
"""Register a service actions platform."""
await platform.async_register_service_actions(hass)

View File

@@ -0,0 +1,3 @@
"""Constants for the Service Actions integration."""
DOMAIN = "services"

View File

@@ -0,0 +1,9 @@
{
"domain": "services",
"name": "Services",
"codeowners": ["@home-assistant/core"],
"config_flow": false,
"documentation": "https://www.home-assistant.io/integrations/services",
"integration_type": "system",
"quality_scale": "internal"
}

View File

@@ -0,0 +1,3 @@
{
"title": "Service actions"
}

View File

@@ -78,6 +78,7 @@ BASE_PRELOAD_PLATFORMS = [
"media_source",
"recorder",
"repairs",
"services",
"system_health",
"trigger",
]

View File

@@ -536,6 +536,16 @@ _FUNCTION_MATCH: dict[str, list[TypeHintMatch]] = {
mandatory=True,
),
],
"services": [
TypeHintMatch(
function_name="async_register_service_actions",
arg_types={
0: "HomeAssistant",
},
return_type="None",
mandatory=True,
),
],
}
_CLASS_MATCH: dict[str, list[ClassTypeHintMatch]] = {

View File

@@ -110,6 +110,7 @@ NO_IOT_CLASS = [
"schedule",
"script",
"search",
"services",
"system_health",
"system_log",
"tag",

View File

@@ -2175,6 +2175,7 @@ NO_QUALITY_SCALE = [
"schedule",
"script",
"search",
"services",
"system_health",
"system_log",
"tag",

View File

@@ -4,9 +4,11 @@ from unittest.mock import patch
from homeassistant.components.abode.const import DOMAIN
from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN, CameraState
from homeassistant.components.services import DOMAIN as SERVICES_DOMAIN
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from .common import setup_platform
@@ -31,6 +33,7 @@ async def test_attributes(hass: HomeAssistant) -> None:
async def test_capture_image(hass: HomeAssistant) -> None:
"""Test the camera capture image service."""
await async_setup_component(hass, SERVICES_DOMAIN, {})
await setup_platform(hass, CAMERA_DOMAIN)
with patch("jaraco.abode.devices.camera.Camera.capture") as mock_capture:

View File

@@ -11,15 +11,18 @@ from jaraco.abode.exceptions import (
from homeassistant.components.abode.const import DOMAIN
from homeassistant.components.abode.services import SERVICE_SETTINGS
from homeassistant.components.alarm_control_panel import DOMAIN as ALARM_DOMAIN
from homeassistant.components.services import DOMAIN as SERVICES_DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from .common import setup_platform
async def test_change_settings(hass: HomeAssistant) -> None:
"""Test change_setting service."""
await async_setup_component(hass, SERVICES_DOMAIN, {})
await setup_platform(hass, ALARM_DOMAIN)
with patch("jaraco.abode.client.Client.set_setting") as mock_set_setting:

View File

@@ -4,6 +4,7 @@ from unittest.mock import patch
from homeassistant.components.abode.const import DOMAIN
from homeassistant.components.abode.services import SERVICE_TRIGGER_AUTOMATION
from homeassistant.components.services import DOMAIN as SERVICES_DOMAIN
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.const import (
ATTR_ENTITY_ID,
@@ -14,6 +15,7 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from .common import setup_platform
@@ -113,6 +115,7 @@ async def test_turn_automation_on(hass: HomeAssistant) -> None:
async def test_trigger_automation(hass: HomeAssistant) -> None:
"""Test the trigger automation service."""
await async_setup_component(hass, SERVICES_DOMAIN, {})
await setup_platform(hass, SWITCH_DOMAIN)
with patch("jaraco.abode.automation.Automation.trigger") as mock: