Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c9664a9
Use ToolResult in ollama (#182548)
balloob Sep 18, 2026
6f9563f
Serve SVG media as attachments (#182095)
frenck Sep 18, 2026
b1f88df
Use ToolResult in llama_cpp (#182547)
balloob Sep 18, 2026
a0eb7e3
Use ToolResult in calendar (#182539)
balloob Sep 18, 2026
9835762
Use ToolResult in the LLM helper, llm and homeassistant (#182538)
balloob Sep 18, 2026
aa8bda6
Bump debugpy to 1.8.22 (#182603)
frenck Sep 18, 2026
528d167
Fix filter time moving average walking its whole window on every samp…
frenck Sep 18, 2026
47f9262
Type UniFi Protect entities against the public device model (#182617)
RaHehl Sep 18, 2026
f938a40
Move cover service registration to services module (#182562)
epenet Sep 18, 2026
d3e91e2
Move tts service registration to services module (#182561)
epenet Sep 18, 2026
3bf5469
Move button service registration to services module (#182563)
epenet Sep 18, 2026
24742fe
Move scene service registration to services module (#182564)
epenet Sep 18, 2026
8620c85
Move lawn mower service registration to services module (#182566)
epenet Sep 18, 2026
6ece674
Move switch service registration to services module (#182565)
epenet Sep 18, 2026
9958b36
Use mock client in Airly tests (#182485)
bieniu Sep 18, 2026
b5a6c53
Cache English fallback translations for all components in a non-Engli…
MindFreeze Sep 18, 2026
b8fe74f
Read the Sofar meter counters from meter_energy (#181729)
darkrain-nl Sep 18, 2026
4161a62
Support attaching media from TTS sources in ntfy integration (#182140)
tr4nt0r Sep 18, 2026
bcfa88e
Retry Denon AVR setup on any receiver request error (#182613)
balloob Sep 18, 2026
b14a513
Move websocket registration to async_setup in HTML5 integration (#181…
tr4nt0r Sep 18, 2026
11a2f45
Bump aioharmony to 1.0.10 (#182642)
bdraco Sep 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions homeassistant/components/button/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType
from homeassistant.util import dt as dt_util
from homeassistant.util.hass_dict import HassKey

from .const import ( # noqa: F401
DATA_COMPONENT,
DEVICE_CLASSES_SCHEMA,
DOMAIN,
SERVICE_PRESS,
ButtonDeviceClass,
)
from .services import async_setup_services

_LOGGER = logging.getLogger(__name__)

DATA_COMPONENT: HassKey[EntityComponent[ButtonEntity]] = HassKey(DOMAIN)
ENTITY_ID_FORMAT = DOMAIN + ".{}"
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA
PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE
Expand All @@ -45,11 +45,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
)
await component.async_setup(config)

component.async_register_entity_service(
SERVICE_PRESS,
None,
"_async_press_action",
)
async_setup_services(hass)

return True

Expand Down
10 changes: 9 additions & 1 deletion homeassistant/components/button/const.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
"""Provides the constants needed for the component."""

from enum import StrEnum
from typing import Final
from typing import TYPE_CHECKING, Final

import probatio

from homeassistant.util.hass_dict import HassKey

if TYPE_CHECKING:
from homeassistant.helpers.entity_component import EntityComponent

from . import ButtonEntity

DOMAIN: Final = "button"
DATA_COMPONENT: HassKey[EntityComponent[ButtonEntity]] = HassKey(DOMAIN)

SERVICE_PRESS = "press"

Expand Down
15 changes: 15 additions & 0 deletions homeassistant/components/button/services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Services for the Button integration."""

from homeassistant.core import HomeAssistant, callback

from .const import DATA_COMPONENT, SERVICE_PRESS


@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Register the button services."""
hass.data[DATA_COMPONENT].async_register_entity_service(
SERVICE_PRESS,
None,
"_async_press_action",
)
15 changes: 10 additions & 5 deletions homeassistant/components/calendar/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@
from homeassistant.components.llm import LLMTools
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er, intent
from homeassistant.helpers.llm import LLM_API_ASSIST, LLMContext, Tool, ToolInput
from homeassistant.helpers.llm import (
LLM_API_ASSIST,
LLMContext,
Tool,
ToolInput,
ToolResult,
)
from homeassistant.util import dt as dt_util
from homeassistant.util.json import JsonObjectType

from . import SERVICE_GET_EVENTS
from .const import DOMAIN
Expand Down Expand Up @@ -40,7 +45,7 @@ def __init__(self, calendars: list[str]) -> None:
@override
async def async_call(
self, hass: HomeAssistant, tool_input: ToolInput, llm_context: LLMContext
) -> JsonObjectType:
) -> ToolResult:
"""Query a calendar."""
data = self.parameters(tool_input.tool_args)
result = intent.async_match_targets(
Expand All @@ -52,7 +57,7 @@ async def async_call(
),
)
if not result.is_match:
return {"success": False, "error": "Calendar not found"}
return ToolResult(data={"error": "Calendar not found"}, error=True)

entity_id = result.states[0].entity_id
if data["range"] == "today":
Expand Down Expand Up @@ -82,7 +87,7 @@ async def async_call(
for event in cast(dict, service_result)[entity_id]["events"]
]

return {"success": True, "result": events}
return ToolResult(data={"events": events})


@callback
Expand Down
83 changes: 4 additions & 79 deletions homeassistant/components/cover/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
import logging
from typing import Any, final, override

import probatio
from propcache.api import cached_property

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
from homeassistant.const import ( # noqa: F401
SERVICE_CLOSE_COVER,
SERVICE_CLOSE_COVER_TILT,
SERVICE_OPEN_COVER,
Expand All @@ -29,7 +28,6 @@
from homeassistant.helpers.entity import Entity, EntityDescription
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import ConfigType
from homeassistant.util.hass_dict import HassKey

from .condition import make_cover_is_closed_condition, make_cover_is_open_condition
from .const import (
Expand All @@ -39,6 +37,7 @@
ATTR_POSITION,
ATTR_SPEED,
ATTR_TILT_POSITION,
DATA_COMPONENT,
DEVICE_CLASSES_SCHEMA,
DOMAIN,
INTENT_CLOSE_COVER,
Expand All @@ -49,11 +48,11 @@
CoverEntityStateAttribute,
CoverState,
)
from .services import async_setup_services
from .trigger import make_cover_closed_trigger, make_cover_opened_trigger

_LOGGER = logging.getLogger(__name__)

DATA_COMPONENT: HassKey[EntityComponent[CoverEntity]] = HassKey(DOMAIN)
ENTITY_ID_FORMAT = DOMAIN + ".{}"
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA
PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE
Expand Down Expand Up @@ -109,81 +108,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:

await component.async_setup(config)

component.async_register_entity_service(
SERVICE_OPEN_COVER,
{probatio.Optional(ATTR_SPEED): cv.string},
"async_handle_open_cover",
[CoverEntityFeature.OPEN],
)

component.async_register_entity_service(
SERVICE_CLOSE_COVER,
{probatio.Optional(ATTR_SPEED): cv.string},
"async_handle_close_cover",
[CoverEntityFeature.CLOSE],
)

component.async_register_entity_service(
SERVICE_SET_COVER_POSITION,
{
probatio.Required(ATTR_POSITION): probatio.All(
probatio.Coerce(int), probatio.Range(min=0, max=100)
),
probatio.Optional(ATTR_SPEED): cv.string,
},
"async_handle_set_cover_position",
[CoverEntityFeature.SET_POSITION],
)

component.async_register_entity_service(
SERVICE_STOP_COVER, None, "async_stop_cover", [CoverEntityFeature.STOP]
)

component.async_register_entity_service(
SERVICE_TOGGLE,
None,
"async_toggle",
[CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE],
)

component.async_register_entity_service(
SERVICE_OPEN_COVER_TILT,
None,
"async_open_cover_tilt",
[CoverEntityFeature.OPEN_TILT],
)

component.async_register_entity_service(
SERVICE_CLOSE_COVER_TILT,
None,
"async_close_cover_tilt",
[CoverEntityFeature.CLOSE_TILT],
)

component.async_register_entity_service(
SERVICE_STOP_COVER_TILT,
None,
"async_stop_cover_tilt",
[CoverEntityFeature.STOP_TILT],
)

component.async_register_entity_service(
SERVICE_SET_COVER_TILT_POSITION,
{
probatio.Required(ATTR_TILT_POSITION): probatio.All(
probatio.Coerce(int), probatio.Range(min=0, max=100)
)
},
"async_set_cover_tilt_position",
[CoverEntityFeature.SET_TILT_POSITION],
)

component.async_register_entity_service(
SERVICE_TOGGLE_COVER_TILT,
None,
"async_toggle_tilt",
[CoverEntityFeature.OPEN_TILT | CoverEntityFeature.CLOSE_TILT],
)
async_setup_services(hass)

return True

Expand Down
10 changes: 9 additions & 1 deletion homeassistant/components/cover/const.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
"""Constants for cover entity platform."""

from enum import IntFlag, StrEnum
from typing import Final
from typing import TYPE_CHECKING, Final

import probatio

from homeassistant.util.hass_dict import HassKey

if TYPE_CHECKING:
from homeassistant.helpers.entity_component import EntityComponent

from . import CoverEntity

DOMAIN: Final = "cover"
DATA_COMPONENT: HassKey[EntityComponent[CoverEntity]] = HassKey(DOMAIN)

ATTR_CURRENT_POSITION = "current_position"
ATTR_CURRENT_TILT_POSITION = "current_tilt_position"
Expand Down
108 changes: 108 additions & 0 deletions homeassistant/components/cover/services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""Services for the Cover integration."""

import probatio

from homeassistant.const import (
SERVICE_CLOSE_COVER,
SERVICE_CLOSE_COVER_TILT,
SERVICE_OPEN_COVER,
SERVICE_OPEN_COVER_TILT,
SERVICE_SET_COVER_POSITION,
SERVICE_SET_COVER_TILT_POSITION,
SERVICE_STOP_COVER,
SERVICE_STOP_COVER_TILT,
SERVICE_TOGGLE,
SERVICE_TOGGLE_COVER_TILT,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv

from .const import (
ATTR_POSITION,
ATTR_SPEED,
ATTR_TILT_POSITION,
DATA_COMPONENT,
CoverEntityFeature,
)


@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Register the cover services."""
component = hass.data[DATA_COMPONENT]

component.async_register_entity_service(
SERVICE_OPEN_COVER,
{probatio.Optional(ATTR_SPEED): cv.string},
"async_handle_open_cover",
[CoverEntityFeature.OPEN],
)

component.async_register_entity_service(
SERVICE_CLOSE_COVER,
{probatio.Optional(ATTR_SPEED): cv.string},
"async_handle_close_cover",
[CoverEntityFeature.CLOSE],
)

component.async_register_entity_service(
SERVICE_SET_COVER_POSITION,
{
probatio.Required(ATTR_POSITION): probatio.All(
probatio.Coerce(int), probatio.Range(min=0, max=100)
),
probatio.Optional(ATTR_SPEED): cv.string,
},
"async_handle_set_cover_position",
[CoverEntityFeature.SET_POSITION],
)

component.async_register_entity_service(
SERVICE_STOP_COVER, None, "async_stop_cover", [CoverEntityFeature.STOP]
)

component.async_register_entity_service(
SERVICE_TOGGLE,
None,
"async_toggle",
[CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE],
)

component.async_register_entity_service(
SERVICE_OPEN_COVER_TILT,
None,
"async_open_cover_tilt",
[CoverEntityFeature.OPEN_TILT],
)

component.async_register_entity_service(
SERVICE_CLOSE_COVER_TILT,
None,
"async_close_cover_tilt",
[CoverEntityFeature.CLOSE_TILT],
)

component.async_register_entity_service(
SERVICE_STOP_COVER_TILT,
None,
"async_stop_cover_tilt",
[CoverEntityFeature.STOP_TILT],
)

component.async_register_entity_service(
SERVICE_SET_COVER_TILT_POSITION,
{
probatio.Required(ATTR_TILT_POSITION): probatio.All(
probatio.Coerce(int), probatio.Range(min=0, max=100)
)
},
"async_set_cover_tilt_position",
[CoverEntityFeature.SET_TILT_POSITION],
)

component.async_register_entity_service(
SERVICE_TOGGLE_COVER_TILT,
None,
"async_toggle_tilt",
[CoverEntityFeature.OPEN_TILT | CoverEntityFeature.CLOSE_TILT],
)
2 changes: 1 addition & 1 deletion homeassistant/components/debugpy/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"integration_type": "service",
"iot_class": "local_push",
"quality_scale": "internal",
"requirements": ["debugpy==1.8.21"]
"requirements": ["debugpy==1.8.22"]
}
4 changes: 2 additions & 2 deletions homeassistant/components/denonavr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging

from denonavr import DenonAVR
from denonavr.exceptions import AvrNetworkError, AvrTimoutError
from denonavr.exceptions import AvrRequestError

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, EVENT_HOMEASSISTANT_STOP, Platform
Expand Down Expand Up @@ -59,7 +59,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: DenonavrConfigEntry) ->
)
try:
await connect_denonavr.async_connect_receiver()
except (AvrNetworkError, AvrTimoutError) as ex:
except AvrRequestError as ex:
raise ConfigEntryNotReady from ex
receiver = connect_denonavr.receiver

Expand Down
Loading
Loading