Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5b8bee1
Harden Z-Wave JS add-on config against concurrent and abandoned flows…
balloobbot Aug 23, 2026
04fa8c9
Bump nettigo_air_monitor to 5.1.0 (#179911)
bieniu Aug 23, 2026
f40533f
Migrate devcontainer.json to use build.dockerfile/build.context (#179…
BirknerAlex Aug 23, 2026
ee8b787
Bump python-pooldose to 0.9.10 (#179903)
lmaertin Aug 23, 2026
7e1ffaf
Fix LG ThinQ failing to set up during a temporary network outage (#17…
marcotesche Aug 23, 2026
41a9ea7
Add config entry migration for Z-Wave JS (#179898)
balloobbot Aug 23, 2026
2c6f11b
Apply Z-Wave JS add-on config reverts directly (#179899)
balloobbot Aug 23, 2026
2d4e451
Add custom IR-filter-only and manual infrared modes to UniFi Protect …
RaHehl Aug 23, 2026
3ad1d0d
Remove redundant stale device removal from Z-Wave JS migration (#179918)
balloobbot Aug 23, 2026
f426931
Replace a caller supplied Authorization header case-insensitively (#1…
balloob Aug 23, 2026
ae33150
Bump midea-local to 10.0.1 (#179925)
chemelli74 Aug 23, 2026
5fb7c21
Bump denon-rs232 to 4.2.2 (#179870)
balloobbot Aug 23, 2026
661fddb
Bump guntamatic to v1.12.0 (#179921)
JensTimmerman Aug 23, 2026
d9f025d
Forward service call context to entity in ai_task generate services (…
balloob Aug 23, 2026
3683ac9
Remove portlandgeneral virtual integration (#179929)
tronikos Aug 23, 2026
1379995
Upgrade ayla-iot-unofficial to 1.5.2 (#179745)
crevetor Aug 23, 2026
1ff0815
Share one Modbus connection between the integrations on a device (#17…
balloobbot Aug 23, 2026
149f031
Use the non-deprecated vobject_instance in caldav (#179819)
balloob Aug 23, 2026
74a4168
Migrate UniFi Protect light discovery to the public API (#176570)
RaHehl Aug 23, 2026
9d12e00
Migrate UniFi Protect camera config switches to the public API (#174963)
RaHehl Aug 23, 2026
c830734
Don't restore non-KNX attributes for KNX sensors (#179932)
farmio Aug 23, 2026
2aa09bc
Add number platform to Midea (#179247)
chemelli74 Aug 23, 2026
40ec3f7
Filter duplicate bed objects from SleepIQ API before entity setup (#1…
derekcentrico Aug 23, 2026
027edb4
Switchbot Cloud: Add new supported devices[Curtain4] (#178783)
XiaoLing-git Aug 23, 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
6 changes: 4 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"name": "Home Assistant Dev",
"context": "..",
"dockerFile": "../Dockerfile.dev",
"build": {
"dockerfile": "../Dockerfile.dev",
"context": ".."
},
"postCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder} && script/setup",
"postStartCommand": "script/bootstrap",
"containerEnv": {
Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/ai_task/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,15 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:

async def async_service_generate_data(call: ServiceCall) -> ServiceResponse:
"""Run the data task service."""
result = await async_generate_data(hass=call.hass, **call.data)
result = await async_generate_data(
hass=call.hass, context=call.context, **call.data
)
return result.as_dict()


async def async_service_generate_image(call: ServiceCall) -> ServiceResponse:
"""Run the image task service."""
return await async_generate_image(hass=call.hass, **call.data)
return await async_generate_image(hass=call.hass, context=call.context, **call.data)


class AITaskPreferences:
Expand Down
14 changes: 11 additions & 3 deletions homeassistant/components/ai_task/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
async_get_chat_log,
)
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.core import Context
from homeassistant.helpers import llm
from homeassistant.helpers.chat_session import ChatSession
from homeassistant.helpers.restore_state import RestoreEntity
Expand Down Expand Up @@ -61,6 +62,7 @@ async def _async_get_ai_task_chat_log(
self,
session: ChatSession,
task: GenDataTask | GenImageTask,
context: Context | None,
) -> AsyncGenerator[ChatLog]:
"""Context manager used to manage the ChatLog used during an AI Task."""
user_llm_hass_api: llm.API | None = None
Expand All @@ -78,7 +80,7 @@ async def _async_get_ai_task_chat_log(
await chat_log.async_provide_llm_data(
llm.LLMContext(
platform=self.platform.domain,
context=None,
context=context,
language=None,
assistant=DOMAIN,
device_id=None,
Expand All @@ -98,11 +100,14 @@ async def internal_async_generate_data(
self,
session: ChatSession,
task: GenDataTask,
context: Context | None = None,
) -> GenDataTaskResult:
"""Run a gen data task."""
if context is not None:
self.async_set_context(context)
self.__last_activity = dt_util.utcnow().isoformat()
self.async_write_ha_state()
async with self._async_get_ai_task_chat_log(session, task) as chat_log:
async with self._async_get_ai_task_chat_log(session, task, context) as chat_log:
return await self._async_generate_data(task, chat_log)

async def _async_generate_data(
Expand All @@ -118,11 +123,14 @@ async def internal_async_generate_image(
self,
session: ChatSession,
task: GenImageTask,
context: Context | None = None,
) -> GenImageTaskResult:
"""Run a gen image task."""
if context is not None:
self.async_set_context(context)
self.__last_activity = dt_util.utcnow().isoformat()
self.async_write_ha_state()
async with self._async_get_ai_task_chat_log(session, task) as chat_log:
async with self._async_get_ai_task_chat_log(session, task, context) as chat_log:
return await self._async_generate_image(task, chat_log)

async def _async_generate_image(
Expand Down
6 changes: 5 additions & 1 deletion homeassistant/components/ai_task/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from homeassistant.components import camera, conversation, image, media_source
from homeassistant.components.http.auth import async_sign_path
from homeassistant.core import HomeAssistant, ServiceResponse, callback
from homeassistant.core import Context, HomeAssistant, ServiceResponse, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import llm
from homeassistant.helpers.chat_session import ChatSession, async_get_chat_session
Expand Down Expand Up @@ -119,6 +119,7 @@ async def async_generate_data(
structure: vol.Schema | None = None,
attachments: list[dict] | None = None,
llm_api: llm.API | None = None,
context: Context | None = None,
) -> GenDataTaskResult:
"""Run a data generation task in the AI Task integration."""
if entity_id is None:
Expand Down Expand Up @@ -156,6 +157,7 @@ async def async_generate_data(
attachments=resolved_attachments or None,
llm_api=llm_api,
),
context,
)


Expand All @@ -166,6 +168,7 @@ async def async_generate_image(
entity_id: str | None = None,
instructions: str,
attachments: list[dict] | None = None,
context: Context | None = None,
) -> ServiceResponse:
"""Run an image generation task in the AI Task integration."""
if entity_id is None:
Expand Down Expand Up @@ -201,6 +204,7 @@ async def async_generate_image(
instructions=instructions,
attachments=resolved_attachments or None,
),
context,
)

service_result = task_result.as_dict()
Expand Down
14 changes: 7 additions & 7 deletions homeassistant/components/caldav/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ def _get_events(
)
event_list = []
for event in vevent_list:
if not hasattr(event.instance, "vevent"):
if not hasattr(event.vobject_instance, "vevent"):
_LOGGER.warning("Skipped event with missing 'vevent' property")
continue
vevent = event.instance.vevent
vevent = event.vobject_instance.vevent
if not self.is_matching(vevent, self.search):
continue
event_list.append(
Expand Down Expand Up @@ -122,10 +122,10 @@ def _get_next_event(
# and they would not be properly parsed using their original start/end dates.
new_events = []
for event in results:
if not hasattr(event.instance, "vevent"):
if not hasattr(event.vobject_instance, "vevent"):
_LOGGER.warning("Skipped event with missing 'vevent' property")
continue
vevent = event.instance.vevent
vevent = event.vobject_instance.vevent
for start_dt in vevent.getrruleset() or []:
_start_of_today: date | datetime
_start_of_tomorrow: datetime | date
Expand All @@ -138,7 +138,7 @@ def _get_next_event(
_start_of_tomorrow = start_of_tomorrow
if _start_of_today <= start_dt < _start_of_tomorrow:
new_event = event.copy()
new_vevent = new_event.instance.vevent # type: ignore[attr-defined]
new_vevent = new_event.vobject_instance.vevent # type: ignore[attr-defined]
if hasattr(new_vevent, "dtend"):
dur = new_vevent.dtend.value - new_vevent.dtstart.value
new_vevent.dtend.value = start_dt + dur
Expand All @@ -147,9 +147,9 @@ def _get_next_event(
elif _start_of_tomorrow <= start_dt:
break
vevents = [
event.instance.vevent
event.vobject_instance.vevent
for event in results + new_events
if hasattr(event.instance, "vevent")
if hasattr(event.vobject_instance, "vevent")
]

# dtstart can be a date or datetime depending if the event lasts a
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/caldav/todo.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ def _get_todo_items(calendar: caldav.Calendar) -> list[TodoItem]:
def _todo_item(resource: caldav.CalendarObjectResource) -> TodoItem | None:
"""Convert a caldav Todo into a TodoItem."""
if (
not hasattr(resource.instance, "vtodo")
or not (todo := resource.instance.vtodo)
not hasattr(resource.vobject_instance, "vtodo")
or not (todo := resource.vobject_instance.vtodo)
or (uid := get_attr_value(todo, "uid")) is None
or (summary := get_attr_value(todo, "summary")) is None
):
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/denon_rs232/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"iot_class": "local_push",
"loggers": ["denon_rs232"],
"quality_scale": "bronze",
"requirements": ["denon-rs232==4.2.1"]
"requirements": ["denon-rs232==4.2.2"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/fujitsu_fglair/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/fujitsu_fglair",
"integration_type": "hub",
"iot_class": "cloud_polling",
"requirements": ["ayla-iot-unofficial==1.4.7"]
"requirements": ["ayla-iot-unofficial==1.5.2"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/guntamatic/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
"integration_type": "device",
"iot_class": "local_polling",
"quality_scale": "silver",
"requirements": ["guntamatic==1.11.1"]
"requirements": ["guntamatic==1.12.0"]
}
4 changes: 3 additions & 1 deletion homeassistant/components/knx/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ async def async_added_to_hass(self) -> None:
)
):
self._attr_native_value = last_sensor_data.native_value
self._attr_extra_state_attributes.update(last_state.attributes)
# only restore KNX specific attributes - others may have changed
if (source := last_state.attributes.get(ATTR_SOURCE)) is not None:
self._attr_extra_state_attributes[ATTR_SOURCE] = source
await super().async_added_to_hass()

@override
Expand Down
11 changes: 11 additions & 0 deletions homeassistant/components/lg_thinq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from dataclasses import dataclass, field
import logging

from aiohttp import ClientError
from thinqconnect import ThinQApi, ThinQAPIException
from thinqconnect.integration import async_get_ha_bridge_list

Expand Down Expand Up @@ -93,6 +94,11 @@ async def async_setup_coordinators(
bridge_list = await async_get_ha_bridge_list(thinq_api)
except ThinQAPIException as exc:
raise ConfigEntryNotReady(exc.message) from exc
except (ClientError, TimeoutError) as exc:
raise ConfigEntryNotReady(
translation_domain=DOMAIN,
translation_key="connection_error",
) from exc

if not bridge_list:
_LOGGER.warning("No devices registered with the correct profile")
Expand Down Expand Up @@ -144,6 +150,11 @@ async def async_setup_mqtt(
translation_key="failed_to_connect_mqtt",
translation_placeholders={"error": str(exc)},
) from exc
except (ClientError, TimeoutError) as exc:
raise ConfigEntryNotReady(
translation_domain=DOMAIN,
translation_key="connection_error",
) from exc

if not result:
_LOGGER.error("Failed to set up mqtt connection")
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/midea/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
_PLATFORMS: list[Platform] = [
Platform.CLIMATE,
Platform.HUMIDIFIER,
Platform.NUMBER,
Platform.SELECT,
]

Expand Down
3 changes: 3 additions & 0 deletions homeassistant/components/midea/device_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
DeviceType.CC: "MDV Wi-Fi Controller",
DeviceType.CF: "Heat Pump",
DeviceType.FB: "Electric Heater",
DeviceType.C2: "Toilet",
DeviceType.CD: "Heat Pump Water Heater",
DeviceType.ED: "Water Drinking Appliance",
DeviceType.X40: "Integrated Ceiling Fan",
DeviceType.A1: "Dehumidifier",
DeviceType.FA: "Fan",
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/midea/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"iot_class": "local_polling",
"loggers": ["midealocal"],
"quality_scale": "bronze",
"requirements": ["midea-local==10.0.0"]
"requirements": ["midea-local==10.0.1"]
}
Loading
Loading