Compare commits

..

1287 Commits

Author SHA1 Message Date
Stefan Agner
fb68146bce Fix diagnostics tests 2025-06-24 17:23:54 +02:00
Stefan Agner
072c570660 More pytest fixes 2025-06-24 17:23:54 +02:00
Stefan Agner
be62023040 Update pytests 2025-06-24 17:23:54 +02:00
Stefan Agner
b9c563538a Update pytests 2025-06-24 17:23:54 +02:00
Stefan Agner
0e78002c4a Set default update interval 2025-06-24 17:23:54 +02:00
Stefan Agner
e921373833 Use /addons to get list of add-ons 2025-06-24 17:23:54 +02:00
Stefan Agner
ccc7eec253 Split hassio data coordinator
Use two data coordinators for hassio data, one for the Core,
Supervisor, and Operating System updates, and one for the add-on
updates. This allows the add-on updates to be fetched independently
of the Core, Supervisor, and Operating System updates.
2025-06-24 17:23:51 +02:00
Manu
d5a8fa9c5c Add DHCP discovery to PlayStation Network integration (#147422)
Add DHCP discovery for PSN
2025-06-24 17:17:02 +02:00
Abílio Costa
cefde21140 Update Shelly test snapshots (#147429) 2025-06-24 18:08:27 +03:00
hanwg
160163b0cc Remove deprecated proxy params from Telegram bot integration (#147288) 2025-06-24 16:46:31 +02:00
Michael Hansen
6ce594539f Bump wyoming to 1.7.1 (#147385)
* Bump wyoming to 1.7.0

* Bump to 1.7.1 for Python version fix

* Address mypy errors
2025-06-24 09:28:09 -05:00
Robert Resch
4ca39ec7c3 Add range icons for wind_direction sensor device class (#147090)
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-06-24 15:00:03 +01:00
Paul Bottein
cfdd7fbbce Add fields and multiple support to object selector (#147215)
* Add schema supports to object selector

* Update format

* Update homeassistant/helpers/selector.py

Co-authored-by: G Johansson <goran.johansson@shiftit.se>

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2025-06-24 09:54:06 -04:00
Paulus Schoutsen
1cb36f4c18 Convert Claude to use subentries (#147285)
* Convert Claude to use subentries

* Add latest changes from Google subentries

* Revert accidental change to Google
2025-06-24 15:36:09 +02:00
Petar Petrov
602c1c64b3 Update ZwaveJS config flow strings (#147421)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-06-24 14:30:12 +01:00
Andre Lengwenus
3b8d6eb851 Log LCN connection established with log level info (#147424) 2025-06-24 15:24:25 +02:00
Franck Nijhof
9bb98eb514 Merge branch 'master' into dev 2025-06-24 13:19:28 +00:00
karwosts
39c431c55c Add 'max_sub_interval' option to derivative sensor (#125870)
* Add 'max_sub_interval' option to derivative sensor

* add strings

* little coverage

* improve test accuracy

* reimplement at dev head

* string

* handle unavailable

* simplify

* Add self to codeowner

* fix on remove

* Update homeassistant/components/derivative/sensor.py

Co-authored-by: Erik Montnemery <erik@montnemery.com>

* Fix parenthesis

* sort strings

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-06-24 15:05:28 +02:00
Franck Nijhof
0171b527d8 2025.6.3 (#147419)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2025-06-24 14:58:48 +02:00
Paulus Schoutsen
7cccdf2205 Add accept keyword to Media selector (#145527)
* Add accept keyword to Media selector

* Adjust test
2025-06-24 07:36:48 -05:00
Petro31
97f3bb3da5 Add default to from_json (#146211) 2025-06-24 14:27:14 +02:00
Parker Wahle
fc62a6cd89 Add streaming support w/ audio to Android IP Webcam integration (#126009)
* Add streaming support w/ audio to Android IP Webcam integration

* ruff reformat

* Fix ruff

* Break long comments and strings

* Add camera test

* Fix docstring

* Remove dead code

* Call library function to get URL

* Simplify

---------

Co-authored-by: Shay Levy <levyshay1@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-06-24 13:54:34 +02:00
Josef Zweck
23b90f5984 Add door state sensors to tedee (#147386) 2025-06-24 12:30:13 +01:00
Paulus Schoutsen
63ac14a19b AI task generate_text -> generate_data (#147370) 2025-06-24 12:12:29 +01:00
Franck Nijhof
94fd9d1657 Bump version to 2025.6.3 2025-06-24 11:09:26 +00:00
Bram Kragten
2f89317fed Update frontend to 20250531.4 (#147414) 2025-06-24 11:09:03 +00:00
Manu
38c7eaf70a Add reauth flow to PlayStation Network integration (#147397)
* Add reauth flow to psn integration

* changes

* catch auth error in coordinator
2025-06-24 12:20:08 +02:00
dependabot[bot]
02e33c3551 Bump sigstore/cosign-installer from 3.8.2 to 3.9.0 (#147072)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-24 10:50:32 +02:00
Bram Kragten
d5187a6a40 Update frontend to 20250531.4 (#147414) 2025-06-24 10:49:51 +02:00
CubeZ2mDeveloper
703032ab27 Added auto-discovery configuration for SONOFF Dongle Max in zha. (#140574)
Co-authored-by: zetao.zheng <1050713479@qq.com>
2025-06-24 10:19:08 +02:00
Maciej Bieniek
438aa3486d Add full device snapshot tests for Shelly (#145620) 2025-06-24 10:16:46 +02:00
Duco Sebel
f2944f4d8e Add support for v2 API for HomeWizard kWh Meter (#147214) 2025-06-24 10:14:06 +02:00
Erik Montnemery
b8044f60fc Fix trigger config validation (#147408) 2025-06-24 10:13:44 +02:00
Michael Hansen
c67b497f30 Bump intents to 2025.6.23 (#147391) 2025-06-24 10:13:04 +02:00
puddly
aefd9c9b41 Bump universal-silabs-flasher to 0.0.31 (#147393) 2025-06-24 10:11:46 +02:00
Stefan Agner
e5d19baf3e Add container arch to system info (#147372) 2025-06-24 09:52:21 +02:00
Manu
121239bcf7 Fix unbound var and tests in PlayStation Network integration (#147398)
fix unbound var and test mocks
2025-06-24 08:53:45 +02:00
Geoff
eff35e93bd New core integration for VegeHub (#129598)
* Initial commit for VegeHub integration

* Moved several pieces to library, continuing.

* All device contact moved to library

* Updated documentation link

* Fixed an error in strings.json

* Removed commented out code and unused file

* Removed unneeded info logging, and a few missed lines of commented code

* Added/removed comments for clarity

* Converted integration to use webhooks.

* Update __init__.py to remove unnecessary code.

Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com>

* Remove unnecessary code from config_flow.py

Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com>

* Simplify unique_id assertion.

* Switch to CONF_ constant for user input

* Added explanation for passing exception.

* Got rid of try-except, since I don't really handle the exceptions her anyway.

* Moved data transform to vegehub library

* Changed references to use HA constants.

* Fixed assigning and returning _attr properties.

* Moved temperature sensor transform to the library.

* Moved sensor names to strings.json

* Made webhook names unique to avoid collisions when multiple devices are added.

* Converted to using entry.runtime_data

* Removed options flow for first PR

* Removed switch support to limit PR to one platform

* Removed/updated outdated tests

* Update homeassistant/components/vegehub/__init__.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Got rid of strings in favor of constants.

* Got rid of unnecessary check

* Imported constant directly.

* Added custom type for entry

* Expanded CONF_ constants into sensor.py

* Get rid of extra `str` and `get`

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Added type to errors

* Added try/except to MAC address retrieval

* Moved functionality out of ConfigFlow that shouldn't have been there

* Removed IP:MAC tracking from ConfigFlow

* Added retries to VegeHub PyPI package, and implemented them in integration

* Removed different sensor types for now

* Fixed typo

* Changed abort to error

* Fixed error reporting in config flow

* Further simplify sensor.py to handle all sensors the same

* Added comment to clarify

* Got rid of unused constants

* Removed unused strings in strings.json

* Added quality_scale.yaml

* Fixed problems in sensor init

* Moved config url and sw version storage into vegehub package

* Get rid of extra declaration

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Removed unnecessary task

* Fix type for entry

* Added a test before setup

* Fixed tests and got test coverage of config flow to 100%

* Fixed test descriptions

* Implemented a coordinator

* Removed unused property

* Fixed a few minor issues with the coordinator implementation

* Removed unused function

* Fixed some tests

* Trying to fix a problem with re-initialization when server reboots. Mostly working.

* Moved hub.setup from async_setup_entry to config flow to avoid running it on system reboot

* Delete tests/testing_config/.storage/http.auth

* Fixed errors in coordinator.py

* Added IP validation for manual input IP addresses

* Moved data into self._discovered to simplify

* Removed redundant typing

* Shortened sensor unique ID and added coordinator handler

* Added call to super()._handle_coordinator_update() so state gets handled correctly

* Fixed == and is

* Got rid of "slot" and moved functionality to lib

* Got rid of mocked aiohttp calls in favor of just mocking the vegehub library

* Rewrote config flow to make more sense.

* Changed order of data and data_description

* Changes to sensor.py

* Got rid of async_update_data in coordinator and moved async_set_updated_data into webhook callback

* Changed sensor updates so that they keep using last known values if update doesn't contain data for them

* Changed config flow to use homeassistant.helpers.service_info zeroconf instead of homeassistant.components zeroconf

* Added types to test parameters

* Changes and notes in config_flow.py

* Minor fix to get existing tests working before making changes to tests

* Removed unused data and simplified data passing

* Fixed tests, removed unused data, moved sensor tests to snapshots

* Mocked async_setup_entry and async_unload_entry

* Eliminated retry step so that retries just happen in the user flow or zeroconf_confirm

* Bumped the library version

* Bumped library version again

* Changed test-before-setup test

* Improved use of coordinator

* Almost done reworking tests. A few more changes still needed.

* Added via device to sensor.py and key reference to strings.json

* Webhook tests are almost, but not quite, working

* Fully functional again

* Change error to assert

* made identifiers and via_device the same

* made the via_device just be the mac

* Fixed strings.json and updated translations

* Fixed test_sensor.py

* Cleaned up tests and added autouse to several fixtures to simplify

* Switched from error to assert, and added exemption to quality scale.

* Cleaned up some tests and added update of IP if unique ID of discovered device is the same.

* Improved zeroconfig to update IP and hostname, and added a test to make sure those work.

* Fixed a comment.

* Improved ip/hostname update test.

* Changed Hub to VegeHub in strings.json for clarity.

* Switched to using a base entity to simplify and make adding platforms in the future easier.

* Moved the vegehub object into the coordinator to simplify.

* Removed actuators from sensors, and added unique name for battery sensor

* Changed coordinator to manage its own data, changed sensors to use descriptions and return their value as a property

* Updated data retrieval keys

* Minor updates to several files

* Fixed a few things for pytest

* Reverted to explicit check for None for pytest

* Fixed a comment and a variable name

* Fixed a comment

* Fix

* Bumped depenency version to eliminate pytest from dependencies.

---------

Co-authored-by: Josef Zweck <24647999+zweckj@users.noreply.github.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-24 06:55:34 +02:00
Paulus Schoutsen
0cf7952964 Remove duplicated subentry device update in Google Gen AI + add merge test (#147396)
* late comments on Google subentries

* Add test that merges 2 config entries
2025-06-23 22:34:06 -04:00
Paulus Schoutsen
56f4039ac2 Migrate Google Gen AI to use subentries (#147281)
* Migrate Google Gen AI to use subentries

* Add reconfig successful msg

* Address comments

* Do not allow addin subentry when not loaded

* Let HA do the migration

* Use config_entries.async_setup

* Remove fallback name on base entity

* Fix

* Fix

* Fix device name assignment in entity and tts modules

* Fix tests

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-23 20:59:32 -04:00
Andrey Kupreychik
6641cb3799 Handle router initialization, connection errors, and missing interfaces in options flow (#143475)
* Handle router initialization and connection errors in options flow

Added checks in the Keenetic NDMS2 options flow to handle cases where the integration is not initialized or there are connection errors. Relevant user feedback and abort reasons are now provided to ensure a better user experience.

* Add filtering saved/default options for interfaces before preparing an options form
2025-06-23 23:52:23 +02:00
Jack Powell
c671ff3cf1 Add PlayStation Network Integration (#133901)
* clean pull request

* Create one device per console

* Requested changes

* Pr/tr4nt0r/1 (#2)

* clean pull request

* Create one device per console

* device setup

* Merge PR1 - Dynamic Device Support

* Merge PR1 - Dynamic Device Support

---------

Co-authored-by: tr4nt0r <4445816+tr4nt0r@users.noreply.github.com>

* nitpicks

* Update config_flow test

* Update quality_scale.yaml

* repair integrations.json

* minor updates

* Add translation string for invalid account

* misc changes post review

* Minor strings updates

* strengthen config_flow test

* Requested changes

* Applied patch to commit a358725

* migrate PlayStationNetwork helper classes to HA

* Revert to standard psn library

* Updates to media_player logic

* add default_factory, change registered_platforms to set

* Improve test coverage

* Add snapshot test for media_player platform

* fix token parse error

* Parametrize media player test

* Add PS3 support

* Add PS3 support

* Add concurrent console support

* Adjust psnawp rate limit

* Convert to package PlatformType

* Update dependency to PSNAWP==3.0.0

* small improvements

* Add PlayStation PC Support

* Refactor active sessions list

* shift async logic to helper

* Implemented suggested changes

* Suggested changes

* Updated tests

* Suggested changes

* Fix test

* Suggested changes

* Suggested changes

* Update config_flow tests

* Group remaining api call in single executor

---------

Co-authored-by: tr4nt0r <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-06-23 23:46:06 +02:00
Manu
646ddf9c2d Add sensors to ntfy integration (#145262)
* Add sensors

* small changes

* test coverage

* changes

* update snapshot
2025-06-23 23:17:43 +02:00
Paulus Schoutsen
95abd69cc6 Add media class to media player search and play intent (#147097)
Co-authored-by: Michael Hansen <mike@rhasspy.org>
2025-06-23 16:12:32 -05:00
Arie Catsman
ab0ea753e9 Optimize Enphase envoy translation strings. (#147389)
optimize Enphase envoy translation strings.
2025-06-23 22:59:50 +02:00
Åke Strandberg
9b915e996b Refactor states and strings for Miele plate power steps (#144992)
* WIP

* Fix type check

* Empty commit
2025-06-23 22:40:46 +02:00
hanwg
dc948e3b6c Add strict typing for Telegram bot integration (#147262)
add strict typing
2025-06-23 22:22:00 +02:00
epenet
8b6205be25 Remove JuiceNet integration (#147206) 2025-06-23 21:46:51 +02:00
Paulus Schoutsen
7f99cd2d2b Clean up start_subentry_reconfigure_flow API for tests (#147381) 2025-06-23 21:45:33 +02:00
Petro31
b4fe6f3843 Add trigger based fan entities to template integration (#145497)
* Add trigger based fan entities to template integration

* more changes

* add tests

* update doc strings

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-06-23 21:20:55 +02:00
Erik Montnemery
c29879274a Refactor DeviceAutomationConditionProtocol (#147377) 2025-06-23 21:18:56 +02:00
Joost Lekkerkerker
512449a76d Add Bluetooth connection to LaMetric (#147342) 2025-06-23 21:01:01 +02:00
Alex Biddulph
fc91047d8d Add sensors for detailed Enphase inverter readings (#146916)
* Add extra details to Enphase inverters

* Bump pyenphase version to 2.1.0

* Add new inverter sensors and translations

* Add new endpoint

* Start updating tests

* Remove duplicate class

* Add `max_reported` sensor

* Move translation strings to correct location

* Update fixtures and snapshots

* Update unit tests

* Fix linting

* Apply suggestions from code review

Co-authored-by: Arie Catsman <120491684+catsmanac@users.noreply.github.com>

* Fix Telegram bot parsing of inline keyboard (#146376)

* bug fix for inline keyboard

* update inline keyboard test

* Update tests/components/telegram_bot/test_telegram_bot.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* revert last_message_id and updated tests

* removed TypeError test

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Handle the new JSON payload from traccar clients (#147254)

* Set `entity_id`

* Update unit tests

* Bump aioamazondevices to 3.1.14 (#147257)

* Bump pyseventeentrack to 1.1.1 (#147253)

Update pyseventeentrack requirement to version 1.1.1

* Bump uiprotect to version 7.14.1 (#147280)

* Fix `state_class`es for energy production

* Make `max_reported` `name` more descriptive

* Update snapshots

* Reuse some translations

* Remove unnecessary translation keys

* Update unit tests

* Update homeassistant/components/enphase_envoy/strings.json

* Update homeassistant/components/enphase_envoy/strings.json

* Fix

---------

Co-authored-by: Arie Catsman <120491684+catsmanac@users.noreply.github.com>
Co-authored-by: hanwg <han.wuguang@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Joakim Sørensen <joasoe@proton.me>
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
Co-authored-by: Shai Ungar <shai.ungar@riskified.com>
Co-authored-by: Raphael Hehl <7577984+RaHehl@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-06-23 20:59:18 +02:00
starkillerOG
6af290eb74 Add Reolink Telephoto main stream (#146975) 2025-06-23 20:53:09 +02:00
starkillerOG
dd3d6f116e Rename second Reolink lens from "autotrack" to "telephoto" (#146898)
* Rename second Reolink lens from "autotrack" to "telephoto"

* Adjust tests
2025-06-23 20:45:24 +02:00
starkillerOG
b4af9a31cb Add multiple cmd_id pushes for Reolink floodlight (#146685)
Allow for multiple cmd_id pushes
2025-06-23 20:44:35 +02:00
starkillerOG
2862f76fca Add support for Reolink Floodlight PoE/WiFi (#146778)
* Add support for Floodlight PoE/WiFi

* Adjust test

* Add test
2025-06-23 20:43:01 +02:00
Matthias Alphart
3806e5b65c Set KNX to quality scale "silver" (#144879)
Update KNX integration quality scale
2025-06-23 20:41:00 +02:00
Marcel van der Veldt
673a2e35ad Add button entity to Music Assistant to add currently playing item to favorites (#145626)
* Add action to Music Assistant to add currently playing item to favorites

* add test

* Convert to button entity

* review comments

* Update test_button.ambr

* Fix

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Robert Resch <robert@resch.dev>
2025-06-23 20:39:46 +02:00
Franck Nijhof
773c25041a 2025.6.2 (#147355)
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
Co-authored-by: Brian Rogers <brg468@hotmail.com>
Co-authored-by: Raphael Hehl <7577984+RaHehl@users.noreply.github.com>
Co-authored-by: starkillerOG <starkiller.og@gmail.com>
Co-authored-by: Andre Lengwenus <alengwenus@gmail.com>
Co-authored-by: Chris Talkington <chris@talkingtontech.com>
Co-authored-by: Maciej Bieniek <bieniu@users.noreply.github.com>
Co-authored-by: elmurato <1382097+elmurato@users.noreply.github.com>
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
Co-authored-by: Hessel <hesselonline@users.noreply.github.com>
Co-authored-by: Ernst Klamer <e.klamer@gmail.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Ravaka Razafimanantsoa <3774520+SeraphicRav@users.noreply.github.com>
Co-authored-by: Allen Porter <allen.porter@gmail.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: J. Diego Rodríguez Royo <jdrr1998@hotmail.com>
Co-authored-by: puddly <32534428+puddly@users.noreply.github.com>
Co-authored-by: Brett Adams <Bre77@users.noreply.github.com>
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
Co-authored-by: hahn-th <15319212+hahn-th@users.noreply.github.com>
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Joakim Sørensen <joasoe@proton.me>
Co-authored-by: Michael Hansen <mike@rhasspy.org>
Fix blocking open in Minecraft Server (#146820)
Fix missing key for ecosmart in older Wallbox models (#146847)
Fix device type filtering in sensor (#146945)
Fix incorrect use of zip in service.async_get_all_descriptions (#147013)
Fix Shelly entity names for gen1 sleeping devices (#147019)
Fix log in onedrive (#147029)
Fix Charge Cable binary sensor in Teslemetry (#147136)
fix too many requests by API (#147197)
Fix reload for Shelly devices with no script support (#147344)
2025-06-23 20:37:52 +02:00
Petro31
e494f66c02 Add label_description to template engine (#147138)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-06-23 19:21:29 +01:00
tronikos
2833e97625 Default to gemini-2.5-flash (#147334) 2025-06-23 20:11:16 +02:00
Joost Lekkerkerker
442fb88011 Add update platform to LaMetric (#147354) 2025-06-23 20:08:13 +02:00
epenet
6b242fd277 Migrate lifx to use runtime_data and HassKey (#147348) 2025-06-23 20:01:21 +02:00
Joost Lekkerkerker
06ed452d8f Add Matter protocol to Switchbot (#147356) 2025-06-23 17:45:31 +00:00
G Johansson
a7de947f00 Add vacuum activity to pylint type hints check (#147162) 2025-06-23 18:12:18 +01:00
epenet
dfa3fddd35 Migrate livisi to use runtime_data (#147352) 2025-06-23 19:09:38 +02:00
Josef Zweck
ce115cbfe1 Bump aiotedee to 0.2.25 (#147349)
* Bump aiotedee to 0.2.24

* bump to 25

* fix snapshot
2025-06-23 19:08:48 +02:00
epenet
e1d5d312b8 Migrate linear_garage_door to use runtime_data (#147351)
Migrate linear_garage_door to use runtime_data/HassKey
2025-06-23 19:08:32 +02:00
Andre Lengwenus
27565df86f Add PARALLEL_UPDATES constant to binary_sensor and sensor for LCN (#147369)
Add PARALLEL_UPDATES to binary_sensor and sensor
2025-06-23 19:08:18 +02:00
Petro31
7eaa60b17c Add trigger vacuum entities to template integration (#145534)
* Add trigger vacuum entities to template integration

* remove comment

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-06-23 18:10:44 +02:00
Foscam-wangzhengyu
7bb9936e81 Replace foscam dependency (#145766)
* Update Public Library

* Update conftest.py
2025-06-23 18:10:31 +02:00
J. Nick Koston
ccbc5ed65b Bump aioesphomeapi to 3.1.1 (#147345) 2025-06-23 17:50:56 +02:00
Ludovic BOUÉ
e98ec38ad8 Matter energy optimization opt-out attribute (#147096)
* ESAStateEnum

* Update snapshot

* Add test

* Update homeassistant/components/matter/strings.json

Co-authored-by: Norbert Rittel <norbert@rittel.de>

* Update homeassistant/components/matter/strings.json

Co-authored-by: Norbert Rittel <norbert@rittel.de>

* Update homeassistant/components/matter/icons.json

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/matter/sensor.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/matter/strings.json

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update sensor.py

* Update snapshot

---------

Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-23 17:26:27 +02:00
Paulus Schoutsen
a11e274434 Address AI Task late comments (#147313) 2025-06-23 16:58:42 +02:00
Alena Bugrova
f8267b13d7 Add Altruist integration to Core (#146158)
* add altruist integration and tests

* requested fixes + remove some deprecated sensors

* add tests for unknown sensor and device attribute in config_flow

* use CONF_ in data_schema

* suggested fixes

* remove test_setup_entry_success

* create ZeroconfServiceInfo in tests

* use CONF_IP_ADDRESS in tests

* add unique id assert

* add integration to strict-typing, set unavailable if no sensor key in data, change device name

* use add_suggested_values_to_schema, mmHg for pressure

* update snapshots and config entry name in tests

* remove changes in devcontainer config

* fixture for create client error, typing in tests, remove "Altruist" from device name

* change native_value_fn return type

* change sensor.py docstring

* remove device id from entry data, fix docstrings

* remove checks for client and device attributes

* use less variables in tests

* change creating AltruistSensor, remove device from arguments

* Update homeassistant/components/altruist/sensor.py

* Update homeassistant/components/altruist/quality_scale.yaml

* Update homeassistant/components/altruist/quality_scale.yaml

* Update quality_scale.yaml

* hassfest run

* suggested fixes

* set suggested_unit_of_measurement for pressure

* use mock_config_entry, update snapshots

* abort if cant create client on zeroconf step

* move sensor names in translatin placeholders

---------

Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-06-23 16:57:51 +02:00
Sanjay Govind
3798e99ac8 Update bosch_alarm to platinum quality scale (#145027)
* update quality scale for bosch_alarm

* update quality scale

* update quality scale
2025-06-23 16:42:14 +02:00
LG-ThinQ-Integration
fa71c40ff5 Bump thinqconnect to 1.0.7 (#147073)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-06-23 16:12:28 +02:00
Petro31
8e6edf5e34 Add trigger based locks to template integration (#145528)
* Add trigger based locks to template integration

* fix comments
2025-06-23 16:11:15 +02:00
Petro31
c1e32aa9b7 Add trigger template alarm control panels (#145461)
* Add trigger template alarm control panels

* updates

* fix jumbled imports

* fix comments
2025-06-23 16:10:50 +02:00
Michael Heyman
b48ebeaa8a Tilt Pi integration (#139726)
* Create component via script.scaffold

* Create sensor definition

* Define coordinator

* Define config flow

* Refine sensor definition and add tests

* Refine coordinator after testing end to end

* Redefine sensor in a more idiomatic way

* Use entity (common-module)

* Follow config-flow conventions more closely

* Use custom ConfigEntry to conform to strict-typing

* Define API object instead of using aio directly

* Test before setup in init

* Add diagnostics

* Make some more quality changes

* Move scan interval to const

* Commit generated files

* Add quality scale

* feedback: Apply consistent language to Tilt Pi refs

* feedback: Remove empty manifest fields

* feedback: Use translations instead of hardcoded name

* feedback: Remove diagnostics

* feedback: Idiomatic and general improvements

* Use tilt-pi library

* feedback: Coordinator data returns dict

* feedback: Move client creation to coordinator

* feedback: Request only Tilt Pi URL from user

* Update homeassistant/components/tilt_pi/entity.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/tilt_pi/sensor.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/tilt_pi/entity.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* feedback: Avoid redundant keyword arguments in function calls

* feedback: Remove unused models and variables

* feedback: Use icons.json

* feedback: Style best practices

* Update homeassistant/components/tilt_pi/entity.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update tests/components/tilt_pi/test_config_flow.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* feedback: Improve config flow unit tests

* feedback: Patch TiltPi client mock

* feedback: Mark entity-device-class as done

* feedback: Align quaity scale with current state

* feeback: Create brands file for Tilt brand

* feedback: Demonstrate recovery in config flow

* feedback: Test coordinator behavior via sensors

* Update homeassistant/components/tilt_pi/config_flow.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/tilt_pi/coordinator.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/tilt_pi/quality_scale.yaml

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/tilt_pi/quality_scale.yaml

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/tilt_pi/quality_scale.yaml

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/tilt_pi/config_flow.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* feedback: Update tilt_pi quality scale

* feedback: Move const to coordinator

* feedback: Correct strings.json for incorrect and missing fields

* feedback: Use tiltpi package version published via CI

* Run ruff format manually

* Add missing string for invalid host

* Fix

* Fix

---------

Co-authored-by: Michael Heyman <michaelheyman@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-06-23 16:09:41 +02:00
Joost Lekkerkerker
0c08b4fc8b Add Matter protocol to Switchbot (#147356) 2025-06-23 16:06:19 +02:00
Ludovic BOUÉ
9ae3129f16 Matter battery storage (#147235)
* BatCapacity

* BatCapacity

* PowerSourceBatTimeRemaining

* BatChargeState

* Update strings.json

Co-authored-by: Norbert Rittel <norbert@rittel.de>

* Review fixes

* Remove uneeded BatCapacity

* Update strings.json

* Update strings.json

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update snapshots

* Update strings.json

* Update snapshot

---------

Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-06-23 16:04:40 +02:00
Joost Lekkerkerker
d38c880c45 Bump demetriek to 1.3.0 (#147350)
* Bump demetriek to 1.3.0

* Fix
2025-06-23 15:32:57 +02:00
epenet
7ec2e0c524 Move lyric coordinator to separate module (#147357) 2025-06-23 15:10:12 +02:00
Franck Nijhof
570315687f Bump version to 2025.6.2 2025-06-23 12:55:05 +00:00
Simone Chemelli
dfd42863bb Fix reload for Shelly devices with no script support (#147344) 2025-06-23 12:54:48 +00:00
J. Nick Koston
105618734c Bump aioesphomeapi to 33.0.0 (#147296)
fixes compat warning with protobuf 6.x

changelog: https://github.com/esphome/aioesphomeapi/compare/v32.2.4...v33.0.0

Not a breaking change for HA since we are already on protobuf 6
2025-06-23 12:54:47 +00:00
Michael Hansen
9d0701198f Bump aioesphomeapi to 32.2.4 (#147100)
Bump aioesphomeapi
2025-06-23 12:54:46 +00:00
Raphael Hehl
f9d5cb957f Bump uiprotect to version 7.14.1 (#147280) 2025-06-23 12:52:42 +00:00
Simone Chemelli
f7d9334445 Bump aioamazondevices to 3.1.14 (#147257) 2025-06-23 12:52:41 +00:00
Joakim Sørensen
60be2cb168 Handle the new JSON payload from traccar clients (#147254) 2025-06-23 12:52:40 +00:00
Robert Resch
ddf8e0de4b Bump deebot-client to 13.4.0 (#147221) 2025-06-23 12:50:27 +00:00
Hessel
7cc6e28916 Wallbox fix too many requests by API (#147197) 2025-06-23 12:50:26 +00:00
hahn-th
802fcab1c6 Bump homematicip to 2.0.6 (#147151) 2025-06-23 12:50:25 +00:00
Marc Mueller
3534396028 [ci] Bump cache key version (#147148) 2025-06-23 12:50:24 +00:00
Brett Adams
458aa3cc22 Fix Charge Cable binary sensor in Teslemetry (#147136) 2025-06-23 12:50:22 +00:00
Martin Hjelmare
39b64b0af3 Improve advanced Z-Wave battery discovery (#147127) 2025-06-23 12:50:21 +00:00
Raphael Hehl
c66d411826 Bump uiprotect to version 7.14.0 (#147102) 2025-06-23 12:50:20 +00:00
Simone Chemelli
0b383b7493 Bump aioamazondevices to 3.1.12 (#147055)
* Bump aioamazondevices to 3.1.10

* bump to 3.1.12
2025-06-23 12:50:19 +00:00
Simone Chemelli
1a3384e8b4 Bump aioamazondevices to 3.1.4 (#146883) 2025-06-23 12:50:18 +00:00
Josef Zweck
2c357265b0 Handle missing widget in lamarzocco (#147047) 2025-06-23 12:47:00 +00:00
Josef Zweck
c395c77cd3 Bump pylamarzocco to 2.0.9 (#147046) 2025-06-23 12:46:59 +00:00
puddly
57eceeea38 Bump ZHA to 0.0.60 (#147045) 2025-06-23 12:46:58 +00:00
J. Diego Rodríguez Royo
f75ba9172c Bump aiohomeconnect to 0.18.0 (#147044) 2025-06-23 12:46:57 +00:00
G Johansson
a15d722f0e Bump holidays lib to 0.75 (#147043) 2025-06-23 12:46:55 +00:00
Josef Zweck
a07531d0e7 Fix log in onedrive (#147029) 2025-06-23 12:46:54 +00:00
Martin Hjelmare
96d6cacae4 Disable Z-Wave idle notification button (#147026)
* Update test

* Disable Z-Wave idle notification button

* Update tests
2025-06-23 12:46:53 +00:00
Maciej Bieniek
766ddfaacc Fix Shelly entity names for gen1 sleeping devices (#147019) 2025-06-23 12:46:52 +00:00
Martin Hjelmare
5ea6cb3846 Disable Z-Wave indidator CC entities by default (#147018)
* Update discovery tests

* Disable Z-Wave indidator CC entities by default
2025-06-23 12:46:52 +00:00
Erik Montnemery
912c4804cb Fix incorrect use of zip in service.async_get_all_descriptions (#147013)
* Fix incorrect use of zip in service.async_get_all_descriptions

* Fix lint errors in test
2025-06-23 12:46:50 +00:00
Allen Porter
8f13520a1c Bump ical to 10.0.4 (#147005)
* Bump ical to 10.0.4

* Bump ical to 10.0.4 in google
2025-06-23 12:46:50 +00:00
Joost Lekkerkerker
d2d5b29e2b Bump pySmartThings to 3.2.5 (#146983) 2025-06-23 12:46:48 +00:00
Ravaka Razafimanantsoa
94a2642ce9 Switchbot Cloud: Fix device type filtering in sensor (#146945)
* Add Smart Lock Ultra support and fix device type filtering in sensor integration

* Adding fix in binary sensor

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-23 12:46:47 +00:00
Josef Zweck
d0060a2b21 Add debug log for update in onedrive (#146907) 2025-06-23 12:46:46 +00:00
starkillerOG
9b744e2fef Bump reolink-aio to 0.14.1 (#146903) 2025-06-23 12:46:45 +00:00
Ernst Klamer
d66dee5411 Bump bthome-ble to 3.13.1 (#146871) 2025-06-23 12:46:45 +00:00
Hessel
da97756157 Fix missing key for ecosmart in older Wallbox models (#146847)
* fix 146839, missing key

* added tests for this issue

* added tests for this issue

* added tests for this issue, formatting

* Prevent loading select on missing key

* Prevent loading select on missing key - formatting fixed

* Update homeassistant/components/wallbox/coordinator.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-06-23 12:46:43 +00:00
Andre Lengwenus
a7b2f800f8 Bump pypck to 0.8.8 (#146841) 2025-06-23 12:46:42 +00:00
starkillerOG
05831493e2 Bump motion blinds to 0.6.28 (#146831) 2025-06-23 12:46:42 +00:00
J. Nick Koston
8e685b1626 Bump aiohttp to 3.12.13 (#146830)
changelog: https://github.com/aio-libs/aiohttp/compare/v3.12.12...v3.12.13

Likely does not affect us at all but just in case, tagging
2025-06-23 12:44:59 +00:00
Franck Nijhof
87ecf552dc Add unique ID support to Trend integration YAML configuration (#147346) 2025-06-23 14:44:58 +02:00
Simone Chemelli
a6e6b6db5a Bump aioamazondevices to 3.1.3 (#146828) 2025-06-23 12:42:08 +00:00
elmurato
d684360ebd Fix blocking open in Minecraft Server (#146820)
Fix blocking open by dnspython
2025-06-23 12:42:07 +00:00
Maciej Bieniek
01a133a2b8 Use Shelly main device area as suggested area for sub-devices (#146810) 2025-06-23 12:42:06 +00:00
Chris Talkington
b249ae408f Update rokuecp to 0.19.5 (#146788) 2025-06-23 12:42:05 +00:00
Andre Lengwenus
04b3227b9b Bump pypck to 0.8.7 (#146657) 2025-06-23 12:42:04 +00:00
starkillerOG
0a8d117129 Bump reolink-aio to 0.14.0 (#146566) 2025-06-23 12:42:03 +00:00
Raphael Hehl
83f26f7393 Bump uiprotect to 7.13.0 (#146410) 2025-06-23 12:42:02 +00:00
Raphael Hehl
9ed6f226c6 Bump uiprotect to 7.12.0 (#146337) 2025-06-23 12:42:00 +00:00
Brian Rogers
2ba9cb1510 Remove address info from Rachio calendar events (#145896)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-23 12:42:00 +00:00
Simone Chemelli
2e155831e6 Fix reload for Shelly devices with no script support (#147344) 2025-06-23 14:38:16 +02:00
Hessel
756b858840 Wallbox fix too many requests by API (#147197) 2025-06-23 14:10:50 +02:00
rrooggiieerr
b2520394f4 Lametric add configuration url (#147118)
* Set cofiguration URL to LaMetric device web interface

* Update LaMetric unit tests to accomodate fro configuration url
2025-06-23 13:47:52 +02:00
Maciej Bieniek
2a97b128c3 Bump IMGW-PIB backend library to version 1.1.0 (#147341) 2025-06-23 13:42:33 +02:00
epenet
d06da8c2da Migrate lcn to use runtime_data (#147333) 2025-06-23 13:41:53 +02:00
Erik Montnemery
2bfb09cb11 Improve test of WS command get_services cache handling (#147134) 2025-06-23 13:29:29 +02:00
Guido Schmitz
bf733fdec5 Remove config flow unique_id migration from devolo Home Control (#147327)
Remove config flow unique_id conversion from devolo Home Control
2025-06-23 13:16:57 +02:00
epenet
3b4eb7c749 Migrate lametric to use runtime_data (#147328)
* Migrate lametric to use runtime_data

* One more

* Drop unused hass_config
2025-06-23 13:15:08 +02:00
Artur Pragacz
1119716c32 Clean superfluous cloud deps from pyproject (#147223) 2025-06-23 13:15:01 +02:00
epenet
0ab23ccb51 Migrate landisgyr_heat_meter to use runtime_data (#147329) 2025-06-23 13:14:38 +02:00
Matrix
436fcb7e85 Fixed YoLink incorrect valve status (#147021)
* Fix valve status

* Fix as suggested
2025-06-23 13:14:18 +02:00
epenet
4d2f0f2de6 Migrate laundrify to use runtime_data (#147331)
* Migrate laundrify to use runtime_data

* Adjust test
2025-06-23 13:14:11 +02:00
Ludovic BOUÉ
82c1751f85 Matter dishwasher alarm (#146842)
* Update binary_sensor.py

* Update silabs_dishwasher.json

DishwasherAlarm

* DishwasherAlarm

* Update snapshot

* DishwasherAlarm

* test_dishwasher_alarm

* DishwasherAlarm

* Update silabs_dishwasher.json

* Update snapshot
2025-06-23 12:40:37 +02:00
epenet
a2785a86dc Migrate ld2410_ble to use runtime_data (#147335) 2025-06-23 12:13:10 +02:00
epenet
741e89383b Migrate leaone to use runtime_data (#147336) 2025-06-23 12:12:32 +02:00
epenet
f64533e9e0 Migrate led_ble to use runtime_data (#147337) 2025-06-23 12:11:03 +02:00
epenet
b13dd4e6ca Migrate lg_netcast to use runtime_data (#147338) 2025-06-23 12:09:51 +02:00
Noah Husby
35f310748e Add switch entity to Russound RIO (#147323)
* Add switch entity to Russound RIO

* Add switch snapshot
2025-06-23 10:42:36 +02:00
epenet
69d2cd0ac0 Migrate lastfm to use runtime_data (#147330) 2025-06-23 10:40:48 +02:00
Marc Mueller
10c573bbc3 Use PEP 695 TypeVar syntax for unifi (#147157) 2025-06-23 10:34:35 +02:00
Brian Rogers
93030ad48d Remove address info from Rachio calendar events (#145896)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-23 10:31:35 +02:00
Noah Husby
a7290f92cf Add number entity to Russound RIO (#147228)
* Add number entity to Russound RIO

* Fixes

* Fix tests

* Change entity name
2025-06-23 00:02:16 +02:00
Simone Chemelli
b47706f360 Add sensor platform to Alexa Devices (#146469)
* Add sensor platform to Amazon Devices

* fix merge after rename

* fix requirements

* cleanup

* Revert "cleanup"

This reverts commit f34892da8a.

* tests

* move logic in sensor entity description

* update tests

* apply review comment

* apply review comments
2025-06-23 00:01:15 +02:00
DeerMaximum
25968925e7 Use has_entity_name in NINA (#146755)
* Comply with has-entity-name rule.

* Fix tests
2025-06-22 23:57:33 +02:00
msw
fcba1183f8 Add water filter replacement and usage sensors to SmartThings (#147279)
* Add "Filter status" binary sensor for Samsung refrigerators

* Add "Water filter usage" sensor for Samsung refrigerators
2025-06-22 23:57:02 +02:00
Guido Schmitz
75946065f2 Combine executor calls in devolo Home Control (#147216) 2025-06-22 23:55:51 +02:00
Markus Adrario
3734c4e91d fix reconfig in case of no connection. (#147275) 2025-06-22 19:05:56 +02:00
Michael
7d421bf223 Fix regex patterns in foobot sensor tests (#147306) 2025-06-22 19:02:43 +02:00
Michael
41e53297c2 Add update entity to immich integration (#147273)
* add update entity

* remove unneccessary entity description

* rename update entity to version

* simplify test

* define static attribute outside of the constructor

* move min version check into coordinator
2025-06-22 16:54:48 +02:00
J. Nick Koston
d4e7667ea0 Bump aioesphomeapi to 33.0.0 (#147296)
fixes compat warning with protobuf 6.x

changelog: https://github.com/esphome/aioesphomeapi/compare/v32.2.4...v33.0.0

Not a breaking change for HA since we are already on protobuf 6
2025-06-22 10:24:16 -04:00
Ravaka Razafimanantsoa
daa4ddabfe Switchbot Cloud: Fix device type filtering in sensor (#146945)
* Add Smart Lock Ultra support and fix device type filtering in sensor integration

* Adding fix in binary sensor

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-22 14:12:09 +02:00
Michael
8cead00bc7 Bump aioimmich to 0.10.1 (#147293)
bump aioimmich to 0.10.1
2025-06-22 12:19:03 +02:00
G Johansson
db3090078b Remove deprecated support feature values in camera (#146988) 2025-06-22 09:31:16 +02:00
Ludovic BOUÉ
66e2fd997b Battery voltage translation key (#147238)
* Add translation_key

* Update strings.json

* Update snapshots

* Switch icon to DC

* Update snapshots
2025-06-22 09:27:44 +02:00
Raphael Hehl
a102eaf0cd Bump uiprotect to version 7.14.1 (#147280) 2025-06-22 02:14:26 +02:00
Shai Ungar
f3533dff44 Bump pyseventeentrack to 1.1.1 (#147253)
Update pyseventeentrack requirement to version 1.1.1
2025-06-21 22:50:53 +01:00
Simone Chemelli
c453eed32d Bump aioamazondevices to 3.1.14 (#147257) 2025-06-21 15:44:22 +02:00
Joakim Sørensen
79a9f34150 Handle the new JSON payload from traccar clients (#147254) 2025-06-21 11:53:17 +02:00
hanwg
7442f7af28 Fix Telegram bot parsing of inline keyboard (#146376)
* bug fix for inline keyboard

* update inline keyboard test

* Update tests/components/telegram_bot/test_telegram_bot.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* revert last_message_id and updated tests

* removed TypeError test

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-21 03:21:10 +02:00
Markus Adrario
2e5de732a7 Bump pyHomee to version 1.2.10 (#147248)
bump pyHomee to version 1.2.10
2025-06-21 00:32:14 +01:00
Michael Hansen
9bcd74c449 Change async_supports_streaming_input to an instance method (#147245) 2025-06-20 15:39:22 -05:00
Noah Husby
ace18e540b Bump aiorussound to 4.6.1 (#147233) 2025-06-20 21:59:59 +02:00
Michael Hansen
65f897793d Use string instead of boolean for voice event (#147244)
Use string instead of bool
2025-06-20 15:18:03 -04:00
Robert Resch
435c08685d Bump deebot-client to 13.4.0 (#147221) 2025-06-20 20:22:33 +02:00
J. Diego Rodríguez Royo
95f292c43d Bump aiohomeconnect to 0.18.1 (#147236) 2025-06-20 19:27:29 +02:00
Manu
9346c584c3 Add reconfigure flow to ntfy integration (#143743) 2025-06-20 18:42:47 +02:00
Michael Hansen
6738085391 Minor clean up missed in previous PR (#147229) 2025-06-20 10:54:11 -05:00
Markus Adrario
d9e5bad55e Use entity name in homee (#147142)
* add name to HomeeEntity

* review change
2025-06-20 16:55:48 +02:00
Maciej Bieniek
f7429f3431 Fix Shelly entity names for gen1 sleeping devices (#147019) 2025-06-20 15:19:39 +02:00
Petar Petrov
46aea5d9dc Bump zwave-js-server-python to 0.64.0 (#147176) 2025-06-20 14:59:54 +02:00
Paulus Schoutsen
33bde48c9c AI Task integration (#145128)
* Add AI Task integration

* Remove GenTextTaskType

* Add AI Task prefs

* Add action to LLM task

* Remove WS command

* Rename result to text for GenTextTaskResult

* Apply suggestions from code review

Co-authored-by: Allen Porter <allen.porter@gmail.com>

* Add supported feature for generate text

* Update const.py

Co-authored-by: HarvsG <11440490+HarvsG@users.noreply.github.com>

* Update homeassistant/components/ai_task/services.yaml

Co-authored-by: HarvsG <11440490+HarvsG@users.noreply.github.com>

* Use WS API to set preferences

* Simplify pref storage

* Simplify pref test

* Update homeassistant/components/ai_task/services.yaml

Co-authored-by: Allen Porter <allen.porter@gmail.com>

---------

Co-authored-by: Allen Porter <allen.porter@gmail.com>
Co-authored-by: HarvsG <11440490+HarvsG@users.noreply.github.com>
2025-06-20 08:56:08 -04:00
Noah Husby
1b73acc025 Add sub-device support to Russound RIO (#146763) 2025-06-20 14:52:34 +02:00
Guido Schmitz
e28965770e Add translations for devolo Home Control exceptions (#147099)
* Add translations for devolo Home Control exceptions

* Adapt invalid_auth message

* Adapt connection_failed message
2025-06-20 14:31:16 +02:00
Kevin Stillhammer
f9d4bde0f6 Bump here-routing to 1.2.0 (#147204)
* Bump here-routing to 1.2.0

* Fix mypy typing errors

* Correct types for call assertion
2025-06-20 13:44:14 +02:00
Duco Sebel
a493bdc208 Implement battery group mode in HomeWizard (#146770)
* Implement battery group mode for HomeWizard P1

* Clean up test

* Disable 'entity_registry_enabled_default'

* Fix failing tests because of 'entity_registry_enabled_default'

* Proof entities are disabled by default

* Undo dev change

* Update homeassistant/components/homewizard/select.py

* Update homeassistant/components/homewizard/select.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/homewizard/strings.json

* Apply suggestions from code review

* Update tests due to updated translations

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-06-20 13:19:45 +02:00
Markus Adrario
9ae9ad1e43 Improve test-coverage for homee locks (#147160)
test for unknown user
2025-06-20 12:28:49 +02:00
epenet
1b60ea8951 Migrate lutron to use runtime_data (#147198) 2025-06-20 12:26:07 +02:00
epenet
313eaff14e Migrate kaleidescape to use runtime_data (#147171)
* Migrate kaleidescape to use runtime_data

* Adjust tests
2025-06-20 12:25:57 +02:00
epenet
7dfd68f8c0 Migrate keenetic_ndms2 to use runtime_data (#147194)
* Migrate keenetic_ndms2 to use runtime_data

* Adjust tests
2025-06-20 12:23:59 +02:00
epenet
544fd2a4a6 Migrate lacrosse_view to use runtime_data (#147202) 2025-06-20 12:23:29 +02:00
epenet
cd51070219 Migrate kmtronic to use runtime_data (#147193) 2025-06-20 11:39:13 +02:00
Marc Mueller
3c91c78383 Use PEP 695 TypeVar syntax for ecovacs (#147153) 2025-06-20 10:41:25 +02:00
Brett Adams
96e0d1f5c6 Fix Charge Cable binary sensor in Teslemetry (#147136) 2025-06-20 10:39:43 +02:00
epenet
2859e7de9b Migrate kodi to use runtime_data (#147191) 2025-06-20 10:38:01 +02:00
Robert Resch
88683a318d Add support of taking a camera snapshot via go2rtc (#145205) 2025-06-20 10:34:43 +02:00
epenet
84e9422254 Move juicenet coordinator to separate module (#147168) 2025-06-20 10:33:17 +02:00
epenet
fde36d5034 Simplify update_listener in konnected (#147172) 2025-06-20 10:31:28 +02:00
Andre Lengwenus
8c1e43c07c Bump pypck to 0.8.9 (#147174) 2025-06-20 10:28:35 +02:00
epenet
05343392a7 Simplify update_listener in keenetic_ndms2 (#147173) 2025-06-20 10:27:47 +02:00
epenet
32314dbb13 Simplify update_listener in kmtronic (#147184) 2025-06-20 10:27:07 +02:00
epenet
8f661fc5cf Migrate kegtron to use runtime_data (#147177) 2025-06-20 10:26:53 +02:00
epenet
e315cb9859 Migrate kostal_plenticore to use runtime_data (#147188) 2025-06-20 10:25:08 +02:00
epenet
d0e77eb1e2 Migrate keymitt_ble to use runtime_data (#147179) 2025-06-20 10:24:56 +02:00
epenet
e23cac8bef Simplify remove listener in kodi (#147183) 2025-06-20 10:23:41 +02:00
epenet
973700542b Move kmtronic coordinator to separate module (#147182) 2025-06-20 10:19:19 +02:00
Krisjanis Lejejs
2e21493c19 Bump hass-nabucasa from 0.102.0 to 0.103.0 (#147186) 2025-06-20 10:18:03 +02:00
Markus Adrario
73bed96a0f remove unwanted attribute in homee sensor tests (#147158) 2025-06-20 08:11:20 +02:00
Markus Adrario
0a5d13f104 fix and improve cover tests for homee (#147164) 2025-06-20 08:10:44 +02:00
epenet
d16ec81727 Migrate justnimbus to use runtime_data (#147170) 2025-06-20 08:10:06 +02:00
Martin Hjelmare
11564e3df5 Fix Z-Wave device class endpoint discovery (#142171)
* Add test fixture and test for Glass 9 shutter

* Fix zwave_js device class discovery matcher

* Fall back to node device class

* Fix test_special_meters modifying node state

* Handle value added after node ready
2025-06-20 08:56:20 +03:00
Michael Hansen
341d9f15f0 Add ask_question action to Assist satellite (#145233)
* Add get_response to Assist satellite and ESPHome

* Rename get_response to ask_question

* Add possible answers to questions

* Add wildcard support and entity test

* Add ESPHome test

* Refactor to remove async_ask_question

* Use single entity_id instead of target

* Fix error message

* Remove ESPHome test

* Clean up

* Revert fix
2025-06-19 16:50:14 -05:00
Marc Mueller
2c13c70e12 Update ruff to 0.12.0 (#147106) 2025-06-19 20:39:09 +02:00
Marc Mueller
73d0d87705 Use PEP 695 TypeVar syntax for nextdns (#147155) 2025-06-19 20:26:07 +02:00
Marc Mueller
b8dfb2c850 Use PEP 695 TypeVar syntax for eheimdigital (#147154) 2025-06-19 20:25:45 +02:00
Marc Mueller
cf67a68454 Use PEP 695 TypeVar syntax for paperless_ngx (#147156) 2025-06-19 20:24:51 +02:00
karwosts
b003429912 Expose statistics selector, use for recorder.get_statistics (#147056)
* Expose statistics selector, use for `recorder.get_statistics`

* code review

* syntax formatting

* rerun ci
2025-06-19 20:04:28 +02:00
hahn-th
4aff032442 Bump homematicip to 2.0.6 (#147151) 2025-06-19 18:55:14 +02:00
Martin Hjelmare
da3d8a6332 Improve advanced Z-Wave battery discovery (#147127) 2025-06-19 18:56:47 +03:00
Marc Mueller
7a5c088149 [ci] Bump cache key version (#147148) 2025-06-19 17:42:30 +02:00
Norbert Rittel
31eec6f471 Add missing hyphen to "mains-powered" and "battery-powered" in zha (#147128)
Add missing hyphen to "mains-powered" and "battery-powered"
2025-06-19 14:36:40 +03:00
G Johansson
c602a0e279 Deprecated hass.http.register_static_path now raises error (#147039) 2025-06-19 13:14:42 +02:00
Marc Mueller
513045e489 Update pytest warnings filter (#147132) 2025-06-19 13:07:42 +02:00
Erik Montnemery
0db6520802 Add comment in helpers.llm.ActionTool explaining limitations (#147116) 2025-06-19 12:59:35 +02:00
Erik Montnemery
5bc2e271d2 Re-raise annotated_yaml.YAMLException as HomeAssistantError (#147129)
* Re-raise annotated_yaml.YAMLException as HomeAssistantError

* Fix comment
2025-06-19 12:52:01 +02:00
G Johansson
77dca49c75 Fix pylint plugin for vacuum entity (#146467)
* Clean out legacy VacuumEntity from pylint plugins

* Fix

* Fix pylint for vacuum

* More fixes

* Revert partial

* Add back state
2025-06-19 12:49:10 +02:00
Franck Nijhof
1baba8b880 Adjust feature request links in issue reporting (#147130) 2025-06-19 12:36:43 +02:00
Markus Adrario
875d81cab2 update pyHomee to v1.2.9 (#147094) 2025-06-19 12:04:59 +02:00
Raphael Hehl
956f726ef3 Bump uiprotect to version 7.14.0 (#147102) 2025-06-19 11:20:29 +02:00
epenet
fada81e1ce Bump ovoenergy to 2.0.1 (#147112) 2025-06-19 08:46:03 +02:00
Simon Lamon
6a16424bb4 Fix nightly build (#147110)
Update builder.yml
2025-06-19 08:20:19 +02:00
Abílio Costa
f90a740429 Use non-autospec mock for Reolink's binary_sensor, camera and diag tests (#147095) 2025-06-19 08:03:48 +02:00
Michael Hansen
3dba7e5bd2 Send intent progress events to ESPHome (#146966) 2025-06-18 22:12:37 -04:00
Erik Montnemery
8d8ff011fc Minor improvements of service helper (#147079) 2025-06-19 00:17:12 +01:00
Michael Hansen
6befd065a1 Bump aioesphomeapi to 32.2.4 (#147100)
Bump aioesphomeapi
2025-06-18 15:49:44 -05:00
Abílio Costa
9adf493acd Use non-autospec mock for Reolink's init tests (#146991) 2025-06-18 17:58:50 +01:00
Michael Hansen
a29d5fb56c tts_output is optional in run-start (#147092) 2025-06-18 12:08:53 -04:00
Petro31
bcb87cf812 Support variables, icon, and picture for all compatible template platforms (#145893)
* Fix template entity variables in blueprints

* add picture and icon tests

* add variable test for all platforms

* apply comments

* Update all test names
2025-06-18 16:49:46 +02:00
Jan Bouwhuis
d01758cea8 Ensure mqtt sensor has a valid native unit of measurement (#146722) 2025-06-18 15:48:38 +02:00
Joakim Sørensen
5487bfe1d9 Bump hass-nabucasa from 0.101.0 to 0.102.0 (#147087) 2025-06-18 15:47:01 +02:00
Simone Chemelli
fec65f40fc Bump aioamazondevices to 3.1.12 (#147055)
* Bump aioamazondevices to 3.1.10

* bump to 3.1.12
2025-06-18 10:20:51 +02:00
Guido Schmitz
596951ea9f Cleanup devolo Home Control tests (#147051) 2025-06-18 09:24:09 +02:00
Norbert Rittel
75d6b885cf Fix typo in state name references of homee (#146905)
Fix typo in state references

Replace wrong semicolons with colon.
2025-06-18 09:23:37 +02:00
Guido Schmitz
3fad76dfa1 Use missed typed ConfigEntry in devolo Home Control (#147049) 2025-06-18 09:22:37 +02:00
Pete Sage
43d8a151ab Remove internals from Sonos test_init.py (#147063)
* fix: test init

* fix: revert

* fix: revert

* fix: revert

* fix: revert

* fix: simplify
2025-06-18 09:21:21 +02:00
starkillerOG
07110e288d If no Reolink HTTP api available, do not set configuration_url (#146684)
* If no http api available, do not set configuration_url

* Add tests
2025-06-18 09:16:08 +02:00
Jan-Philipp Benecke
ba2aac4614 Bump aiowebdav2 to 0.4.6 (#147054) 2025-06-18 09:15:27 +02:00
msw
3449dae7a2 Capitalize "Ice Bites" and switch to "Cubed ice" (#147060) (#147061) 2025-06-18 09:14:45 +02:00
G Johansson
b8cd3f3635 Bump holidays lib to 0.75 (#147043) 2025-06-18 10:11:01 +03:00
Martin Hjelmare
be53ad5449 Disable Z-Wave idle notification button (#147026)
* Update test

* Disable Z-Wave idle notification button

* Update tests
2025-06-18 08:29:04 +03:00
J. Diego Rodríguez Royo
ffd940e07c Set quality scale at Home Connect manifest (#147050) 2025-06-17 21:42:40 +01:00
Josef Zweck
5e31b5ac4f Handle missing widget in lamarzocco (#147047) 2025-06-17 21:25:27 +02:00
puddly
81257f9d57 Bump ZHA to 0.0.60 (#147045) 2025-06-17 22:06:53 +03:00
Josef Zweck
ce1678719a Bump pylamarzocco to 2.0.9 (#147046) 2025-06-17 20:59:41 +02:00
Guido Schmitz
fc6844b3c9 Add _attr_has_entity_name to devolo Home Network device tracker platform (#146978)
* Add _attr_has_entity_name to devolo Home Network device tracker platform

* Set name

* Fix tests
2025-06-17 20:49:52 +02:00
J. Diego Rodríguez Royo
8e82e3aa3a Bump aiohomeconnect to 0.18.0 (#147044) 2025-06-17 20:48:09 +02:00
G Johansson
3bc68941e6 Remove not used constant in climate (#147041) 2025-06-17 20:43:16 +02:00
Josef Zweck
e69b38ab2c Fix log in onedrive (#147029) 2025-06-17 19:57:52 +02:00
Abílio Costa
ed9503324d Fix flaky Reolink webhook test (#147036) 2025-06-17 17:18:48 +01:00
Allen Porter
22a06a6c2e Bump ical to 10.0.4 (#147005)
* Bump ical to 10.0.4

* Bump ical to 10.0.4 in google
2025-06-17 07:06:51 -07:00
Michael Hansen
3b611b9b03 Add TTS response timeout for idle state (#146984)
* Add TTS response timeout for idle state

* Consider time spent sending TTS audio in timeout
2025-06-17 09:39:18 -04:00
Noah Husby
79cc3bffc6 Bump aiorussound to 4.6.0 (#147023) 2025-06-17 14:40:56 +02:00
Martin Hjelmare
5c455304a5 Disable Z-Wave indidator CC entities by default (#147018)
* Update discovery tests

* Disable Z-Wave indidator CC entities by default
2025-06-17 15:39:22 +03:00
Erik Montnemery
058f860be7 Fix incorrect use of zip in service.async_get_all_descriptions (#147013)
* Fix incorrect use of zip in service.async_get_all_descriptions

* Fix lint errors in test
2025-06-17 14:24:31 +02:00
Joost Lekkerkerker
ef319c966d Bump nextcord to 3.1.0 (#147020) 2025-06-17 14:11:55 +02:00
Robin Lintermann
adc4e9fdc1 Bump pysmarlaapi version to 0.9.0 (#146629)
Bump pysmarlaapi version
Fix default values of entities
2025-06-17 11:23:50 +02:00
Maciej Bieniek
40a00fb790 Address late review for NextDNS integration (#146980)
key instead of Key
2025-06-17 11:23:03 +02:00
G Johansson
0926b16095 Remove deprecated support feature values in cover (#146987) 2025-06-17 10:46:08 +02:00
G Johansson
308c89af4a Remove deprecated support feature values in media_player (#146986) 2025-06-17 10:33:41 +02:00
G Johansson
b0c2a47288 Remove deprecated support feature values in vacuum (#146982) 2025-06-17 10:32:58 +02:00
Joost Lekkerkerker
c446cce2cc Bump pySmartThings to 3.2.5 (#146983) 2025-06-16 22:44:14 +01:00
Abílio Costa
e02267ad89 Improve bootstrap file logging test (#146670) 2025-06-16 21:55:16 +01:00
Thomas55555
36381e6753 Bump aioautomower to 2025.6.0 (#146979) 2025-06-16 22:52:23 +02:00
Manu
6533562f4e Rename Xiaomi Miio integration to Xiaomi Home (#146555)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-06-16 21:51:54 +01:00
Ludovic BOUÉ
1bc6ea98ce Set Matter SolarPower tagList in fixture (#146837)
Update solar_power.json

Set tagList to [{"0":null,"1":15,"2":2,"3":"Solar"}]
2025-06-16 22:46:27 +02:00
elmurato
bab34b844b Fix blocking open in Minecraft Server (#146820)
Fix blocking open by dnspython
2025-06-16 22:46:11 +02:00
Etienne C.
ad3dac0373 Removed rounding of durations in Here Travel Time sensors (#146838)
* Removed rounding of durations

* Set duration sensors unit to seconds

* Updated Here Travel Time tests

* Update homeassistant/components/here_travel_time/sensor.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/here_travel_time/sensor.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Updated Here Travel Time tests

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-06-16 22:20:01 +02:00
Maciej Bieniek
c5d93e5456 Fix translation key in NextDNS integration (#146976)
* Fix translation key

* Better wording
2025-06-16 21:37:19 +02:00
J. Diego Rodríguez Royo
ef9b46dce5 Record current IQS state for Home Connect (#131703)
* Home Connect quality scale

* Update current iqs

* Docs rules done

* parallel-updates rule

* Complete appropriate-polling's comment

* Apply suggestions

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-16 21:30:06 +02:00
Abílio Costa
6f3ceb83c2 Use non-autospec mock for Reolink's button tests (#146969) 2025-06-16 21:14:02 +02:00
Joost Lekkerkerker
589577a04c Add diagnostics support to Meater (#146967) 2025-06-16 20:17:30 +02:00
Joost Lekkerkerker
cb21bb6542 Make Meater cook state an enum (#146958) 2025-06-16 19:13:34 +01:00
mswilson
ad64139b8e Add switch for Samsung ice bites (and rename ice maker) (#146925)
* Add switch for ice bites (and rename ice maker)

Fixes: home-assistant/home-assistant.io#37826

* Fix tests

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-16 19:31:49 +02:00
Joost Lekkerkerker
9ae0cfc7e5 Create entities directly on setup in Meater (#146953)
* Don't wait an update when adding devices in Meater

* Fix
2025-06-16 18:23:20 +02:00
Joost Lekkerkerker
dffaf49eca Use runtime data in Meater (#146961) 2025-06-16 17:18:21 +02:00
Maciej Bieniek
4add783108 Use entity base class for NextDNS entities (#146934)
* Add entity module

* Add NextDnsEntityDescription class

* Remove NextDnsEntityDescription

* Create DeviceInfo in entity module

* Use property
2025-06-16 16:58:47 +02:00
Joost Lekkerkerker
421251308f Add Meater sensor tests (#146952) 2025-06-16 16:19:35 +02:00
Aviad Levy
cce878213f Add Telegram Bot message reactions (#146354) 2025-06-16 14:48:59 +01:00
Joost Lekkerkerker
664441eaec Improve Meater config flow tests (#146951) 2025-06-16 15:40:43 +02:00
Maciej Bieniek
d4686a3cce Add config flow data description for NextDNS (#146938)
* Add config flow data description

* Better wording
2025-06-16 15:28:25 +02:00
Hessel
6e92247799 Fix missing key for ecosmart in older Wallbox models (#146847)
* fix 146839, missing key

* added tests for this issue

* added tests for this issue

* added tests for this issue, formatting

* Prevent loading select on missing key

* Prevent loading select on missing key - formatting fixed

* Update homeassistant/components/wallbox/coordinator.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-06-16 15:15:17 +02:00
Etienne C.
f5355c833e Add duration device class in Here Travel Time sensors (#146804) 2025-06-16 15:14:43 +02:00
Joost Lekkerkerker
add9f4c5ab Move Meater coordinator to module (#146946)
* Move Meater coordinator to module

* Fix tests
2025-06-16 14:48:44 +02:00
starkillerOG
38973fe64a Add Reolink privacy mask switch (#146906) 2025-06-16 14:40:19 +02:00
epenet
d657964729 Simplify habitica service actions (#146746) 2025-06-16 14:37:38 +02:00
Nathan Spencer
25c408484c Set goalzero total run time sensor device class to duration (#146897) 2025-06-16 14:35:56 +02:00
Florian von Garrel
c335b5b37c Add verify ssl option to paperless-ngx integration (#146802)
* add verify ssl config option

* Refactoring

* Use .get() with default value instead of migration

* Reconfigure fix

* minor changes
2025-06-16 14:31:22 +02:00
Josef Zweck
61b00892c3 Add debug log for update in onedrive (#146907) 2025-06-16 14:17:36 +02:00
Maciej Bieniek
e47e2c92fe Change PARALLEL_UPDATES to 0 for read-only NextDNS platforms (#146939)
Change PARALLEL_UPDATES to 0 for read-only platforms
2025-06-16 14:11:48 +02:00
Duco Sebel
3283965b45 Re-enable v2 API support for HomeWizard P1 Meter (#146927) 2025-06-16 14:11:35 +02:00
epenet
4a9cbc79f2 Bump pysml to 0.1.5 (#146935) 2025-06-16 12:56:03 +01:00
epenet
33978ce59e Bump pyosoenergyapi to 1.1.5 (#146942) 2025-06-16 12:46:38 +01:00
epenet
d5262231a1 Bump pymysensors to 0.25.0 (#146941) 2025-06-16 13:37:39 +02:00
Brett Adams
b563f9078a Significantly improve Tesla Fleet config flow (#146794)
* Improved config flow

* Tests

* Improvements

* Dashboard url & tests

* Apply suggestions from code review

Co-authored-by: Norbert Rittel <norbert@rittel.de>

* revert oauth change

* fully restore oauth file

* remove CONF_DOMAIN

* Add pick_implementation back in

* Use try else

* Improve translation

* use CONF_DOMAIN

---------

Co-authored-by: Norbert Rittel <norbert@rittel.de>
2025-06-16 13:29:17 +02:00
epenet
e8667dfbe0 Bump nessclient to 1.2.0 (#146937) 2025-06-16 12:11:57 +01:00
dependabot[bot]
8d4f5d78ff Bump dawidd6/action-download-artifact from 10 to 11 (#146928)
Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 10 to 11.
- [Release notes](https://github.com/dawidd6/action-download-artifact/releases)
- [Commits](https://github.com/dawidd6/action-download-artifact/compare/v10...v11)

---
updated-dependencies:
- dependency-name: dawidd6/action-download-artifact
  dependency-version: '11'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 10:42:10 +02:00
mbo18
e354a850c9 Bump python-rflink to 0.0.67 (#146908)
* update python-rflink

* remove from FORBIDDEN_PACKAGE_EXCEPTIONS
2025-06-16 10:36:20 +02:00
Ernst Klamer
5ea026d369 Bump bthome-ble to 3.13.1 (#146871) 2025-06-16 11:29:00 +03:00
Brett Adams
ddfe17d0a4 Bump tesla-fleet-api to match Protobuf compatibility (#146918)
Bump for v1.2.0
2025-06-16 10:12:34 +02:00
Yuxin Wang
85aa7bef1e Add sensor categorizations for APCUPSD (#146863)
* Add sensor categorizations

* Fix snapshot problem

* Fix snapshot problem
2025-06-16 08:43:31 +02:00
Paulus Schoutsen
8498928e47 Move Google Gen AI fixture to allow reuse (#146921) 2025-06-15 23:00:27 -04:00
Paulus Schoutsen
fa21269f0d Simplify ChatLog dependencies (#146351) 2025-06-15 17:41:15 -04:00
starkillerOG
5f5869ffc6 Bump reolink-aio to 0.14.1 (#146903) 2025-06-15 20:53:32 +02:00
Nathan Spencer
7a2d99a450 Bump pylitterbot to 2024.2.0 (#146901) 2025-06-15 20:41:07 +02:00
Andre Lengwenus
6b669ce40c Bump pypck to 0.8.8 (#146841) 2025-06-15 19:32:13 +02:00
Markus Adrario
fdf4ed2aa5 Homee add button_state to event entities (#146860)
* use entityDescription

* Add new event and adapt tests

* change translation

* use references in strings
2025-06-15 18:17:52 +02:00
Simone Chemelli
1361d10cd7 Bump aioamazondevices to 3.1.4 (#146883) 2025-06-15 08:30:19 -07:00
Marc Mueller
8c7ba11493 Fix telegram_bot RuntimeWarning in tests (#146781) 2025-06-15 11:23:17 +03:00
Marc Mueller
29ce17abf4 Update eq3btsmart to 2.1.0 (#146335)
* Update eq3btsmart to 2.1.0

* Update import names

* Update register callbacks

* Updated data model

* Update Thermostat set value methods

* Update Thermostat init

* Thermostat status and device_data are always given

* Minor compatibility fixes

---------

Co-authored-by: Lennard Beers <l.beers@outlook.de>
2025-06-15 10:17:01 +02:00
Markus Lanthaler
c988d1ce36 Add support for Gemini's new TTS capabilities (#145872)
* Add support for Gemini TTS

* Add tests

* Use wave library and update a few comments
2025-06-14 22:21:04 -07:00
Paulus Schoutsen
ec02f6d010 Extract Google LLM base entity class (#146817) 2025-06-14 22:17:52 -07:00
Simone Chemelli
9f19c4250a Bump aioamazondevices to 3.1.3 (#146828) 2025-06-15 01:45:28 +03:00
Marc Mueller
d7b583ae51 Update pydantic to 2.11.7 (#146835) 2025-06-14 23:31:09 +02:00
Maciej Bieniek
152e5254e2 Use Shelly main device area as suggested area for sub-devices (#146810) 2025-06-14 13:53:51 -04:00
starkillerOG
3f8f7cd578 Bump motion blinds to 0.6.28 (#146831) 2025-06-14 19:01:41 +02:00
Chris Talkington
ed3fb62ffc Update rokuecp to 0.19.5 (#146788) 2025-06-14 18:49:16 +02:00
J. Nick Koston
1d14e1f018 Bump aiohttp to 3.12.13 (#146830)
changelog: https://github.com/aio-libs/aiohttp/compare/v3.12.12...v3.12.13

Likely does not affect us at all but just in case, tagging
2025-06-14 17:13:20 +01:00
hahn-th
2ac8901a0d Improve code quality in async_setup_entry of switches in homematicip_cloud (#146816)
improve setup of switches
2025-06-14 17:26:08 +02:00
Joris Pelgröm
6204fd5363 Add polling to LetPot coordinator (#146823)
- Adds polling (update_interval) to the coordinator for the LetPot integration. Push remains the primary update mechanism for all entities, but:
   - Polling makes entities go unavailable when the device can't be reached, which otherwise won't happen.
   - Pump changes do not always trigger a status push by the device (not sure why), polling makes the integration catch up to reality.
2025-06-14 16:24:48 +02:00
Brett Adams
ce52ef64db Bump tesla-fleet-api to 1.1.3 (#146793) 2025-06-14 08:39:27 -05:00
Paulus Schoutsen
059c12798d Drop user prompt from LLMContext (#146787) 2025-06-13 22:01:39 -04:00
epenet
56aa809074 Simplify google_photos service actions (#146744) 2025-06-13 18:57:11 -07:00
Marc Mueller
3d2dca5f0c Adjust scripts for compatibility with Python 3.14 (#146774) 2025-06-13 21:54:25 -04:00
starkillerOG
cdb2b407be Add Reolink baby cry sensitivity (#146773)
* Add baby cry sensitivity

* Adjust tests
2025-06-14 00:11:13 +01:00
Ian
186ed451a9 Bump nextbus client to 2.3.0 (#146780) 2025-06-14 00:09:29 +01:00
Franck Nijhof
a75646d047 2025.6.1 (#146764) 2025-06-13 22:15:26 +02:00
Franck Nijhof
25d1480f2a Hotfix ruff warnings 2025-06-13 18:09:05 +00:00
hahn-th
2175754a1f Fix throttling issue in HomematicIP Cloud (#146683)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-13 17:57:39 +00:00
hahn-th
761a0877e6 Fix throttling issue in HomematicIP Cloud (#146683)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-13 19:57:03 +02:00
Franck Nijhof
df5f253146 Bump version to 2025.6.1 2025-06-13 17:20:24 +00:00
J. Nick Koston
a017d9415b Bump aiodns to 3.5.0 (#146758) 2025-06-13 17:20:09 +00:00
Marc Mueller
e89c3b1e92 Ignore lingering pycares shutdown thread (#146733) 2025-06-13 17:20:07 +00:00
Allen Porter
d4ffeedc87 Partial revert of update to remote calendar to fix issue where calendar does not update (#146702)
Partial revert
2025-06-13 17:20:06 +00:00
Allen Porter
cb74b2663f Revert scan interval change in local calendar (#146700) 2025-06-13 17:20:05 +00:00
tronikos
4ec711bd63 Fix opower to work with aiohttp>=3.12.7 by disabling cookie quoting (#146697)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-13 17:20:03 +00:00
Simone Chemelli
e81c8ce44d Bump aioamazondevices to 3.1.2 (#146690) 2025-06-13 17:20:02 +00:00
Simone Chemelli
c2cf348255 Filter speak notify entity for WHA devices in Alexa Devices (#146688) 2025-06-13 17:20:00 +00:00
Simon Lamon
e048a3da38 Bump linkplay to v0.2.12 (#146669) 2025-06-13 17:19:59 +00:00
Tsvi Mostovicz
7cf3116f5b Bump hdate to 1.1.2 (#146659) 2025-06-13 17:19:58 +00:00
epenet
5cd7ea06ad Bump wakeonlan to 3.1.0 (#146655)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-13 17:19:56 +00:00
Simone Chemelli
52c62b31fd Fix cookies with aiohttp >= 3.12.7 for Vodafone Station (#146647) 2025-06-13 17:19:55 +00:00
Paul Bottein
b2bb0aeb64 Update frontend to 20250531.3 (#146638) 2025-06-13 17:19:53 +00:00
Vasilis Valatsos
f0fc87e2b6 Drop HostKeyAlgorithms in aruba (#146619) 2025-06-13 17:19:52 +00:00
epenet
e7a88e99f9 Fix fan is_on status in xiaomi_miio (#146592) 2025-06-13 17:19:50 +00:00
Avi Miller
c3e3a36b4c Fix palette handling for LIFX Ceiling SKY effect (#146582)
Signed-off-by: Avi Miller <me@dje.li>
2025-06-13 17:19:49 +00:00
J. Nick Koston
91bc56b15c Bump aiodns to 3.5.0 (#146758) 2025-06-13 19:12:52 +02:00
Paulus Schoutsen
d1e2c62433 Remove unnecessary string formatting. (#146762) 2025-06-13 10:10:47 -07:00
Duco Sebel
524c16fbe1 Bumb python-homewizard-energy to 9.1.1 (#146723)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-13 18:59:28 +02:00
Marc Mueller
2fdd3d66bc Update pydantic to 2.11.6 (#146745) 2025-06-13 18:53:05 +02:00
Simone Chemelli
6a1e3b60ee Filter speak notify entity for WHA devices in Alexa Devices (#146688) 2025-06-13 18:49:18 +02:00
DeerMaximum
434cd95a66 Use ConfigEntry.runtime_data to store runtime data in NINA (#146754)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-06-13 18:47:21 +02:00
Vasilis Valatsos
1a5bc2c7e0 Drop HostKeyAlgorithms in aruba (#146619) 2025-06-13 18:47:07 +02:00
epenet
a66e9a1a2c Simplify reolink service actions (#146751) 2025-06-13 18:08:59 +02:00
Paulus Schoutsen
d880ce6bb4 Clean up Google conversation entity (#146736) 2025-06-13 10:30:14 -04:00
Paulus Schoutsen
c96023dcae Clean up Anthropic conversation entity (#146737) 2025-06-13 10:29:26 -04:00
Paulus Schoutsen
2f8ad4d5bf Clean up Ollama conversation entity (#146738) 2025-06-13 10:29:19 -04:00
Marc Mueller
038a848d53 Fix androidtv isfile patcher in tests (#146696) 2025-06-13 16:25:09 +02:00
epenet
ff17d79e73 Bump wakeonlan to 3.1.0 (#146655)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-13 08:58:44 -05:00
tronikos
a8201009f3 Fix opower to work with aiohttp>=3.12.7 by disabling cookie quoting (#146697)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-13 08:58:27 -05:00
Simone Chemelli
a349653282 Bump aioamazondevices to 3.1.2 (#146690) 2025-06-13 16:53:18 +03:00
epenet
355ee1178e Add callback decorator to async_setup_services (#146729) 2025-06-13 15:16:55 +02:00
Marc Mueller
30c5df3eaa Adjust core create_task tests with event_loop patch (#146699) 2025-06-13 15:16:28 +02:00
Marc Mueller
10874af19a Ignore lingering pycares shutdown thread (#146733) 2025-06-13 15:09:37 +02:00
Marc Mueller
704118b3d0 Remove unnecessary patch from toon tests (#146691) 2025-06-13 12:53:33 +02:00
Marc Mueller
7c575d0316 Fix asuswrt test patch (#146692) 2025-06-13 12:52:56 +02:00
starkillerOG
ab3f11bfe7 Add Reolink IR brightness entity (#146717) 2025-06-13 12:50:12 +02:00
Allen Porter
f0357539ad Add myself as a remote calendar code owner (#146703) 2025-06-13 12:48:24 +02:00
Allen Porter
e70a2dd257 Partial revert of update to remote calendar to fix issue where calendar does not update (#146702)
Partial revert
2025-06-13 12:47:56 +02:00
Allen Porter
5ef99a15a5 Revert scan interval change in local calendar (#146700) 2025-06-13 12:46:01 +02:00
Marc Mueller
6421973cd6 Remove unnecessary patch from panel_custom tests (#146695) 2025-06-13 10:46:26 +02:00
Marc Mueller
7201171eb5 Replace unnecessary pydantic import in matrix tests (#146693) 2025-06-13 10:45:54 +02:00
Abílio Costa
1fb438fa6c Add missing mock value to Reolink test (#146689) 2025-06-13 07:43:21 +02:00
starkillerOG
89ae68c5af Reolink check if camera and motion supported (#146666) 2025-06-12 22:19:46 +01:00
Paul Bottein
c78b66d5d5 Update frontend to 20250531.3 (#146638) 2025-06-12 16:52:09 -04:00
starkillerOG
d756cf91ce Add model_id to Reolink IPC camera (#146664) 2025-06-12 20:41:13 +01:00
Simon Lamon
8d13bf93ab Bump linkplay to v0.2.12 (#146669) 2025-06-12 20:38:42 +01:00
Franck Nijhof
e86e793842 Tweak non-English issue detection (#146636) 2025-06-12 13:38:20 -04:00
Tsvi Mostovicz
7e6bb021ce Bump hdate to 1.1.2 (#146659) 2025-06-12 18:29:47 +01:00
starkillerOG
680b70aa29 Reolink add diagnostics for baichuan (#146667)
* Add baichuan diagnostics

* adjust tests
2025-06-12 19:26:37 +02:00
Andre Lengwenus
8eebebc586 Bump pypck to 0.8.7 (#146657) 2025-06-12 17:36:50 +01:00
epenet
48e4624ba0 Add basic xiaomi_miio fan tests (#146593) 2025-06-12 17:33:45 +01:00
epenet
b0cf974b34 Simplify swiss public transport service actions (#146611) 2025-06-12 16:27:20 +02:00
Simone Chemelli
171f7c5f81 Fix cookies with aiohttp >= 3.12.7 for Vodafone Station (#146647) 2025-06-12 16:24:10 +02:00
Avi Miller
8807c530a9 Fix palette handling for LIFX Ceiling SKY effect (#146582)
Signed-off-by: Avi Miller <me@dje.li>
2025-06-12 14:32:04 +02:00
dependabot[bot]
28bd90aeb0 Bump actions/attest-build-provenance from 2.3.0 to 2.4.0 (#146594)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 14:18:04 +02:00
dependabot[bot]
af1eccabce Bump github/codeql-action from 3.28.19 to 3.29.0 (#146595)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 14:17:36 +02:00
Pete Sage
afc0a2789d Update Sonos to use SonosConfigEntry and runtime data (#145512)
* fix: initial

* fix: cleanup

* fix: cleanup

* fix: cleanup

* fix: SonosConfigEntry

* add config_entry.py

* fix: sonos_data to runtime_data

* fix: move to helpers.py
2025-06-12 14:05:51 +02:00
epenet
78ed1097c4 Simplify netgear_lte service actions (#146606) 2025-06-12 14:02:17 +02:00
epenet
2991726d35 Simplify screenlogic service actions (#146609) 2025-06-12 14:02:06 +02:00
epenet
c34596e54d Simplify seventeentrack service actions (#146610)
* Simplify seventeentrack service actions

* callback
2025-06-12 14:01:53 +02:00
epenet
74a92e2cd8 Simplify tado service actions (#146614) 2025-06-12 14:01:45 +02:00
Franck Nijhof
e19f178864 Make duplicate issue detection more strict (#146633) 2025-06-12 13:55:26 +02:00
epenet
9dfbccf0cb Improve type hints in xiaomi_miio fan (#146596) 2025-06-12 12:18:46 +02:00
epenet
64e503bc27 Fix fan is_on status in xiaomi_miio (#146592) 2025-06-12 12:18:23 +02:00
epenet
9d1e60cf7e Simplify mealie service actions (#146601) 2025-06-12 12:17:27 +02:00
epenet
4160521349 Simplify overseerr service actions (#146607) 2025-06-12 12:17:00 +02:00
epenet
14c30ef2df Mark async_setup_services as callback (#146617) 2025-06-12 11:34:56 +02:00
epenet
e14cf8a5b9 Remove deprecated service in plex (#146608)
* Remove deprecated service in plex

* Update json/yaml
2025-06-12 10:43:03 +02:00
epenet
30dbd5a900 Simplify synology_dsm service actions (#146612) 2025-06-12 10:42:40 +02:00
G Johansson
25e6eab008 Not valid hvac modes now fails in Climate (#145242)
* Not valid hvac modes now fails

* Fix some tests

* Some more

* More

* fix ruff

* HVAC

* Fritzbox

* Clean up

* Use dict[key]

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-12 07:15:07 +02:00
Thomas55555
8bf562b7b6 Add strings for pick implementation (#146557)
* Add string for pick implementation

* add missing
2025-06-12 06:02:26 +02:00
rappenze
7cb3c397b2 Support more dimmer devices in fibaro (#145864) 2025-06-11 23:55:38 +02:00
Christopher Boyd
f44f2522ef Add 'AdvancedToggle' to list of supported Lutron button types (#145676) 2025-06-11 23:54:22 +02:00
Denis Shulyaka
8c9acf5a4d Separate steps for openai_conversation options flow (#141533) 2025-06-11 23:54:01 +02:00
starkillerOG
e46e7f5a81 Bump reolink-aio to 0.14.0 (#146566) 2025-06-11 23:52:31 +02:00
Franck Nijhof
7aa6c8b941 2025.6.0 (#145650) 2025-06-11 21:28:56 +02:00
Calvin C
c01f521199 Bump hyperion-py to 0.7.6 and add switch for Audio Capture to Hyperion Integration (#145952)
Co-authored-by: ToniCipriani <ToniCipriani@users.noreply.github.com>
Co-authored-by: Robert Resch <robert@resch.dev>
2025-06-11 21:20:22 +02:00
Franck Nijhof
54d8d71de5 Bump version to 2025.6.0 2025-06-11 19:14:05 +00:00
Robert Resch
fb4c77d43b Add aiofiles to pyproject.toml (#146561) 2025-06-11 18:39:53 +00:00
Robert Resch
4a15f12a0b Add aiofiles to pyproject.toml (#146561) 2025-06-11 20:32:38 +02:00
Franck Nijhof
cada2f84a9 Hotfix ruff warnings 2025-06-11 18:13:03 +00:00
Franck Nijhof
dc4627f413 Bump version to 2025.6.0b9 2025-06-11 18:07:37 +00:00
Joost Lekkerkerker
02524b8b9b Make issue creation check architecture instead of uname (#146537) 2025-06-11 18:06:36 +00:00
Ståle Storø Hauknes
8d24d775f1 Set suggested precision for Airthings sensors (#145966) 2025-06-11 20:04:03 +02:00
epenet
aca0e69081 Simplify service registration in recorder (#146237) 2025-06-11 20:01:13 +02:00
andreimoraru
60b8230ecc Bump yt-dlp to 2025.06.09 (#146553)
* Bumped yt-dlp to 2025.06.09

* fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-11 18:00:53 +00:00
Paul Bottein
75e6f23a82 Update frontend to 20250531.2 (#146551) 2025-06-11 18:00:52 +00:00
Petar Petrov
1f221712a2 Remove the Delete button on the ZwaveJS device page (#146544) 2025-06-11 18:00:51 +00:00
Paul Bottein
43797c03cc Update frontend to 20250531.1 (#146542) 2025-06-11 18:00:49 +00:00
Erik Montnemery
89637a618e Handle changes to source entities in generic_thermostat helper (#146541) 2025-06-11 18:00:48 +00:00
Erik Montnemery
fd605e0abe Handle changes to source entities in generic_hygrostat helper (#146538) 2025-06-11 17:58:52 +00:00
G Johansson
f4e5036275 New helper for templating args in command_line (#145899) 2025-06-11 19:58:28 +02:00
rappenze
59aba339d8 Add support for more cover devices in Fibaro (#146486) 2025-06-11 19:56:38 +02:00
Franck Nijhof
e73bcc73b5 Bump version to 2025.6.0b8 2025-06-11 17:26:20 +00:00
Erik Montnemery
c02707a90f Handle changes to source entity in statistics helper (#146523) 2025-06-11 17:25:57 +00:00
Erik Montnemery
232f853d68 Simplify helper_integration.async_handle_source_entity_changes (#146516) 2025-06-11 17:22:28 +00:00
Tsvi Mostovicz
91e296a0c8 Bump hdate to 1.1.1 (#146536) 2025-06-11 16:58:43 +00:00
Simon Lamon
bcedb06862 Bump linkplay to v0.2.11 (#146530) 2025-06-11 16:56:36 +00:00
Erik Montnemery
2ab32220ed Handle changes to source entity in utility_meter (#146526) 2025-06-11 16:56:35 +00:00
Erik Montnemery
273ccb3929 Handle changes to source entity in trend helper (#146525) 2025-06-11 16:56:33 +00:00
Erik Montnemery
caaa4d5f35 Handle changes to source entity in threshold helper (#146524) 2025-06-11 16:56:32 +00:00
Erik Montnemery
0cf1fd1d41 Handle changes to source entity in integration helper (#146522) 2025-06-11 16:54:26 +00:00
Erik Montnemery
5ee39df330 Handle changes to source entity in history_stats helper (#146521) 2025-06-11 16:54:25 +00:00
Martin Hjelmare
cc972d20f6 Remove Z-Wave useless reconfigure options (#146520)
* Remove emulate hardware option

* Remove log level option
2025-06-11 16:54:24 +00:00
Erik Montnemery
e0f32cfd54 Allow removing entity registry items twice (#146519) 2025-06-11 16:54:22 +00:00
Jesse Hills
6384c800c3 Fix solax state class of Today's Generated Energy (#146492) 2025-06-11 16:50:15 +00:00
tronikos
82de2ed8e1 Rename Amazon Devices to Alexa Devices (#146362)
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-11 16:50:14 +00:00
Aidan Timson
af72d1854f Add guide for Honeywell Lyric application credentials setup (#146281)
* Add guide for Honeywell Lyric application credentials setup

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-11 16:50:13 +00:00
Shay Levy
0cff7cbccd Remove stale Shelly BLU TRV devices (#145994)
* Remove stale Shelly BLU TRV devices

* Add test

* Remove config entry from device
2025-06-11 16:50:11 +00:00
Kevin Stillhammer
6f4e16eed1 Fix stale options in here_travel_time (#145911) 2025-06-11 16:50:10 +00:00
Petro31
66be2f9240 Fix delay_on and delay_off restarting when a new trigger occurs during the delay (#145050) 2025-06-11 16:50:09 +00:00
Joost Lekkerkerker
864e440685 Make issue creation check architecture instead of uname (#146537) 2025-06-11 18:39:46 +02:00
tronikos
2f6fcb5801 Rename Amazon Devices to Alexa Devices (#146362)
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-11 18:35:26 +02:00
G Johansson
bdb6124aa3 Remove previously deprecated cached_property (#146478)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-06-11 18:22:11 +02:00
epenet
613e2fd4b3 Simplify google_mail service actions (#146511) 2025-06-11 18:19:57 +02:00
Kevin Stillhammer
0e71ef3861 Fix stale options in here_travel_time (#145911) 2025-06-11 18:17:11 +02:00
andreimoraru
5076c10959 Bump yt-dlp to 2025.06.09 (#146553)
* Bumped yt-dlp to 2025.06.09

* fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-11 17:53:25 +02:00
Shay Levy
ab2fc4e9a6 Remove stale Shelly BLU TRV devices (#145994)
* Remove stale Shelly BLU TRV devices

* Add test

* Remove config entry from device
2025-06-11 17:39:49 +02:00
Erik Montnemery
e39edcc234 Remove unused attribute EntityInfo.custom_component (#146550) 2025-06-11 17:27:17 +02:00
Paul Bottein
54c8e59bcd Update frontend to 20250531.2 (#146551) 2025-06-11 17:12:34 +02:00
Franck Nijhof
c806555879 Add non-English issue detection using GitHub AI models (#146547) 2025-06-11 16:52:35 +02:00
G Johansson
4836930cb1 Remove previously deprecated StrEnum backport (#146477) 2025-06-11 16:41:40 +02:00
epenet
4a8faad62e Simplify fully_kiosk service actions (#146509) 2025-06-11 16:34:48 +02:00
peteS-UK
ba69301dda Move available property to entity.py for Squeezebox (#146531) 2025-06-11 16:34:08 +02:00
Aidan Timson
724c349194 Add guide for Honeywell Lyric application credentials setup (#146281)
* Add guide for Honeywell Lyric application credentials setup

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-06-11 16:24:37 +02:00
epenet
9346f8d658 Simplify blink service actions (#146508) 2025-06-11 16:21:42 +02:00
hanwg
0af41d9cb1 Bug fix for Telegram bot integration: Handle plain text parse_mode (#146535) 2025-06-11 16:19:22 +02:00
Marc Mueller
b02c0419b4 Update types packages (#146546) 2025-06-11 16:15:54 +02:00
Marc Mueller
0bc6408137 Update pytest-unordered to 0.7.0 (#146545) 2025-06-11 15:01:27 +01:00
Tsvi Mostovicz
3f1d2b1b71 Bump hdate to 1.1.1 (#146536) 2025-06-11 15:46:52 +02:00
Paul Bottein
bcfdee23e3 Update frontend to 20250531.1 (#146542) 2025-06-11 15:46:19 +02:00
Franck Nijhof
4a50f4ffc1 Add duplicate issue detection using GitHub AI models (#146487) 2025-06-11 15:42:37 +02:00
Petar Petrov
9ee45518e9 Remove the Delete button on the ZwaveJS device page (#146544) 2025-06-11 15:39:02 +02:00
Erik Montnemery
09a5ac5979 Handle changes to source entities in generic_thermostat helper (#146541) 2025-06-11 15:26:52 +02:00
Erik Montnemery
296b5c627a Handle changes to source entities in generic_hygrostat helper (#146538) 2025-06-11 15:18:04 +02:00
Erik Montnemery
120338d510 Handle changes to source entity in utility_meter (#146526) 2025-06-11 15:17:52 +02:00
Erik Montnemery
9b4ab60adb Handle changes to source entity in trend helper (#146525) 2025-06-11 15:17:42 +02:00
Erik Montnemery
51b0642789 Handle changes to source entity in threshold helper (#146524) 2025-06-11 15:17:34 +02:00
Erik Montnemery
cb9c213496 Handle changes to source entity in statistics helper (#146523) 2025-06-11 15:17:19 +02:00
Erik Montnemery
cb42d99c28 Handle changes to source entity in integration helper (#146522) 2025-06-11 15:17:08 +02:00
Erik Montnemery
cf5cdf3cdb Handle changes to source entity in history_stats helper (#146521) 2025-06-11 15:16:51 +02:00
epenet
acf31f609a Adjust urllib3 constraint (#145485)
* Remove urllib3 upper bound constraint

* Disable neato

* Disable neato tests

* Simplify test ignore

* Add to PACKAGE_CHECK_VERSION_RANGE

* Adjust

* Adjust

* Force 2.0
2025-06-11 15:11:58 +02:00
Simon Lamon
42377ff7ac Bump linkplay to v0.2.11 (#146530) 2025-06-11 15:10:00 +02:00
Petro31
3e0aab55a8 Fix delay_on and delay_off restarting when a new trigger occurs during the delay (#145050) 2025-06-11 14:08:10 +01:00
Erik Montnemery
0362012bb3 Correct misleading comment for const.ATTR_RESTORED (#146528) 2025-06-11 13:29:16 +02:00
Jesse Hills
ba5d0f2723 Fix solax state class of Today's Generated Energy (#146492) 2025-06-11 12:46:40 +02:00
Erik Montnemery
167e688139 Allow removing entity registry items twice (#146519) 2025-06-11 12:42:09 +02:00
Martin Hjelmare
c49d95b230 Remove Z-Wave useless reconfigure options (#146520)
* Remove emulate hardware option

* Remove log level option
2025-06-11 13:31:07 +03:00
Erik Montnemery
c4c8f88765 Simplify helper_integration.async_handle_source_entity_changes (#146516) 2025-06-11 12:27:51 +02:00
epenet
f908e0cf4d Bump pybotvac to 0.0.28 (#146513) 2025-06-11 12:19:54 +02:00
epenet
29c720a66d Bump weheat to 2025.6.10 (#146515) 2025-06-11 12:19:06 +02:00
epenet
4e628dbd9f Bump sensorpush-api to 2.1.3 (#146514) 2025-06-11 12:18:55 +02:00
Franck Nijhof
b6c8718ae4 Bump version to 2025.6.0b7 2025-06-11 10:17:18 +00:00
Åke Strandberg
c8b70cc0fb Graceful handling of missing datapoint in myuplink (#146517) 2025-06-11 10:17:09 +00:00
Robert Resch
6d1f621e55 Bump deebot-client to 13.3.0 (#146507) 2025-06-11 10:17:08 +00:00
Erik Montnemery
671a33b31c Do not remove derivative config entry when input sensor is removed (#146506)
* Do not remove derivative config entry when input sensor is removed

* Add comments

* Update homeassistant/helpers/helper_integration.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

---------

Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-11 10:17:06 +00:00
Michael Hansen
7afc469306 Bump intents to 2025.6.10 (#146491) 2025-06-11 10:17:05 +00:00
Felix Schneider
8fd52248b7 Bump apsystems to 2.7.0 (#146485) 2025-06-11 10:17:04 +00:00
Joost Lekkerkerker
69ba2aab11 Remove DHCP discovery from Amazon Devices (#146476) 2025-06-11 10:17:02 +00:00
Tsvi Mostovicz
f1df6dcda5 Fix Jewish calendar not updating (#146465) 2025-06-11 10:17:01 +00:00
Joost Lekkerkerker
43e16bb913 Split deprecated system issue in 2 places (#146453) 2025-06-11 10:15:11 +00:00
Petro31
4147211f94 Add color_temp_kelvin to set_temperature action variables (#146448) 2025-06-11 10:10:40 +00:00
Joost Lekkerkerker
63e49c5d3c Explain Nest setup (#146217) 2025-06-11 10:10:39 +00:00
hahn-th
35580c0849 Bump homematicip to 2.0.4 (#144096)
* Bump to 2.0.2 with all necessary changes

* bump to prerelease

* add addiional tests

* Bump to homematicip 2.0.3

* do not delete device

* Setup BRAND_SWITCH_MEASURING as light

* bump to 2.0.4

* refactor test_remove_obsolete_entities

* move test

* use const from homematicip lib
2025-06-11 10:10:38 +00:00
Petro31
37d904dfdc Add color_temp_kelvin to set_temperature action variables (#146448) 2025-06-11 11:58:07 +02:00
Åke Strandberg
a53997dfc7 Graceful handling of missing datapoint in myuplink (#146517) 2025-06-11 11:55:28 +02:00
Joost Lekkerkerker
dd216ac15b Split deprecated system issue in 2 places (#146453) 2025-06-11 11:35:14 +02:00
Erik Montnemery
2afdec4711 Do not remove derivative config entry when input sensor is removed (#146506)
* Do not remove derivative config entry when input sensor is removed

* Add comments

* Update homeassistant/helpers/helper_integration.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

---------

Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-11 11:19:44 +02:00
karwosts
5b4c309170 Create a deprecation/repair for sensor.sun_solar_rising (#146462)
* Create a deprecation/repair for `sensor.sun_solar_rising`

* test

* Update homeassistant/components/sun/strings.json
2025-06-11 11:02:14 +02:00
hanwg
8deec55204 Add service validation for send file for Telegram bot integration (#146192)
* added service validation for send file

* update strings

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* updated exception in tests

* removed TypeError since it is not thrown

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-11 10:59:08 +02:00
Robert Resch
f0a2c4e30a Bump deebot-client to 13.3.0 (#146507) 2025-06-11 10:49:38 +02:00
Joost Lekkerkerker
e9a71a8d7f Explain Nest setup (#146217) 2025-06-11 10:31:08 +02:00
Felix Schneider
1462366764 Bump apsystems to 2.7.0 (#146485) 2025-06-11 10:26:01 +02:00
Artur Pragacz
33528eb6bd Update pywizlight to 0.6.3 (#146490) 2025-06-11 08:26:55 +02:00
epenet
776a014ab0 Drop deprecated add_event service in google (#146432) 2025-06-10 20:35:17 -07:00
Michael Hansen
ea202eff66 Bump intents to 2025.6.10 (#146491) 2025-06-10 18:16:18 -05:00
Tsvi Mostovicz
b7404f5a05 Fix Jewish calendar not updating (#146465) 2025-06-10 21:25:47 +02:00
Joost Lekkerkerker
d015dff855 Remove DHCP discovery from Amazon Devices (#146476) 2025-06-10 20:55:00 +02:00
Joost Lekkerkerker
2f1977fa0c Fix typo in hassio (#146474) 2025-06-10 20:52:43 +02:00
Erik Montnemery
26fe23eb5c Improve support for trigger platforms with multiple triggers (#144827)
* Improve support for trigger platforms with multiple triggers

* Adjust zwave_js

* Refactor the Trigger class

* Silence mypy

* Adjust

* Revert "Adjust"

This reverts commit 17b3d16a267d54c082b12f07550faa8ac4ac3a49.

* Revert "Silence mypy"

This reverts commit c2a011b16f9b02880fc3dc673b5b12501f7995fc.

* Reapply "Adjust"

This reverts commit c64ba202dd.

* Apply suggestions from code review

* Revert "Apply suggestions from code review"

This reverts commit 0314955c5a.
2025-06-10 20:48:51 +02:00
hahn-th
dbfecf99dc Bump homematicip to 2.0.4 (#144096)
* Bump to 2.0.2 with all necessary changes

* bump to prerelease

* add addiional tests

* Bump to homematicip 2.0.3

* do not delete device

* Setup BRAND_SWITCH_MEASURING as light

* bump to 2.0.4

* refactor test_remove_obsolete_entities

* move test

* use const from homematicip lib
2025-06-10 20:44:06 +02:00
hanwg
4d28992f2b Add Telegram bot webhooks tests (#146436)
* add tests for webhooks

* added asserts
2025-06-10 19:58:15 +02:00
Franck Nijhof
8949a595fe Bump version to 2025.6.0b6 2025-06-10 17:45:26 +00:00
Markus Adrario
7a428a66bd Add support for HeatIt Thermostat TF056 to homee (#145515)
* adapt climate for Heatit TF 056

* add sensors & numbers for Heatit TF056

* Add select for Heatit TF056

* Adapt climat tests for changes

* Fix sentence case

* fix review comments

* Update homeassistant/components/homee/climate.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* fix tests

* update diagnostics snapshot for this change

---------

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-06-10 19:41:13 +02:00
Simone Chemelli
bf8ef0a767 Fix EntityCategory for binary_sensor platform in Amazon Devices (#146472)
* Fix EntityCategory for  binary_sensor platform in Amazon Devices

* update snapshots
2025-06-10 17:41:02 +00:00
Simone Chemelli
39962a3f48 Avoid closing shared aiohttp session in Vodafone Station (#146471) 2025-06-10 17:41:00 +00:00
G Johansson
4964621014 Fix incorrect categories handling in holiday (#146470) 2025-06-10 17:40:59 +00:00
Joost Lekkerkerker
18e1a26da1 Catch exception before retrying in AirGradient (#146460) 2025-06-10 17:40:58 +00:00
Joost Lekkerkerker
1d91ca5716 Bump pySmartThings to 3.2.4 (#146459) 2025-06-10 17:40:57 +00:00
Luca Schröder
1040646610 Update caldav to 1.6.0 (#146456)
Fixes #140798
2025-06-10 17:40:56 +00:00
Robert Resch
fcd71931e7 Update wording deprecated system package integration repair (#146450)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-10 17:40:55 +00:00
Joost Lekkerkerker
bdbb74aff1 Return expected state in SmartThings water heater (#146449) 2025-06-10 17:40:53 +00:00
Marc Mueller
6f4029983a Update requests to 2.32.4 (#146445) 2025-06-10 17:40:52 +00:00
J. Diego Rodríguez Royo
b2d25b1883 Improvements for Home Connect application credentials string (#146443) 2025-06-10 17:40:51 +00:00
J. Diego Rodríguez Royo
ba19d4f043 Fix typo at application credentials string at Home Connect integration (#146442)
Fix typos
2025-06-10 17:40:50 +00:00
tronikos
b222fe5afa Handle grpc errors in Google Assistant SDK (#146438) 2025-06-10 17:40:49 +00:00
Franck Nijhof
f945defa2b Reformat Dockerfile to reduce merge conflicts (#146435) 2025-06-10 17:38:37 +00:00
G Johansson
481bf2694b Fix incorrect categories handling in holiday (#146470) 2025-06-10 19:28:48 +02:00
Simone Chemelli
5cc9cc3c99 Fix EntityCategory for binary_sensor platform in Amazon Devices (#146472)
* Fix EntityCategory for  binary_sensor platform in Amazon Devices

* update snapshots
2025-06-10 19:28:37 +02:00
Whitney Young
87ce683b39 Add tests for initial state of OpenUV sensors (#146464)
This is a followup to #146408 to add test coverage.
2025-06-10 19:28:29 +02:00
J. Nick Koston
4f0e4bc1ca Bump aiohttp to 3.12.12 (#146426) 2025-06-10 17:28:13 +00:00
J. Nick Koston
41abc8404d Bump yarl to 1.20.1 (#146424) 2025-06-10 17:26:03 +00:00
Jamin
2b08c4c344 Check hangup error in voip (#146423)
Check hangup error

Prevent an error where the call end future may have already been set
when a hangup is detected.
2025-06-10 17:26:02 +00:00
J. Nick Koston
97d91ddddb Bump propcache to 0.3.2 (#146418) 2025-06-10 17:26:01 +00:00
Whitney Young
ec30b12fd1 Fix initial state of UV protection window (#146408)
The `binary_sensor` is created when the config entry is loaded after the
`async_config_entry_first_refresh` has completed (during the forward of
setup to platforms). Therefore, the update coordinator will already have
data and will not trigger the invocation of
`_handle_coordinator_update`.

Fixing this just means performing the same update at initialization.
2025-06-10 17:25:59 +00:00
Erik Montnemery
9997fc11b1 Handle changes to source entity in derivative helper (#146407)
* Handle changes to source entity in derivative helper

* Rename helper function, improve docstring

* Add tests

* Improve derivative tests

* Deduplicate tests

* Rename helpers/helper_entity.py to helpers/helper_integration.py

* Rename tests
2025-06-10 17:25:59 +00:00
wittypluck
c6ff0e6492 Fix CO concentration unit in OpenWeatherMap (#146403) 2025-06-10 17:25:58 +00:00
G Johansson
a3220ecae6 Bump pynordpool to 0.3.0 (#146396) 2025-06-10 17:25:57 +00:00
Erik Montnemery
218864d08c Update switch_as_x to handle wrapped switch moved to another device (#146387)
* Update switch_as_x to handle wrapped switch moved to another device

* Reload switch_as_x config entry after updating device

* Make sure the switch_as_x entity is not removed
2025-06-10 17:25:56 +00:00
Erik Montnemery
3d0d70ece6 Fix switch_as_x entity_id tracking (#146386) 2025-06-10 17:25:55 +00:00
Simone Chemelli
f629731930 Bump aioamazondevices to 3.0.6 (#146385) 2025-06-10 17:25:53 +00:00
Simone Chemelli
936d56f9af Avoid closing shared aiohttp session in Vodafone Station (#146471) 2025-06-10 19:18:19 +02:00
J. Nick Koston
e7a7b2417b Bump aioesphomeapi to 32.2.1 (#146375) 2025-06-10 17:03:20 +00:00
Michael Davie
0b24a9abc3 Bump env-canada to v0.11.2 (#146371) 2025-06-10 17:03:19 +00:00
David Knowles
ca77b5210f Bump pydrawise to 2025.6.0 (#146369) 2025-06-10 17:03:18 +00:00
Simon Lamon
0874f1c350 Bump python-linkplay to v0.2.10 (#146359) 2025-06-10 17:03:17 +00:00
Jan-Philipp Benecke
d89b99f42b Improve error logging in trend binary sensor (#146358) 2025-06-10 17:03:16 +00:00
J. Diego Rodríguez Royo
7bd6ec68a8 Explain Home Connect setup (#146356)
* Explain Home Connect setup

* Avoid using "we"

* Fix login spelling

* Fix signup spelling
2025-06-10 17:03:15 +00:00
J. Nick Koston
bfe2eeb833 Shift ESPHome log parsing to the library (#146349) 2025-06-10 17:03:14 +00:00
Klaas Schoute
e97ab1fe3c Change interval for Powerfox integration (#146348) 2025-06-10 17:03:13 +00:00
J. Nick Koston
b3ee2a8885 Bump aioesphomeapi to 32.2.0 (#146344) 2025-06-10 17:03:12 +00:00
Michael
80b09e3212 Bump py-synologydsm-api to 2.7.3 (#146338)
bump py-synologydsm-api to 2.7.3
2025-06-10 17:03:11 +00:00
tronikos
0eb3714abc Allow different manufacturer than Amazon in Amazon Devices (#146333) 2025-06-10 17:03:10 +00:00
Sanjay Govind
7991977443 Fix bosch alarm areas not correctly subscribing to alarms (#146322)
* Fix bosch alarm areas not correctly subscribing to alarms

* add test
2025-06-10 17:03:09 +00:00
J. Nick Koston
5e5431c9f9 Use entity unique id for ESPHome media player formats (#146318) 2025-06-10 17:03:08 +00:00
Simon Lamon
1fc05d1a30 Do not probe linkplay device if another config entry already contains the host (#146305)
* Do not probe if config entry already contains the host

* Add unit test

* Use common fixture
2025-06-10 17:03:07 +00:00
J. Nick Koston
21833e7c31 Bump aiohttp to 3.12.11 (#146298) 2025-06-10 16:59:07 +00:00
G Johansson
79daeb23a9 Bump holidays to 0.74 (#146290) 2025-06-10 16:55:33 +00:00
J. Nick Koston
761c2578fb Bump aiohttp-fast-zlib to 0.3.0 (#146285)
changelog: https://github.com/Bluetooth-Devices/aiohttp-fast-zlib/compare/v0.2.3...v0.3.0

proper aiohttp 3.12 support
2025-06-10 16:48:33 +00:00
Brett Adams
4d3145e559 Add missing write state to Teslemetry (#146267) 2025-06-10 16:47:33 +00:00
Michael
91e29a3bf1 Bump aioimmich to 0.9.1 (#146222)
bump aioimmich to 0.9.1
2025-06-10 16:47:32 +00:00
Joost Lekkerkerker
f6a4486c65 Explain Withings setup (#146216) 2025-06-10 16:47:31 +00:00
Joost Lekkerkerker
fc8b512931 Remove zeroconf discovery from Spotify (#146213) 2025-06-10 16:47:30 +00:00
Brett Adams
e5dd15da82 Fix Export Rule Select Entity in Tessie (#146203)
Fix TessieExportRuleSelectEntity
2025-06-10 16:47:29 +00:00
Brett Adams
e4140d71ab Prevent energy history returning zero in Teslemetry (#146202) 2025-06-10 16:47:28 +00:00
J. Nick Koston
8312780c47 Bump aiohttp to 3.12.9 (#146178) 2025-06-10 16:44:14 +00:00
Raphael Hehl
5accc3dec2 Bump uiprotect to 7.11.0 (#146171)
Bump uiprotect to version 7.11.0
2025-06-10 16:42:40 +00:00
Iskra kranj
d875989866 Bump pyiskra to 0.1.21 (#146156) 2025-06-10 16:42:39 +00:00
Michael
38c92a2338 Bump aioimmich to 0.9.0 (#146154)
bump aioimmich to 0.9.0
2025-06-10 16:42:38 +00:00
J. Nick Koston
ce76b5db16 Bump aiohttp to 3.12.8 (#146153) 2025-06-10 16:39:58 +00:00
Ian
dfc4889d45 Throttle Nextbus if we are reaching the rate limit (#146064)
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Robert Resch <robert@resch.dev>
2025-06-10 16:32:59 +00:00
Andrea Turri
41431282ee Add evaporate water program id for Miele oven (#145996) 2025-06-10 16:32:58 +00:00
Arie Catsman
5821b2f03c fix possible mac collision in enphase_envoy (#145549)
* fix possible mac collision in enphase_envoy

* remove redundant device registry async_get
2025-06-10 16:32:57 +00:00
starkillerOG
78d2bf736c Reolink conserve battery (#145452) 2025-06-10 16:32:56 +00:00
starkillerOG
d71ddcf69e Reolink conserve battery (#145452) 2025-06-10 18:05:55 +02:00
Robert Resch
3af2746fea Update wording deprecated system package integration repair (#146450)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-10 18:04:22 +02:00
Joost Lekkerkerker
5b6d7142fb Bump pySmartThings to 3.2.4 (#146459) 2025-06-10 17:37:21 +02:00
Whitney Young
7aa9301038 Fix initial state of UV protection window (#146408)
The `binary_sensor` is created when the config entry is loaded after the
`async_config_entry_first_refresh` has completed (during the forward of
setup to platforms). Therefore, the update coordinator will already have
data and will not trigger the invocation of
`_handle_coordinator_update`.

Fixing this just means performing the same update at initialization.
2025-06-10 17:35:40 +02:00
hanwg
627831dfaf Fix Telegram bot leave_chat service action (#146139)
* bug fix for leave chat

* update strings
2025-06-10 17:33:54 +02:00
Joost Lekkerkerker
db8a6f8583 Catch exception before retrying in AirGradient (#146460) 2025-06-10 17:31:30 +02:00
Paulus Schoutsen
014010acbd Assist Pipeline: Intent progress event when we start streaming (#146388)
Intent progress event when we start streaming
2025-06-10 09:55:43 -05:00
Arie Catsman
9b90ed04e5 fix possible mac collision in enphase_envoy (#145549)
* fix possible mac collision in enphase_envoy

* remove redundant device registry async_get
2025-06-10 16:25:26 +02:00
hanwg
0f27d0bf4a Bug fix for Telegram bot integration: fix async_unload_entry error for polling bot (#146277)
* removed reload from update_listener

* removed reload from update_listener
2025-06-10 16:24:51 +02:00
Andrea Turri
1fa55f96f8 Add evaporate water program id for Miele oven (#145996) 2025-06-10 16:23:55 +02:00
Jamin
2d60115ec6 Check hangup error in voip (#146423)
Check hangup error

Prevent an error where the call end future may have already been set
when a hangup is detected.
2025-06-10 16:22:53 +02:00
Luca Schröder
3b81480091 Update caldav to 1.6.0 (#146456)
Fixes #140798
2025-06-10 16:20:35 +02:00
Will Schlitzer
255acfa8c0 Fix typo in overseerr component docstring (#146457)
Change 'airgradient' to 'overseerr' in sensor.py
2025-06-10 16:15:40 +02:00
Marc Mueller
4617cc4e0a Update awesomeversion to 25.5.0 (#146032) 2025-06-10 15:44:53 +02:00
tronikos
b9e8cfb291 Handle grpc errors in Google Assistant SDK (#146438) 2025-06-10 15:31:32 +02:00
J. Nick Koston
7da1671b06 Shift ESPHome log parsing to the library (#146349) 2025-06-10 15:30:19 +02:00
Marc Mueller
6c5f7eabff Fix RuntimeWarning in rest tests (#146452) 2025-06-10 15:26:07 +02:00
Ian
f448f488ba Throttle Nextbus if we are reaching the rate limit (#146064)
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Robert Resch <robert@resch.dev>
2025-06-10 15:03:20 +02:00
Marc Mueller
20b5d5a755 Add requests to hassfest requirements check (#146446) 2025-06-10 15:01:05 +02:00
Marc Mueller
bb38a3a8ac Update requests to 2.32.4 (#146445) 2025-06-10 15:00:41 +02:00
Brett Adams
d0d1fb2da7 Prevent energy history returning zero in Teslemetry (#146202) 2025-06-10 15:00:02 +02:00
Marc Mueller
d82be09ed4 Update aiomealie to 0.9.6 (#146447) 2025-06-10 14:53:56 +02:00
Joost Lekkerkerker
110627e16e Return expected state in SmartThings water heater (#146449) 2025-06-10 14:52:24 +02:00
Klaas Schoute
b77ef7304a Change interval for Powerfox integration (#146348) 2025-06-10 14:38:52 +02:00
Erik Montnemery
16a0b7f44e Handle changes to source entity in derivative helper (#146407)
* Handle changes to source entity in derivative helper

* Rename helper function, improve docstring

* Add tests

* Improve derivative tests

* Deduplicate tests

* Rename helpers/helper_entity.py to helpers/helper_integration.py

* Rename tests
2025-06-10 14:31:18 +02:00
Joost Lekkerkerker
4fdbb9c0e2 Remove __all__ from switch_as_x (#146331)
* Remove `__all__` from switch_as_x

* Update homeassistant/components/switch_as_x/__init__.py
2025-06-10 14:21:01 +02:00
J. Diego Rodríguez Royo
c32a988838 Improvements for Home Connect application credentials string (#146443) 2025-06-10 14:11:07 +02:00
Jan-Philipp Benecke
927c9d3480 Improve error logging in trend binary sensor (#146358) 2025-06-10 14:10:49 +02:00
Joost Lekkerkerker
bf776d33b2 Explain Withings setup (#146216) 2025-06-10 14:10:35 +02:00
epenet
279539265b Use async_load_fixture in modern_forms tests (#146011) 2025-06-10 12:38:25 +02:00
J. Diego Rodríguez Royo
4acad77437 Fix typo at application credentials string at Home Connect integration (#146442)
Fix typos
2025-06-10 11:56:24 +02:00
J. Nick Koston
0c5b7401b9 Use entity unique id for ESPHome media player formats (#146318) 2025-06-10 11:48:11 +02:00
Erik Montnemery
ce739fd9b6 Restore entity ID and user customizations of deleted entities (#145278)
* Restore entity ID and user customizations of deleted entities

* Clear removed areas, categories and labels from deleted entities

* Correct test

* Fix logic for disabled_by and hidden_by

* Improve test coverage

* Fix sorting

* Always restore disabled_by and hidden_by

* Update mqtt test

* Update pglab tests
2025-06-10 11:47:54 +02:00
Erik Montnemery
11d9014be0 Restore user customizations of deleted devices (#145191)
* Restore user customizations of deleted devices

* Apply suggestions from code review

* Improve test coverage

* Always restore disabled_by
2025-06-10 11:47:39 +02:00
J. Nick Koston
c9dcb1c11b Bump propcache to 0.3.2 (#146418) 2025-06-10 11:44:34 +02:00
J. Diego Rodríguez Royo
ef7f32a28d Explain Home Connect setup (#146356)
* Explain Home Connect setup

* Avoid using "we"

* Fix login spelling

* Fix signup spelling
2025-06-10 11:41:36 +02:00
J. Nick Koston
4f5cf5797f Bump yarl to 1.20.1 (#146424) 2025-06-10 11:26:29 +02:00
Retha Runolfsson
4c5485ad04 Bump pyswitchbot to 0.66.0 (#146430)
bump pyswitchbot to 0.66.0
2025-06-10 11:16:08 +02:00
Franck Nijhof
5ad96dedfa Reformat Dockerfile to reduce merge conflicts (#146435) 2025-06-10 11:14:31 +02:00
epenet
0c18fe35e5 Migrate cloudflare to use runtime data (#146429) 2025-06-10 09:50:31 +02:00
epenet
6a23ad96ca Move google assistant sdk services to separate module (#146434) 2025-06-10 00:49:56 -07:00
J. Nick Koston
def0384608 Bump aiohttp to 3.12.12 (#146426) 2025-06-10 09:39:53 +02:00
Raphael Hehl
a4d12694da Bump uiprotect to 7.13.0 (#146410) 2025-06-09 19:26:54 -05:00
J. Nick Koston
2278e3f06f Bump aioesphomeapi to 32.2.1 (#146375) 2025-06-09 19:25:29 -05:00
Will Schlitzer
0144a0bb1f Fix minor docstring typos in jellyfin component media_source.py (#146398) 2025-06-09 20:12:32 +02:00
Imeon-Energy
7cc8f91bf9 Basic entity class for Imeon inverter integration (#145778)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: TheBushBoy <theodavid@icloud.com>
2025-06-09 20:04:25 +02:00
hanwg
d58157ca9e Bug fix for Telegram bot integration: handle last message id (#146378) 2025-06-09 20:01:16 +02:00
David Knowles
f401ffb08c Bump pydrawise to 2025.6.0 (#146369) 2025-06-09 20:00:37 +02:00
Simone Chemelli
8f7b831b94 Bump aioamazondevices to 3.0.6 (#146385) 2025-06-09 19:59:02 +02:00
wittypluck
9ed6b591a5 Fix CO concentration unit in OpenWeatherMap (#146403) 2025-06-09 19:55:09 +02:00
Michael Davie
98ea067285 Bump env-canada to v0.11.2 (#146371) 2025-06-09 12:53:44 -05:00
G Johansson
7e507dd378 Bump pynordpool to 0.3.0 (#146396) 2025-06-09 19:51:46 +02:00
Erik Montnemery
8e87223c40 Update switch_as_x to handle wrapped switch moved to another device (#146387)
* Update switch_as_x to handle wrapped switch moved to another device

* Reload switch_as_x config entry after updating device

* Make sure the switch_as_x entity is not removed
2025-06-09 17:04:55 +02:00
Abílio Costa
0cce4d1b81 Test all device classes in Sensor device condition/trigger tests (#146366) 2025-06-09 14:22:58 +01:00
Erik Montnemery
46dcc91510 Fix switch_as_x entity_id tracking (#146386) 2025-06-09 13:24:40 +02:00
Markus Adrario
b1a2af9fd3 Add Homee diagnostics platform (#146340)
* Initial dignostics implementation

* Add diagnostics tests

* change data-set for device diagnostics

* adapt for upcoming pyHomee release

* other solution

* fix review and more
2025-06-09 13:24:07 +02:00
Michael Arthur
5d58cdd98e DNSIP: Add literal to querytype (#146367) 2025-06-09 09:36:17 +02:00
Simon Lamon
a8aebbce9a Bump python-linkplay to v0.2.10 (#146359) 2025-06-08 16:43:20 -05:00
tronikos
f1244c182a Allow different manufacturer than Amazon in Amazon Devices (#146333) 2025-06-08 11:47:46 -07:00
Simon Lamon
560eeac457 Do not probe linkplay device if another config entry already contains the host (#146305)
* Do not probe if config entry already contains the host

* Add unit test

* Use common fixture
2025-06-08 19:47:00 +02:00
J. Nick Koston
d33080d79e Bump aioesphomeapi to 32.2.0 (#146344) 2025-06-08 11:15:00 -05:00
Michael
25f02c5b38 Bump py-synologydsm-api to 2.7.3 (#146338)
bump py-synologydsm-api to 2.7.3
2025-06-08 17:02:06 +01:00
Raphael Hehl
cb01af9f92 Bump uiprotect to 7.12.0 (#146337) 2025-06-08 10:57:50 -05:00
Sanjay Govind
9a6ebb0848 Fix bosch alarm areas not correctly subscribing to alarms (#146322)
* Fix bosch alarm areas not correctly subscribing to alarms

* add test
2025-06-08 14:35:54 +02:00
Pete Sage
fd30dd0aee Add tests for sonos switch alarms on and off (#146314)
* fix: add tests for switch on/off

* fix: simplify

* fix: simplify

* fix: comment

* fix: comment
2025-06-08 11:45:20 +02:00
tronikos
4a5e261709 Fix typo in Utility Meter always_available (#146320) 2025-06-08 10:53:48 +03:00
Marc Mueller
2842f55460 Add additional package version range checks (#146299)
* Add additional package version range checks

* Add exception for scipy
2025-06-08 00:06:20 +02:00
J. Nick Koston
7573a74cb0 Migrate rest to use aiohttp (#146306) 2025-06-07 13:44:25 -05:00
J. Nick Koston
636b484d9d Migrate onvif to use onvif-zeep-async 4.0.1 with aiohttp (#146297) 2025-06-07 13:39:59 -05:00
G Johansson
a979f884f9 Bump holidays to 0.74 (#146290) 2025-06-07 20:18:24 +03:00
J. Nick Koston
990ea78dec Bump aiohttp to 3.12.11 (#146298) 2025-06-07 12:08:32 -05:00
Marc Mueller
ee6db3bd23 Update numpy to 2.3.0 (#146296) 2025-06-07 18:43:18 +02:00
Arie Catsman
ae5606aa2f Migrate Enphase envoy from httpx to aiohttp (#146283)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-06-07 10:52:54 -05:00
Marc Mueller
7f9f106729 Update airtouch5py to 0.3.0 (#146278) 2025-06-07 16:58:53 +02:00
J. Nick Koston
44c63ce6f1 Bump aiohttp-fast-zlib to 0.3.0 (#146285)
changelog: https://github.com/Bluetooth-Devices/aiohttp-fast-zlib/compare/v0.2.3...v0.3.0

proper aiohttp 3.12 support
2025-06-07 17:30:43 +03:00
hanwg
cbf7ca6a9a Add bronze quality scale for Telegram bot integration (#146148)
* added quality scale

* updated appropriate-polling comment

* Remove entities comment

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-07 14:47:48 +02:00
Brett Adams
eb892df65a Change default range sensors in Teslemetry (#146268) 2025-06-07 10:51:57 +02:00
Brett Adams
24b5886d88 Add missing write state to Teslemetry (#146267) 2025-06-07 04:43:16 +02:00
Willem-Jan van Rootselaar
d5e902a170 Update python-bsblan requirement to version 2.1.0 (#146253) 2025-06-06 22:47:44 +03:00
hanwg
d907e4c10b Handle error in setup_entry for Telegram Bot (#146242)
* handle error in setup_entry

* Update homeassistant/components/telegram_bot/__init__.py

Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>

---------

Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-06-06 15:00:48 +01:00
Robin Lintermann
c4be3c4de2 Smarla integration number platform (#145747)
Add number platform to smarla integration
2025-06-06 12:13:06 +02:00
Retha Runolfsson
626591f832 Fix unit test for switchbot integration (#146247)
fix unit test
2025-06-06 12:06:01 +02:00
epenet
2bd3196183 Move abode services to separate module (#146142)
* Move abode services to separate module

* Rename

* Adjust test imports
2025-06-06 10:20:57 +02:00
epenet
fd93cf375d Tweak zwave_js service registration (#146244) 2025-06-06 09:41:51 +02:00
epenet
6bf8b84d26 Rename service registration method (#146236) 2025-06-06 08:08:06 +02:00
Michael
c72fea57a1 Bump aioimmich to 0.9.1 (#146222)
bump aioimmich to 0.9.1
2025-06-05 21:50:19 +02:00
Renat Sibgatulin
17dad7d8ae Bump aioairq to v0.4.6 (#146169)
This version exposes an API to control LED brightness.
2025-06-05 18:27:20 +02:00
Joost Lekkerkerker
14664719d9 Remove zeroconf discovery from Spotify (#146213) 2025-06-05 18:02:11 +02:00
epenet
b14cd1e14b Move elkm1 services to separate module (#146147)
* Move elkm1 services to separate module

* Rename
2025-06-05 16:51:01 +02:00
Retha Runolfsson
fd38d9788d Bump pyswitchbot to 0.65.0 (#146133)
* update pyswitchbot to 0.65.0

* fix relay switch 1pm test

* fix ma to a
2025-06-05 16:42:24 +02:00
epenet
0b3b641328 Move services to separate module in opentherm_gw (#146098)
* Move services to separate module in opentherm_gw

* Rename
2025-06-05 16:40:18 +02:00
Brett Adams
6ef77f8243 Fix Export Rule Select Entity in Tessie (#146203)
Fix TessieExportRuleSelectEntity
2025-06-05 16:39:55 +02:00
Ludovic BOUÉ
3a27143012 Matter add Service Area Cluster to vacuum_cleaner fixture (#145743)
Update vacuum_cleaner.json

Service Area Cluster
2025-06-05 16:39:08 +02:00
Samuel Xiao
9a6c642bdf Bump switchbot-api to 2.5.0 (#146205)
* update switchbot-api to 2.5.0

* update switchbot-api to 2.5.0
2025-06-05 16:16:45 +02:00
epenet
38b8d0b018 Move google_sheets services to separate module (#146160)
* Move google_sheets services to separate module

* Move to async_setup

* Do not remove the services

* hassfest

* Rename
2025-06-05 15:07:15 +02:00
epenet
4d3443dbf5 Move amcrest services to separate module (#146144)
* Move amcrest services to separate module

* Rename
2025-06-05 14:43:22 +02:00
Marc Mueller
4f99e54402 Update pandas to 2.3.0 (#146206) 2025-06-05 14:42:21 +02:00
epenet
d6615e3d44 Move ffmpeg services to separate module (#146149)
* Move ffmpeg services to separate module

* Fix tests

* Rename
2025-06-05 14:39:44 +02:00
Willem-Jan van Rootselaar
9c23331ead Bump python-bsblan to version 2.0.1 (#146198)
* Bump python-bsblan to version 2.0.1

* Remove 'bsblan' exception for 'python-bsblan' from forbidden package exceptions
2025-06-05 13:07:16 +02:00
epenet
5fb2802bf4 Move zoneminder services to separate module (#146151) 2025-06-05 06:35:32 +02:00
epenet
b4864e6a8a Move matrix services to separate module (#146161) 2025-06-05 06:35:10 +02:00
Raphael Hehl
04c34877f4 Bump uiprotect to 7.11.0 (#146171)
Bump uiprotect to version 7.11.0
2025-06-04 23:32:44 +03:00
Ludovic BOUÉ
bdeb61fafc Matter Extractor hood fixture (#146174)
* Create extractor_hood.json

* Matter Extractor hood fixture

* Format document
2025-06-04 21:17:51 +02:00
J. Nick Koston
76d4257f51 Bump aiohttp to 3.12.9 (#146178) 2025-06-04 20:12:19 +02:00
Markus Adrario
c6c7e7eae1 Add homee reconfiguration flow (#146065)
* Add a reconfigure flow to homee

* Add tests for reconfiguration flow

* string refinement

* fix review comments

* more review fixes
2025-06-04 15:27:07 +02:00
Iskra kranj
07557e27b0 Bump pyiskra to 0.1.21 (#146156) 2025-06-04 14:51:40 +02:00
J. Nick Koston
f211da60e0 Bump aiohttp to 3.12.8 (#146153) 2025-06-04 12:57:40 +01:00
Michael
64b74d00f7 Bump aioimmich to 0.9.0 (#146154)
bump aioimmich to 0.9.0
2025-06-04 13:35:16 +02:00
Franck Nijhof
6c098c3e0a Bump version to 2025.6.0b5 2025-06-04 09:02:53 +00:00
J. Nick Koston
bfb140d2e9 Bump aioesphomeapi to 32.0.0 (#146135) 2025-06-04 09:00:59 +00:00
J. Nick Koston
f71a1a7a89 Bump protobuf to 6.31.1 (#146128)
changelog: https://github.com/protocolbuffers/protobuf/compare/v30.2...v31.1
2025-06-04 09:00:57 +00:00
Erwin Douna
e8aab39620 SMA fix strings (#146112)
* Fix

* Feedback
2025-06-04 09:00:55 +00:00
J. Nick Koston
1d578d8563 Bump habluetooth to 3.49.0 (#146111)
* Bump habluetooth to 3.49.0

changelog: https://github.com/Bluetooth-Devices/habluetooth/compare/v3.48.2...v3.49.0

* update diag

* diag
2025-06-04 09:00:53 +00:00
J. Nick Koston
abfd443541 Bump bleak-esphome to 2.16.0 (#146110) 2025-06-04 09:00:51 +00:00
Brett Adams
81cbb6e5cf Fix BMS and Charge states in Teslemetry (#146091)
Fix BMS and Charge states
2025-06-04 09:00:49 +00:00
Retha Runolfsson
010c5cab87 Fix nightlatch option for all switchbot locks (#146090) 2025-06-04 09:00:47 +00:00
SNoof85
415858119a Add state class measurement to Freebox temperature sensors (#146074) 2025-06-04 09:00:44 +00:00
Simone Chemelli
1838a731d6 Bump aioamazondevices to 3.0.5 (#146073) 2025-06-04 09:00:42 +00:00
Shay Levy
1e304fad65 Fix Shelly BLU TRV calibrate button (#146066) 2025-06-04 09:00:40 +00:00
Michael
999c9b3dc5 Don't use multi-line conditionals in immich (#146062) 2025-06-04 09:00:37 +00:00
epenet
e15edbd54b Adjust SamsungTV on/off logging (#146045)
* Adjust SamsungTV on/off logging

* Update coordinator.py
2025-06-04 09:00:35 +00:00
epenet
e5cb77d168 Adjust ConnectionFailure logging in SamsungTV (#146044) 2025-06-04 09:00:32 +00:00
starkillerOG
cf521d4c7c Improve debug logging Reolink (#146033)
Add debug logging
2025-06-04 09:00:25 +00:00
J. Nick Koston
6f09474193 Bump grpcio to 1.72.1 (#146029) 2025-06-04 09:00:21 +00:00
Robert Resch
7626933352 Bump go2rtc-client to 0.2.1 (#146019)
* Bump go2rtc-client to 0.2.0

* Bump go2rtc-client to 0.2.1

* Clean up hassfest exception

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-04 08:56:07 +00:00
starkillerOG
9e1d8c2fc6 Bump reolink-aio to 0.13.5 (#145974)
* Add debug logging

* Bump reolink-aio to 0.13.5

* Revert "Add debug logging"

This reverts commit f96030a6c8.
2025-06-04 08:43:30 +00:00
Simone Chemelli
6defed2915 Bump aioamazondevices to 3.0.4 (#145971) 2025-06-04 08:43:28 +00:00
Simone Chemelli
d729eed7c2 Add diagnostics to Amazon devices (#145964) 2025-06-04 08:43:26 +00:00
Noah Groß
f280032dcf Bump python-picnic-api2 to 1.3.1 (#145962) 2025-06-04 08:43:21 +00:00
Allen Porter
7e85137012 Bump ical to 10.0.0 (#145954) 2025-06-04 08:43:18 +00:00
TimL
88f2c3abd3 Bump pysmlight to v0.2.5 (#145949) 2025-06-04 08:43:15 +00:00
Michael
1a21e01f85 Bump aioimmich to 0.8.0 (#145908) 2025-06-04 08:43:13 +00:00
Ian
d302e817c8 NextBus: Bump py_nextbusnext to 2.2.0 (#145904) 2025-06-04 08:43:09 +00:00
Martin Hjelmare
1e1b0424d7 Fix removal of devices during Z-Wave migration (#145867) 2025-06-04 08:43:07 +00:00
Robert Resch
03f028b7e2 Deprecate hddtemp (#145850) 2025-06-04 08:43:05 +00:00
Robert Resch
b1d35de8e4 Deprecate eddystone temperature integration (#145833) 2025-06-04 08:43:02 +00:00
Erwin Douna
ea6b9e5260 SMA add missing strings for DHCP (#145782) 2025-06-04 08:42:59 +00:00
J. Nick Koston
96cb645644 Bump aioesphomeapi to 32.0.0 (#146135) 2025-06-04 09:34:04 +01:00
Claudio Ruggeri - CR-Tech
9b0db3bd51 Bump pymodbus to 3.9.2 (#145948) 2025-06-04 10:28:34 +02:00
Robert Resch
ffdefd1e0f Deprecate eddystone temperature integration (#145833) 2025-06-04 10:00:50 +02:00
Max Velitchko
59ad0268a9 Bump pyvera to 0.3.16 (#146089)
* Update vera integration with the latest pyvera package

* python3 -m script.gen_requirements_all

* Fix license
2025-06-04 07:47:41 +01:00
dependabot[bot]
f28851e76f Bump github/codeql-action from 3.28.18 to 3.28.19 (#146131)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.18 to 3.28.19.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3.28.18...v3.28.19)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.19
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-04 07:41:34 +01:00
J. Nick Koston
4f5c1d544b Bump protobuf to 6.31.1 (#146128)
changelog: https://github.com/protocolbuffers/protobuf/compare/v30.2...v31.1
2025-06-04 07:40:10 +01:00
Marc Mueller
a8ccf1c6fc Update pytest to 8.4.0 (#146114) 2025-06-04 08:09:19 +02:00
Ian
e3f7e5706b Add config option for controlling Ollama think parameter (#146000)
* Add config option for controlling Ollama think parameter

Allows enabling or disable thinking for supported models. Neither option
will dislay thinking content in the chat. Future support for displaying
think content will require frontend changes for formatting.

* Add thinking strings
2025-06-03 20:42:16 -07:00
Erwin Douna
7ad1e756e7 SMA fix strings (#146112)
* Fix

* Feedback
2025-06-03 21:54:44 +02:00
Norbert Rittel
8868f214f3 Replace "numbers" with "digits" in invalid_backbone_key message of knx (#146124)
The KNX Backbone Key has a length of 128 bits, so written as a hexadecimal number that yields 32 digits.

This fix thus replaces "numbers" with "digits" in the `invalid_backbone_key` message.
2025-06-03 20:47:54 +02:00
J. Nick Koston
3ecff19a45 Bump habluetooth to 3.49.0 (#146111)
* Bump habluetooth to 3.49.0

changelog: https://github.com/Bluetooth-Devices/habluetooth/compare/v3.48.2...v3.49.0

* update diag

* diag
2025-06-03 16:56:20 +02:00
Ian
74421db747 NextBus: Bump py_nextbusnext to 2.2.0 (#145904) 2025-06-03 13:20:14 +02:00
J. Nick Koston
1cccfac3dc Bump bleak-esphome to 2.16.0 (#146110) 2025-06-03 11:57:58 +01:00
David Bonnes
c254548a64 Add required_features to WaterHeater entity service registrations (#141873) 2025-06-03 12:51:46 +02:00
epenet
7f8b782e95 Adjust SamsungTV on/off logging (#146045)
* Adjust SamsungTV on/off logging

* Update coordinator.py
2025-06-03 12:30:18 +02:00
Erwin Douna
cd518d4a46 SMA add missing strings for DHCP (#145782) 2025-06-03 12:12:56 +02:00
Retha Runolfsson
c5db07e84d Fix nightlatch option for all switchbot locks (#146090) 2025-06-03 12:11:02 +02:00
epenet
d1e0225520 Adjust ConnectionFailure logging in SamsungTV (#146044) 2025-06-03 12:05:33 +02:00
Robin Lintermann
d439bb68eb Smarla integration improve tests (#145803)
* Improve smarla integration tests

* Do not import descriptions instead use seperate list
2025-06-03 11:49:24 +02:00
Matthias Alphart
980dbf364d Add exception translations for KNX services (#146104) 2025-06-03 11:31:32 +02:00
SNoof85
842e7ce171 Add state class measurement to Freebox temperature sensors (#146074) 2025-06-03 11:23:52 +02:00
epenet
8afec8ada9 Use async_load_fixture in youtube tests (#146018) 2025-06-03 11:07:56 +02:00
Simone Chemelli
7b699f7733 Avoid services unload for Homematicip Cloud (#146050)
* Avoid services unload

* fix tests

* apply review comments

* cleanup

* apply review comment
2025-06-03 11:01:23 +02:00
Noah Groß
d448ef9f16 Bump python-picnic-api2 to 1.3.1 (#145962) 2025-06-03 10:57:59 +02:00
epenet
03912a1704 Use async_load_fixture in tplink_omada tests (#146014) 2025-06-03 10:54:22 +02:00
epenet
54c20d5d5a Use async_load_fixture in remaining tests (#146021) 2025-06-03 10:52:51 +02:00
epenet
2dbf24e798 Use async_load_fixture in skybell tests (#146017) 2025-06-03 10:47:03 +02:00
epenet
791654a420 Move services to separate module in nzbget (#146093) 2025-06-03 10:41:40 +02:00
epenet
5fe07e49e4 Move services to separate module in insteon (#146094) 2025-06-03 10:41:13 +02:00
epenet
0bd287788c Move service registration to async_setup in icloud (#146095) 2025-06-03 10:40:48 +02:00
Brett Adams
40e0c0f98d Fix BMS and Charge states in Teslemetry (#146091)
Fix BMS and Charge states
2025-06-03 10:40:20 +02:00
Pär Holmdahl
85b608912b Add energy sensor to adax (#145995)
* 2nd attempt to add energysensors to Adax component

* Ruff format changes

* I did not reuse the first call for information.. Now i do..

* Fixed some tests after the last change

* Remove extra attributes

* Dont use info logger

* aggregate if not rooms

* Raise error if no rooms are discovered

* Move code out of try catch

* Catch more specific errors

* removed platforms from manifest.json

* remove attribute translation key

* Getting rid of the summation of energy used..

* Fixed errorness in test

* set roomproperty in Init

* concatenated the two functions

* use raw Wh values and suggest a konversion for HomeAssistant

* Use snapshot testing

* Update homeassistant/components/adax/coordinator.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/adax/strings.json

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/adax/sensor.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/adax/sensor.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/adax/sensor.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/adax/sensor.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Removing un needed logg

* Removing initial value

* Changing tests to snapshot_platform

* Removing available property from sensor.py and doing a ruff formating..

* Fix a broken indent

* Add fix for coordinator updates in Adax energisensor and namesetting

* Update homeassistant/components/adax/sensor.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/adax/coordinator.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/adax/coordinator.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Update homeassistant/components/adax/sensor.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* generated snapshots

* Ruff changes

* Even more ruff changes, that did not appear on ruff command locally

* Trying to fix CI updates

* Update homeassistant/components/adax/sensor.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

* Improve AdaxEnergySensor by simplifying code and ensuring correct handling of energy values. Adjust how room and device information is retrieved to avoid duplication and improve readability.

* Removed a test för device_id as per request..

* Make supersure that value is int and not "Any"

* removing executable status

* Update tests/components/adax/test_sensor.py

Co-authored-by: Josef Zweck <josef@zweck.dev>

---------

Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-06-03 10:36:43 +02:00
Pete Sage
987753dd1c Bump aiokem to 1.0.1 (#146085) 2025-06-03 10:16:08 +02:00
epenet
5df05fb6dd Move async_register_services to async_setup (#146092) 2025-06-03 08:38:02 +02:00
Simone Chemelli
f295ca27af Bump aioamazondevices to 3.0.5 (#146073) 2025-06-03 01:18:49 +03:00
Marc Mueller
8f75cc6a33 Update pyatmo to 9.2.1 (#146077) 2025-06-02 23:47:50 +02:00
Marc Mueller
19c71f0f49 Update python-homewizard-energy to 8.3.3 (#146076) 2025-06-02 23:34:50 +02:00
Marc Mueller
22c2028c00 Update typing-extensions to 4.14.0 (#146054) 2025-06-02 23:15:53 +02:00
Ian
39f687e3a3 Bump ollama to 0.5.1 (#146063)
* Bump ollama to 0.5.1
* Add ollama to license exceptions
2025-06-02 22:43:00 +02:00
Shay Levy
6692b9b71f Fix Shelly BLU TRV calibrate button (#146066) 2025-06-02 22:38:17 +03:00
J. Nick Koston
2f5787e7be Bump aiohttp to 3.12.7 (#146028) 2025-06-02 21:27:08 +02:00
Simone Chemelli
bbda1761bf Avoid services unload for Isy994 (#146069)
* Avoid services unload for Isy994

* cleanup
2025-06-02 21:19:10 +02:00
Robert Resch
ecc10e9793 Bump go2rtc-client to 0.2.1 (#146019)
* Bump go2rtc-client to 0.2.0

* Bump go2rtc-client to 0.2.1

* Clean up hassfest exception

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-02 20:48:40 +02:00
Simone Chemelli
9e1e889fd7 Rename mispelled services python files (#146049) 2025-06-02 20:41:31 +02:00
Michael
eefe1e6f0f Don't use multi-line conditionals in immich (#146062) 2025-06-02 19:58:54 +02:00
Marc Mueller
397ed87f2d Update aiohomekit to 3.2.15 (#146059)
* Update aiohomekit to 3.2.15

* Remove Python version exception for homekit_controller
2025-06-02 18:23:04 +01:00
Marc Mueller
15830f383e Update pyoverkiz to 1.17.2 (#146056) 2025-06-02 18:21:26 +01:00
epenet
87395efc6e Add awesomeversion to dependency version checks (#146047) 2025-06-02 17:28:13 +02:00
Marc Mueller
27d79bb10a Update yamllint to 1.37.1 (#146038) 2025-06-02 16:35:31 +02:00
Simone Chemelli
7427db70aa Move async_setup_services to async_setup (#146048)
* Moved async_setup_services to async_setup

* fix schema missing
2025-06-02 16:23:20 +02:00
Marc Mueller
77d5bffa85 Update pytest warnings filter (#146024) 2025-06-02 16:01:23 +02:00
Marc Mueller
ab7c7b8d89 Update ruff to 0.11.12 (#146037)
* Update ruff to 0.11.12
* Replace ruff legacy alias with ruff-check
2025-06-02 16:01:10 +02:00
Simon Lamon
93b8cc38d8 Small nmbs sensor attributes refactoring (#145956)
Attributes refactoring
2025-06-02 15:13:23 +02:00
Pete Sage
e5f95b3aff Add diagnostics tests for Sonos (#146040)
* fix: add tests for diagnostics

* fix: add new files

* fix: add new files
2025-06-02 15:12:34 +02:00
starkillerOG
613728ad3b Improve debug logging Reolink (#146033)
Add debug logging
2025-06-02 15:12:13 +02:00
starkillerOG
cb1bfe6ebe Bump reolink-aio to 0.13.5 (#145974)
* Add debug logging

* Bump reolink-aio to 0.13.5

* Revert "Add debug logging"

This reverts commit f96030a6c8.
2025-06-02 15:11:56 +02:00
Joost Lekkerkerker
434179ab3f Remove NMBS YAML import (#145733)
* Remove NMBS YAML import

* Remove NMBS YAML import
2025-06-02 15:10:46 +02:00
TimL
eb53277fcc Bump pysmlight to 0.2.6 (#146039)
Co-authored-by: Tim Lunn <tim@feathertop.org>
2025-06-02 15:04:34 +02:00
J. Nick Koston
850ddb3667 Bump grpcio to 1.72.1 (#146029) 2025-06-02 15:04:02 +02:00
epenet
5a727a4fa3 Avoid constant alias for integration DOMAIN (#145788)
* Avoid constant alias for integration DOMAIN

* Tweak

* Improve

* Three more

---------

Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-06-02 10:37:29 +02:00
karwosts
33fc700952 Make sun solar_rising a binary_sensor (#140956)
* Make sun solar_rising a binary_sensor.

* Add a state translation

* code review

* fix test

* move PLATFORMS

* Update strings.json
2025-06-02 10:32:48 +02:00
Joakim Sørensen
ad493e077e Submit legacy integrations for analytics (#145787)
* Submit legacy integrations for analytics

* adjustments
2025-06-02 10:29:17 +02:00
Marc Mueller
a2b2f6f20a Update pre-commit to 4.2.0 (#145986) 2025-06-02 09:56:20 +02:00
Marc Mueller
ee57fd413a Update freezegun to 1.5.2 (#145982) 2025-06-02 09:53:12 +02:00
Martin Hjelmare
f5d585e0f0 Fix removal of devices during Z-Wave migration (#145867) 2025-06-02 09:52:02 +02:00
Simone Chemelli
1899388f35 Add diagnostics to Amazon devices (#145964) 2025-06-02 09:48:42 +02:00
Allen Porter
4d833e9b1c Bump ical to 10.0.0 (#145954) 2025-06-02 09:47:05 +02:00
Robert Resch
6d827cd412 Deprecate hddtemp (#145850) 2025-06-02 09:45:14 +02:00
epenet
ebfbea39ff Use async_load_fixture in twitch tests (#146016) 2025-06-02 09:27:53 +02:00
dependabot[bot]
89a40f1c48 Bump dawidd6/action-download-artifact from 9 to 10 (#146015) 2025-06-02 09:21:26 +02:00
epenet
664eb7af10 Use async_load_fixture in moehlenhoff_alpha2 tests (#146012) 2025-06-02 08:59:19 +02:00
epenet
33b99b6627 Use async_load_fixture in netatmo tests (#146013) 2025-06-02 08:59:11 +02:00
epenet
0cf2ee0bcb Remove unnecessary DOMAIN alias in tests (l-r) (#146009)
* Remove unnecessary DOMAIN alias in tests (l-r)

* Keep late import in lirc
2025-06-02 08:54:55 +02:00
hanwg
85a86c3f11 Add config flow for telegram bot integration (#144617)
* added config flow for telegram integration

* added chat id in config entry title and added config flow tests

* fix import issue when there are no notifiers in configuration.yaml

* Revert "fix import issue when there are no notifiers in configuration.yaml"

This reverts commit b5b83e2a9a.

* Revert "added chat id in config entry title and added config flow tests"

This reverts commit 30c2bb4ae4.

* Revert "added config flow for telegram integration"

This reverts commit 1f44afcd45.

* added config and subentry flows

* added options flow to configure webhooks

* refactor module setup so it only load once

* moved service registration from async_setup_entry to async_setup

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* import only last yaml config

* import only last yaml config

* reduced scope of try-block

* create issue when importing from yaml

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* handle options update by reloading telegram bot

* handle import errors for create issue

* include bot's platform when creating issues

* handle options reload without needing HA restart

* moved url and trusted_networks inputs from options to new config flow step

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* minor fixes

* refactor config flow

* moved constants to const.py

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/telegram_bot/config_flow.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/telegram_bot/config_flow.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/telegram_bot/config_flow.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* added options flow tests

* Update homeassistant/components/telegram_bot/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/telegram_bot/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/telegram_bot/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/telegram_bot/config_flow.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update homeassistant/components/telegram_bot/config_flow.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* added reconfigure flow

* added reauth flow

* added tests for reconfigure flow

* added tests for reauth

* added tests for subentry flow

* added tests for user and webhooks flow with error scenarios

* added import flow tests

* handle webhook deregister exception

* added config entry id to all services

* fix leave chat bug

* Update homeassistant/components/telegram_bot/__init__.py

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* removed leave chat bug fixes

* Update homeassistant/components/telegram_bot/strings.json

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* handle other error types for import

* reuse translations

* added test for duplicated config entry for user step

* added tests

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-02 08:52:31 +02:00
epenet
de4a5fa30b Remove unnecessary DOMAIN alias in tests (s-z) (#146010) 2025-06-02 08:48:37 +02:00
Marc Mueller
43ac550ca0 Update pydantic to 2.11.5 (#145985)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-06-02 08:48:22 +02:00
Marc Mueller
c3c4d224b2 Update PyTurboJPEG to 1.8.0 (#145984)
Co-authored-by: Allen Porter <allen.porter@gmail.com>
2025-06-02 08:40:10 +02:00
Marc Mueller
6f865beacd Update attrs to 25.3.0 (#145977) 2025-06-02 07:58:35 +02:00
Marc Mueller
de25195383 Update bcrypt to 4.3.0 (#145978) 2025-06-02 07:56:51 +02:00
Marc Mueller
0139d2cabf Update cryptography to 45.0.3 (#145979) 2025-06-02 07:53:58 +02:00
Marc Mueller
17542614b5 Update aiohttp-cors to 0.8.1 (#145976)
* Update aiohttp-cors to 0.8.1

* Fix mypy
2025-06-02 07:52:23 +02:00
Marc Mueller
885367e690 Update coverage to 7.8.2 (#145983) 2025-06-02 07:47:56 +02:00
Marc Mueller
f8c44aad25 Update pytest-cov to 6.1.1 (#145989) 2025-06-02 07:34:11 +02:00
Marc Mueller
2323cc2869 Update numpy to 2.2.6 (#145981) 2025-06-01 21:23:30 -07:00
Marc Mueller
7f0249bbf7 Update pytest-timeout to 2.4.0 (#145990) 2025-06-02 06:17:39 +02:00
Marc Mueller
7a23b778a4 Update pytest-xdist to 3.7.0 (#145991) 2025-06-02 06:16:17 +02:00
Marc Mueller
d910924032 Update syrupy to 4.9.1 (#145992) 2025-06-02 06:14:52 +02:00
Marc Mueller
0b93a8c2f2 Update types packages (#145993) 2025-06-02 06:13:08 +02:00
Marc Mueller
5e377b89fc Update pytest-asyncio to 1.0.0 (#145988)
* Update pytest-asyncio to 1.0.0

* Remove event_loop fixture uses
2025-06-02 06:12:22 +02:00
Marc Mueller
dd85a1e5f0 Update mypy-dev to 1.17.0a2 (#146002)
* Update mypy-dev to 1.17.0a2

* Fix
2025-06-02 06:06:38 +02:00
Simone Chemelli
b96a7aebcd Bump aioamazondevices to 3.0.4 (#145971) 2025-06-01 21:15:18 +02:00
Michael
3cfcf382da Bump aioimmich to 0.8.0 (#145908) 2025-06-01 21:14:19 +02:00
epenet
ed9fd2c643 Use async_load_fixture in async test functions (b-i) (#145714)
* Use async_load_fixture in async test functions (b-i)

* Adjust
2025-06-01 06:31:37 -07:00
epenet
a007e8dc26 Use async_load_fixture in async test functions (l-z) (#145717)
* Use async_load_fixture in async test functions (l-z)

* Adjust
2025-06-01 06:29:17 -07:00
TimL
b318644998 Bump pysmlight to v0.2.5 (#145949) 2025-06-01 03:14:08 +02:00
Ståle Storø Hauknes
0434eea3ab Add sound pressure to Airthings (#145946)
Add sound pressure
2025-06-01 02:05:19 +02:00
Bram Kragten
06d869aaa5 Bump version to 2025.6.0b4 2025-05-31 21:25:06 +02:00
Josef Zweck
907cebdd6d Increase update intervals in lamarzocco (#145939) 2025-05-31 21:25:02 +02:00
Josef Zweck
745902bc7e Bump pylamarzocco to 2.0.8 (#145938) 2025-05-31 21:25:01 +02:00
Bram Kragten
ef0b3c9f9c Update frontend to 20250531.0 (#145933) 2025-05-31 21:25:00 +02:00
J. Nick Koston
532c077ddf Bump aiohttp to 3.12.6 (#145919)
* Bump aiohttp to 3.12.5

changelog: https://github.com/aio-libs/aiohttp/compare/v3.12.4...v3.12.5

* .6

* fix mock
2025-05-31 21:24:59 +02:00
tronikos
cd905a6593 Bump opower to 0.12.3 (#145918) 2025-05-31 21:24:59 +02:00
Josef Zweck
d0bf9d9bfb Move server device creation to init in jellyfin (#145910)
* Move server device creation to init in jellyfin

* move device creation to after coordinator refresh
2025-05-31 21:24:58 +02:00
Jordan Harvey
ddc79a631d Bump pyprobeplus to 1.0.1 (#145897) 2025-05-31 21:24:57 +02:00
Simon Lamon
6015f60db4 Bump python-linkplay to v0.2.9 (#145892) 2025-05-31 21:24:57 +02:00
Iskra kranj
a6608bd7ea Bump pyiskra to 0.1.19 (#145889) 2025-05-31 21:24:56 +02:00
Brett Adams
fb2d8c6406 Add streaming to charge cable connected in Teslemetry (#145880) 2025-05-31 21:24:55 +02:00
Brett Adams
c84ffb54d2 Bump tesla-fleet-api to 1.1.1. (#145869)
bump
2025-05-31 21:24:54 +02:00
Samuel Xiao
306bbdc697 Bump switchbot-api to 2.4.0 (#145786)
* update switchbot-api version to 2.4.0

* debug for test code
2025-05-31 21:24:54 +02:00
Robert Resch
9879ecad85 Deprecate snips integration (#145784) 2025-05-31 21:24:53 +02:00
Joost Lekkerkerker
f0fcef5744 Add more Amazon Devices DHCP matches (#145776) 2025-05-31 21:24:52 +02:00
Josef Zweck
c19b984660 Increase update intervals in lamarzocco (#145939) 2025-05-31 20:25:57 +02:00
Josef Zweck
0d6bb8a325 Bump pylamarzocco to 2.0.8 (#145938) 2025-05-31 20:25:47 +02:00
Joost Lekkerkerker
094b969301 Add more Amazon Devices DHCP matches (#145776) 2025-05-31 20:25:24 +02:00
Brett Adams
ddef6fdb98 Add streaming to charge cable connected in Teslemetry (#145880) 2025-05-31 20:01:10 +02:00
Robert Resch
cabf7860b3 Deprecate snips integration (#145784) 2025-05-31 20:00:34 +02:00
Bram Kragten
0c0a2403e5 Update frontend to 20250531.0 (#145933) 2025-05-31 17:54:36 +02:00
tronikos
be6c3d8bbd Bump opower to 0.12.3 (#145918) 2025-05-31 11:22:49 +02:00
Josef Zweck
c01536ee58 Move server device creation to init in jellyfin (#145910)
* Move server device creation to init in jellyfin

* move device creation to after coordinator refresh
2025-05-31 11:19:32 +02:00
J. Nick Koston
a9f36a50e4 Bump aiohttp to 3.12.6 (#145919)
* Bump aiohttp to 3.12.5

changelog: https://github.com/aio-libs/aiohttp/compare/v3.12.4...v3.12.5

* .6

* fix mock
2025-05-31 11:12:00 +02:00
Samuel Xiao
6d11c0395f Bump switchbot-api to 2.4.0 (#145786)
* update switchbot-api version to 2.4.0

* debug for test code
2025-05-30 20:22:40 +02:00
Brett Adams
66bb638dd0 Bump tesla-fleet-api to 1.1.1. (#145869)
bump
2025-05-30 20:21:51 +02:00
Iskra kranj
0d72bfef70 Bump pyiskra to 0.1.19 (#145889) 2025-05-30 20:21:14 +02:00
markhannon
6e44552d41 Minor cleanup of Zimi Integration (#144293) 2025-05-30 19:53:33 +02:00
Simon Lamon
9ec02633b3 Bump python-linkplay to v0.2.9 (#145892) 2025-05-30 19:35:08 +02:00
Jordan Harvey
5d340332bf Bump pyprobeplus to 1.0.1 (#145897) 2025-05-30 19:33:03 +02:00
Bram Kragten
aa8a6058b5 Bump version to 2025.6.0b3 2025-05-30 12:56:51 +02:00
J. Diego Rodríguez Royo
48103bd244 Bump aiohomeconnect to 0.17.1 (#145873) 2025-05-30 12:56:45 +02:00
Robert Resch
600ac17a5f Deprecate sms integration (#145847) 2025-05-30 12:56:44 +02:00
Michael
d46f28792c Bump aioimmich to 0.7.0 (#145845) 2025-05-30 12:56:43 +02:00
starkillerOG
0f7379c941 Reolink fallback to download command for playback (#145842) 2025-05-30 12:56:43 +02:00
J. Nick Koston
4317fad798 Bump aiohttp to 3.12.4 (#145838) 2025-05-30 12:56:42 +02:00
J. Nick Koston
5cfccb7e1d Bump aiohttp to 3.12.3 (#145837) 2025-05-30 12:56:41 +02:00
Matthew FitzGerald-Chamberlain
097eecd78a Bump pyaprilaire to 0.9.1 (#145836) 2025-05-30 12:56:40 +02:00
Brett Adams
64b4642c49 Fix Tessie volume max and step (#145835)
* Use fixed volume max and step

* Update snapshot
2025-05-30 12:56:39 +02:00
Michael
0e87d14ca8 Use mime type provided by Immich (#145830)
use mime type from immich instead of guessing it
2025-05-30 12:56:38 +02:00
Josef Zweck
4d22b35a9f Bump aiotedee to 0.2.23 (#145822)
* Bump aiotedee to 0.2.23

* update snapshot
2025-05-30 12:56:37 +02:00
G Johansson
26586b4514 Fix language selections in workday (#145813) 2025-05-30 12:56:36 +02:00
Robert Resch
95fb2a7d7f Deprecate decora integration (#145807) 2025-05-30 12:56:35 +02:00
Robert Resch
fa66ea31d3 Deprecate tensorflow (#145806)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-05-30 12:56:34 +02:00
André Lersveen
e0d3b819e5 Set correct nobo_hub max temperature (#145751)
Max temperature 30°C is implemented upstream in pynobo and the Nobø Energy Hub app also stops at 30°C.
2025-05-30 12:56:34 +02:00
J. Diego Rodríguez Royo
1e973c1d74 Bump aiohomeconnect to 0.17.1 (#145873) 2025-05-30 01:40:11 +02:00
starkillerOG
618ada64f8 Ensure Reolink host device is setup first (#145843) 2025-05-29 19:32:21 +02:00
Robert Resch
2d6802e06a Deprecate tensorflow (#145806)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-05-29 14:35:35 +01:00
starkillerOG
9687a34a70 Reolink fallback to download command for playback (#145842) 2025-05-29 15:31:50 +02:00
Michael
5ba0ceb6c2 Bump aioimmich to 0.7.0 (#145845) 2025-05-29 15:30:02 +02:00
G Johansson
d8e3e88c63 Fix language selections in workday (#145813) 2025-05-29 15:28:54 +02:00
Robert Resch
d1d1bca29d Deprecate sms integration (#145847) 2025-05-29 14:12:51 +02:00
Michael
80189495c5 Use mime type provided by Immich (#145830)
use mime type from immich instead of guessing it
2025-05-29 10:28:02 +02:00
Josef Zweck
cad6c72cfa Bump aiotedee to 0.2.23 (#145822)
* Bump aiotedee to 0.2.23

* update snapshot
2025-05-29 10:35:05 +03:00
J. Nick Koston
23ac22e213 Remove default args to ESPHome test fixture calls (#145840) 2025-05-29 01:45:37 -05:00
J. Nick Koston
55e664fc0d Bump aiohttp to 3.12.4 (#145838) 2025-05-28 21:08:01 -05:00
Brett Adams
881ce45afa Fix Tessie volume max and step (#145835)
* Use fixed volume max and step

* Update snapshot
2025-05-29 03:58:29 +02:00
André Lersveen
b80195df81 Set correct nobo_hub max temperature (#145751)
Max temperature 30°C is implemented upstream in pynobo and the Nobø Energy Hub app also stops at 30°C.
2025-05-29 03:52:05 +02:00
Matthew FitzGerald-Chamberlain
e57ce0a9df Bump pyaprilaire to 0.9.1 (#145836) 2025-05-29 03:43:28 +02:00
J. Nick Koston
ff66ad7705 Bump aiohttp to 3.12.3 (#145837) 2025-05-28 19:38:06 -05:00
Robert Resch
33e98ebffa Remove decora-wifi from excluded requirements (#145832) 2025-05-29 00:14:38 +02:00
Robert Resch
8fd9e2046e Deprecate decora integration (#145807) 2025-05-28 23:54:48 +02:00
Bram Kragten
17a0b4f3d0 Bump version to 2025.6.0b2 2025-05-28 23:18:38 +02:00
Bram Kragten
d0d228d9f4 Update frontend to 20250528.0 (#145828)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-05-28 23:18:33 +02:00
Michael
309acb961b Fix Immich media source browsing with multiple config entries (#145823)
fix media source browsing with multiple config entries
2025-05-28 23:18:32 +02:00
Michael Hansen
12f8ebb3ea Bump intents to 2025.5.28 (#145816) 2025-05-28 23:18:32 +02:00
David Bonnes
612861061c Fix HOMEASSISTANT_STOP unsubscribe in data update coordinator (#145809)
* initial commit

* a better approach

* Add comment
2025-05-28 23:18:31 +02:00
Robert Resch
83af5ec36b Deprecate keyboard integration (#145805) 2025-05-28 23:18:30 +02:00
starkillerOG
74102d0319 Bump reolink-aio to 0.13.4 (#145799) 2025-05-28 23:18:29 +02:00
Robert Resch
fbd05a0fcf Deprecate lirc integration (#145797) 2025-05-28 23:18:29 +02:00
Robert Resch
a53c786fe0 Deprecate pandora integration (#145785) 2025-05-28 23:18:28 +02:00
Josef Zweck
eb2728e5b9 Fix uom for prebrew numbers in lamarzocco (#145772) 2025-05-28 23:18:27 +02:00
J. Diego Rodríguez Royo
3f17223387 Add more information about possible hostnames at Home Connect (#145770) 2025-05-28 23:18:26 +02:00
Robert Resch
74104cf107 Deprecate GStreamer integration (#145768) 2025-05-28 23:18:25 +02:00
Robert Resch
13b4879723 Deprecate dlib image processing integrations (#145767) 2025-05-28 23:18:25 +02:00
Erik Montnemery
f1ec0b2c59 Handle late abort when creating subentry (#145765)
* Handle late abort when creating subentry

* Move error handling to the base class

* Narrow down expected error in test
2025-05-28 23:18:24 +02:00
Josef Zweck
6d44daf599 Bump pylamarzocco to 2.0.7 (#145763) 2025-05-28 23:18:23 +02:00
Joost Lekkerkerker
644a6f5569 Add more Amazon Devices DHCP matches (#145754) 2025-05-28 23:18:22 +02:00
Abílio Costa
fb83396522 Add Shelly zwave virtual integration (#145749) 2025-05-28 23:18:22 +02:00
Raphael Hehl
e825bd0bdb Bump uiprotect to version 7.10.1 (#145737)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2025-05-28 23:18:21 +02:00
G Johansson
61823ec7e2 Fix dns resolver error in dnsip config flow validation (#145735)
Fix dns resolver error in dnsip
2025-05-28 23:18:20 +02:00
Michael
cd133cbbe3 Add level of collections in Immich media source tree (#145734)
* add layer for collections in media source tree

* re-arange tests, add test for collection layer

* fix
2025-05-28 23:18:19 +02:00
Erik Montnemery
0e7a1bb76c Make async_remove_stale_devices_links_keep_entity_device move entities (#145719)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-05-28 23:18:18 +02:00
Josef Zweck
f86bf69ebc Update otp description for amazon_devices (#145701)
* Update otp description from amazon_devices

* separate

* Update strings.json
2025-05-28 23:18:18 +02:00
Jan Bouwhuis
adddf330fd Ensure mqtt sensor unit of measurement validation for state class measurement_angle (#145648) 2025-05-28 23:18:17 +02:00
Bram Kragten
32c2f47ab5 Update frontend to 20250528.0 (#145828)
Co-authored-by: Robert Resch <robert@resch.dev>
2025-05-28 23:17:14 +02:00
Ståle Storø Hauknes
e2fc2dce84 Move Airthings coordinator to separate module (#145827)
* Create coordinator

* Fix sensor.py
2025-05-28 22:38:33 +02:00
Michael
afa97f8ec1 Add level of collections in Immich media source tree (#145734)
* add layer for collections in media source tree

* re-arange tests, add test for collection layer

* fix
2025-05-28 20:51:27 +02:00
Michael
2708c1c94c Fix Immich media source browsing with multiple config entries (#145823)
fix media source browsing with multiple config entries
2025-05-28 20:49:20 +02:00
Michael Hansen
d76ed6a3c2 Bump intents to 2025.5.28 (#145816) 2025-05-28 21:14:13 +03:00
epenet
695f69bd90 Remove unnecessary DOMAIN alias in tests (e-k) (#145818) 2025-05-28 21:06:25 +03:00
epenet
7da8e24e21 Remove unnecessary DOMAIN alias in tests (a-d) (#145817) 2025-05-28 21:00:38 +03:00
David Bonnes
9d0fc0d513 Fix HOMEASSISTANT_STOP unsubscribe in data update coordinator (#145809)
* initial commit

* a better approach

* Add comment
2025-05-28 17:52:51 +01:00
Robert Resch
ca567aa7fc Deprecate lirc integration (#145797) 2025-05-28 17:28:37 +01:00
Robert Resch
27af2d8ec6 Deprecate keyboard integration (#145805) 2025-05-28 17:22:18 +02:00
Lennart Nederstigt
59ea6f375a Add hardwired chime toggle to Reolink Battery Doorbell (#145779)
Co-authored-by: starkillerOG <starkiller.og@gmail.com>
2025-05-28 17:10:38 +02:00
Marc Mueller
6c365c94ed Update sqlalchemy to 2.0.41 (#145790) 2025-05-28 16:39:10 +02:00
Marc Mueller
6693fc764f Update httpcore to 1.0.9 and h11 to 0.16.0 (#145789) 2025-05-28 16:35:11 +02:00
starkillerOG
e855b6c2bc Bump reolink-aio to 0.13.4 (#145799) 2025-05-28 16:33:20 +02:00
Abílio Costa
23a1dddc23 Add Shelly zwave virtual integration (#145749) 2025-05-28 14:56:47 +01:00
epenet
bd5fef1ddb Use async_load_fixture in async test functions (a) (#145718) 2025-05-28 15:51:49 +02:00
epenet
c3ade400fb Use Platform constant in tests (#145801)
* Use Platform constant in tests

* spelling

* Fix platform
2025-05-28 15:51:37 +02:00
epenet
1889f0ef66 Use Platform constant in hue tests (#145798) 2025-05-28 14:43:48 +02:00
epenet
6b28af8282 Remove unnecessary DOMAIN alias in components (#145791) 2025-05-28 14:04:35 +02:00
Robert Resch
f59001d45f Deprecate pandora integration (#145785) 2025-05-28 13:12:55 +02:00
Erik Montnemery
a857461059 Handle late abort when creating subentry (#145765)
* Handle late abort when creating subentry

* Move error handling to the base class

* Narrow down expected error in test
2025-05-28 12:26:28 +02:00
epenet
e4cc842584 Use async_load_json_(array/object)_fixture in async test functions (#145773) 2025-05-28 12:09:05 +02:00
Robert Resch
bb52058920 Deprecate GStreamer integration (#145768) 2025-05-28 11:16:08 +02:00
J. Diego Rodríguez Royo
c1676570da Add more information about possible hostnames at Home Connect (#145770) 2025-05-28 10:57:01 +02:00
G Johansson
4858b2171e Modernize tests for smhi (#139334)
* Modernize tests for smhi

* Fixes

* Mods

* Fix weather

* Coverage 100%

* Fix init test

* Fixes

* Fixes

* Remove waits
2025-05-28 10:56:07 +02:00
Jan Bouwhuis
192aa76cd7 Ensure mqtt sensor unit of measurement validation for state class measurement_angle (#145648) 2025-05-28 10:16:40 +02:00
Josef Zweck
ddf611bfdf Fix uom for prebrew numbers in lamarzocco (#145772) 2025-05-28 10:15:24 +02:00
Robert Resch
3164394982 Deprecate dlib image processing integrations (#145767) 2025-05-28 09:58:44 +02:00
Josef Zweck
b250a03ff5 Bump pylamarzocco to 2.0.7 (#145763) 2025-05-28 09:39:33 +02:00
dependabot[bot]
2dd7f035f6 Bump docker/build-push-action from 6.17.0 to 6.18.0 (#145764)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-28 09:10:37 +02:00
Joost Lekkerkerker
2c08b3f30c Add more Amazon Devices DHCP matches (#145754) 2025-05-28 08:43:59 +02:00
Josef Zweck
c3ec30ce3b Update otp description for amazon_devices (#145701)
* Update otp description from amazon_devices

* separate

* Update strings.json
2025-05-28 08:13:28 +02:00
Erik Montnemery
9d4375ca76 Make async_remove_stale_devices_links_keep_entity_device move entities (#145719)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-05-27 23:00:52 +02:00
Raphael Hehl
3870b87db9 Bump uiprotect to version 7.10.1 (#145737)
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2025-05-27 22:58:46 +02:00
Joost Lekkerkerker
ff2fd7e9ef Add DHCP discovery to LG ThinQ (#145746) 2025-05-27 16:45:30 -04:00
G Johansson
719dd09eb3 Fix dns resolver error in dnsip config flow validation (#145735)
Fix dns resolver error in dnsip
2025-05-27 22:17:34 +02:00
Bram Kragten
10adb57b83 Bump version to 2025.6.0b1 2025-05-27 22:16:13 +02:00
Bram Kragten
3160fe9abc Update frontend to 20250527.0 (#145741) 2025-05-27 22:14:02 +02:00
Erwin Douna
6adb27d173 Tado update mobile devices interval (#145738)
Update the mobile devices interval to five minutes
2025-05-27 22:14:01 +02:00
Joost Lekkerkerker
6e6aae2ea3 Fix unbound local variable in Acmeda config flow (#145729) 2025-05-27 22:14:00 +02:00
Kevin Stillhammer
41a140d16c Debug log the update response in google_travel_time (#145725)
Debug log the update response
2025-05-27 22:14:00 +02:00
Kevin Stillhammer
8880ab6498 Catch PermissionDenied(Route API disabled) in google_travel_time (#145722)
Catch PermissionDenied(Route API disabled)
2025-05-27 22:13:59 +02:00
Martin Hjelmare
389becc4f6 Disable advanced window cover position Matter sensor by default (#145713)
* Disable advanced window cover position Matter sensor by default

* Enanble disabled sensors in snapshot test
2025-05-27 22:13:58 +02:00
Martin Hjelmare
923530972a Remove static pin code length Matter sensors (#145711)
* Remove static Matter sensors

* Clean up translation strings
2025-05-27 22:13:57 +02:00
Martin Hjelmare
b84850df9f Fix error stack trace for HomeAssistantError in websocket service call (#145699)
* Add test

* Fix error stack trace for HomeAssistantError in websocket service call
2025-05-27 22:13:56 +02:00
Joost Lekkerkerker
9e7dc1d11d Use string type for amazon devices OTP code (#145698) 2025-05-27 22:13:56 +02:00
Petar Petrov
2830ed6147 Change description on recommended/custom Z-Wave install step (#145688)
Change description on recommended/custom Z-WaveJS step
2025-05-27 22:13:55 +02:00
Petar Petrov
bfa919d078 Remove confirm screen after Z-Wave usb discovery (#145682)
* Remove confirm screen after Z-Wave usb discovery

* Simplify async_step_usb
2025-05-27 22:13:54 +02:00
Jan Bouwhuis
f09c28e61f Fix justnimbus CI test (#145681) 2025-05-27 22:13:54 +02:00
J. Nick Koston
bfdba7713e Bump aiohttp to 3.12.2 (#145671) 2025-05-27 22:13:53 +02:00
Kevin Stillhammer
d6cadc1e3f Support addresses with comma in google_travel_time (#145663)
Support addresses with comma
2025-05-27 22:13:52 +02:00
Joost Lekkerkerker
20a6a3f195 Handle Google Nest DHCP flows (#145658)
* Handle Google Nest DHCP flows

* Handle Google Nest DHCP flows
2025-05-27 22:13:51 +02:00
Joost Lekkerkerker
f60de45b52 Fix Amazon devices offline handling (#145656) 2025-05-27 22:13:50 +02:00
Joost Lekkerkerker
77031d1ae4 Fix Aquacell snapshot (#145651) 2025-05-27 22:13:49 +02:00
Jan Bouwhuis
9483a88ee1 Fix translation for sensor measurement angle state class (#145649) 2025-05-27 22:13:48 +02:00
Bram Kragten
2cf2613dbd Update frontend to 20250527.0 (#145741) 2025-05-27 22:12:07 +02:00
Jan Bouwhuis
181a3d142e Revert "squeezebox Better result for testing (#144622)" (#145739)
This reverts commit 987af8f7df.
2025-05-27 21:36:51 +02:00
Elias Wernicke
c20ad5fde1 Add complete intent function for shopping list component (#128565)
* add intent

* add tests

* raise IntentHandleError

* add check for non completed

* Prefer completing non complete items

* cleanup

* cleanup tests

* rename test

Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>

* remove duplicated test

* update test

* complete all items

* fix event

* remove type def

* return speech slots

---------

Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-05-27 14:35:14 -05:00
Erwin Douna
4fcebf18dc Tado update mobile devices interval (#145738)
Update the mobile devices interval to five minutes
2025-05-27 21:27:52 +02:00
Joost Lekkerkerker
a6e04be076 Remove niko_home_control YAML import (#145732) 2025-05-27 19:58:05 +02:00
Erwin Douna
330a8e197d MELCloud remove deprecated YAML import strings (#145731)
Remove deprecated YAML import strings
2025-05-27 19:50:31 +02:00
Joost Lekkerkerker
4300e846e6 Fix unbound local variable in Acmeda config flow (#145729) 2025-05-27 19:29:04 +02:00
Kevin Stillhammer
07fd1f99df Support addresses with comma in google_travel_time (#145663)
Support addresses with comma
2025-05-27 18:53:45 +02:00
Kevin Stillhammer
481639bcf9 Catch PermissionDenied(Route API disabled) in google_travel_time (#145722)
Catch PermissionDenied(Route API disabled)
2025-05-27 18:45:49 +02:00
Martin Hjelmare
376008940b Disable advanced window cover position Matter sensor by default (#145713)
* Disable advanced window cover position Matter sensor by default

* Enanble disabled sensors in snapshot test
2025-05-27 17:46:21 +02:00
epenet
b2c2db3394 Add check for transient packages restricting Python version (#145695) 2025-05-27 17:45:51 +02:00
Kevin Stillhammer
a636e38d24 Debug log the update response in google_travel_time (#145725)
Debug log the update response
2025-05-27 17:44:48 +02:00
Martin Hjelmare
ae1294830c Remove static pin code length Matter sensors (#145711)
* Remove static Matter sensors

* Clean up translation strings
2025-05-27 17:35:11 +02:00
Robin Lintermann
d87fdf028b Improve smarla base entity (#145710) 2025-05-27 15:58:19 +02:00
Petar Petrov
6f5d5d4cdb Change text of installing and starting Z-WaveJs add-on steps (#145702) 2025-05-27 14:51:22 +02:00
epenet
12fdd7034a Simplify boolean check in onewire (#145700) 2025-05-27 13:30:44 +02:00
Martin Hjelmare
f295d72cd9 Fix error stack trace for HomeAssistantError in websocket service call (#145699)
* Add test

* Fix error stack trace for HomeAssistantError in websocket service call
2025-05-27 12:54:57 +02:00
Petar Petrov
2605fda185 Remove confirm screen after Z-Wave usb discovery (#145682)
* Remove confirm screen after Z-Wave usb discovery

* Simplify async_step_usb
2025-05-27 12:53:30 +02:00
Joost Lekkerkerker
2189dc3e2a Use string type for amazon devices OTP code (#145698) 2025-05-27 12:33:02 +02:00
Franck Nijhof
8364d8a2e3 Bump version to 2025.7.0dev0 (#145647)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-05-27 10:59:34 +02:00
epenet
96c9636086 Add check for packages restricting Python version (#145690)
* Add check for packages restricting Python version

* Apply suggestions from code review

* until

* until
2025-05-27 10:44:00 +02:00
Petar Petrov
7b1dfc35d1 Change description on recommended/custom Z-Wave install step (#145688)
Change description on recommended/custom Z-WaveJS step
2025-05-27 10:04:29 +02:00
Norbert Rittel
2e94730491 Replace "Invalid API key" with common string in overseerr (#145689)
Replace "Invalid API key" with common string
2025-05-27 09:56:16 +02:00
Markus Adrario
11c6998bf2 Add homee siren platform (#145675)
* port siren.py from custom component

* Add Siren Tests

* last small nits
2025-05-27 09:48:59 +02:00
epenet
055a024d10 Add async-timeout to forbidden packages (#145679) 2025-05-27 08:57:35 +02:00
Joost Lekkerkerker
f73afd71fd Fix Amazon devices offline handling (#145656) 2025-05-27 08:49:25 +02:00
Jan Bouwhuis
ec64194ab9 Fix justnimbus CI test (#145681) 2025-05-27 08:48:06 +02:00
karwosts
d49a613c62 Add read_only entity_id to Trend options flow (#145657) 2025-05-27 08:42:08 +02:00
Artur Pragacz
6fc064fa6a Test that recorder is not promoted to earlier stage in bootstrap (#142695)
Test that recorder is not promoted to earlier stage
2025-05-27 08:23:39 +02:00
Artur Pragacz
b36b591ccf Improve error message for global timeout (#141563)
* Improve error message for global timeout

* Add test

* Message works with zone too
2025-05-27 07:49:18 +02:00
J. Nick Koston
d25ba79427 Bump aiohttp to 3.12.2 (#145671) 2025-05-26 21:58:46 -05:00
Joost Lekkerkerker
df35f30321 Handle Google Nest DHCP flows (#145658)
* Handle Google Nest DHCP flows

* Handle Google Nest DHCP flows
2025-05-26 15:01:35 -07:00
Jan Bouwhuis
1e3d06a993 Fix translation for sensor measurement angle state class (#145649) 2025-05-26 22:47:53 +01:00
Florian von Garrel
2ee6bf7340 Add update platform to paperless integration (#145638)
* Add uüdate platform to paperless integration

* Add tests to paperless

* Add translation

* Fixed update unavailable

* Fetch remote version in update platform

* changed diagnostics

* changed diagnostic data

* Code quality

* revert changes

* code quality
2025-05-26 23:24:53 +02:00
Joost Lekkerkerker
13a8e5e021 Fix Aquacell snapshot (#145651) 2025-05-26 23:08:07 +02:00
Franck Nijhof
3438a4f063 Bump version to 2025.6.0b0 2025-05-26 20:31:18 +00:00
Markus Jacobsen
9a73006681 Simplify Bang & Olufsen testing setup (#139830)
* Add and use integration fixture

* Simplify WebSocket testing

* Remove integration fixture return value

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-05-26 22:14:27 +02:00
Joost Lekkerkerker
4aade14c9e Fix CI (#145644)
* Fix CI

* Fix CI
2025-05-26 21:55:33 +02:00
epenet
8abbd35c54 Add ability to load test fixtures on the executor (#144534) 2025-05-26 21:50:28 +02:00
Allen Porter
34f92d584b Bump gcal_sync to 7.1.0 (#145642) 2025-05-26 21:48:13 +02:00
Guido Schmitz
a7919c5ce7 Move coordinator and getting data closer together in devolo Home Network (#144814) 2025-05-26 21:44:45 +02:00
ngolf
405725f8ee Add last update to aquacell (#143661) 2025-05-26 21:43:55 +02:00
Cerallin
393ea0251b Add add_package action to seventeentrack (#144488)
* Fix schema name, add_packages -> get_packages

* Add "add_package" service

* Update description

* Update descriptions
2025-05-26 21:40:12 +02:00
LG-ThinQ-Integration
cdd3ce428f Add select for ventilator's control (#140849)
* Add select for ventilator's control

* Removed wind_strength and it will be provided by fan

---------

Co-authored-by: yunseon.park <yunseon.park@lge.com>
2025-05-26 21:37:05 +02:00
wittypluck
b17d62177c Add Air Pollution support to OpenWeatherMap (#137949)
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-05-26 21:34:48 +02:00
tdfountain
16394061cb Add additional outlet sensors to NUT (#143309)
Add outlet sensors for current, power, and real powre
2025-05-26 21:34:15 +02:00
Jan Bouwhuis
b1403838bb Add translation string and references for sensor Measurement Angle state class (#145639) 2025-05-26 21:22:10 +02:00
jukrebs
e857db281f Set new IOmeter datacoordinator debouncer cooldown (#143665) 2025-05-26 21:21:35 +02:00
Sören Beye
5f63612b66 Increase resolution of sun updates around sunrise/sundown (#140403) 2025-05-26 21:20:18 +02:00
Phill (pssc)
987af8f7df squeezebox Better result for testing (#144622) 2025-05-26 21:16:11 +02:00
Matthew FitzGerald-Chamberlain
0ab7d46d7c Support AprilAire humidifier auto mode (#144647) 2025-05-26 21:15:40 +02:00
peteS-UK
072d0dc567 Update coordinator logging levels for Squeezebox (#144620) 2025-05-26 21:14:15 +02:00
Jason Mahdjoub
9b9d4d7dab Set correct state_class for battery_stored and increase timeout to prevent Imeon integration disconnections (#144925) 2025-05-26 21:13:47 +02:00
Gaylord GIRARD
84305563ab Add state class measurement to Freebox rate sensors (#142757)
* Update sensor.py

Update sensor.py to add state_class=SensorStateClass.MEASUREMENT as per long-term-statistics requierment

* Update sensor.py

remove duplicate import of SensorStateClass in freebox sensor to satisfy ruff

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-05-26 21:13:35 +02:00
Brett Adams
db489a5069 Improve device tracker platform in Teslemetry (#145268) 2025-05-26 21:12:39 +02:00
Allen Porter
2ef0a8557f Bump ical to 9.2.5 (#145636) 2025-05-26 21:12:05 +02:00
Brett Adams
001164ce1b Remove available property for streaming in Teslemetry (#145352) 2025-05-26 21:11:35 +02:00
karwosts
848eb797e0 Add read_only selectors to Filter Options Flow (#145526) 2025-05-26 21:08:30 +02:00
asafhas
fd4dafaac5 Fix trigger condition and alarm message in Tuya Alarm (#132963)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-05-26 21:05:09 +02:00
Erwin Douna
0b6ea36e24 Add Tado user agent (#145637) 2025-05-26 21:04:46 +02:00
Claudio Ruggeri - CR-Tech
b667fb2728 Fix NaN values in Modbus slaves sensors (#139969)
* Fix NaN values in Modbus slaves sensors

* fixXbdraco
2025-05-26 21:04:38 +02:00
J. Diego Rodríguez Royo
2dc2b0ffac Delete Home Connect program switches related strings (#144610) 2025-05-26 21:02:27 +02:00
Dave Ingram
d6375a79a1 Expose filter/pump timers for Tuya pet fountains (#131863)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-05-26 21:01:45 +02:00
Speak to the Geek
c36f8c38ae YouTube Component - Enable SensorStateClass for Long Term Statistic Support (#142670)
* Youtube Component Support SensorStateClass in sensor.py

Added support for long term statistics by including the appropriate state class type for subscriber and view counts.

* Update sensor.py

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-05-26 20:59:07 +02:00
Chuck Deal
c4485c1814 Add Sunbeam Dual Zone Heated Bedding to Tuya integration (#135405) 2025-05-26 20:58:11 +02:00
Joost Lekkerkerker
e2a916ff9d Make sure we can set up OAuth based integrations via discovery (#145144) 2025-05-26 20:48:07 +02:00
Joost Lekkerkerker
a2b02537a6 Add deprecation issues for supervised and core installation methods (#145323)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-05-26 20:45:12 +02:00
thargor
b8a96d2a76 update pyfronius to 0.8.0 (#141984) 2025-05-26 20:23:41 +02:00
David Poll
670e8dd434 Add as_function to allow macros to return values (#142033) 2025-05-26 20:22:45 +02:00
Florian von Garrel
27b0488f05 Update Paperless strings (#145633)
* minor changed

* Update snapshots
2025-05-26 19:53:54 +02:00
Simone Chemelli
6003f3d135 Add action exceptions to UptimeRobot integration (#143587)
* Add action exceptions to UptimeRobot integration

* fix tests and strings
2025-05-26 19:47:46 +02:00
epenet
c3dec7fb2f Add ability to set exceptions in dependency version checks (#145442)
* Add ability to set exceptions in dependency version checks

* Fix message

* Improve

* Auto-load from requirements.txt

* Revert "Auto-load from requirements.txt"

This reverts commit f893d4611a4b6ebedccaa639622c3f8f4ea64005.
2025-05-26 19:45:26 +02:00
TheJulianJES
cfa4d37909 Add icons for ZHA fan modes (#145634) 2025-05-26 19:44:31 +02:00
Bram Kragten
8ce3ead782 Update frontend to 20250526.0 (#145628) 2025-05-26 19:44:22 +02:00
Abílio Costa
b626204f63 Add default device class display precision for Sensor (#145013)
* Add default device class display precision for Sensor

* Renaming, docstrings, cleanup

* Simplify units list

* Fix tests

* Fix missing precision when suggested is specified

* Update snapshots

* Fix when unit of measurement is not valid

* Fix tests

* Fix deprecated unit usage

* Fix goalzero tests

The sensor native_value method was accessing the data dict and trowing,
since the mock did not have any data for the sensors.

Since now the precision is always specified (it was missing for those
sensors), the throw was hitting async_update_entity_options in _update_suggested_precision.
Previously, async_update_entity_options was not called since it had no
precision.

* Fix metoffice

* Fix smartthings

* Add default sensor data for Tesla Wall Connector tests

* Update snapshots

* Revert spaces

* Update smartthings snapshots

* Add missing sensor mock for tesla wall connector

* Address review comments

* Add doc comment

* Add cap to doc comment

* Update comment

* Update snapshots

* Update comment
2025-05-26 19:40:29 +02:00
Joost Lekkerkerker
b15989f2bf Make tests less dependent on issue registry size (#145631)
* Make tests less dependent on issue registry size

* Make tests less dependent on issue registry size
2025-05-26 19:39:11 +02:00
Erik Montnemery
eec7666416 Update squeezebox test snapshots (#145632) 2025-05-26 19:35:07 +02:00
TheJulianJES
5ea6811d01 Add translation for ZHA light effect (#145630)
* Add translations for ZHA light effects

* Add icons for ZHA light effects

* Fix capitalization of "Color loop"

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-05-26 19:31:25 +02:00
Erik Montnemery
4e1d5fbeb0 Add WS command to help reset custom entity_id (#145504)
* Add WS command to help reset custom entity_id

* Calculate suggested object id from entity properties

* Fix logic and add additional tests

* Adjust test

* Update folder_watcher test

* Handle current entity id matches the automatic entity id

* Don't store calculated_object_id

* Update snapshots

* Update snapshots

* Update test

* Tweak logic for reusing current entity_id

* Improve test

* Don't assign same entity_id to several entities

* Prioritize custom entity name

* Update snapshots

* Update snapshots
2025-05-26 19:28:27 +02:00
Sid
bf92db6fd5 Add diagnostics to eheimdigital (#145382)
* Add diagnotics to eheimdigital

* Diagnostics are now with data in tests
2025-05-26 19:25:15 +02:00
Sid
03a26836ed Refactor eheimdigital tests to use fixtures (#145428) 2025-05-26 19:13:20 +02:00
Adrian Freund
99ebac5452 Add translation keys for zha fan states (#145629) 2025-05-26 19:02:52 +02:00
J. Nick Koston
01ea58eb9b Bump aiohttp to 3.12.1 (#145627)
changelog: https://github.com/aio-libs/aiohttp/compare/v3.12.1rc0...v3.12.1

No changes since 3.12.1rc0, only the version number
2025-05-26 11:54:00 -05:00
epenet
039383ab22 Add pyserial-asyncio to forbidden packages (#145625) 2025-05-26 18:40:13 +02:00
Perchun Pak
8fb4f1f7f9 Update mcstatus to 12.0.1 in Minecraft Server (#144704)
Update mcstatus to 12.0.1
2025-05-26 18:39:13 +02:00
Simone Chemelli
15a7d13768 Use model details data from library for Amazon Devices (#145601)
* Log warning for unknown models for Amazon Devices

* use method from library

* apply review comment

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-05-26 18:24:23 +02:00
J. Nick Koston
51562e5ab4 Bump aiohttp to 3.12.1rc0 (#145624) 2025-05-26 11:05:26 -05:00
peteS-UK
8623d96deb Squeezebox add alarms support - switch platform. Part 1 (#141055)
* initial

* remove dupe name definition

* snapshot update

* name def updates

* test update for new entity name

* remove attributes

* icon translations

* merge fixes

* Snapshot update post merge

* update to class initialisation

* move entity delete to coordinator

* remove some comments

* move known_alarms to coordinator

* test_switch update for syrupy change

* listener and sets

* check self.available

* remove refresh from conftest

* test update

* test tweak

* move listener to switch platform

* updates revew

* SWITCH_DOMAIN
2025-05-26 17:41:28 +02:00
Sören Beye
3dc7b75e4b Allow nested schema validation in event automation trigger (#126771)
* Allow nested schema validation in event automation trigger

* Fix rfxtrx device trigger

* Don't create nested voluptuous schemas

* Fix editing mistake

* Fix format

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-05-26 17:34:13 +02:00
Florian von Garrel
c14d17f88c Add status sensors to paperless (#145591)
* Add first status sensor and coordinator

* New snapshot

* Add comment

* Add test for forbidden status endpoint

* Changed comment

* Fixed translation

* Minor changes and code optimization

* Add common translation; minor tweaks

* Moved translation from common to integration
2025-05-26 17:24:23 +02:00
Simone Chemelli
b7ce0f63a9 Add notify platform to Amazon Devices (#145589)
* Add notify platform to Amazon Devices

* apply review comment

* leftover

* tests leftovers

* remove sound notification

* missing await
2025-05-26 17:17:32 +02:00
Marcel van der Veldt
c2a5e1aaf9 Prefer source name in Music Assistant integration (#145622)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-05-26 17:07:05 +02:00
David Poll
13d7234f97 Add apply to make macros/callables useful in filters and tests (#144227) 2025-05-26 17:00:07 +02:00
avee87
ca50fca738 Add twice-daily forecasts to MetOffice (#145472) 2025-05-26 16:56:15 +02:00
epenet
acbfe54c7b Drop obsolete IGNORE_PIN in gen_requirements_all.py (#145487)
Drop IGNORE_PIN in gen_requirements_all.py
2025-05-26 16:49:42 +02:00
Robert Resch
49f9166646 Deprecate cups integration (#145615) 2025-05-26 16:48:41 +02:00
Åke Strandberg
42cacd28e7 Add tests to miele fan entity and api push data pathway (#144481)
* Use device class transation

* WIP

* Test api push

* Use constants

* Use callbacks registered with mock

* Add comment

* Adress review comments

* Empty commit

* Fix tests

* Updates after review
2025-05-26 16:38:41 +02:00
Marcel van der Veldt
6f9a39ab89 Add select source action to Music Assistant (#145619) 2025-05-26 16:28:18 +02:00
starkillerOG
0d81694640 Add event browsing to Reolink recordings (#144259) 2025-05-26 16:20:55 +02:00
epenet
109bcf362a Use shorthand attributes in xiaomi_miio (part 3) (#145617) 2025-05-26 16:16:18 +02:00
Erik Montnemery
0260a03447 Store information about add-ons and folders which could not be backed up (#145367)
* Store information about add-ons and folders which could not be backed up

* Address review comments
2025-05-26 16:07:33 +02:00
Simone Chemelli
0802fc8a21 Add switch platform to Amazon Devices (#145588)
* Add switch platform to Amazon Devices

* apply review comment

* make logic generic

* test cleanup
2025-05-26 16:01:11 +02:00
epenet
c346b932f0 Use shorthand attributes in xiaomi_miio (part 2) (#145616)
* Use shorthand attributes in xiaomi_miio (part 2)

* Brightness

* Is_on
2025-05-26 15:57:01 +02:00
avee87
a14f3ab6b1 Fix clear night weather condition for metoffice (#145470) 2025-05-26 15:43:28 +02:00
dontinelli
14cd00a116 Add user picture to fyta (#140934)
* Add user picture

* FYTA integration: Add separate entities for both default and user plant images (#12)

* Refactor FYTA integration to provide both default and user plant images as separate entities

* Refactor FYTA tests by removing unused CONF_USER_IMAGE option and related test cases

* Update FytaPlantImageEntity to set entity name based on image type

* Refactor FYTA image tests to accommodate separate plant and user image entities, updating assertions and snapshots accordingly.

* Enhance FYTA image handling by introducing FytaImageEntityDescription for better separation of plant and user images, and update image URL retrieval logic. Additionally, add localized strings for image entities in strings.json.

* Correct typo

* Update FYTA image snapshots to reflect changes in translation keys for plant and user images.

* Update homeassistant/components/fyta/image.py

* Update homeassistant/components/fyta/image.py

---------

Co-authored-by: dontinelli <73341522+dontinelli@users.noreply.github.com>

* Update QS + ruff

* Revert MINOR_VERSION increase and remove obsolete migration test

* Update snapshot

* Resolve comments

* Update snapshot

* Fix

---------

Co-authored-by: Alexander <chimera88@gmx.de>
2025-05-26 15:40:15 +02:00
Thomas D
486535c189 Add scene platform to Qbus integration (#144032)
* Add scene platform

* Remove updating last_activated

* Simplify device info

* Move _attr_name to specific classes

* Refactor device info

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-05-26 15:37:07 +02:00
Abílio Costa
54dce53628 Add sensor tests for device class enums (#145523) 2025-05-26 14:28:30 +01:00
starkillerOG
a3b7cd7b4d Implement NVR download for Reolink recordings (#144121) 2025-05-26 15:23:11 +02:00
Robin Lintermann
dafda420e5 Add smarla integration (#143081)
* Added smarla integration

* Apply suggested changes

* Bump pysmarlaapi version and reevaluate quality scale

* Focus on switch platform

* Bump pysmarlaapi version

* Change default name of device

* Code refactoring

* Removed obsolete reload function

* Code refactoring and clean up

* Bump pysmarlaapi version

* Refactoring and changed access token format

* Fix tests for smarla config_flow

* Update quality_scale

* Major rework of tests and refactoring

* Bump pysmarlaapi version

* Use object equality operator when applicable

* Refactoring

* Patch both connection objects

* Refactor tests

* Fix leaking tests

* Implemented full test coverage

* Bump pysmarlaapi version

* Fix tests

* Improve tests

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-05-26 15:21:23 +02:00
Yuxin Wang
68a4e1a112 Add reconfigure config flow to APCUPSD (#143801)
* Add reconfigure config flow

* Add reconfigure config flow

* Add more subtests for wrong device

* Reduce the patch scopes

* Address comments

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-05-26 15:10:30 +02:00
epenet
d3275c3833 Use shorthand attributes in xiaomi_miio (#145614) 2025-05-26 15:07:05 +02:00
Retha Runolfsson
2d5867cab6 Add switchbot air purifier support (#144552)
* add support for air purifier

* add unit tests for air purifier

* fix aqi translation

* fix aqi translation

* add air purifier table

* fix air purifier

* remove init and add options for aqi level
2025-05-26 15:06:33 +02:00
Retha Runolfsson
49cf66269c Set quality scale to 🥇 gold for switchbot integration (#144608)
* update quality scale

* update to gold
2025-05-26 15:06:07 +02:00
G Johansson
5642d6450f Add template to command args in command_line notify (#125170)
* Add template to command args in command_line notify

* coverage

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-05-26 15:05:44 +02:00
Sid
6ddc2193d6 Add exception handler and exception translations to eheimdigital (#145476)
* Add exception handler and exception translations to eheimdigital

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-05-26 15:05:11 +02:00
Jeef
5202bbb6af Update Weatherflow wind direction icons to use Ranged Icon Translation (#140166)
* feat: Wind direction icons

* optimize funciton

* float to int

* no-verify

* pre-change for icon translation changes

---------

Co-authored-by: Jeff Stein <6491743+jeffor@users.noreply.github.com>
2025-05-26 15:05:00 +02:00
avee87
39906cf65b Add state_class to metoffice sensors (#145496)
* Add state_class to metoffice sensors

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-05-26 15:04:26 +02:00
peteS-UK
c7745e0d02 Add support for SEARCH_MEDIA feature (#143261)
* initial

* initial

* add tests

* Update for list return

* translate exception

* tests for errors

* review tweaks

* test fix

* force content_type to lowercase

* Allow media_content_type = None

* new test
2025-05-26 15:01:17 +02:00
Simone Chemelli
1c1f5a779b Cleanup non-existing climate and humidifier devices for Comelit (#144624)
* Cleanup non-existing climate and humidifier devices for Comelit

* skip removing main hub device

* add tests

* complete tests

* improve logging

* fix post rebase

* apply  review comments

* typos

* fix identifiers

* fix ruff post merge

* clean post merge
2025-05-26 14:59:01 +02:00
Jan Rieger
ba0f6c3ba2 Add translations to Unifi Protect (#145548)
* Add translations to Unifi Protect

* address comments

* change `CO` to `CO alarm`
2025-05-26 14:56:55 +02:00
Andrea Turri
150110e221 add/fix miele program ids mapping (#145577)
* add/fix miele program ids mapping

* fix mistyped keys and base translations
2025-05-26 14:56:16 +02:00
Sasha Hilton
e95e9e1a33 bump starlink-grpc-core to 1.2.3 due to API change upstream (#145261) 2025-05-26 14:47:00 +02:00
epenet
c68ab714b7 Add init type hints to XiaomiMiioEntity derived entities (#145611) 2025-05-26 14:46:07 +02:00
epenet
2d2e0d0fb9 Add init type hints to XiaomiCoordinatedMiioEntity derived entities (#145612) 2025-05-26 14:45:55 +02:00
G Johansson
970359c6a0 Empty response returns empty list in Nord Pool (#145514) 2025-05-26 14:25:07 +02:00
Markus Adrario
e22fbe553b Add Homee event platform (#145569)
* add event.py

* Add strings and code improvements

* Add tests for event

* last fixes

* fix review comments

* update test snapshot
2025-05-26 14:00:30 +02:00
Petar Petrov
87c3e2c7ce Download backup if restore fails in Z-Wave migration (#145434)
* ZWaveJS migration: Download backup if restore fails

* update test

* PR comment
2025-05-26 13:56:37 +02:00
Petro31
13a6c13b89 Allow base64_encode to support bytes and strings (#145227) 2025-05-26 13:56:11 +02:00
epenet
cc504da03a Improve type hints in XiaomiGatewayDevice derived entities (#145605) 2025-05-26 13:21:00 +02:00
Petro31
25f3ab3640 Add from_hex filter (#145229) 2025-05-26 13:16:56 +02:00
Åke Strandberg
2cf09abb4c Fulfilled quality rules - gold and platinum tiers for Miele integration (#144773)
Fulfilled quality rules - gold and platinum tiers
2025-05-26 11:24:01 +02:00
Maciej Bieniek
c1c74a6f61 Mark Shelly quality as silver (#145610) 2025-05-26 12:22:46 +03:00
Avi Miller
8f9f531dd7 Bump aiolifx to 1.1.5 to improve the identification of LIFX Luna (#145416)
Signed-off-by: Avi Miller <me@dje.li>
2025-05-26 11:22:11 +02:00
Jan Bouwhuis
34d11521c0 Fix reference to "tilt command topic" in MQTT translation strings (#145563)
* Fix reference to "tilt command topic" in MQTT translation strings

* Missed one
2025-05-26 11:13:24 +02:00
Josef Zweck
561be22a60 Disable last cleaning sensor for gs3mp model in lamarzocco (#145576)
* Disable last cleaning sensor for gs3mp model in lamarzocco

* is comparison
2025-05-26 11:13:15 +02:00
Jan Bouwhuis
301d308d5a Add payload ON and OFF options to MQTT switch subentry component (#144627)
* Add payload ON and OFF options to MQTT switch component

* Add `state_on` and `state_off` options
2025-05-26 11:12:42 +02:00
Simone Chemelli
d975135a7c Improve Bluetooth binary_sensor for Amazon Devices (#145600)
Improve blueetooth binary_sensor for Amazon Devices
2025-05-26 11:00:09 +02:00
Simone Chemelli
19ee8886d6 Add more mac-addresses for Amazon Devices autodiscovery (#145598)
* Add more mac-addresses for Amazon Devices autodiscovery

* some more
2025-05-26 10:59:13 +02:00
Maciej Bieniek
7f4cc99a3e Use sub-devices for Shelly multi-channel devices (#144100)
* Shelly RPC sub-devices

* Better varaible name

* Add get_rpc_device_info helper

* Revert channel name changes

* Use get_rpc_device_info

* Add get_rpc_device_info helper

* Use get_block_device_info

* Use helpers in the button platform

* Fix channel name and roller mode for block devices

* Fix EM3 gen1

* Fix channel name for RPC devices

* Revert test changes

* Fix/improve test_block_get_block_channel_name

* Fix test_get_rpc_channel_name_multiple_components

* Fix tests

* Fix tests

* Fix tests

* Use key instead of index to generate sub-device identifier

* Improve logic for Pro RGBWW PM

* Split channels for em1

* Better channel name

* Cleaning

* has_entity_name is True

* Add get_block_sub_device_name() function

* Improve block functions

* Add get_rpc_sub_device_name() function

* Remove _attr_name

* Remove name for button with device class

* Fix names of virtual components

* Better Input name

* Fix get_rpc_channel_name()

* Fix names for Inputs

* get_rpc_channel_name() improvement

* Better variable name

* Clean RPC functions

* Fix input_name type

* Fix test

* Fix entity_ids for Blu Trv

* Fix get_block_channel_name()

* Fix for Blu Trv, once again

* Revert name for reboot button

* Fix button tests

* Fix tests

* Fix coordinator tests

* Fix tests for cover platform

* Fix tests for event platform

* Fix entity_ids in init tests

* Fix get_block_channel_name() for lights

* Fix tests for light platform

* Fix test for logbook

* Update snapshots for number platform

* Fix tests for sensor platform

* Fix tests for switch platform

* Fix tests for utils

* Uncomment

* Fix tests for flood

* Fix Valve entity name

* Fix climate tests

* Fix test for diagnostics

* Fix tests for init

* Remove old snapshots

* Add tests for 2PM Gen3

* Add comment

* More tests

* Cleaning

* Clean fixtures

* Update tests

* Anonymize coordinates in fixtures

* Split Pro 3EM entities into sub-devices

* Make sub-device names more unique

* 3EM (gen1) does not support sub-devices

* Coverage

* Rename "device temperature" sensor to the "relay temperature"

* Update tests after rebase

* Support sub-devices for 3EM (gen1)

* Mark has-entity-name rule as done 🎉

* Rename `relay temperature` to `temperature`
2025-05-26 10:47:22 +02:00
epenet
d4333665fc Add issue trackers to requirements script exceptions (#145608) 2025-05-26 10:21:38 +02:00
TheJulianJES
ba0c03ddbb Bump ZHA to 0.0.59 (#145597) 2025-05-26 06:53:09 +02:00
Ivan Lopez Hernandez
32eb4af6ef Enable message Streaming in the Gemini integration. (#144937)
* Added streaming implementation

* Indicate the entity supports streaming

* Added tests

* Removed unused snapshots

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-05-25 21:50:55 -04:00
Josef Zweck
e4b519d77a Bump pylamarzocco to 2.0.6 (#145595) 2025-05-25 23:59:06 +02:00
Raphael Hehl
14c4cf7b63 Bump uiprotect to version 7.10.0 (#145596) 2025-05-25 23:51:52 +02:00
Paulus Schoutsen
1cc2baa95e Pipeline to stream TTS on tool call (#145477) 2025-05-25 14:59:07 -05:00
Raphael Hehl
f472bf7c87 Bump uiprotect to version 7.9.2 (#145583) 2025-05-25 18:42:02 +02:00
Joost Lekkerkerker
bc9683312e Change cooler name to fridge in SmartThings (#145590) 2025-05-25 18:40:04 +02:00
Joost Lekkerkerker
6634efa3aa Add DHCP discovery to Amazon Devices (#145587)
* Add DHCP discovery to Amazon Devices

* Add DHCP discovery to Amazon Devices

* Add DHCP discovery to Amazon Devices
2025-05-25 18:20:44 +02:00
Simone Chemelli
d0b2331a5f New integration Amazon Devices (#144422)
* New integration Amazon Devices

* apply review comments

* bump aioamazondevices

* Add notify platform

* pylance

* full coverage for coordinator tests

* cleanup imports

* Add switch platform

* update quality scale: docs items

* update quality scale: brands

* apply review comments

* fix new ruff rule

* simplify EntityDescription code

* remove additional platforms for first PR

* apply review comments

* update IQS

* apply last review comments

* snapshot update

* apply review comments

* apply review comments
2025-05-25 17:42:07 +02:00
Maciej Bieniek
46951bf223 Add returned energy sensor for Shelly RPC switch component (#145490)
* Add returned energy sensor for switch component

* Add test

* More tests

* Make returned energy sensor disabled by default
2025-05-25 16:16:55 +02:00
Marc Mueller
565f051ffc Fix aiohttp MockPayloadWriter (#145579) 2025-05-25 14:38:08 +02:00
Florian von Garrel
8c971904ca Add reauth and reconfigure to paperless (#145469)
* Add reauth and reconfigure

* Reauth and reconfigure in different functions

* Add duplicate check

* Add test for reconfigure duplicate

* Removed seconds config entry fixture
2025-05-25 14:03:13 +02:00
Josef Zweck
d0bc71752b Safe get for backflush status in lamarzocco (#145559)
* Safe get for backflush status in lamarzocco

* add correct default
2025-05-25 14:01:15 +02:00
Franck Nijhof
6b1484a7f0 Merge branch 'master' into dev 2025-05-25 10:40:31 +00:00
Joost Lekkerkerker
5eebadc730 Add SmartThings freezer and cooler temperatures (#145468) 2025-05-25 10:38:57 +02:00
tronikos
fa37bc272e Bump opower to 0.12.2 (#145573) 2025-05-25 10:37:50 +02:00
Simone Chemelli
535d128f8a Remove global registry reference in coordinator for UptimeRobot (#142938)
* Remove global registry reference in coordinator for UptimeRobot

* rework current_monitors listing

* fix logic
2025-05-25 02:03:07 +02:00
J. Nick Koston
13d530d110 Bump aiohttp to 3.12.0 (#145570) 2025-05-24 18:10:58 -05:00
Pete Sage
57f754b42b Bump aiokem to 0.5.12 (#145565) 2025-05-24 18:04:26 -05:00
Josef Zweck
1e0a2b704f Bump pylamarzocco to 2.0.5 (#145560) 2025-05-24 23:46:51 +02:00
Simone Chemelli
526a8ee31f Add preset mode to Comelit climate (#145195) 2025-05-25 00:37:21 +03:00
J. Nick Koston
ce02a5544d Bump aiohttp to 3.12.0rc1 (#145562) 2025-05-24 16:12:16 -05:00
Simon Lamon
1044a5341d Bump python-linkplay to v0.2.8 (#145550)
* Bump linkplay to v0.2.7

* Bump linkplay to v0.2.8
2025-05-24 21:53:41 +02:00
Jan Bouwhuis
a707cbc51b Fix translation strings for MQTT subentries (#145529) 2025-05-24 21:26:49 +02:00
tronikos
adf8e50313 Add data descriptions in the Android TV Remote Configure Android apps (#145537)
* Add data descriptions in the Android TV Remote Configure Android apps

* Update homeassistant/components/androidtv_remote/strings.json

---------

Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-05-24 21:20:04 +02:00
tronikos
8356bdb506 Bump androidtvremote2 to 0.2.2 (#145542) 2025-05-24 17:41:40 +02:00
Abílio Costa
5c7aa833ec Simplify ZBT-1 setup string (#145532) 2025-05-24 11:41:16 +02:00
Jan Bouwhuis
f92d14d87c Bump incomfort-client to v0.6.9 (#145546) 2025-05-24 10:53:08 +02:00
J. Nick Koston
2d3a6d780c Bump aiohttp to 3.12.0rc0 (#145540)
changelog: https://github.com/aio-libs/aiohttp/compare/v3.12.0b3...v3.12.0rc0
2025-05-24 09:52:48 +02:00
Petro31
c359765a29 Remove inactive codeowner from template integration (#145535) 2025-05-23 23:59:22 +02:00
Michael
d8ed10bcc7 Use _handle_coordinator_update() instead of own callback in Feedreader event entity (#145520)
use _handle_coordinator_update() instead of own callback
2025-05-23 21:10:26 +02:00
karwosts
19259d5cad Add read_only selectors to Statistics Options Flow (#145522) 2025-05-23 17:58:45 +02:00
epenet
102230bf9d Remove repoze.lru from license exceptions (#145519)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-05-23 17:46:09 +02:00
Jan Bouwhuis
2a38f03ec9 Add MQTT fan as entity platform on MQTT subentries (#144698) 2025-05-23 17:40:54 +02:00
Ludovic BOUÉ
e22ea85e84 Add Matter Pump device type (#145335)
* Pump status

* Pump speed

* PumpStatusRunning

* ControlModeEnum

* Add tests

* Clean code

* Update tests and sensors

* Review fixes

* Add RPM unit

* Fix for unknown value

* Update snapshot

* OperationMode

* Update snapshots

* Update snapshot

* Update tests/components/matter/test_select.py

Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>

* Handle SupplyFault bit enabled too

* Review fix

* Unmove

* Remove pump_operation_mode

* Update snapshot

---------

Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
2025-05-23 17:20:27 +02:00
Michael
ed0ff93d1e Bump py-sucks to 0.9.11 (#145518)
bump py-sucks to 0.9.11
2025-05-23 17:12:43 +02:00
Franck Nijhof
3e6473d130 2025.5.3 (#145516) 2025-05-23 17:09:32 +02:00
karwosts
7af731694f Support readonly selectors in config_flows (#129456)
* Allow disabled selectors in config flows. Show hidden options for history_stats.

* fix tests

* use optional instead of required

* rename flag to readonly

* rename to read_only

* Update to use read_only field as part of selector definition

* lint fix

* Fix test

* All selectors
2025-05-23 17:05:43 +02:00
epenet
83ec45e4fc Use runtime_data in xiaomi_miio (#145517)
* Use runtime_data in xiaomi_miio

* Reduce changes
2025-05-23 17:03:33 +02:00
Michael
086e97821f Add automatic backup event entity to Home Assistant Backup system (#145350)
* add automatic backup event entity

* add tests

* fix test

* Apply suggestions from code review

Co-authored-by: Josef Zweck <josef@zweck.dev>

* implement _handle_coordinator_update

* add translations for event attributes

* simplify condition

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

---------

Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-05-23 17:01:57 +02:00
Petro31
5048d1512c Add trigger based template cover (#145455)
* Add trigger based template cover

* address comments

* update position template in test
2025-05-23 16:32:21 +02:00
Denis Shulyaka
199c565bf2 Add Anthropic Claude 4 support (#145505)
Add Claude 4 support

Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-05-23 10:31:44 -04:00
epenet
cbeefdaf26 Mark humidifier methods and properties as mandatory in pylint plugin (#145507) 2025-05-23 16:26:22 +02:00
Michael
4747de4703 Don't manipulate hvac modes based on device active mode in AVM Fritz!SmartHome (#145513) 2025-05-23 16:12:13 +02:00
Franck Nijhof
9a183bc16a Bump version to 2025.5.3 2025-05-23 14:03:47 +00:00
Robert Resch
e540247c14 Bump deebot-client to 13.2.1 (#145492) 2025-05-23 14:03:02 +00:00
rappenze
0aef8b58d8 Bump pyfibaro to 0.8.3 (#145488) 2025-05-23 14:03:01 +00:00
tronikos
f0501f917b Fix strings related to Google search tool in Google AI (#145480) 2025-05-23 14:02:59 +00:00
tronikos
97004e13cb Make Gemma models work in Google AI (#145479)
* Make Gemma models work in Google AI

* move one line to be improve readability
2025-05-23 14:02:58 +00:00
tronikos
f867a0af24 Bump opower to 0.12.1 (#145464) 2025-05-23 14:02:57 +00:00
Joost Lekkerkerker
d3b3839ffa Bump pysmartthings to 3.2.3 (#145444) 2025-05-23 14:02:56 +00:00
starkillerOG
1a227d6a10 Reolink fix device migration (#145443) 2025-05-23 14:02:54 +00:00
Joost Lekkerkerker
fc8c403a3a Bump yt-dlp to 2025.05.22 (#145441) 2025-05-23 14:02:53 +00:00
Josef Zweck
c1bf596eba Mark backflush binary sensor not supported for GS3 MP in lamarzocco (#145406) 2025-05-23 14:02:52 +00:00
Michael
63f69a9e3d Bump py-synologydsm-api to 2.7.2 (#145403)
bump py-synologydsm-api to 2.7.2
2025-05-23 14:02:51 +00:00
Josef Zweck
e13b014b6f Bump pylamarzocco to 2.0.4 (#145402) 2025-05-23 14:02:49 +00:00
c0ffeeca7
be0d4d926c OTBR: remove links to obsolete multiprotocol docs (#145394) 2025-05-23 14:02:48 +00:00
Raj Laud
2403fff81f Bump pysqueezebox to v0.12.1 (#145384) 2025-05-23 14:02:47 +00:00
Andy
8c475787cc Fix: Revert Ecovacs mower total_stats_area unit to square meters (#145380) 2025-05-23 14:02:45 +00:00
peteS-UK
d9fe1edd82 Add initial coordinator refresh for players in Squeezebox (#145347)
* initial

* add test for new player
2025-05-23 14:02:44 +00:00
Michael
f5cf64700a Fix limit of shown backups on Synology DSM location (#145342) 2025-05-23 14:02:43 +00:00
Josef Zweck
777b04d7a5 Handle more exceptions in azure_storage (#145320) 2025-05-23 14:02:41 +00:00
Josef Zweck
9fc78ed4e2 Add cloud as after_dependency to onedrive (#145301) 2025-05-23 14:02:40 +00:00
Matthew FitzGerald-Chamberlain
d03af549d4 Bump pyaprilaire to 0.9.0 (#145260) 2025-05-23 14:02:39 +00:00
G Johansson
d91f01243c Bump holidays to 0.73 (#145238) 2025-05-23 14:02:38 +00:00
Martin Hjelmare
5094208db6 Fix Z-Wave config entry unique id after NVM restore (#145221)
* Fix Z-Wave config entry unique id after NVM restore

* Remove stale comment
2025-05-23 14:01:37 +00:00
Simone Chemelli
006f66a841 Bump aiocomelit to 0.12.3 (#145209) 2025-05-23 14:01:36 +00:00
Maikel Punie
64b7d77840 Bump velbusaio to 2025.5.0 (#145198) 2025-05-23 14:01:35 +00:00
Martin Hjelmare
abf6a809b8 Fix Z-Wave unique id update during controller migration (#145185) 2025-05-23 14:01:33 +00:00
Martin Hjelmare
1b7dd205c7 Improve Z-Wave config flow tests (#144871)
* Improve Z-Wave config flow tests

* Fix test

* Use identify check for result type
2025-05-23 14:01:32 +00:00
Keilin Bickar
3e00366a61 Bump sense-energy to 0.13.8 (#145156) 2025-05-23 13:50:34 +00:00
karwosts
a17275b559 Fix history_stats with sliding window that ends before now (#145117) 2025-05-23 13:50:33 +00:00
Jan-Philipp Benecke
9534a919ce Add missing device condition translations to lock component (#145104) 2025-05-23 13:45:44 +00:00
Joost Lekkerkerker
422dbfef88 Map auto to heat_cool for thermostat in SmartThings (#145098) 2025-05-23 13:45:43 +00:00
Robert Resch
8e44684a61 Fix proberly Ecovacs mower area sensors (#145078) 2025-05-23 13:45:41 +00:00
Manu
642e7fd487 Bump aiontfy to 0.5.2 (#145044) 2025-05-23 13:45:40 +00:00
peteS-UK
9bb9132e7b Fix album and artist returning "None" rather than None for Squeezebox media player. (#144971)
* fix

* snapshot update

* cast type
2025-05-23 13:45:39 +00:00
J. Nick Koston
41be82f167 Bump ESPHome stable BLE version to 2025.5.0 (#144857) 2025-05-23 13:45:37 +00:00
Marc Hörsken
47140e14d9 Postpone update in WMSPro after service call (#144836)
* Reduce stress on WMS WebControl pro with higher scan interval

Avoid delays and connection issues due to overloaded hub.
Fixes #133832 and #134413

* Schedule an entity state update after performing an action

Avoid delaying immediate status updates, e.g. on/off changes.

* Replace scheduled state updates with delayed action completion

Suggested-by: joostlek
2025-05-23 13:45:36 +00:00
TheOneValen
926502b0f1 Allow image send with read-only access (matrix notify) (#144819) 2025-05-23 13:45:35 +00:00
disforw
78351ff7a7 Fix QNAP fail to load (#144675)
* Update coordinator.py

* Update coordinator.py

@peternash

* Update coordinator.py

* Update coordinator.py

* Update coordinator.py

* Update coordinator.py
2025-05-23 13:45:33 +00:00
wuede
c333726867 Netatmo: do not fail on schedule updates (#142933)
* do not fail on schedule updates

* add test to check that the store data remains unchanged
2025-05-23 13:45:32 +00:00
starkillerOG
fc2fe32f34 Reolink fix device migration (#145443) 2025-05-23 15:33:03 +02:00
epenet
528a509479 Mark light methods and properties as mandatory in pylint plugin (#145510) 2025-05-23 14:28:41 +01:00
Franck Nijhof
bca4793c69 Add concentration conversion support for mg/m³ (#145325) 2025-05-23 14:24:18 +01:00
Josef Zweck
0c9b1b5c58 Add cloud as after_dependency to onedrive (#145301) 2025-05-23 15:07:06 +02:00
Robert Resch
7bf4239789 Bump deebot-client to 13.2.1 (#145492) 2025-05-23 14:54:18 +02:00
epenet
71ac2d3d75 Improve type hints in xiaomi_miio humidifier (#145506) 2025-05-23 14:54:09 +02:00
Denis Shulyaka
f019e8a36c Bump Anthropic library to 0.52.0 (#145494) 2025-05-23 14:48:54 +02:00
J. Nick Koston
44560dd298 Bump aiohttp to 3.12.0b3 (#145358) 2025-05-23 14:44:47 +02:00
Jan Bouwhuis
e8ea5c9d62 Add MQTT cover as entity platform on MQTT subentries (#144381)
* Add MQTT cover as entity platform on MQTT subentries

* Revert change vol.Coerce wrappers on cover schema

* Fix template validator and cleanup redundant validators

* Cleanup more redundant validators
2025-05-23 14:25:00 +02:00
Jan Bouwhuis
17297ab929 Improve mqtt subentry selector validation and remove redundant validators (#145499) 2025-05-23 13:23:36 +02:00
rappenze
041c09380b Bump pyfibaro to 0.8.3 (#145488) 2025-05-23 12:05:13 +02:00
Markus Lanthaler
553d420db9 Add support for Tuya Wireless Switch entity (#123284)
Add support for Tuya Wireless Switch entity
2025-05-23 08:42:09 +02:00
Joost Lekkerkerker
3f99a0bb65 Add diagnostics to Paperless-ngx (#145465)
* Add diagnostics to Paperless-ngx

* Add diagnostics to Paperless-ngx
2025-05-23 08:09:54 +02:00
Joost Lekkerkerker
c3d318ff51 Add paperless-ngx to strict typing (#145466) 2025-05-23 08:08:44 +02:00
Erik Montnemery
19345b0e18 Prefer to create backups in local storage if selected (#145331) 2025-05-23 08:00:35 +02:00
tronikos
e13abf2034 Make Gemma models work in Google AI (#145479)
* Make Gemma models work in Google AI

* move one line to be improve readability
2025-05-22 22:02:30 -07:00
tronikos
61248c561d Fix strings related to Google search tool in Google AI (#145480) 2025-05-22 22:01:48 -07:00
epenet
8561721faf Add pytest/codecov to forbidden runtime dependencies (#145447)
Add pytest/codecov to forbidden runtime packages
2025-05-22 23:15:21 +02:00
Manu
2f318927bc Add pending damage and pending quest items sensors (#145449)
Add pending damage and quest items sensors
2025-05-22 23:10:49 +02:00
tronikos
a15572bb8c Bump opower to 0.12.1 (#145464) 2025-05-22 22:22:20 +02:00
Bonne Eggleston
b532776d78 Make Powerwall energy sensors TOTAL_INCREASING to fix hardware swaps (#145165) 2025-05-22 14:49:39 -05:00
Abílio Costa
4ad34c57b5 Replace empty mock in GoalZero tests (#145463) 2025-05-22 20:22:09 +01:00
Abílio Costa
228beacca8 Add default sensor data for Tesla Wall Connector tests (#145462) 2025-05-22 21:20:57 +02:00
Norbert Rittel
c130a9f31c Fix typo in reauth_confirm description of metoffice (#145458) 2025-05-22 21:12:37 +02:00
Michael
622ab922b5 Add configuration url to Immich device info (#145456)
add configuration url to device info
2025-05-22 21:09:28 +02:00
epenet
6de2258325 Mark device_tracker methods and properties as mandatory in pylint plugin (#145309) 2025-05-22 19:15:00 +01:00
jz-v
d8e0be69d1 Add HomeKit thermostat fan state mapping for preheating, defrosting (#145353)
Co-authored-by: J. Nick Koston <nick@koston.org>
2025-05-22 11:57:01 -05:00
Petro31
4ee9fdc9fb Add AbstractTemplateVacuum to prepare for trigger based template vacuums (#144990)
* Add AbstractTemplateVacuum

* fix typo from copypaste

* update after rebase
2025-05-22 17:50:26 +02:00
Petro31
a8823cc1d1 Add AbstractTempleAlarmControlPanel class to prepare for trigger based template alarm control panels (#144974)
* Add AbstractTempleAlarmControlPanel class

* update after rebase

* remove unused list
2025-05-22 17:50:15 +02:00
Petro31
83ee9e9540 Add AbstractTemplate cover to prepare for trigger based template covers (#144907)
* Add AbstractTemplate cover to prepare for trigger based template covers

* add reflection and improve test coverage

* update class after rebase

* remove test
2025-05-22 17:49:50 +02:00
Petro31
9a74390143 Add AbstractTemplateLock to prepare for trigger based template locks (#144978)
* Add AbstractTemplateLock

* update after rebase
2025-05-22 17:33:57 +02:00
Joost Lekkerkerker
64d6552890 Bump pysmartthings to 3.2.3 (#145444) 2025-05-22 17:26:59 +02:00
Joost Lekkerkerker
65ebdb4292 Bump yt-dlp to 2025.05.22 (#145441) 2025-05-22 17:26:04 +02:00
Petro31
7a55abaa42 Add AbstractTemplateFan class in preparation for trigger based entity (#144968)
* Add AbstractTemplateFan class in preparation for trigger based entity

* update after rebase
2025-05-22 17:18:48 +02:00
dalan
8f05a639f3 HomeKit Bridge integration: Adding h264_qsv as valid VIDEO_CODEC option (#145448) 2025-05-22 09:52:58 -05:00
Franck Nijhof
f66feabaaf 2025.5.2 (#145072)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
Co-authored-by: Allen Porter <allen.porter@gmail.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: TimL <tl@smlight.tech>
Co-authored-by: Seweryn Zeman <seweryn.zeman@jazzy.pro>
Co-authored-by: hahn-th <15319212+hahn-th@users.noreply.github.com>
Co-authored-by: Luke Lashley <conway220@gmail.com>
Co-authored-by: starkillerOG <starkiller.og@gmail.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Arie Catsman <120491684+catsmanac@users.noreply.github.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com>
Co-authored-by: Ruben van Dijk <15885455+RubenNL@users.noreply.github.com>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: Simone Chemelli <simone.chemelli@gmail.com>
Co-authored-by: Thomas55555 <59625598+Thomas55555@users.noreply.github.com>
Co-authored-by: Øyvind Matheson Wergeland <oyvind@wergeland.org>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
Co-authored-by: Brett Adams <Bre77@users.noreply.github.com>
Co-authored-by: rjblake <richard.blake@gmail.com>
Co-authored-by: Daniel Hjelseth Høyer <github@dahoiv.net>
Co-authored-by: Matthias Alphart <farmio@alphart.net>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Odd Stråbø <oddstr13@openshell.no>
Co-authored-by: puddly <32534428+puddly@users.noreply.github.com>
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
fix privacy mode availability for NVR IPC cams (#144569)
fix enphase_envoy diagnostics home endpoint name (#144634)
Close Octoprint aiohttp session on unload (#144670)
Fix strings typo for Comelit (#144672)
Fix wrong state in Husqvarna Automower (#144684)
Fix Netgear handeling of missing MAC in device registry (#144722)
Fix blocking call in azure storage (#144803)
Fix Z-Wave unique id after controller reset (#144813)
Fix blocking call in azure_storage config flow (#144818)
Fix wall connector states in Teslemetry (#144855)
Fix Reolink setup when ONVIF push is unsupported (#144869)
Fix some Home Connect translation strings (#144905)
Fix unknown Pure AQI in Sensibo (#144924)
Fix Home Assistant Yellow config entry data (#144948)
Fix ESPHome entities unavailable if deep sleep enabled after entry setup (#144970)
fix from ZHA event `unique_id` (#145006)
Fix climate idle state for Comelit (#145059)
Fix fan AC mode in SmartThings AC (#145064)
Fix Ecovacs mower area sensors (#145071)
2025-05-16 23:08:52 +02:00
Franck Nijhof
0ef098a9f3 Pin rpds-py to 0.24.0 (#145074) 2025-05-16 20:40:02 +00:00
Franck Nijhof
02b028add3 Bump version to 2025.5.2 2025-05-16 19:31:36 +00:00
Robert Resch
34455f9743 Fix Ecovacs mower area sensors (#145071) 2025-05-16 19:31:15 +00:00
Joost Lekkerkerker
8c4eec231f Don't create entities for Smartthings smarttags (#145066) 2025-05-16 19:31:14 +00:00
Joost Lekkerkerker
621a14d7cc Fix fan AC mode in SmartThings AC (#145064) 2025-05-16 19:31:12 +00:00
Joost Lekkerkerker
4906e78a5c Only set suggested area for new SmartThings devices (#145063) 2025-05-16 19:31:11 +00:00
Bram Kragten
146e440d59 Update frontend to 20250516.0 (#145062) 2025-05-16 19:31:10 +00:00
Joost Lekkerkerker
e2ede3ed19 Map SmartThings auto mode correctly (#145061) 2025-05-16 19:31:09 +00:00
Simone Chemelli
b76ac68fb1 Fix climate idle state for Comelit (#145059) 2025-05-16 19:31:07 +00:00
Joost Lekkerkerker
0691ad9362 Set SmartThings oven setpoint to unknown if its 1 Fahrenheit (#145038) 2025-05-16 19:31:06 +00:00
Joost Lekkerkerker
715f116954 Bump pySmartThings to 3.2.2 (#145033) 2025-05-16 19:31:05 +00:00
puddly
9f0db98745 Strip _CLIENT suffix from ZHA event unique_id (#145006) 2025-05-16 19:31:03 +00:00
Odd Stråbø
0ba55c31e8 Fix ESPHome entities unavailable if deep sleep enabled after entry setup (#144970) 2025-05-16 19:31:02 +00:00
Robert Resch
19b7cfbd4a Bump deebot-client to 13.2.0 (#144957) 2025-05-16 19:31:01 +00:00
Erik Montnemery
a9520888cf Fix Home Assistant Yellow config entry data (#144948) 2025-05-16 19:31:00 +00:00
Matthias Alphart
f086f4a955 Ignore Fronius Gen24 firmware 1.35.4-1 SSL verification issue for new setups (#144940) 2025-05-16 19:30:59 +00:00
G Johansson
a657964c25 Fix unknown Pure AQI in Sensibo (#144924)
* Fix unknown Pure AQI in Sensibo

* Fix mypy
2025-05-16 19:30:57 +00:00
Daniel Hjelseth Høyer
543104b36c Update mill library 0.12.5 (#144911)
* Update mill library 0.12.5

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Update mill library 0.12.5

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

---------

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2025-05-16 19:30:56 +00:00
Daniel Hjelseth Høyer
bf1d2069e4 Update Tibber lib 0.31.2 (#144908)
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
2025-05-16 19:30:55 +00:00
rjblake
e5e1c9fb05 Fix some Home Connect translation strings (#144905)
* Update strings.json

Corrected program names:
changed "Pre_rinse" to "Pre-Rinse"
changed "Kurz 60°C" to "Speed 60°C"

Both match the Home Connect app; although the UK documentation refers to "Speed 60°C" as "Quick 60°C"

* Adjust casing

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-05-16 19:30:53 +00:00
starkillerOG
4c4be88323 Fix Reolink setup when ONVIF push is unsupported (#144869)
* Fix setup when ONVIF push is not supported

* fix styling
2025-05-16 19:30:52 +00:00
Brett Adams
5a83627dc5 Fix wall connector states in Teslemetry (#144855)
* Fix wall connector

* Update snapshot
2025-05-16 19:30:51 +00:00
Allen Porter
3123a7b168 Bump ical to 9.2.4 (#144852) 2025-05-16 19:30:50 +00:00
Luke Lashley
8161ce6ea8 Bump python-snoo to 0.6.6 (#144849) 2025-05-16 19:30:49 +00:00
Josef Zweck
d9cbd1b65f Bump pylamarzocco to 2.0.3 (#144825) 2025-05-16 19:30:47 +00:00
Josef Zweck
b7c07209b8 Fix blocking call in azure_storage config flow (#144818)
* Fix blocking call in azure_storage config flow

* Fix blocking call in azure_storage config_flow as well

* move session getting to event flow
2025-05-16 19:30:46 +00:00
Martin Hjelmare
6c3a4f17f0 Fix Z-Wave unique id after controller reset (#144813) 2025-05-16 19:30:45 +00:00
Josef Zweck
d82feb807f Fix blocking call in azure storage (#144803) 2025-05-16 19:30:43 +00:00
Jan Bouwhuis
c373fa9296 Do not show an empty component name on MQTT device subentries not as None if it is not set (#144792) 2025-05-16 19:30:42 +00:00
starkillerOG
139b48440f Cleanup wrongly combined Reolink devices (#144771) 2025-05-16 19:30:41 +00:00
Joost Lekkerkerker
9de1d3b143 Fill in Plaato URL via placeholders (#144754) 2025-05-16 19:29:35 +00:00
Martin Hjelmare
b69ebdaecb Repair Z-Wave unknown controller (#144738)
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-05-16 19:23:25 +00:00
starkillerOG
f25e50b017 Fix Netgear handeling of missing MAC in device registry (#144722) 2025-05-16 19:23:24 +00:00
Simone Chemelli
a4a7601f9f Bump aiocomelit to 0.12.1 (#144720) 2025-05-16 19:23:22 +00:00
Øyvind Matheson Wergeland
41a503f76f Bump gcal-sync to 7.0.1 (#144718)
Co-authored-by: Allen Porter <allen.porter@gmail.com>
2025-05-16 19:23:21 +00:00
Allen Porter
f1a3d62db2 Bump ical to 9.2.2 (#144713) 2025-05-16 19:23:20 +00:00
Allen Porter
e465276464 Bump voluptuous-openapi to 0.1.0 (#144703) 2025-05-16 19:23:18 +00:00
Thomas55555
47b45444eb Fix wrong state in Husqvarna Automower (#144684) 2025-05-16 19:22:02 +00:00
Simone Chemelli
cf0911cc56 Avoid closing shared session for Comelit (#144682) 2025-05-16 19:22:00 +00:00
Simone Chemelli
da79d5b2e3 Fix strings typo for Comelit (#144672) 2025-05-16 19:21:59 +00:00
G Johansson
358b0c1c17 Bump holidays to 0.72 (#144671) 2025-05-16 19:21:58 +00:00
Ruben van Dijk
543348fe58 Close Octoprint aiohttp session on unload (#144670) 2025-05-16 19:21:57 +00:00
Simon Lamon
0635856761 Bump python-linkplay to v0.2.5 (#144666)
Bump linkplay to 0.2.5
2025-05-16 19:21:55 +00:00
Allen Porter
081afe6034 Bump ical to 9.2.1 (#144642) 2025-05-16 19:21:54 +00:00
Arie Catsman
ca14322227 bump pyenphase to 1.26.1 (#144641) 2025-05-16 19:21:53 +00:00
Josef Zweck
a54816a6e5 Bump pylamarzocco to 2.0.2 (#144635)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-05-16 19:21:51 +00:00
Arie Catsman
27db4e90b5 fix enphase_envoy diagnostics home endpoint name (#144634) 2025-05-16 19:21:50 +00:00
J. Nick Koston
e9cc624d93 Mark inkbird coordinator as not needing connectable (#144584) 2025-05-16 19:19:59 +00:00
starkillerOG
5a95f43992 Bump reolink_aio to 0.13.3 (#144583) 2025-05-16 19:19:58 +00:00
J. Nick Koston
36a35132c0 Bump aiodiscover to 2.7.0 (#144571) 2025-05-16 19:19:57 +00:00
starkillerOG
2fbc75f89b Reolink fix privacy mode availability for NVR IPC cams (#144569)
* Correct "available" for IPC cams

* Check privacy mode when updating
2025-05-16 19:19:56 +00:00
Luke Lashley
48aa6be889 Don't scale Roborock mop Path (#144421)
don't scale mop path
2025-05-16 19:19:55 +00:00
hahn-th
bde04bc47b Doorbell Event is fired just once in homematicip_cloud (#144357)
* fire event if event type if correct

* Fix requested changes
2025-05-16 19:19:53 +00:00
Seweryn Zeman
7d163aa659 Removed unused file_id param from open_ai_conversation request (#143878) 2025-05-16 19:19:52 +00:00
TimL
010b044379 Allow dns hostnames to be retained for SMLIGHT user flow. (#142514)
* Dont overwrite host with local IP

* adjust test for user flow change
2025-05-16 19:19:50 +00:00
Franck Nijhof
00627b82e0 2025.5.1 (#144564) 2025-05-09 17:03:40 +02:00
Franck Nijhof
13aba6201e Bump version to 2025.5.1 2025-05-09 13:29:29 +00:00
starkillerOG
f392e0c1c7 Prevent errors during cleaning of connections/identifiers in device registry (#144558) 2025-05-09 13:28:33 +00:00
starkillerOG
181eca6c82 Reolink clean device registry mac (#144554) 2025-05-09 13:28:32 +00:00
Bram Kragten
196d923ac6 Update frontend to 20250509.0 (#144549) 2025-05-09 13:28:30 +00:00
Josef Zweck
4ad387c967 Fix statistics coordinator subscription for lamarzocco (#144541) 2025-05-09 13:28:29 +00:00
J. Nick Koston
cb475bf153 Bump aiodns to 3.4.0 (#144511) 2025-05-09 13:28:28 +00:00
Michael
47acceea08 Fix removing of smarthome templates on startup of AVM Fritz!SmartHome integration (#144506) 2025-05-09 13:28:26 +00:00
J. Nick Koston
fd6fb7e3bc Bump forecast-solar to 4.2.0 (#144502) 2025-05-09 13:28:25 +00:00
Erik Montnemery
30f7e9b441 Don't encrypt or decrypt unknown files in backup archives (#144495) 2025-05-09 13:28:24 +00:00
Matthias Alphart
a8beec2691 Ignore Fronius Gen24 firmware 1.35.4-1 SSL verification issue (#144463) 2025-05-09 13:28:23 +00:00
Fredrik Erlandsson
23244fb79f Fix point import error (#144462)
* fix import error

* fix failing tests

* Apply suggestions from code review

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-05-09 13:28:22 +00:00
Martin Hjelmare
e5c56629e2 Fix Z-Wave reset accumulated values button entity category (#144459) 2025-05-09 13:28:20 +00:00
Josef Zweck
a793503c8a Bump pylamarzocco to 2.0.1 (#144454) 2025-05-09 13:28:19 +00:00
DukeChocula
054c7a0adc Add LAP-V102S-AUSR to VeSync (#144437)
Update const.py

Added LAP-V102S-AUSR to Vital 100S
2025-05-09 13:28:18 +00:00
Tamer Wahba
6eb2d1aa7c fix homekit air purifier temperature sensor to convert unit (#144435) 2025-05-09 13:28:16 +00:00
Martin Hjelmare
619fdea5df Fix Z-Wave restore nvm command to wait for driver ready (#144413) 2025-05-09 13:28:15 +00:00
2794 changed files with 117903 additions and 22522 deletions

View File

@@ -1,15 +1,14 @@
name: Report an issue with Home Assistant Core
description: Report an issue with Home Assistant Core.
type: Bug
body:
- type: markdown
attributes:
value: |
This issue form is for reporting bugs only!
If you have a feature or enhancement request, please use the [feature request][fr] section of our [Community Forum][fr].
If you have a feature or enhancement request, please [request them here instead][fr].
[fr]: https://community.home-assistant.io/c/feature-requests
[fr]: https://github.com/orgs/home-assistant/discussions
- type: textarea
validations:
required: true

View File

@@ -10,8 +10,8 @@ contact_links:
url: https://www.home-assistant.io/help
about: We use GitHub for tracking bugs, check our website for resources on getting help.
- name: Feature Request
url: https://community.home-assistant.io/c/feature-requests
about: Please use our Community Forum for making feature requests.
url: https://github.com/orgs/home-assistant/discussions
about: Please use this link to request new features or enhancements to existing features.
- name: I'm unsure where to go
url: https://www.home-assistant.io/join-chat
about: If you are unsure where to go, then joining our chat is recommended; Just ask!

View File

@@ -94,7 +94,7 @@ jobs:
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@v9
uses: dawidd6/action-download-artifact@v11
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/frontend
@@ -105,10 +105,10 @@ jobs:
- name: Download nightly wheels of intents
if: needs.init.outputs.channel == 'dev'
uses: dawidd6/action-download-artifact@v9
uses: dawidd6/action-download-artifact@v11
with:
github_token: ${{secrets.GITHUB_TOKEN}}
repo: home-assistant/intents-package
repo: OHF-Voice/intents-package
branch: main
workflow: nightly.yaml
workflow_conclusion: success
@@ -324,7 +324,7 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Install Cosign
uses: sigstore/cosign-installer@v3.8.2
uses: sigstore/cosign-installer@v3.9.1
with:
cosign-release: "v2.2.3"
@@ -509,7 +509,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker image
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: . # So action will not pull the repository again
file: ./script/hassfest/docker/Dockerfile
@@ -522,7 +522,7 @@ jobs:
- name: Push Docker image
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
id: push
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: . # So action will not pull the repository again
file: ./script/hassfest/docker/Dockerfile
@@ -531,7 +531,7 @@ jobs:
- name: Generate artifact attestation
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
uses: actions/attest-build-provenance@db473fddc028af60658334401dc6fa3ffd8669fd # v2.3.0
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
with:
subject-name: ${{ env.HASSFEST_IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }}

View File

@@ -37,10 +37,10 @@ on:
type: boolean
env:
CACHE_VERSION: 2
CACHE_VERSION: 3
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 1
HA_SHORT_VERSION: "2025.6"
HA_SHORT_VERSION: "2025.7"
DEFAULT_PYTHON: "3.13"
ALL_PYTHON_VERSIONS: "['3.13']"
# 10.3 is the oldest supported version
@@ -360,7 +360,7 @@ jobs:
- name: Run ruff
run: |
. venv/bin/activate
pre-commit run --hook-stage manual ruff --all-files --show-diff-on-failure
pre-commit run --hook-stage manual ruff-check --all-files --show-diff-on-failure
env:
RUFF_OUTPUT_FORMAT: github

View File

@@ -24,11 +24,11 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.28.18
uses: github/codeql-action/init@v3.29.0
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.28.18
uses: github/codeql-action/analyze@v3.29.0
with:
category: "/language:python"

View File

@@ -0,0 +1,385 @@
name: Auto-detect duplicate issues
# yamllint disable-line rule:truthy
on:
issues:
types: [labeled]
permissions:
issues: write
models: read
jobs:
detect-duplicates:
runs-on: ubuntu-latest
steps:
- name: Check if integration label was added and extract details
id: extract
uses: actions/github-script@v7.0.1
with:
script: |
// Debug: Log the event payload
console.log('Event name:', context.eventName);
console.log('Event action:', context.payload.action);
console.log('Event payload keys:', Object.keys(context.payload));
// Check the specific label that was added
const addedLabel = context.payload.label;
if (!addedLabel) {
console.log('No label found in labeled event payload');
core.setOutput('should_continue', 'false');
return;
}
console.log(`Label added: ${addedLabel.name}`);
if (!addedLabel.name.startsWith('integration:')) {
console.log('Added label is not an integration label, skipping duplicate detection');
core.setOutput('should_continue', 'false');
return;
}
console.log(`Integration label added: ${addedLabel.name}`);
let currentIssue;
let integrationLabels = [];
try {
const issue = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number
});
currentIssue = issue.data;
// Check if potential-duplicate label already exists
const hasPotentialDuplicateLabel = currentIssue.labels
.some(label => label.name === 'potential-duplicate');
if (hasPotentialDuplicateLabel) {
console.log('Issue already has potential-duplicate label, skipping duplicate detection');
core.setOutput('should_continue', 'false');
return;
}
integrationLabels = currentIssue.labels
.filter(label => label.name.startsWith('integration:'))
.map(label => label.name);
} catch (error) {
core.error(`Failed to fetch issue #${context.payload.issue.number}:`, error.message);
core.setOutput('should_continue', 'false');
return;
}
// Check if we've already posted a duplicate detection comment recently
let comments;
try {
comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
per_page: 10
});
} catch (error) {
core.error('Failed to fetch comments:', error.message);
// Continue anyway, worst case we might post a duplicate comment
comments = { data: [] };
}
// Check if we've already posted a duplicate detection comment
const recentDuplicateComment = comments.data.find(comment =>
comment.user && comment.user.login === 'github-actions[bot]' &&
comment.body.includes('<!-- workflow: detect-duplicate-issues -->')
);
if (recentDuplicateComment) {
console.log('Already posted duplicate detection comment, skipping');
core.setOutput('should_continue', 'false');
return;
}
core.setOutput('should_continue', 'true');
core.setOutput('current_number', currentIssue.number);
core.setOutput('current_title', currentIssue.title);
core.setOutput('current_body', currentIssue.body);
core.setOutput('current_url', currentIssue.html_url);
core.setOutput('integration_labels', JSON.stringify(integrationLabels));
console.log(`Current issue: #${currentIssue.number}`);
console.log(`Integration labels: ${integrationLabels.join(', ')}`);
- name: Fetch similar issues
id: fetch_similar
if: steps.extract.outputs.should_continue == 'true'
uses: actions/github-script@v7.0.1
env:
INTEGRATION_LABELS: ${{ steps.extract.outputs.integration_labels }}
CURRENT_NUMBER: ${{ steps.extract.outputs.current_number }}
with:
script: |
const integrationLabels = JSON.parse(process.env.INTEGRATION_LABELS);
const currentNumber = parseInt(process.env.CURRENT_NUMBER);
if (integrationLabels.length === 0) {
console.log('No integration labels found, skipping duplicate detection');
core.setOutput('has_similar', 'false');
return;
}
// Use GitHub search API to find issues with matching integration labels
console.log(`Searching for issues with integration labels: ${integrationLabels.join(', ')}`);
// Build search query for issues with any of the current integration labels
const labelQueries = integrationLabels.map(label => `label:"${label}"`);
// Calculate date 6 months ago
const sixMonthsAgo = new Date();
sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
const dateFilter = `created:>=${sixMonthsAgo.toISOString().split('T')[0]}`;
let searchQuery;
if (labelQueries.length === 1) {
searchQuery = `repo:${context.repo.owner}/${context.repo.repo} is:issue ${labelQueries[0]} ${dateFilter}`;
} else {
searchQuery = `repo:${context.repo.owner}/${context.repo.repo} is:issue (${labelQueries.join(' OR ')}) ${dateFilter}`;
}
console.log(`Search query: ${searchQuery}`);
let result;
try {
result = await github.rest.search.issuesAndPullRequests({
q: searchQuery,
per_page: 15,
sort: 'updated',
order: 'desc'
});
} catch (error) {
core.error('Failed to search for similar issues:', error.message);
if (error.status === 403 && error.message.includes('rate limit')) {
core.error('GitHub API rate limit exceeded');
}
core.setOutput('has_similar', 'false');
return;
}
// Filter out the current issue, pull requests, and newer issues (higher numbers)
const similarIssues = result.data.items
.filter(item =>
item.number !== currentNumber &&
!item.pull_request &&
item.number < currentNumber // Only include older issues (lower numbers)
)
.map(item => ({
number: item.number,
title: item.title,
body: item.body,
url: item.html_url,
state: item.state,
createdAt: item.created_at,
updatedAt: item.updated_at,
comments: item.comments,
labels: item.labels.map(l => l.name)
}));
console.log(`Found ${similarIssues.length} issues with matching integration labels`);
console.log('Raw similar issues:', JSON.stringify(similarIssues.slice(0, 3), null, 2));
if (similarIssues.length === 0) {
console.log('No similar issues found, setting has_similar to false');
core.setOutput('has_similar', 'false');
return;
}
console.log('Similar issues found, setting has_similar to true');
core.setOutput('has_similar', 'true');
// Clean the issue data to prevent JSON parsing issues
const cleanedIssues = similarIssues.slice(0, 15).map(item => {
// Handle body with improved truncation and null handling
let cleanBody = '';
if (item.body && typeof item.body === 'string') {
// Remove control characters
const cleaned = item.body.replace(/[\u0000-\u001F\u007F-\u009F]/g, '');
// Truncate to 1000 characters and add ellipsis if needed
cleanBody = cleaned.length > 1000
? cleaned.substring(0, 1000) + '...'
: cleaned;
}
return {
number: item.number,
title: item.title.replace(/[\u0000-\u001F\u007F-\u009F]/g, ''), // Remove control characters
body: cleanBody,
url: item.url,
state: item.state,
createdAt: item.createdAt,
updatedAt: item.updatedAt,
comments: item.comments,
labels: item.labels
};
});
console.log(`Cleaned issues count: ${cleanedIssues.length}`);
console.log('First cleaned issue:', JSON.stringify(cleanedIssues[0], null, 2));
core.setOutput('similar_issues', JSON.stringify(cleanedIssues));
- name: Detect duplicates using AI
id: ai_detection
if: steps.extract.outputs.should_continue == 'true' && steps.fetch_similar.outputs.has_similar == 'true'
uses: actions/ai-inference@v1.1.0
with:
model: openai/gpt-4o
system-prompt: |
You are a Home Assistant issue duplicate detector. Your task is to identify TRUE DUPLICATES - issues that report the EXACT SAME problem, not just similar or related issues.
CRITICAL: An issue is ONLY a duplicate if:
- It describes the SAME problem with the SAME root cause
- Issues about the same integration but different problems are NOT duplicates
- Issues with similar symptoms but different causes are NOT duplicates
Important considerations:
- Open issues are more relevant than closed ones for duplicate detection
- Recently updated issues may indicate ongoing work or discussion
- Issues with more comments are generally more relevant and active
- Older closed issues might be resolved differently than newer approaches
- Consider the time between issues - very old issues may have different contexts
Rules:
1. ONLY mark as duplicate if the issues describe IDENTICAL problems
2. Look for issues that report the same problem or request the same functionality
3. Different error messages = NOT a duplicate (even if same integration)
4. For CLOSED issues, only mark as duplicate if they describe the EXACT same problem
5. For OPEN issues, use a lower threshold (90%+ similarity)
6. Prioritize issues with higher comment counts as they indicate more activity/relevance
7. When in doubt, do NOT mark as duplicate
8. Return ONLY a JSON array of issue numbers that are duplicates
9. If no duplicates are found, return an empty array: []
10. Maximum 5 potential duplicates, prioritize open issues with comments
11. Consider the age of issues - prefer recent duplicates over very old ones
Example response format:
[1234, 5678, 9012]
prompt: |
Current issue (just created):
Title: ${{ steps.extract.outputs.current_title }}
Body: ${{ steps.extract.outputs.current_body }}
Other issues to compare against (each includes state, creation date, last update, and comment count):
${{ steps.fetch_similar.outputs.similar_issues }}
Analyze these issues and identify which ones describe IDENTICAL problems and thus are duplicates of the current issue. When sorting them, consider their state (open/closed), how recently they were updated, and their comment count (higher = more relevant).
max-tokens: 100
- name: Post duplicate detection results
id: post_results
if: steps.extract.outputs.should_continue == 'true' && steps.fetch_similar.outputs.has_similar == 'true'
uses: actions/github-script@v7.0.1
env:
AI_RESPONSE: ${{ steps.ai_detection.outputs.response }}
SIMILAR_ISSUES: ${{ steps.fetch_similar.outputs.similar_issues }}
with:
script: |
const aiResponse = process.env.AI_RESPONSE;
console.log('Raw AI response:', JSON.stringify(aiResponse));
let duplicateNumbers = [];
try {
// Clean the response of any potential control characters
const cleanResponse = aiResponse.trim().replace(/[\u0000-\u001F\u007F-\u009F]/g, '');
console.log('Cleaned AI response:', cleanResponse);
duplicateNumbers = JSON.parse(cleanResponse);
// Ensure it's an array and contains only numbers
if (!Array.isArray(duplicateNumbers)) {
console.log('AI response is not an array, trying to extract numbers');
const numberMatches = cleanResponse.match(/\d+/g);
duplicateNumbers = numberMatches ? numberMatches.map(n => parseInt(n)) : [];
}
// Filter to only valid numbers
duplicateNumbers = duplicateNumbers.filter(n => typeof n === 'number' && !isNaN(n));
} catch (error) {
console.log('Failed to parse AI response as JSON:', error.message);
console.log('Raw response:', aiResponse);
// Fallback: try to extract numbers from the response
const numberMatches = aiResponse.match(/\d+/g);
duplicateNumbers = numberMatches ? numberMatches.map(n => parseInt(n)) : [];
console.log('Extracted numbers as fallback:', duplicateNumbers);
}
if (!Array.isArray(duplicateNumbers) || duplicateNumbers.length === 0) {
console.log('No duplicates detected by AI');
return;
}
console.log(`AI detected ${duplicateNumbers.length} potential duplicates: ${duplicateNumbers.join(', ')}`);
// Get details of detected duplicates
const similarIssues = JSON.parse(process.env.SIMILAR_ISSUES);
const duplicates = similarIssues.filter(issue => duplicateNumbers.includes(issue.number));
if (duplicates.length === 0) {
console.log('No matching issues found for detected numbers');
return;
}
// Create comment with duplicate detection results
const duplicateLinks = duplicates.map(issue => `- [#${issue.number}: ${issue.title}](${issue.url})`).join('\n');
const commentBody = [
'<!-- workflow: detect-duplicate-issues -->',
'### 🔍 **Potential duplicate detection**',
'',
'I\'ve analyzed similar issues and found the following potential duplicates:',
'',
duplicateLinks,
'',
'**What to do next:**',
'1. Please review these issues to see if they match your issue',
'2. If you find an existing issue that covers your problem:',
' - Consider closing this issue',
' - Add your findings or 👍 on the existing issue instead',
'3. If your issue is different or adds new aspects, please clarify how it differs',
'',
'This helps keep our issues organized and ensures similar issues are consolidated for better visibility.',
'',
'*This message was generated automatically by our duplicate detection system.*'
].join('\n');
try {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
body: commentBody
});
console.log(`Posted duplicate detection comment with ${duplicates.length} potential duplicates`);
// Add the potential-duplicate label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
labels: ['potential-duplicate']
});
console.log('Added potential-duplicate label to the issue');
} catch (error) {
core.error('Failed to post duplicate detection comment or add label:', error.message);
if (error.status === 403) {
core.error('Permission denied or rate limit exceeded');
}
// Don't throw - we've done the analysis, just couldn't post the result
}

View File

@@ -0,0 +1,193 @@
name: Auto-detect non-English issues
# yamllint disable-line rule:truthy
on:
issues:
types: [opened]
permissions:
issues: write
models: read
jobs:
detect-language:
runs-on: ubuntu-latest
steps:
- name: Check issue language
id: detect_language
uses: actions/github-script@v7.0.1
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
ISSUE_USER_TYPE: ${{ github.event.issue.user.type }}
with:
script: |
// Get the issue details from environment variables
const issueNumber = process.env.ISSUE_NUMBER;
const issueTitle = process.env.ISSUE_TITLE || '';
const issueBody = process.env.ISSUE_BODY || '';
const userType = process.env.ISSUE_USER_TYPE;
// Skip language detection for bot users
if (userType === 'Bot') {
console.log('Skipping language detection for bot user');
core.setOutput('should_continue', 'false');
return;
}
console.log(`Checking language for issue #${issueNumber}`);
console.log(`Title: ${issueTitle}`);
// Combine title and body for language detection
const fullText = `${issueTitle}\n\n${issueBody}`;
// Check if the text is too short to reliably detect language
if (fullText.trim().length < 20) {
console.log('Text too short for reliable language detection');
core.setOutput('should_continue', 'false'); // Skip processing for very short text
return;
}
core.setOutput('issue_number', issueNumber);
core.setOutput('issue_text', fullText);
core.setOutput('should_continue', 'true');
- name: Detect language using AI
id: ai_language_detection
if: steps.detect_language.outputs.should_continue == 'true'
uses: actions/ai-inference@v1.1.0
with:
model: openai/gpt-4o-mini
system-prompt: |
You are a language detection system. Your task is to determine if the provided text is written in English or another language.
Rules:
1. Analyze the text and determine the primary language of the USER'S DESCRIPTION only
2. IGNORE markdown headers (lines starting with #, ##, ###, etc.) as these are from issue templates, not user input
3. IGNORE all code blocks (text between ``` or ` markers) as they may contain system-generated error messages in other languages
4. IGNORE error messages, logs, and system output even if not in code blocks - these often appear in the user's system language
5. Consider technical terms, code snippets, URLs, and file paths as neutral (they don't indicate non-English)
6. Focus ONLY on the actual sentences and descriptions written by the user explaining their issue
7. If the user's explanation/description is in English but includes non-English error messages or logs, consider it ENGLISH
8. Return ONLY a JSON object with two fields:
- "is_english": boolean (true if the user's description is primarily in English, false otherwise)
- "detected_language": string (the name of the detected language, e.g., "English", "Spanish", "Chinese", etc.)
9. Be lenient - if the user's explanation is in English with non-English system output, it's still English
10. Common programming terms, error messages, and technical jargon should not be considered as non-English
11. If you cannot reliably determine the language, set detected_language to "undefined"
Example response:
{"is_english": false, "detected_language": "Spanish"}
prompt: |
Please analyze the following issue text and determine if it is written in English:
${{ steps.detect_language.outputs.issue_text }}
max-tokens: 50
- name: Process non-English issues
if: steps.detect_language.outputs.should_continue == 'true'
uses: actions/github-script@v7.0.1
env:
AI_RESPONSE: ${{ steps.ai_language_detection.outputs.response }}
ISSUE_NUMBER: ${{ steps.detect_language.outputs.issue_number }}
with:
script: |
const issueNumber = parseInt(process.env.ISSUE_NUMBER);
const aiResponse = process.env.AI_RESPONSE;
console.log('AI language detection response:', aiResponse);
let languageResult;
try {
languageResult = JSON.parse(aiResponse.trim());
// Validate the response structure
if (!languageResult || typeof languageResult.is_english !== 'boolean') {
throw new Error('Invalid response structure');
}
} catch (error) {
core.error(`Failed to parse AI response: ${error.message}`);
console.log('Raw AI response:', aiResponse);
// Log more details for debugging
core.warning('Defaulting to English due to parsing error');
// Default to English if we can't parse the response
return;
}
if (languageResult.is_english) {
console.log('Issue is in English, no action needed');
return;
}
// If language is undefined or not detected, skip processing
if (!languageResult.detected_language || languageResult.detected_language === 'undefined') {
console.log('Language could not be determined, skipping processing');
return;
}
console.log(`Issue detected as non-English: ${languageResult.detected_language}`);
// Post comment explaining the language requirement
const commentBody = [
'<!-- workflow: detect-non-english-issues -->',
'### 🌐 Non-English issue detected',
'',
`This issue appears to be written in **${languageResult.detected_language}** rather than English.`,
'',
'The Home Assistant project uses English as the primary language for issues to ensure that everyone in our international community can participate and help resolve issues. This allows any of our thousands of contributors to jump in and provide assistance.',
'',
'**What to do:**',
'1. Re-create the issue using the English language',
'2. If you need help with translation, consider using:',
' - Translation tools like Google Translate',
' - AI assistants like ChatGPT or Claude',
'',
'This helps our community provide the best possible support and ensures your issue gets the attention it deserves from our global contributor base.',
'',
'Thank you for your understanding! 🙏'
].join('\n');
try {
// Add comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body: commentBody
});
console.log('Posted language requirement comment');
// Add non-english label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
labels: ['non-english']
});
console.log('Added non-english label');
// Close the issue
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
state: 'closed',
state_reason: 'not_planned'
});
console.log('Closed the issue');
} catch (error) {
core.error('Failed to process non-English issue:', error.message);
if (error.status === 403) {
core.error('Permission denied or rate limit exceeded');
}
}

View File

@@ -1,8 +1,8 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.0
rev: v0.12.0
hooks:
- id: ruff
- id: ruff-check
args:
- --fix
- id: ruff-format
@@ -30,7 +30,7 @@ repos:
- --branch=master
- --branch=rc
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.35.1
rev: v1.37.1
hooks:
- id: yamllint
- repo: https://github.com/pre-commit/mirrors-prettier

View File

@@ -65,7 +65,9 @@ homeassistant.components.aladdin_connect.*
homeassistant.components.alarm_control_panel.*
homeassistant.components.alert.*
homeassistant.components.alexa.*
homeassistant.components.alexa_devices.*
homeassistant.components.alpha_vantage.*
homeassistant.components.altruist.*
homeassistant.components.amazon_polly.*
homeassistant.components.amberelectric.*
homeassistant.components.ambient_network.*
@@ -386,6 +388,7 @@ homeassistant.components.overseerr.*
homeassistant.components.p1_monitor.*
homeassistant.components.pandora.*
homeassistant.components.panel_custom.*
homeassistant.components.paperless_ngx.*
homeassistant.components.peblar.*
homeassistant.components.peco.*
homeassistant.components.pegel_online.*
@@ -500,6 +503,7 @@ homeassistant.components.tautulli.*
homeassistant.components.tcp.*
homeassistant.components.technove.*
homeassistant.components.tedee.*
homeassistant.components.telegram_bot.*
homeassistant.components.text.*
homeassistant.components.thethingsnetwork.*
homeassistant.components.threshold.*

2
.vscode/tasks.json vendored
View File

@@ -45,7 +45,7 @@
{
"label": "Ruff",
"type": "shell",
"command": "pre-commit run ruff --all-files",
"command": "pre-commit run ruff-check --all-files",
"group": {
"kind": "test",
"isDefault": true

27
CODEOWNERS generated
View File

@@ -57,6 +57,8 @@ build.json @home-assistant/supervisor
/tests/components/aemet/ @Noltari
/homeassistant/components/agent_dvr/ @ispysoftware
/tests/components/agent_dvr/ @ispysoftware
/homeassistant/components/ai_task/ @home-assistant/core
/tests/components/ai_task/ @home-assistant/core
/homeassistant/components/air_quality/ @home-assistant/core
/tests/components/air_quality/ @home-assistant/core
/homeassistant/components/airgradient/ @airgradienthq @joostlek
@@ -89,6 +91,10 @@ build.json @home-assistant/supervisor
/tests/components/alert/ @home-assistant/core @frenck
/homeassistant/components/alexa/ @home-assistant/cloud @ochlocracy @jbouwh
/tests/components/alexa/ @home-assistant/cloud @ochlocracy @jbouwh
/homeassistant/components/alexa_devices/ @chemelli74
/tests/components/alexa_devices/ @chemelli74
/homeassistant/components/altruist/ @airalab @LoSk-p
/tests/components/altruist/ @airalab @LoSk-p
/homeassistant/components/amazon_polly/ @jschlyter
/homeassistant/components/amberelectric/ @madpilot
/tests/components/amberelectric/ @madpilot
@@ -303,6 +309,7 @@ build.json @home-assistant/supervisor
/homeassistant/components/crownstone/ @Crownstone @RicArch97
/tests/components/crownstone/ @Crownstone @RicArch97
/homeassistant/components/cups/ @fabaff
/tests/components/cups/ @fabaff
/homeassistant/components/daikin/ @fredrike
/tests/components/daikin/ @fredrike
/homeassistant/components/date/ @home-assistant/core
@@ -324,8 +331,8 @@ build.json @home-assistant/supervisor
/tests/components/demo/ @home-assistant/core
/homeassistant/components/denonavr/ @ol-iver @starkillerOG
/tests/components/denonavr/ @ol-iver @starkillerOG
/homeassistant/components/derivative/ @afaucogney
/tests/components/derivative/ @afaucogney
/homeassistant/components/derivative/ @afaucogney @karwosts
/tests/components/derivative/ @afaucogney @karwosts
/homeassistant/components/devialet/ @fwestenberg
/tests/components/devialet/ @fwestenberg
/homeassistant/components/device_automation/ @home-assistant/core
@@ -781,8 +788,6 @@ build.json @home-assistant/supervisor
/tests/components/jellyfin/ @RunC0deRun @ctalkington
/homeassistant/components/jewish_calendar/ @tsvi
/tests/components/jewish_calendar/ @tsvi
/homeassistant/components/juicenet/ @jesserockz
/tests/components/juicenet/ @jesserockz
/homeassistant/components/justnimbus/ @kvanzuijlen
/tests/components/justnimbus/ @kvanzuijlen
/homeassistant/components/jvc_projector/ @SteveEasley @msavazzi
@@ -1164,6 +1169,8 @@ build.json @home-assistant/supervisor
/tests/components/ping/ @jpbede
/homeassistant/components/plaato/ @JohNan
/tests/components/plaato/ @JohNan
/homeassistant/components/playstation_network/ @jackjpowell
/tests/components/playstation_network/ @jackjpowell
/homeassistant/components/plex/ @jjlawren
/tests/components/plex/ @jjlawren
/homeassistant/components/plugwise/ @CoMPaTech @bouwew
@@ -1271,8 +1278,8 @@ build.json @home-assistant/supervisor
/tests/components/rehlko/ @bdraco @peterager
/homeassistant/components/remote/ @home-assistant/core
/tests/components/remote/ @home-assistant/core
/homeassistant/components/remote_calendar/ @Thomas55555
/tests/components/remote_calendar/ @Thomas55555
/homeassistant/components/remote_calendar/ @Thomas55555 @allenporter
/tests/components/remote_calendar/ @Thomas55555 @allenporter
/homeassistant/components/renault/ @epenet
/tests/components/renault/ @epenet
/homeassistant/components/renson/ @jimmyd-be
@@ -1548,8 +1555,8 @@ build.json @home-assistant/supervisor
/tests/components/tedee/ @patrickhilker @zweckj
/homeassistant/components/tellduslive/ @fredrike
/tests/components/tellduslive/ @fredrike
/homeassistant/components/template/ @Petro31 @PhracturedBlue @home-assistant/core
/tests/components/template/ @Petro31 @PhracturedBlue @home-assistant/core
/homeassistant/components/template/ @Petro31 @home-assistant/core
/tests/components/template/ @Petro31 @home-assistant/core
/homeassistant/components/tesla_fleet/ @Bre77
/tests/components/tesla_fleet/ @Bre77
/homeassistant/components/tesla_wall_connector/ @einarhauks
@@ -1575,6 +1582,8 @@ build.json @home-assistant/supervisor
/tests/components/tile/ @bachya
/homeassistant/components/tilt_ble/ @apt-itude
/tests/components/tilt_ble/ @apt-itude
/homeassistant/components/tilt_pi/ @michaelheyman
/tests/components/tilt_pi/ @michaelheyman
/homeassistant/components/time/ @home-assistant/core
/tests/components/time/ @home-assistant/core
/homeassistant/components/time_date/ @fabaff
@@ -1663,6 +1672,8 @@ build.json @home-assistant/supervisor
/tests/components/vallox/ @andre-richter @slovdahl @viiru- @yozik04
/homeassistant/components/valve/ @home-assistant/core
/tests/components/valve/ @home-assistant/core
/homeassistant/components/vegehub/ @ghowevege
/tests/components/vegehub/ @ghowevege
/homeassistant/components/velbus/ @Cereal2nd @brefra
/tests/components/velbus/ @Cereal2nd @brefra
/homeassistant/components/velux/ @Julius2342 @DeerMaximum @pawlizio

View File

@@ -38,8 +38,7 @@ def validate_python() -> None:
def ensure_config_path(config_dir: str) -> None:
"""Validate the configuration directory."""
# pylint: disable-next=import-outside-toplevel
from . import config as config_util
from . import config as config_util # noqa: PLC0415
lib_dir = os.path.join(config_dir, "deps")
@@ -80,8 +79,7 @@ def ensure_config_path(config_dir: str) -> None:
def get_arguments() -> argparse.Namespace:
"""Get parsed passed in arguments."""
# pylint: disable-next=import-outside-toplevel
from . import config as config_util
from . import config as config_util # noqa: PLC0415
parser = argparse.ArgumentParser(
description="Home Assistant: Observe, Control, Automate.",
@@ -177,8 +175,7 @@ def main() -> int:
validate_os()
if args.script is not None:
# pylint: disable-next=import-outside-toplevel
from . import scripts
from . import scripts # noqa: PLC0415
return scripts.run(args.script)
@@ -188,8 +185,7 @@ def main() -> int:
ensure_config_path(config_dir)
# pylint: disable-next=import-outside-toplevel
from . import config, runner
from . import config, runner # noqa: PLC0415
safe_mode = config.safe_mode_enabled(config_dir)

View File

@@ -52,28 +52,28 @@ _LOGGER = logging.getLogger(__name__)
def _generate_secret() -> str:
"""Generate a secret."""
import pyotp # pylint: disable=import-outside-toplevel
import pyotp # noqa: PLC0415
return str(pyotp.random_base32())
def _generate_random() -> int:
"""Generate a 32 digit number."""
import pyotp # pylint: disable=import-outside-toplevel
import pyotp # noqa: PLC0415
return int(pyotp.random_base32(length=32, chars=list("1234567890")))
def _generate_otp(secret: str, count: int) -> str:
"""Generate one time password."""
import pyotp # pylint: disable=import-outside-toplevel
import pyotp # noqa: PLC0415
return str(pyotp.HOTP(secret).at(count))
def _verify_otp(secret: str, otp: str, count: int) -> bool:
"""Verify one time password."""
import pyotp # pylint: disable=import-outside-toplevel
import pyotp # noqa: PLC0415
return bool(pyotp.HOTP(secret).verify(otp, count))

View File

@@ -37,7 +37,7 @@ DUMMY_SECRET = "FPPTH34D4E3MI2HG"
def _generate_qr_code(data: str) -> str:
"""Generate a base64 PNG string represent QR Code image of data."""
import pyqrcode # pylint: disable=import-outside-toplevel
import pyqrcode # noqa: PLC0415
qr_code = pyqrcode.create(data)
@@ -59,7 +59,7 @@ def _generate_qr_code(data: str) -> str:
def _generate_secret_and_qr_code(username: str) -> tuple[str, str, str]:
"""Generate a secret, url, and QR code."""
import pyotp # pylint: disable=import-outside-toplevel
import pyotp # noqa: PLC0415
ota_secret = pyotp.random_base32()
url = pyotp.totp.TOTP(ota_secret).provisioning_uri(
@@ -107,7 +107,7 @@ class TotpAuthModule(MultiFactorAuthModule):
def _add_ota_secret(self, user_id: str, secret: str | None = None) -> str:
"""Create a ota_secret for user."""
import pyotp # pylint: disable=import-outside-toplevel
import pyotp # noqa: PLC0415
ota_secret: str = secret or pyotp.random_base32()
@@ -163,7 +163,7 @@ class TotpAuthModule(MultiFactorAuthModule):
def _validate_2fa(self, user_id: str, code: str) -> bool:
"""Validate two factor authentication code."""
import pyotp # pylint: disable=import-outside-toplevel
import pyotp # noqa: PLC0415
if (ota_secret := self._users.get(user_id)) is None: # type: ignore[union-attr]
# even we cannot find user, we still do verify
@@ -196,7 +196,7 @@ class TotpSetupFlow(SetupFlow[TotpAuthModule]):
Return self.async_show_form(step_id='init') if user_input is None.
Return self.async_create_entry(data={'result': result}) if finish.
"""
import pyotp # pylint: disable=import-outside-toplevel
import pyotp # noqa: PLC0415
errors: dict[str, str] = {}

View File

@@ -1,29 +0,0 @@
"""Enum backports from standard lib.
This file contained the backport of the StrEnum of Python 3.11.
Since we have dropped support for Python 3.10, we can remove this backport.
This file is kept for now to avoid breaking custom components that might
import it.
"""
from __future__ import annotations
from enum import StrEnum as _StrEnum
from functools import partial
from homeassistant.helpers.deprecation import (
DeprecatedAlias,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
# StrEnum deprecated as of 2024.5 use enum.StrEnum instead.
_DEPRECATED_StrEnum = DeprecatedAlias(_StrEnum, "enum.StrEnum", "2025.5")
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())

View File

@@ -1,31 +0,0 @@
"""Functools backports from standard lib.
This file contained the backport of the cached_property implementation of Python 3.12.
Since we have dropped support for Python 3.11, we can remove this backport.
This file is kept for now to avoid breaking custom components that might
import it.
"""
from __future__ import annotations
# pylint: disable-next=hass-deprecated-import
from functools import cached_property as _cached_property, partial
from homeassistant.helpers.deprecation import (
DeprecatedAlias,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
# cached_property deprecated as of 2024.5 use functools.cached_property instead.
_DEPRECATED_cached_property = DeprecatedAlias(
_cached_property, "functools.cached_property", "2025.5"
)
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())

View File

@@ -171,8 +171,6 @@ FRONTEND_INTEGRATIONS = {
# Stage 0 is divided into substages. Each substage has a name, a set of integrations and a timeout.
# The substage containing recorder should have no timeout, as it could cancel a database migration.
# Recorder freezes "recorder" timeout during a migration, but it does not freeze other timeouts.
# The substages preceding it should also have no timeout, until we ensure that the recorder
# is not accidentally promoted as a dependency of any of the integrations in them.
# If we add timeouts to the frontend substages, we should make sure they don't apply in recovery mode.
STAGE_0_INTEGRATIONS = (
# Load logging and http deps as soon as possible
@@ -396,7 +394,7 @@ async def async_setup_hass(
def open_hass_ui(hass: core.HomeAssistant) -> None:
"""Open the UI."""
import webbrowser # pylint: disable=import-outside-toplevel
import webbrowser # noqa: PLC0415
if hass.config.api is None or "frontend" not in hass.config.components:
_LOGGER.warning("Cannot launch the UI because frontend not loaded")
@@ -563,8 +561,7 @@ async def async_enable_logging(
if not log_no_color:
try:
# pylint: disable-next=import-outside-toplevel
from colorlog import ColoredFormatter
from colorlog import ColoredFormatter # noqa: PLC0415
# basicConfig must be called after importing colorlog in order to
# ensure that the handlers it sets up wraps the correct streams.
@@ -608,7 +605,7 @@ async def async_enable_logging(
)
threading.excepthook = lambda args: logging.getLogger().exception(
"Uncaught thread exception",
exc_info=( # type: ignore[arg-type]
exc_info=( # type: ignore[arg-type] # noqa: LOG014
args.exc_type,
args.exc_value,
args.exc_traceback,
@@ -929,7 +926,11 @@ async def _async_set_up_integrations(
await _async_setup_multi_components(hass, stage_all_domains, config)
continue
try:
async with hass.timeout.async_timeout(timeout, cool_down=COOLDOWN_TIME):
async with hass.timeout.async_timeout(
timeout,
cool_down=COOLDOWN_TIME,
cancel_message=f"Bootstrap stage {name} timeout",
):
await _async_setup_multi_components(hass, stage_all_domains, config)
except TimeoutError:
_LOGGER.warning(
@@ -941,7 +942,11 @@ async def _async_set_up_integrations(
# Wrap up startup
_LOGGER.debug("Waiting for startup to wrap up")
try:
async with hass.timeout.async_timeout(WRAP_UP_TIMEOUT, cool_down=COOLDOWN_TIME):
async with hass.timeout.async_timeout(
WRAP_UP_TIMEOUT,
cool_down=COOLDOWN_TIME,
cancel_message="Bootstrap startup wrap up timeout",
):
await hass.async_block_till_done()
except TimeoutError:
_LOGGER.warning(
@@ -1054,5 +1059,5 @@ async def _async_setup_multi_components(
_LOGGER.error(
"Error setting up integration %s - received exception",
domain,
exc_info=(type(result), result, result.__traceback__),
exc_info=(type(result), result, result.__traceback__), # noqa: LOG014
)

View File

@@ -3,6 +3,7 @@
"name": "Amazon",
"integrations": [
"alexa",
"alexa_devices",
"amazon_polly",
"aws",
"aws_s3",

View File

@@ -0,0 +1,6 @@
{
"domain": "shelly",
"name": "shelly",
"integrations": ["shelly"],
"iot_standards": ["zwave"]
}

View File

@@ -1,5 +1,11 @@
{
"domain": "sony",
"name": "Sony",
"integrations": ["braviatv", "ps4", "sony_projector", "songpal"]
"integrations": [
"braviatv",
"ps4",
"sony_projector",
"songpal",
"playstation_network"
]
}

View File

@@ -1,5 +1,6 @@
{
"domain": "switchbot",
"name": "SwitchBot",
"integrations": ["switchbot", "switchbot_cloud"]
"integrations": ["switchbot", "switchbot_cloud"],
"iot_standards": ["matter"]
}

View File

@@ -0,0 +1,5 @@
{
"domain": "tilt",
"name": "Tilt",
"integrations": ["tilt_ble", "tilt_pi"]
}

View File

@@ -14,30 +14,24 @@ from jaraco.abode.exceptions import (
)
from jaraco.abode.helpers.timeline import Groups as GROUPS
from requests.exceptions import ConnectTimeout, HTTPError
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_DATE,
ATTR_DEVICE_ID,
ATTR_ENTITY_ID,
ATTR_TIME,
CONF_PASSWORD,
CONF_USERNAME,
EVENT_HOMEASSISTANT_STOP,
Platform,
)
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, ServiceCall
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.dispatcher import dispatcher_send
from homeassistant.helpers.typing import ConfigType
from .const import CONF_POLLING, DOMAIN, LOGGER
SERVICE_SETTINGS = "change_setting"
SERVICE_CAPTURE_IMAGE = "capture_image"
SERVICE_TRIGGER_AUTOMATION = "trigger_automation"
from .services import async_setup_services
ATTR_DEVICE_NAME = "device_name"
ATTR_DEVICE_TYPE = "device_type"
@@ -45,22 +39,12 @@ ATTR_EVENT_CODE = "event_code"
ATTR_EVENT_NAME = "event_name"
ATTR_EVENT_TYPE = "event_type"
ATTR_EVENT_UTC = "event_utc"
ATTR_SETTING = "setting"
ATTR_USER_NAME = "user_name"
ATTR_APP_TYPE = "app_type"
ATTR_EVENT_BY = "event_by"
ATTR_VALUE = "value"
CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False)
CHANGE_SETTING_SCHEMA = vol.Schema(
{vol.Required(ATTR_SETTING): cv.string, vol.Required(ATTR_VALUE): cv.string}
)
CAPTURE_IMAGE_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
AUTOMATION_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
PLATFORMS = [
Platform.ALARM_CONTROL_PANEL,
Platform.BINARY_SENSOR,
@@ -85,7 +69,7 @@ class AbodeSystem:
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Abode component."""
setup_hass_services(hass)
async_setup_services(hass)
return True
@@ -138,60 +122,6 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return unload_ok
def setup_hass_services(hass: HomeAssistant) -> None:
"""Home Assistant services."""
def change_setting(call: ServiceCall) -> None:
"""Change an Abode system setting."""
setting = call.data[ATTR_SETTING]
value = call.data[ATTR_VALUE]
try:
hass.data[DOMAIN].abode.set_setting(setting, value)
except AbodeException as ex:
LOGGER.warning(ex)
def capture_image(call: ServiceCall) -> None:
"""Capture a new image."""
entity_ids = call.data[ATTR_ENTITY_ID]
target_entities = [
entity_id
for entity_id in hass.data[DOMAIN].entity_ids
if entity_id in entity_ids
]
for entity_id in target_entities:
signal = f"abode_camera_capture_{entity_id}"
dispatcher_send(hass, signal)
def trigger_automation(call: ServiceCall) -> None:
"""Trigger an Abode automation."""
entity_ids = call.data[ATTR_ENTITY_ID]
target_entities = [
entity_id
for entity_id in hass.data[DOMAIN].entity_ids
if entity_id in entity_ids
]
for entity_id in target_entities:
signal = f"abode_trigger_automation_{entity_id}"
dispatcher_send(hass, signal)
hass.services.async_register(
DOMAIN, SERVICE_SETTINGS, change_setting, schema=CHANGE_SETTING_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_CAPTURE_IMAGE, capture_image, schema=CAPTURE_IMAGE_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_TRIGGER_AUTOMATION, trigger_automation, schema=AUTOMATION_SCHEMA
)
async def setup_hass_events(hass: HomeAssistant) -> None:
"""Home Assistant start and stop callbacks."""

View File

@@ -0,0 +1,90 @@
"""Support for the Abode Security System."""
from __future__ import annotations
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.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send
from .const import DOMAIN, LOGGER
SERVICE_SETTINGS = "change_setting"
SERVICE_CAPTURE_IMAGE = "capture_image"
SERVICE_TRIGGER_AUTOMATION = "trigger_automation"
ATTR_SETTING = "setting"
ATTR_VALUE = "value"
CHANGE_SETTING_SCHEMA = vol.Schema(
{vol.Required(ATTR_SETTING): cv.string, vol.Required(ATTR_VALUE): cv.string}
)
CAPTURE_IMAGE_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
AUTOMATION_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
def _change_setting(call: ServiceCall) -> None:
"""Change an Abode system setting."""
setting = call.data[ATTR_SETTING]
value = call.data[ATTR_VALUE]
try:
call.hass.data[DOMAIN].abode.set_setting(setting, value)
except AbodeException as ex:
LOGGER.warning(ex)
def _capture_image(call: ServiceCall) -> None:
"""Capture a new image."""
entity_ids = call.data[ATTR_ENTITY_ID]
target_entities = [
entity_id
for entity_id in call.hass.data[DOMAIN].entity_ids
if entity_id in entity_ids
]
for entity_id in target_entities:
signal = f"abode_camera_capture_{entity_id}"
dispatcher_send(call.hass, signal)
def _trigger_automation(call: ServiceCall) -> None:
"""Trigger an Abode automation."""
entity_ids = call.data[ATTR_ENTITY_ID]
target_entities = [
entity_id
for entity_id in call.hass.data[DOMAIN].entity_ids
if entity_id in entity_ids
]
for entity_id in target_entities:
signal = f"abode_trigger_automation_{entity_id}"
dispatcher_send(call.hass, signal)
@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Home Assistant services."""
hass.services.async_register(
DOMAIN, SERVICE_SETTINGS, _change_setting, schema=CHANGE_SETTING_SCHEMA
)
hass.services.async_register(
DOMAIN, SERVICE_CAPTURE_IMAGE, _capture_image, schema=CAPTURE_IMAGE_SCHEMA
)
hass.services.async_register(
DOMAIN,
SERVICE_TRIGGER_AUTOMATION,
_trigger_automation,
schema=AUTOMATION_SCHEMA,
)

View File

@@ -40,9 +40,10 @@ class AcmedaFlowHandler(ConfigFlow, domain=DOMAIN):
entry.unique_id for entry in self._async_current_entries()
}
hubs: list[aiopulse.Hub] = []
with suppress(TimeoutError):
async with timeout(5):
hubs: list[aiopulse.Hub] = [
hubs = [
hub
async for hub in aiopulse.Hub.discover()
if hub.id not in already_configured

View File

@@ -8,7 +8,7 @@ from homeassistant.core import HomeAssistant
from .const import CONNECTION_TYPE, LOCAL
from .coordinator import AdaxCloudCoordinator, AdaxConfigEntry, AdaxLocalCoordinator
PLATFORMS = [Platform.CLIMATE]
PLATFORMS = [Platform.CLIMATE, Platform.SENSOR]
async def async_setup_entry(hass: HomeAssistant, entry: AdaxConfigEntry) -> bool:

View File

@@ -41,7 +41,30 @@ class AdaxCloudCoordinator(DataUpdateCoordinator[dict[str, dict[str, Any]]]):
async def _async_update_data(self) -> dict[str, dict[str, Any]]:
"""Fetch data from the Adax."""
rooms = await self.adax_data_handler.get_rooms() or []
try:
if hasattr(self.adax_data_handler, "fetch_rooms_info"):
rooms = await self.adax_data_handler.fetch_rooms_info() or []
_LOGGER.debug("fetch_rooms_info returned: %s", rooms)
else:
_LOGGER.debug("fetch_rooms_info method not available, using get_rooms")
rooms = []
if not rooms:
_LOGGER.debug(
"No rooms from fetch_rooms_info, trying get_rooms as fallback"
)
rooms = await self.adax_data_handler.get_rooms() or []
_LOGGER.debug("get_rooms fallback returned: %s", rooms)
if not rooms:
raise UpdateFailed("No rooms available from Adax API")
except OSError as e:
raise UpdateFailed(f"Error communicating with API: {e}") from e
for room in rooms:
room["energyWh"] = int(room.get("energyWh", 0))
return {r["id"]: r for r in rooms}

View File

@@ -0,0 +1,77 @@
"""Support for Adax energy sensors."""
from __future__ import annotations
from typing import cast
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorStateClass,
)
from homeassistant.const import UnitOfEnergy
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AdaxConfigEntry
from .const import CONNECTION_TYPE, DOMAIN, LOCAL
from .coordinator import AdaxCloudCoordinator
async def async_setup_entry(
hass: HomeAssistant,
entry: AdaxConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Adax energy sensors with config flow."""
if entry.data.get(CONNECTION_TYPE) != LOCAL:
cloud_coordinator = cast(AdaxCloudCoordinator, entry.runtime_data)
# Create individual energy sensors for each device
async_add_entities(
AdaxEnergySensor(cloud_coordinator, device_id)
for device_id in cloud_coordinator.data
)
class AdaxEnergySensor(CoordinatorEntity[AdaxCloudCoordinator], SensorEntity):
"""Representation of an Adax energy sensor."""
_attr_has_entity_name = True
_attr_translation_key = "energy"
_attr_device_class = SensorDeviceClass.ENERGY
_attr_native_unit_of_measurement = UnitOfEnergy.WATT_HOUR
_attr_suggested_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
_attr_state_class = SensorStateClass.TOTAL_INCREASING
_attr_suggested_display_precision = 3
def __init__(
self,
coordinator: AdaxCloudCoordinator,
device_id: str,
) -> None:
"""Initialize the energy sensor."""
super().__init__(coordinator)
self._device_id = device_id
room = coordinator.data[device_id]
self._attr_unique_id = f"{room['homeId']}_{device_id}_energy"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, device_id)},
name=room["name"],
manufacturer="Adax",
)
@property
def available(self) -> bool:
"""Return True if entity is available."""
return (
super().available and "energyWh" in self.coordinator.data[self._device_id]
)
@property
def native_value(self) -> int:
"""Return the native value of the sensor."""
return int(self.coordinator.data[self._device_id]["energyWh"])

View File

@@ -15,7 +15,7 @@ from homeassistant.helpers.entity_platform import (
)
from . import AgentDVRConfigEntry
from .const import ATTRIBUTION, CAMERA_SCAN_INTERVAL_SECS, DOMAIN as AGENT_DOMAIN
from .const import ATTRIBUTION, CAMERA_SCAN_INTERVAL_SECS, DOMAIN
SCAN_INTERVAL = timedelta(seconds=CAMERA_SCAN_INTERVAL_SECS)
@@ -82,7 +82,7 @@ class AgentCamera(MjpegCamera):
still_image_url=f"{device.client._server_url}{device.still_image_url}&size={device.mjpegStreamWidth}x{device.mjpegStreamHeight}", # noqa: SLF001
)
self._attr_device_info = DeviceInfo(
identifiers={(AGENT_DOMAIN, self.unique_id)},
identifiers={(DOMAIN, self.unique_id)},
manufacturer="Agent",
model="Camera",
name=f"{device.client.name} {device.name}",

View File

@@ -0,0 +1,134 @@
"""Integration to offer AI tasks to Home Assistant."""
import logging
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import (
HassJobType,
HomeAssistant,
ServiceCall,
ServiceResponse,
SupportsResponse,
callback,
)
from homeassistant.helpers import config_validation as cv, storage
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import UNDEFINED, ConfigType, UndefinedType
from .const import (
ATTR_INSTRUCTIONS,
ATTR_TASK_NAME,
DATA_COMPONENT,
DATA_PREFERENCES,
DOMAIN,
SERVICE_GENERATE_DATA,
AITaskEntityFeature,
)
from .entity import AITaskEntity
from .http import async_setup as async_setup_http
from .task import GenDataTask, GenDataTaskResult, async_generate_data
__all__ = [
"DOMAIN",
"AITaskEntity",
"AITaskEntityFeature",
"GenDataTask",
"GenDataTaskResult",
"async_generate_data",
"async_setup",
"async_setup_entry",
"async_unload_entry",
]
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Register the process service."""
entity_component = EntityComponent[AITaskEntity](_LOGGER, DOMAIN, hass)
hass.data[DATA_COMPONENT] = entity_component
hass.data[DATA_PREFERENCES] = AITaskPreferences(hass)
await hass.data[DATA_PREFERENCES].async_load()
async_setup_http(hass)
hass.services.async_register(
DOMAIN,
SERVICE_GENERATE_DATA,
async_service_generate_data,
schema=vol.Schema(
{
vol.Required(ATTR_TASK_NAME): cv.string,
vol.Optional(ATTR_ENTITY_ID): cv.entity_id,
vol.Required(ATTR_INSTRUCTIONS): cv.string,
}
),
supports_response=SupportsResponse.ONLY,
job_type=HassJobType.Coroutinefunction,
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up a config entry."""
return await hass.data[DATA_COMPONENT].async_setup_entry(entry)
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.data[DATA_COMPONENT].async_unload_entry(entry)
async def async_service_generate_data(call: ServiceCall) -> ServiceResponse:
"""Run the run task service."""
result = await async_generate_data(hass=call.hass, **call.data)
return result.as_dict()
class AITaskPreferences:
"""AI Task preferences."""
KEYS = ("gen_data_entity_id",)
gen_data_entity_id: str | None = None
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the preferences."""
self._store: storage.Store[dict[str, str | None]] = storage.Store(
hass, 1, DOMAIN
)
async def async_load(self) -> None:
"""Load the data from the store."""
data = await self._store.async_load()
if data is None:
return
for key in self.KEYS:
setattr(self, key, data[key])
@callback
def async_set_preferences(
self,
*,
gen_data_entity_id: str | None | UndefinedType = UNDEFINED,
) -> None:
"""Set the preferences."""
changed = False
for key, value in (("gen_data_entity_id", gen_data_entity_id),):
if value is not UNDEFINED:
if getattr(self, key) != value:
setattr(self, key, value)
changed = True
if not changed:
return
self._store.async_delay_save(self.as_dict, 10)
@callback
def as_dict(self) -> dict[str, str | None]:
"""Get the current preferences."""
return {key: getattr(self, key) for key in self.KEYS}

View File

@@ -0,0 +1,34 @@
"""Constants for the AI Task integration."""
from __future__ import annotations
from enum import IntFlag
from typing import TYPE_CHECKING, Final
from homeassistant.util.hass_dict import HassKey
if TYPE_CHECKING:
from homeassistant.helpers.entity_component import EntityComponent
from . import AITaskPreferences
from .entity import AITaskEntity
DOMAIN = "ai_task"
DATA_COMPONENT: HassKey[EntityComponent[AITaskEntity]] = HassKey(DOMAIN)
DATA_PREFERENCES: HassKey[AITaskPreferences] = HassKey(f"{DOMAIN}_preferences")
SERVICE_GENERATE_DATA = "generate_data"
ATTR_INSTRUCTIONS: Final = "instructions"
ATTR_TASK_NAME: Final = "task_name"
DEFAULT_SYSTEM_PROMPT = (
"You are a Home Assistant expert and help users with their tasks."
)
class AITaskEntityFeature(IntFlag):
"""Supported features of the AI task entity."""
GENERATE_DATA = 1
"""Generate data based on instructions."""

View File

@@ -0,0 +1,103 @@
"""Entity for the AI Task integration."""
from collections.abc import AsyncGenerator
import contextlib
from typing import final
from propcache.api import cached_property
from homeassistant.components.conversation import (
ChatLog,
UserContent,
async_get_chat_log,
)
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.helpers import llm
from homeassistant.helpers.chat_session import async_get_chat_session
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.util import dt as dt_util
from .const import DEFAULT_SYSTEM_PROMPT, DOMAIN, AITaskEntityFeature
from .task import GenDataTask, GenDataTaskResult
class AITaskEntity(RestoreEntity):
"""Entity that supports conversations."""
_attr_should_poll = False
_attr_supported_features = AITaskEntityFeature(0)
__last_activity: str | None = None
@property
@final
def state(self) -> str | None:
"""Return the state of the entity."""
if self.__last_activity is None:
return None
return self.__last_activity
@cached_property
def supported_features(self) -> AITaskEntityFeature:
"""Flag supported features."""
return self._attr_supported_features
async def async_internal_added_to_hass(self) -> None:
"""Call when the entity is added to hass."""
await super().async_internal_added_to_hass()
state = await self.async_get_last_state()
if (
state is not None
and state.state is not None
and state.state not in (STATE_UNAVAILABLE, STATE_UNKNOWN)
):
self.__last_activity = state.state
@final
@contextlib.asynccontextmanager
async def _async_get_ai_task_chat_log(
self,
task: GenDataTask,
) -> AsyncGenerator[ChatLog]:
"""Context manager used to manage the ChatLog used during an AI Task."""
# pylint: disable-next=contextmanager-generator-missing-cleanup
with (
async_get_chat_session(self.hass) as session,
async_get_chat_log(
self.hass,
session,
None,
) as chat_log,
):
await chat_log.async_provide_llm_data(
llm.LLMContext(
platform=self.platform.domain,
context=None,
language=None,
assistant=DOMAIN,
device_id=None,
),
user_llm_prompt=DEFAULT_SYSTEM_PROMPT,
)
chat_log.async_add_user_content(UserContent(task.instructions))
yield chat_log
@final
async def internal_async_generate_data(
self,
task: GenDataTask,
) -> GenDataTaskResult:
"""Run a gen data task."""
self.__last_activity = dt_util.utcnow().isoformat()
self.async_write_ha_state()
async with self._async_get_ai_task_chat_log(task) as chat_log:
return await self._async_generate_data(task, chat_log)
async def _async_generate_data(
self,
task: GenDataTask,
chat_log: ChatLog,
) -> GenDataTaskResult:
"""Handle a gen data task."""
raise NotImplementedError

View File

@@ -0,0 +1,54 @@
"""HTTP endpoint for AI Task integration."""
from typing import Any
import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant, callback
from .const import DATA_PREFERENCES
@callback
def async_setup(hass: HomeAssistant) -> None:
"""Set up the HTTP API for the conversation integration."""
websocket_api.async_register_command(hass, websocket_get_preferences)
websocket_api.async_register_command(hass, websocket_set_preferences)
@websocket_api.websocket_command(
{
vol.Required("type"): "ai_task/preferences/get",
}
)
@callback
def websocket_get_preferences(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Get AI task preferences."""
preferences = hass.data[DATA_PREFERENCES]
connection.send_result(msg["id"], preferences.as_dict())
@websocket_api.websocket_command(
{
vol.Required("type"): "ai_task/preferences/set",
vol.Optional("gen_data_entity_id"): vol.Any(str, None),
}
)
@websocket_api.require_admin
@callback
def websocket_set_preferences(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Set AI task preferences."""
preferences = hass.data[DATA_PREFERENCES]
msg.pop("type")
msg_id = msg.pop("id")
preferences.async_set_preferences(**msg)
connection.send_result(msg_id, preferences.as_dict())

View File

@@ -0,0 +1,7 @@
{
"services": {
"generate_data": {
"service": "mdi:file-star-four-points-outline"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"domain": "ai_task",
"name": "AI Task",
"codeowners": ["@home-assistant/core"],
"dependencies": ["conversation"],
"documentation": "https://www.home-assistant.io/integrations/ai_task",
"integration_type": "system",
"quality_scale": "internal"
}

View File

@@ -0,0 +1,19 @@
generate_data:
fields:
task_name:
example: "home summary"
required: true
selector:
text:
instructions:
example: "Generate a funny notification that the garage door was left open"
required: true
selector:
text:
entity_id:
required: false
selector:
entity:
domain: ai_task
supported_features:
- ai_task.AITaskEntityFeature.GENERATE_DATA

View File

@@ -0,0 +1,22 @@
{
"services": {
"generate_data": {
"name": "Generate data",
"description": "Uses AI to run a task that generates data.",
"fields": {
"task_name": {
"name": "Task name",
"description": "Name of the task."
},
"instructions": {
"name": "Instructions",
"description": "Instructions on what needs to be done."
},
"entity_id": {
"name": "Entity ID",
"description": "Entity ID to run the task on. If not provided, the preferred entity will be used."
}
}
}
}
}

View File

@@ -0,0 +1,75 @@
"""AI tasks to be handled by agents."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from .const import DATA_COMPONENT, DATA_PREFERENCES, AITaskEntityFeature
async def async_generate_data(
hass: HomeAssistant,
*,
task_name: str,
entity_id: str | None = None,
instructions: str,
) -> GenDataTaskResult:
"""Run a task in the AI Task integration."""
if entity_id is None:
entity_id = hass.data[DATA_PREFERENCES].gen_data_entity_id
if entity_id is None:
raise HomeAssistantError("No entity_id provided and no preferred entity set")
entity = hass.data[DATA_COMPONENT].get_entity(entity_id)
if entity is None:
raise HomeAssistantError(f"AI Task entity {entity_id} not found")
if AITaskEntityFeature.GENERATE_DATA not in entity.supported_features:
raise HomeAssistantError(
f"AI Task entity {entity_id} does not support generating data"
)
return await entity.internal_async_generate_data(
GenDataTask(
name=task_name,
instructions=instructions,
)
)
@dataclass(slots=True)
class GenDataTask:
"""Gen data task to be processed."""
name: str
"""Name of the task."""
instructions: str
"""Instructions on what needs to be done."""
def __str__(self) -> str:
"""Return task as a string."""
return f"<GenDataTask {self.name}: {id(self)}>"
@dataclass(slots=True)
class GenDataTaskResult:
"""Result of gen data task."""
conversation_id: str
"""Unique identifier for the conversation."""
data: Any
"""Data generated by the task."""
def as_dict(self) -> dict[str, Any]:
"""Return result as a dict."""
return {
"conversation_id": self.conversation_id,
"data": self.data,
}

View File

@@ -51,9 +51,16 @@ class AirGradientCoordinator(DataUpdateCoordinator[AirGradientData]):
async def _async_setup(self) -> None:
"""Set up the coordinator."""
self._current_version = (
await self.client.get_current_measures()
).firmware_version
try:
self._current_version = (
await self.client.get_current_measures()
).firmware_version
except AirGradientError as error:
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="update_error",
translation_placeholders={"error": str(error)},
) from error
async def _async_update_data(self) -> AirGradientData:
try:

View File

@@ -39,14 +39,14 @@ class AirlyFlowHandler(ConfigFlow, domain=DOMAIN):
)
self._abort_if_unique_id_configured()
try:
location_point_valid = await test_location(
location_point_valid = await check_location(
websession,
user_input["api_key"],
user_input["latitude"],
user_input["longitude"],
)
if not location_point_valid:
location_nearest_valid = await test_location(
location_nearest_valid = await check_location(
websession,
user_input["api_key"],
user_input["latitude"],
@@ -88,7 +88,7 @@ class AirlyFlowHandler(ConfigFlow, domain=DOMAIN):
)
async def test_location(
async def check_location(
client: ClientSession,
api_key: str,
latitude: float,

View File

@@ -7,5 +7,5 @@
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["aioairq"],
"requirements": ["aioairq==0.4.4"]
"requirements": ["aioairq==0.4.6"]
}

View File

@@ -5,23 +5,22 @@ from __future__ import annotations
from datetime import timedelta
import logging
from airthings import Airthings, AirthingsDevice, AirthingsError
from airthings import Airthings
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import CONF_SECRET, DOMAIN
from .const import CONF_SECRET
from .coordinator import AirthingsDataUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
PLATFORMS: list[Platform] = [Platform.SENSOR]
SCAN_INTERVAL = timedelta(minutes=6)
type AirthingsDataCoordinatorType = DataUpdateCoordinator[dict[str, AirthingsDevice]]
type AirthingsConfigEntry = ConfigEntry[AirthingsDataCoordinatorType]
type AirthingsConfigEntry = ConfigEntry[AirthingsDataUpdateCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: AirthingsConfigEntry) -> bool:
@@ -32,21 +31,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirthingsConfigEntry) ->
async_get_clientsession(hass),
)
async def _update_method() -> dict[str, AirthingsDevice]:
"""Get the latest data from Airthings."""
try:
return await airthings.update_devices() # type: ignore[no-any-return]
except AirthingsError as err:
raise UpdateFailed(f"Unable to fetch data: {err}") from err
coordinator = AirthingsDataUpdateCoordinator(hass, airthings)
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
config_entry=entry,
name=DOMAIN,
update_method=_update_method,
update_interval=SCAN_INTERVAL,
)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator

View File

@@ -0,0 +1,36 @@
"""The Airthings integration."""
from datetime import timedelta
import logging
from airthings import Airthings, AirthingsDevice, AirthingsError
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(minutes=6)
class AirthingsDataUpdateCoordinator(DataUpdateCoordinator[dict[str, AirthingsDevice]]):
"""Coordinator for Airthings data updates."""
def __init__(self, hass: HomeAssistant, airthings: Airthings) -> None:
"""Initialize the coordinator."""
super().__init__(
hass,
_LOGGER,
name=DOMAIN,
update_method=self._update_method,
update_interval=SCAN_INTERVAL,
)
self.airthings = airthings
async def _update_method(self) -> dict[str, AirthingsDevice]:
"""Get the latest data from Airthings."""
try:
return await self.airthings.update_devices() # type: ignore[no-any-return]
except AirthingsError as err:
raise UpdateFailed(f"Unable to fetch data: {err}") from err

View File

@@ -19,6 +19,7 @@ from homeassistant.const import (
SIGNAL_STRENGTH_DECIBELS,
EntityCategory,
UnitOfPressure,
UnitOfSoundPressure,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
@@ -27,32 +28,44 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AirthingsConfigEntry, AirthingsDataCoordinatorType
from . import AirthingsConfigEntry
from .const import DOMAIN
from .coordinator import AirthingsDataUpdateCoordinator
SENSORS: dict[str, SensorEntityDescription] = {
"radonShortTermAvg": SensorEntityDescription(
key="radonShortTermAvg",
native_unit_of_measurement="Bq/m³",
translation_key="radon",
suggested_display_precision=0,
),
"temp": SensorEntityDescription(
key="temp",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=1,
),
"humidity": SensorEntityDescription(
key="humidity",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"pressure": SensorEntityDescription(
key="pressure",
device_class=SensorDeviceClass.ATMOSPHERIC_PRESSURE,
native_unit_of_measurement=UnitOfPressure.MBAR,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=1,
),
"sla": SensorEntityDescription(
key="sla",
device_class=SensorDeviceClass.SOUND_PRESSURE,
native_unit_of_measurement=UnitOfSoundPressure.WEIGHTED_DECIBEL_A,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"battery": SensorEntityDescription(
key="battery",
@@ -60,40 +73,47 @@ SENSORS: dict[str, SensorEntityDescription] = {
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"co2": SensorEntityDescription(
key="co2",
device_class=SensorDeviceClass.CO2,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"voc": SensorEntityDescription(
key="voc",
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"light": SensorEntityDescription(
key="light",
native_unit_of_measurement=PERCENTAGE,
translation_key="light",
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"lux": SensorEntityDescription(
key="lux",
device_class=SensorDeviceClass.ILLUMINANCE,
native_unit_of_measurement=LIGHT_LUX,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"virusRisk": SensorEntityDescription(
key="virusRisk",
translation_key="virus_risk",
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"mold": SensorEntityDescription(
key="mold",
translation_key="mold",
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"rssi": SensorEntityDescription(
key="rssi",
@@ -102,18 +122,21 @@ SENSORS: dict[str, SensorEntityDescription] = {
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"pm1": SensorEntityDescription(
key="pm1",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
device_class=SensorDeviceClass.PM1,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
"pm25": SensorEntityDescription(
key="pm25",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
device_class=SensorDeviceClass.PM25,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
}
@@ -140,7 +163,7 @@ async def async_setup_entry(
class AirthingsHeaterEnergySensor(
CoordinatorEntity[AirthingsDataCoordinatorType], SensorEntity
CoordinatorEntity[AirthingsDataUpdateCoordinator], SensorEntity
):
"""Representation of a Airthings Sensor device."""
@@ -149,7 +172,7 @@ class AirthingsHeaterEnergySensor(
def __init__(
self,
coordinator: AirthingsDataCoordinatorType,
coordinator: AirthingsDataUpdateCoordinator,
airthings_device: AirthingsDevice,
entity_description: SensorEntityDescription,
) -> None:

View File

@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/airtouch5",
"iot_class": "local_push",
"loggers": ["airtouch5py"],
"requirements": ["airtouch5py==0.2.11"]
"requirements": ["airtouch5py==0.3.0"]
}

View File

@@ -0,0 +1,33 @@
"""Alexa Devices integration."""
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from .coordinator import AmazonConfigEntry, AmazonDevicesCoordinator
PLATFORMS = [
Platform.BINARY_SENSOR,
Platform.NOTIFY,
Platform.SENSOR,
Platform.SWITCH,
]
async def async_setup_entry(hass: HomeAssistant, entry: AmazonConfigEntry) -> bool:
"""Set up Alexa Devices platform."""
coordinator = AmazonDevicesCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: AmazonConfigEntry) -> bool:
"""Unload a config entry."""
await entry.runtime_data.api.close()
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@@ -0,0 +1,74 @@
"""Support for binary sensors."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Final
from aioamazondevices.api import AmazonDevice
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import AmazonConfigEntry
from .entity import AmazonEntity
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
@dataclass(frozen=True, kw_only=True)
class AmazonBinarySensorEntityDescription(BinarySensorEntityDescription):
"""Alexa Devices binary sensor entity description."""
is_on_fn: Callable[[AmazonDevice], bool]
BINARY_SENSORS: Final = (
AmazonBinarySensorEntityDescription(
key="online",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
entity_category=EntityCategory.DIAGNOSTIC,
is_on_fn=lambda _device: _device.online,
),
AmazonBinarySensorEntityDescription(
key="bluetooth",
entity_category=EntityCategory.DIAGNOSTIC,
translation_key="bluetooth",
is_on_fn=lambda _device: _device.bluetooth_state,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AmazonConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Alexa Devices binary sensors based on a config entry."""
coordinator = entry.runtime_data
async_add_entities(
AmazonBinarySensorEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in BINARY_SENSORS
for serial_num in coordinator.data
)
class AmazonBinarySensorEntity(AmazonEntity, BinarySensorEntity):
"""Binary sensor device."""
entity_description: AmazonBinarySensorEntityDescription
@property
def is_on(self) -> bool:
"""Return True if the binary sensor is on."""
return self.entity_description.is_on_fn(self.device)

View File

@@ -0,0 +1,63 @@
"""Config flow for Alexa Devices integration."""
from __future__ import annotations
from typing import Any
from aioamazondevices.api import AmazonEchoApi
from aioamazondevices.exceptions import CannotAuthenticate, CannotConnect
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_CODE, CONF_COUNTRY, CONF_PASSWORD, CONF_USERNAME
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.selector import CountrySelector
from .const import CONF_LOGIN_DATA, DOMAIN
class AmazonDevicesConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Alexa Devices."""
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
errors = {}
if user_input:
client = AmazonEchoApi(
user_input[CONF_COUNTRY],
user_input[CONF_USERNAME],
user_input[CONF_PASSWORD],
)
try:
data = await client.login_mode_interactive(user_input[CONF_CODE])
except CannotConnect:
errors["base"] = "cannot_connect"
except CannotAuthenticate:
errors["base"] = "invalid_auth"
else:
await self.async_set_unique_id(data["customer_info"]["user_id"])
self._abort_if_unique_id_configured()
user_input.pop(CONF_CODE)
return self.async_create_entry(
title=user_input[CONF_USERNAME],
data=user_input | {CONF_LOGIN_DATA: data},
)
finally:
await client.close()
return self.async_show_form(
step_id="user",
errors=errors,
data_schema=vol.Schema(
{
vol.Required(
CONF_COUNTRY, default=self.hass.config.country
): CountrySelector(),
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_CODE): cv.string,
}
),
)

View File

@@ -0,0 +1,8 @@
"""Alexa Devices constants."""
import logging
_LOGGER = logging.getLogger(__package__)
DOMAIN = "alexa_devices"
CONF_LOGIN_DATA = "login_data"

View File

@@ -0,0 +1,58 @@
"""Support for Alexa Devices."""
from datetime import timedelta
from aioamazondevices.api import AmazonDevice, AmazonEchoApi
from aioamazondevices.exceptions import (
CannotAuthenticate,
CannotConnect,
CannotRetrieveData,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_COUNTRY, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryError
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import _LOGGER, CONF_LOGIN_DATA
SCAN_INTERVAL = 30
type AmazonConfigEntry = ConfigEntry[AmazonDevicesCoordinator]
class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
"""Base coordinator for Alexa Devices."""
config_entry: AmazonConfigEntry
def __init__(
self,
hass: HomeAssistant,
entry: AmazonConfigEntry,
) -> None:
"""Initialize the scanner."""
super().__init__(
hass,
_LOGGER,
name=entry.title,
config_entry=entry,
update_interval=timedelta(seconds=SCAN_INTERVAL),
)
self.api = AmazonEchoApi(
entry.data[CONF_COUNTRY],
entry.data[CONF_USERNAME],
entry.data[CONF_PASSWORD],
entry.data[CONF_LOGIN_DATA],
)
async def _async_update_data(self) -> dict[str, AmazonDevice]:
"""Update device data."""
try:
await self.api.login_mode_stored_data()
return await self.api.get_devices_data()
except (CannotConnect, CannotRetrieveData) as err:
raise UpdateFailed(f"Error occurred while updating {self.name}") from err
except CannotAuthenticate as err:
raise ConfigEntryError("Could not authenticate") from err

View File

@@ -0,0 +1,66 @@
"""Diagnostics support for Alexa Devices integration."""
from __future__ import annotations
from typing import Any
from aioamazondevices.api import AmazonDevice
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceEntry
from .coordinator import AmazonConfigEntry
TO_REDACT = {CONF_PASSWORD, CONF_USERNAME, CONF_NAME, "title"}
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: AmazonConfigEntry
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
coordinator = entry.runtime_data
devices: list[dict[str, dict[str, Any]]] = [
build_device_data(device) for device in coordinator.data.values()
]
return {
"entry": async_redact_data(entry.as_dict(), TO_REDACT),
"device_info": {
"last_update success": coordinator.last_update_success,
"last_exception": repr(coordinator.last_exception),
"devices": devices,
},
}
async def async_get_device_diagnostics(
hass: HomeAssistant, entry: AmazonConfigEntry, device_entry: DeviceEntry
) -> dict[str, Any]:
"""Return diagnostics for a device."""
coordinator = entry.runtime_data
assert device_entry.serial_number
return build_device_data(coordinator.data[device_entry.serial_number])
def build_device_data(device: AmazonDevice) -> dict[str, Any]:
"""Build device data for diagnostics."""
return {
"account name": device.account_name,
"capabilities": device.capabilities,
"device family": device.device_family,
"device type": device.device_type,
"device cluster members": device.device_cluster_members,
"online": device.online,
"serial number": device.serial_number,
"software version": device.software_version,
"do not disturb": device.do_not_disturb,
"response style": device.response_style,
"bluetooth state": device.bluetooth_state,
}

View File

@@ -0,0 +1,57 @@
"""Defines a base Alexa Devices entity."""
from aioamazondevices.api import AmazonDevice
from aioamazondevices.const import SPEAKER_GROUP_MODEL
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import AmazonDevicesCoordinator
class AmazonEntity(CoordinatorEntity[AmazonDevicesCoordinator]):
"""Defines a base Alexa Devices entity."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: AmazonDevicesCoordinator,
serial_num: str,
description: EntityDescription,
) -> None:
"""Initialize the entity."""
super().__init__(coordinator)
self._serial_num = serial_num
model_details = coordinator.api.get_model_details(self.device) or {}
model = model_details.get("model")
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, serial_num)},
name=self.device.account_name,
model=model,
model_id=self.device.device_type,
manufacturer=model_details.get("manufacturer", "Amazon"),
hw_version=model_details.get("hw_version"),
sw_version=(
self.device.software_version if model != SPEAKER_GROUP_MODEL else None
),
serial_number=serial_num if model != SPEAKER_GROUP_MODEL else None,
)
self.entity_description = description
self._attr_unique_id = f"{serial_num}-{description.key}"
@property
def device(self) -> AmazonDevice:
"""Return the device."""
return self.coordinator.data[self._serial_num]
@property
def available(self) -> bool:
"""Return True if entity is available."""
return (
super().available
and self._serial_num in self.coordinator.data
and self.device.online
)

View File

@@ -0,0 +1,12 @@
{
"entity": {
"binary_sensor": {
"bluetooth": {
"default": "mdi:bluetooth",
"state": {
"off": "mdi:bluetooth-off"
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
{
"domain": "alexa_devices",
"name": "Alexa Devices",
"codeowners": ["@chemelli74"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/alexa_devices",
"integration_type": "hub",
"iot_class": "cloud_polling",
"loggers": ["aioamazondevices"],
"quality_scale": "bronze",
"requirements": ["aioamazondevices==3.1.14"]
}

View File

@@ -0,0 +1,78 @@
"""Support for notification entity."""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import Any, Final
from aioamazondevices.api import AmazonDevice, AmazonEchoApi
from aioamazondevices.const import SPEAKER_GROUP_FAMILY
from homeassistant.components.notify import NotifyEntity, NotifyEntityDescription
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import AmazonConfigEntry
from .entity import AmazonEntity
PARALLEL_UPDATES = 1
@dataclass(frozen=True, kw_only=True)
class AmazonNotifyEntityDescription(NotifyEntityDescription):
"""Alexa Devices notify entity description."""
is_supported: Callable[[AmazonDevice], bool] = lambda _device: True
method: Callable[[AmazonEchoApi, AmazonDevice, str], Awaitable[None]]
subkey: str
NOTIFY: Final = (
AmazonNotifyEntityDescription(
key="speak",
translation_key="speak",
subkey="AUDIO_PLAYER",
is_supported=lambda _device: _device.device_family != SPEAKER_GROUP_FAMILY,
method=lambda api, device, message: api.call_alexa_speak(device, message),
),
AmazonNotifyEntityDescription(
key="announce",
translation_key="announce",
subkey="AUDIO_PLAYER",
method=lambda api, device, message: api.call_alexa_announcement(
device, message
),
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AmazonConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Alexa Devices notification entity based on a config entry."""
coordinator = entry.runtime_data
async_add_entities(
AmazonNotifyEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in NOTIFY
for serial_num in coordinator.data
if sensor_desc.subkey in coordinator.data[serial_num].capabilities
and sensor_desc.is_supported(coordinator.data[serial_num])
)
class AmazonNotifyEntity(AmazonEntity, NotifyEntity):
"""Binary sensor notify platform."""
entity_description: AmazonNotifyEntityDescription
async def async_send_message(
self, message: str, title: str | None = None, **kwargs: Any
) -> None:
"""Send a message."""
await self.entity_description.method(self.coordinator.api, self.device, message)

View File

@@ -0,0 +1,76 @@
rules:
# Bronze
action-setup:
status: exempt
comment: no actions
appropriate-polling: done
brands: done
common-modules: done
config-flow-test-coverage: done
config-flow: done
dependency-transparency: done
docs-actions:
status: exempt
comment: no actions
docs-high-level-description: done
docs-installation-instructions: done
docs-removal-instructions: done
entity-event-setup:
status: exempt
comment: entities do not explicitly subscribe to events
entity-unique-id: done
has-entity-name: done
runtime-data: done
test-before-configure: done
test-before-setup: done
unique-config-entry: done
# Silver
action-exceptions: todo
config-entry-unloading: done
docs-configuration-parameters: todo
docs-installation-parameters: todo
entity-unavailable: done
integration-owner: done
log-when-unavailable: done
parallel-updates: done
reauthentication-flow: todo
test-coverage:
status: todo
comment: all tests missing
# Gold
devices: done
diagnostics: todo
discovery-update-info:
status: exempt
comment: Network information not relevant
discovery:
status: exempt
comment: There are a ton of mac address ranges in use, but also by kindles which are not supported by this integration
docs-data-update: todo
docs-examples: todo
docs-known-limitations: todo
docs-supported-devices: todo
docs-supported-functions: todo
docs-troubleshooting: todo
docs-use-cases: todo
dynamic-devices: todo
entity-category: done
entity-device-class: done
entity-disabled-by-default: done
entity-translations: done
exception-translations: todo
icon-translations: done
reconfiguration-flow: todo
repair-issues:
status: exempt
comment: no known use cases for repair issues or flows, yet
stale-devices:
status: todo
comment: automate the cleanup process
# Platinum
async-dependency: done
inject-websession: todo
strict-typing: done

View File

@@ -0,0 +1,88 @@
"""Support for sensors."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Final
from aioamazondevices.api import AmazonDevice
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
)
from homeassistant.const import LIGHT_LUX, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
from .coordinator import AmazonConfigEntry
from .entity import AmazonEntity
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
@dataclass(frozen=True, kw_only=True)
class AmazonSensorEntityDescription(SensorEntityDescription):
"""Amazon Devices sensor entity description."""
native_unit_of_measurement_fn: Callable[[AmazonDevice, str], str] | None = None
SENSORS: Final = (
AmazonSensorEntityDescription(
key="temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement_fn=lambda device, _key: (
UnitOfTemperature.CELSIUS
if device.sensors[_key].scale == "CELSIUS"
else UnitOfTemperature.FAHRENHEIT
),
),
AmazonSensorEntityDescription(
key="illuminance",
device_class=SensorDeviceClass.ILLUMINANCE,
native_unit_of_measurement=LIGHT_LUX,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AmazonConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Amazon Devices sensors based on a config entry."""
coordinator = entry.runtime_data
async_add_entities(
AmazonSensorEntity(coordinator, serial_num, sensor_desc)
for sensor_desc in SENSORS
for serial_num in coordinator.data
if coordinator.data[serial_num].sensors.get(sensor_desc.key) is not None
)
class AmazonSensorEntity(AmazonEntity, SensorEntity):
"""Sensor device."""
entity_description: AmazonSensorEntityDescription
@property
def native_unit_of_measurement(self) -> str | None:
"""Return the unit of measurement of the sensor."""
if self.entity_description.native_unit_of_measurement_fn:
return self.entity_description.native_unit_of_measurement_fn(
self.device, self.entity_description.key
)
return super().native_unit_of_measurement
@property
def native_value(self) -> StateType:
"""Return the state of the sensor."""
return self.device.sensors[self.entity_description.key].value

View File

@@ -0,0 +1,60 @@
{
"common": {
"data_country": "Country code",
"data_code": "One-time password (OTP code)",
"data_description_country": "The country of your Amazon account.",
"data_description_username": "The email address of your Amazon account.",
"data_description_password": "The password of your Amazon account.",
"data_description_code": "The one-time password to log in to your account. Currently, only tokens from OTP applications are supported."
},
"config": {
"flow_title": "{username}",
"step": {
"user": {
"data": {
"country": "[%key:component::alexa_devices::common::data_country%]",
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]",
"code": "[%key:component::alexa_devices::common::data_description_code%]"
},
"data_description": {
"country": "[%key:component::alexa_devices::common::data_description_country%]",
"username": "[%key:component::alexa_devices::common::data_description_username%]",
"password": "[%key:component::alexa_devices::common::data_description_password%]",
"code": "[%key:component::alexa_devices::common::data_description_code%]"
}
}
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
"entity": {
"binary_sensor": {
"bluetooth": {
"name": "Bluetooth"
}
},
"notify": {
"speak": {
"name": "Speak"
},
"announce": {
"name": "Announce"
}
},
"switch": {
"do_not_disturb": {
"name": "Do not disturb"
}
}
}
}

View File

@@ -0,0 +1,84 @@
"""Support for switches."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Final
from aioamazondevices.api import AmazonDevice
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import AmazonConfigEntry
from .entity import AmazonEntity
PARALLEL_UPDATES = 1
@dataclass(frozen=True, kw_only=True)
class AmazonSwitchEntityDescription(SwitchEntityDescription):
"""Alexa Devices switch entity description."""
is_on_fn: Callable[[AmazonDevice], bool]
subkey: str
method: str
SWITCHES: Final = (
AmazonSwitchEntityDescription(
key="do_not_disturb",
subkey="AUDIO_PLAYER",
translation_key="do_not_disturb",
is_on_fn=lambda _device: _device.do_not_disturb,
method="set_do_not_disturb",
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AmazonConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Alexa Devices switches based on a config entry."""
coordinator = entry.runtime_data
async_add_entities(
AmazonSwitchEntity(coordinator, serial_num, switch_desc)
for switch_desc in SWITCHES
for serial_num in coordinator.data
if switch_desc.subkey in coordinator.data[serial_num].capabilities
)
class AmazonSwitchEntity(AmazonEntity, SwitchEntity):
"""Switch device."""
entity_description: AmazonSwitchEntityDescription
async def _switch_set_state(self, state: bool) -> None:
"""Set desired switch state."""
method = getattr(self.coordinator.api, self.entity_description.method)
if TYPE_CHECKING:
assert method is not None
await method(self.device, state)
await self.coordinator.async_request_refresh()
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
await self._switch_set_state(True)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off."""
await self._switch_set_state(False)
@property
def is_on(self) -> bool:
"""Return True if switch is on."""
return self.entity_description.is_on_fn(self.device)

View File

@@ -0,0 +1,27 @@
"""The Altruist integration."""
from __future__ import annotations
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from .coordinator import AltruistConfigEntry, AltruistDataUpdateCoordinator
PLATFORMS = [Platform.SENSOR]
async def async_setup_entry(hass: HomeAssistant, entry: AltruistConfigEntry) -> bool:
"""Set up Altruist from a config entry."""
coordinator = AltruistDataUpdateCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: AltruistConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@@ -0,0 +1,107 @@
"""Config flow for the Altruist integration."""
import logging
from typing import Any
from altruistclient import AltruistClient, AltruistDeviceModel, AltruistError
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
from .const import CONF_HOST, DOMAIN
_LOGGER = logging.getLogger(__name__)
class AltruistConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Altruist."""
device: AltruistDeviceModel
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}
ip_address = ""
if user_input is not None:
ip_address = user_input[CONF_HOST]
try:
client = await AltruistClient.from_ip_address(
async_get_clientsession(self.hass), ip_address
)
except AltruistError:
errors["base"] = "no_device_found"
else:
self.device = client.device
await self.async_set_unique_id(
client.device_id, raise_on_progress=False
)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=self.device.id,
data={
CONF_HOST: ip_address,
},
)
data_schema = self.add_suggested_values_to_schema(
vol.Schema({vol.Required(CONF_HOST): str}),
{CONF_HOST: ip_address},
)
return self.async_show_form(
step_id="user",
data_schema=data_schema,
errors=errors,
description_placeholders={
"ip_address": ip_address,
},
)
async def async_step_zeroconf(
self, discovery_info: ZeroconfServiceInfo
) -> ConfigFlowResult:
"""Handle zeroconf discovery."""
_LOGGER.debug("Zeroconf discovery: %s", discovery_info)
try:
client = await AltruistClient.from_ip_address(
async_get_clientsession(self.hass), str(discovery_info.ip_address)
)
except AltruistError:
return self.async_abort(reason="no_device_found")
self.device = client.device
_LOGGER.debug("Zeroconf device: %s", client.device)
await self.async_set_unique_id(client.device_id)
self._abort_if_unique_id_configured()
self.context.update(
{
"title_placeholders": {
"name": self.device.id,
}
}
)
return await self.async_step_discovery_confirm()
async def async_step_discovery_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm discovery."""
if user_input is not None:
return self.async_create_entry(
title=self.device.id,
data={
CONF_HOST: self.device.ip_address,
},
)
self._set_confirm_only()
return self.async_show_form(
step_id="discovery_confirm",
description_placeholders={
"model": self.device.id,
},
)

View File

@@ -0,0 +1,5 @@
"""Constants for the Altruist integration."""
DOMAIN = "altruist"
CONF_HOST = "host"

View File

@@ -0,0 +1,64 @@
"""Coordinator module for Altruist integration in Home Assistant.
This module defines the AltruistDataUpdateCoordinator class, which manages
data updates for Altruist sensors using the AltruistClient.
"""
from datetime import timedelta
import logging
from altruistclient import AltruistClient, AltruistError
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import CONF_HOST
_LOGGER = logging.getLogger(__name__)
UPDATE_INTERVAL = timedelta(seconds=15)
type AltruistConfigEntry = ConfigEntry[AltruistDataUpdateCoordinator]
class AltruistDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str]]):
"""Coordinates data updates for Altruist sensors."""
client: AltruistClient
def __init__(
self,
hass: HomeAssistant,
config_entry: AltruistConfigEntry,
) -> None:
"""Initialize the data update coordinator for Altruist sensors."""
device_id = config_entry.unique_id
super().__init__(
hass,
logger=_LOGGER,
config_entry=config_entry,
name=f"Altruist {device_id}",
update_interval=UPDATE_INTERVAL,
)
self._ip_address = config_entry.data[CONF_HOST]
async def _async_setup(self) -> None:
try:
self.client = await AltruistClient.from_ip_address(
async_get_clientsession(self.hass), self._ip_address
)
await self.client.fetch_data()
except AltruistError as e:
raise ConfigEntryNotReady("Error in Altruist setup") from e
async def _async_update_data(self) -> dict[str, str]:
try:
fetched_data = await self.client.fetch_data()
except AltruistError as ex:
raise UpdateFailed(
f"The Altruist {self.client.device_id} is unavailable: {ex}"
) from ex
return {item["value_type"]: item["value"] for item in fetched_data}

View File

@@ -0,0 +1,15 @@
{
"entity": {
"sensor": {
"pm_10": {
"default": "mdi:thought-bubble"
},
"pm_25": {
"default": "mdi:thought-bubble-outline"
},
"radiation": {
"default": "mdi:radioactive"
}
}
}
}

View File

@@ -0,0 +1,12 @@
{
"domain": "altruist",
"name": "Altruist",
"codeowners": ["@airalab", "@LoSk-p"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/altruist",
"integration_type": "device",
"iot_class": "local_polling",
"quality_scale": "bronze",
"requirements": ["altruistclient==0.1.1"],
"zeroconf": ["_altruist._tcp.local."]
}

View File

@@ -0,0 +1,83 @@
rules:
# Bronze
action-setup:
status: exempt
comment: |
This integration does not provide additional actions.
appropriate-polling: done
brands: done
common-modules: done
config-flow-test-coverage: done
config-flow: done
dependency-transparency: done
docs-actions:
status: exempt
comment: |
This integration does not provide additional actions.
docs-high-level-description: done
docs-installation-instructions: done
docs-removal-instructions: done
entity-event-setup:
status: exempt
comment: |
Entities of this integration does not explicitly subscribe to events.
entity-unique-id: done
has-entity-name: done
runtime-data: done
test-before-configure: done
test-before-setup: done
unique-config-entry: done
# Silver
action-exceptions:
status: exempt
comment: |
This integration does not provide additional actions.
config-entry-unloading: done
docs-configuration-parameters:
status: exempt
comment: |
This integration does not provide options flow.
docs-installation-parameters: done
entity-unavailable: done
integration-owner: done
log-when-unavailable: done
parallel-updates: todo
reauthentication-flow: todo
test-coverage: done
# Gold
devices: done
diagnostics: todo
discovery-update-info: todo
discovery: done
docs-data-update: todo
docs-examples: todo
docs-known-limitations: todo
docs-supported-devices: todo
docs-supported-functions: todo
docs-troubleshooting: todo
docs-use-cases: todo
dynamic-devices:
status: exempt
comment: |
Device type integration
entity-category: todo
entity-device-class: done
entity-disabled-by-default: todo
entity-translations: done
exception-translations: todo
icon-translations: done
reconfiguration-flow: todo
repair-issues:
status: exempt
comment: No known use cases for repair issues or flows, yet
stale-devices:
status: exempt
comment: |
Device type integration
# Platinum
async-dependency: done
inject-websession: done
strict-typing: done

View File

@@ -0,0 +1,249 @@
"""Defines the Altruist sensor platform."""
from collections.abc import Callable
from dataclasses import dataclass
import logging
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_MILLION,
PERCENTAGE,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
EntityCategory,
UnitOfPressure,
UnitOfSoundPressure,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AltruistConfigEntry
from .coordinator import AltruistDataUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
@dataclass(frozen=True)
class AltruistSensorEntityDescription(SensorEntityDescription):
"""Class to describe a Sensor entity."""
native_value_fn: Callable[[str], float] = float
state_class = SensorStateClass.MEASUREMENT
SENSOR_DESCRIPTIONS = [
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.HUMIDITY,
key="BME280_humidity",
translation_key="humidity",
native_unit_of_measurement=PERCENTAGE,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "BME280"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.PRESSURE,
key="BME280_pressure",
translation_key="pressure",
native_unit_of_measurement=UnitOfPressure.PA,
suggested_unit_of_measurement=UnitOfPressure.MMHG,
suggested_display_precision=0,
translation_placeholders={"sensor_name": "BME280"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.TEMPERATURE,
key="BME280_temperature",
translation_key="temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "BME280"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.PRESSURE,
key="BMP_pressure",
translation_key="pressure",
native_unit_of_measurement=UnitOfPressure.PA,
suggested_unit_of_measurement=UnitOfPressure.MMHG,
suggested_display_precision=0,
translation_placeholders={"sensor_name": "BMP"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.TEMPERATURE,
key="BMP_temperature",
translation_key="temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "BMP"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.TEMPERATURE,
key="BMP280_temperature",
translation_key="temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "BMP280"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.PRESSURE,
key="BMP280_pressure",
translation_key="pressure",
native_unit_of_measurement=UnitOfPressure.PA,
suggested_unit_of_measurement=UnitOfPressure.MMHG,
suggested_display_precision=0,
translation_placeholders={"sensor_name": "BMP280"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.HUMIDITY,
key="HTU21D_humidity",
translation_key="humidity",
native_unit_of_measurement=PERCENTAGE,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "HTU21D"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.TEMPERATURE,
key="HTU21D_temperature",
translation_key="temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "HTU21D"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.PM10,
translation_key="pm_10",
key="SDS_P1",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
suggested_display_precision=2,
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.PM25,
translation_key="pm_25",
key="SDS_P2",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
suggested_display_precision=2,
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.HUMIDITY,
key="SHT3X_humidity",
translation_key="humidity",
native_unit_of_measurement=PERCENTAGE,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "SHT3X"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.TEMPERATURE,
key="SHT3X_temperature",
translation_key="temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "SHT3X"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
key="signal",
native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
entity_category=EntityCategory.DIAGNOSTIC,
suggested_display_precision=0,
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.SOUND_PRESSURE,
key="PCBA_noiseMax",
translation_key="noise_max",
native_unit_of_measurement=UnitOfSoundPressure.DECIBEL,
suggested_display_precision=0,
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.SOUND_PRESSURE,
key="PCBA_noiseAvg",
translation_key="noise_avg",
native_unit_of_measurement=UnitOfSoundPressure.DECIBEL,
suggested_display_precision=0,
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.CO2,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
translation_key="co2",
key="CCS_CO2",
suggested_display_precision=2,
translation_placeholders={"sensor_name": "CCS"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS,
key="CCS_TVOC",
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
suggested_display_precision=2,
),
AltruistSensorEntityDescription(
key="GC",
native_unit_of_measurement="μR/h",
translation_key="radiation",
suggested_display_precision=2,
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.CO2,
translation_key="co2",
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
key="SCD4x_co2",
suggested_display_precision=2,
translation_placeholders={"sensor_name": "SCD4x"},
),
]
async def async_setup_entry(
hass: HomeAssistant,
config_entry: AltruistConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Add sensors for passed config_entry in HA."""
coordinator = config_entry.runtime_data
async_add_entities(
AltruistSensor(coordinator, sensor_description)
for sensor_description in SENSOR_DESCRIPTIONS
if sensor_description.key in coordinator.data
)
class AltruistSensor(CoordinatorEntity[AltruistDataUpdateCoordinator], SensorEntity):
"""Implementation of a Altruist sensor."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: AltruistDataUpdateCoordinator,
description: AltruistSensorEntityDescription,
) -> None:
"""Initialize the Altruist sensor."""
super().__init__(coordinator)
self._device = coordinator.client.device
self.entity_description: AltruistSensorEntityDescription = description
self._attr_unique_id = f"{self._device.id}-{description.key}"
self._attr_device_info = DeviceInfo(
connections={(CONNECTION_NETWORK_MAC, self._device.id)},
manufacturer="Robonomics",
model="Altruist",
sw_version=self._device.fw_version,
configuration_url=f"http://{self._device.ip_address}",
serial_number=self._device.id,
)
@property
def available(self) -> bool:
"""Return True if entity is available."""
return (
super().available and self.entity_description.key in self.coordinator.data
)
@property
def native_value(self) -> float | int:
"""Return the native value of the sensor."""
string_value = self.coordinator.data[self.entity_description.key]
return self.entity_description.native_value_fn(string_value)

View File

@@ -0,0 +1,51 @@
{
"config": {
"flow_title": "{name}",
"step": {
"discovery_confirm": {
"description": "Do you want to start setup {model}?"
},
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]"
},
"data_description": {
"host": "Altruist IP address or hostname in the local network"
},
"description": "Fill in Altruist IP address or hostname in your local network"
}
},
"abort": {
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
},
"error": {
"no_device_found": "[%key:common::config_flow::error::cannot_connect%]"
}
},
"entity": {
"sensor": {
"humidity": {
"name": "{sensor_name} humidity"
},
"pressure": {
"name": "{sensor_name} pressure"
},
"temperature": {
"name": "{sensor_name} temperature"
},
"noise_max": {
"name": "Maximum noise"
},
"noise_avg": {
"name": "Average noise"
},
"co2": {
"name": "{sensor_name} CO2"
},
"radiation": {
"name": "Radiation level"
}
}
}
}

View File

@@ -16,10 +16,7 @@ from amcrest import AmcrestError, ApiWrapper, LoginError
import httpx
import voluptuous as vol
from homeassistant.auth.models import User
from homeassistant.auth.permissions.const import POLICY_CONTROL
from homeassistant.const import (
ATTR_ENTITY_ID,
CONF_AUTHENTICATION,
CONF_BINARY_SENSORS,
CONF_HOST,
@@ -30,21 +27,17 @@ from homeassistant.const import (
CONF_SENSORS,
CONF_SWITCHES,
CONF_USERNAME,
ENTITY_MATCH_ALL,
ENTITY_MATCH_NONE,
HTTP_BASIC_AUTHENTICATION,
Platform,
)
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import Unauthorized, UnknownUser
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv, discovery
from homeassistant.helpers.dispatcher import async_dispatcher_send, dispatcher_send
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.service import async_extract_entity_ids
from homeassistant.helpers.typing import ConfigType
from .binary_sensor import BINARY_SENSOR_KEYS, BINARY_SENSORS, check_binary_sensors
from .camera import CAMERA_SERVICES, STREAM_SOURCE_LIST
from .camera import STREAM_SOURCE_LIST
from .const import (
CAMERAS,
COMM_RETRIES,
@@ -58,6 +51,7 @@ from .const import (
)
from .helpers import service_signal
from .sensor import SENSOR_KEYS
from .services import async_setup_services
from .switch import SWITCH_KEYS
_LOGGER = logging.getLogger(__name__)
@@ -455,47 +449,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
if not hass.data[DATA_AMCREST][DEVICES]:
return False
def have_permission(user: User | None, entity_id: str) -> bool:
return not user or user.permissions.check_entity(entity_id, POLICY_CONTROL)
async def async_extract_from_service(call: ServiceCall) -> list[str]:
if call.context.user_id:
user = await hass.auth.async_get_user(call.context.user_id)
if user is None:
raise UnknownUser(context=call.context)
else:
user = None
if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_ALL:
# Return all entity_ids user has permission to control.
return [
entity_id
for entity_id in hass.data[DATA_AMCREST][CAMERAS]
if have_permission(user, entity_id)
]
if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_NONE:
return []
call_ids = await async_extract_entity_ids(hass, call)
entity_ids = []
for entity_id in hass.data[DATA_AMCREST][CAMERAS]:
if entity_id not in call_ids:
continue
if not have_permission(user, entity_id):
raise Unauthorized(
context=call.context, entity_id=entity_id, permission=POLICY_CONTROL
)
entity_ids.append(entity_id)
return entity_ids
async def async_service_handler(call: ServiceCall) -> None:
args = [call.data[arg] for arg in CAMERA_SERVICES[call.service][2]]
for entity_id in await async_extract_from_service(call):
async_dispatcher_send(hass, service_signal(call.service, entity_id), *args)
for service, params in CAMERA_SERVICES.items():
hass.services.async_register(DOMAIN, service, async_service_handler, params[0])
async_setup_services(hass)
return True

View File

@@ -0,0 +1,62 @@
"""Support for Amcrest IP cameras."""
from __future__ import annotations
from homeassistant.auth.models import User
from homeassistant.auth.permissions.const import POLICY_CONTROL
from homeassistant.const import ATTR_ENTITY_ID, ENTITY_MATCH_ALL, ENTITY_MATCH_NONE
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import Unauthorized, UnknownUser
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.service import async_extract_entity_ids
from .camera import CAMERA_SERVICES
from .const import CAMERAS, DATA_AMCREST, DOMAIN
from .helpers import service_signal
@callback
def async_setup_services(hass: HomeAssistant) -> None:
"""Set up the Amcrest IP Camera services."""
def have_permission(user: User | None, entity_id: str) -> bool:
return not user or user.permissions.check_entity(entity_id, POLICY_CONTROL)
async def async_extract_from_service(call: ServiceCall) -> list[str]:
if call.context.user_id:
user = await hass.auth.async_get_user(call.context.user_id)
if user is None:
raise UnknownUser(context=call.context)
else:
user = None
if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_ALL:
# Return all entity_ids user has permission to control.
return [
entity_id
for entity_id in hass.data[DATA_AMCREST][CAMERAS]
if have_permission(user, entity_id)
]
if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_NONE:
return []
call_ids = await async_extract_entity_ids(hass, call)
entity_ids = []
for entity_id in hass.data[DATA_AMCREST][CAMERAS]:
if entity_id not in call_ids:
continue
if not have_permission(user, entity_id):
raise Unauthorized(
context=call.context, entity_id=entity_id, permission=POLICY_CONTROL
)
entity_ids.append(entity_id)
return entity_ids
async def async_service_handler(call: ServiceCall) -> None:
args = [call.data[arg] for arg in CAMERA_SERVICES[call.service][2]]
for entity_id in await async_extract_from_service(call):
async_dispatcher_send(hass, service_signal(call.service, entity_id), *args)
for service, params in CAMERA_SERVICES.items():
hass.services.async_register(DOMAIN, service, async_service_handler, params[0])

View File

@@ -24,7 +24,7 @@ from homeassistant.components.recorder import (
get_instance as get_recorder_instance,
)
from homeassistant.config_entries import SOURCE_IGNORE
from homeassistant.const import ATTR_DOMAIN, __version__ as HA_VERSION
from homeassistant.const import ATTR_DOMAIN, BASE_PLATFORMS, __version__ as HA_VERSION
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
@@ -225,7 +225,8 @@ class Analytics:
LOGGER.error(err)
return
configuration_set = set(yaml_configuration)
configuration_set = _domains_from_yaml_config(yaml_configuration)
er_platforms = {
entity.platform
for entity in ent_reg.entities.values()
@@ -370,3 +371,13 @@ class Analytics:
for entry in entries
if entry.source != SOURCE_IGNORE and entry.disabled_by is None
)
def _domains_from_yaml_config(yaml_configuration: dict[str, Any]) -> set[str]:
"""Extract domains from the YAML configuration."""
domains = set(yaml_configuration)
for platforms in conf_util.extract_platform_integrations(
yaml_configuration, BASE_PLATFORMS
).values():
domains.update(platforms)
return domains

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from homeassistant.components.camera import CameraEntityFeature
from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging
from homeassistant.const import (
CONF_HOST,
@@ -31,6 +32,7 @@ class IPWebcamCamera(MjpegCamera):
"""Representation of a IP Webcam camera."""
_attr_has_entity_name = True
_attr_supported_features = CameraEntityFeature.STREAM
def __init__(self, coordinator: AndroidIPCamDataUpdateCoordinator) -> None:
"""Initialize the camera."""
@@ -46,3 +48,17 @@ class IPWebcamCamera(MjpegCamera):
identifiers={(DOMAIN, coordinator.config_entry.entry_id)},
name=coordinator.config_entry.data[CONF_HOST],
)
self._coordinator = coordinator
async def stream_source(self) -> str:
"""Get the stream source for the Android IP camera."""
return self._coordinator.cam.get_rtsp_url(
video_codec="h264", # most compatible & recommended
# while "opus" is compatible with more devices,
# HA's stream integration requires AAC or MP3,
# and IP webcam doesn't provide MP3 audio.
# aac is supported on select devices >= android 4.1.
# The stream will be quiet on devices that don't support aac,
# but it won't fail.
audio_codec="aac",
)

View File

@@ -7,6 +7,6 @@
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["androidtvremote2"],
"requirements": ["androidtvremote2==0.2.1"],
"requirements": ["androidtvremote2==0.2.2"],
"zeroconf": ["_androidtvremote2._tcp.local."]
}

View File

@@ -51,6 +51,10 @@
"app_id": "Application ID",
"app_icon": "Application icon",
"app_delete": "Check to delete this application"
},
"data_description": {
"app_id": "E.g. com.plexapp.android for https://play.google.com/store/apps/details?id=com.plexapp.android",
"app_icon": "Image URL. From the Play Store app page, right click on the icon and select 'Copy image address' and then paste it here. Alternatively, download the image, upload it under /config/www/ and use the URL /local/filename"
}
}
}

View File

@@ -6,11 +6,16 @@ from functools import partial
import anthropic
from homeassistant.config_entries import ConfigEntry
from homeassistant.config_entries import ConfigEntry, ConfigSubentry
from homeassistant.const import CONF_API_KEY, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import (
config_validation as cv,
device_registry as dr,
entity_registry as er,
)
from homeassistant.helpers.typing import ConfigType
from .const import CONF_CHAT_MODEL, DOMAIN, LOGGER, RECOMMENDED_CHAT_MODEL
@@ -20,13 +25,24 @@ CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
type AnthropicConfigEntry = ConfigEntry[anthropic.AsyncClient]
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up Anthropic."""
await async_migrate_integration(hass)
return True
async def async_setup_entry(hass: HomeAssistant, entry: AnthropicConfigEntry) -> bool:
"""Set up Anthropic from a config entry."""
client = await hass.async_add_executor_job(
partial(anthropic.AsyncAnthropic, api_key=entry.data[CONF_API_KEY])
)
try:
model_id = entry.options.get(CONF_CHAT_MODEL, RECOMMENDED_CHAT_MODEL)
# Use model from first conversation subentry for validation
subentries = list(entry.subentries.values())
if subentries:
model_id = subentries[0].data.get(CONF_CHAT_MODEL, RECOMMENDED_CHAT_MODEL)
else:
model_id = RECOMMENDED_CHAT_MODEL
model = await client.models.retrieve(model_id=model_id, timeout=10.0)
LOGGER.debug("Anthropic model: %s", model.display_name)
except anthropic.AuthenticationError as err:
@@ -45,3 +61,68 @@ async def async_setup_entry(hass: HomeAssistant, entry: AnthropicConfigEntry) ->
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload Anthropic."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
async def async_migrate_integration(hass: HomeAssistant) -> None:
"""Migrate integration entry structure."""
entries = hass.config_entries.async_entries(DOMAIN)
if not any(entry.version == 1 for entry in entries):
return
api_keys_entries: dict[str, ConfigEntry] = {}
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
for entry in entries:
use_existing = False
subentry = ConfigSubentry(
data=entry.options,
subentry_type="conversation",
title=entry.title,
unique_id=None,
)
if entry.data[CONF_API_KEY] not in api_keys_entries:
use_existing = True
api_keys_entries[entry.data[CONF_API_KEY]] = entry
parent_entry = api_keys_entries[entry.data[CONF_API_KEY]]
hass.config_entries.async_add_subentry(parent_entry, subentry)
conversation_entity = entity_registry.async_get_entity_id(
"conversation",
DOMAIN,
entry.entry_id,
)
if conversation_entity is not None:
entity_registry.async_update_entity(
conversation_entity,
config_entry_id=parent_entry.entry_id,
config_subentry_id=subentry.subentry_id,
new_unique_id=subentry.subentry_id,
)
device = device_registry.async_get_device(
identifiers={(DOMAIN, entry.entry_id)}
)
if device is not None:
device_registry.async_update_device(
device.id,
new_identifiers={(DOMAIN, subentry.subentry_id)},
add_config_subentry_id=subentry.subentry_id,
add_config_entry_id=parent_entry.entry_id,
)
if parent_entry.entry_id != entry.entry_id:
device_registry.async_update_device(
device.id,
remove_config_entry_id=entry.entry_id,
)
if not use_existing:
await hass.config_entries.async_remove(entry.entry_id)
else:
hass.config_entries.async_update_entry(
entry,
options={},
version=2,
)

View File

@@ -5,20 +5,21 @@ from __future__ import annotations
from collections.abc import Mapping
from functools import partial
import logging
from types import MappingProxyType
from typing import Any
from typing import Any, cast
import anthropic
import voluptuous as vol
from homeassistant.config_entries import (
ConfigEntry,
ConfigEntryState,
ConfigFlow,
ConfigFlowResult,
OptionsFlow,
ConfigSubentryFlow,
SubentryFlowResult,
)
from homeassistant.const import CONF_API_KEY, CONF_LLM_HASS_API
from homeassistant.core import HomeAssistant
from homeassistant.const import CONF_API_KEY, CONF_LLM_HASS_API, CONF_NAME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import llm
from homeassistant.helpers.selector import (
NumberSelector,
@@ -36,6 +37,7 @@ from .const import (
CONF_RECOMMENDED,
CONF_TEMPERATURE,
CONF_THINKING_BUDGET,
DEFAULT_CONVERSATION_NAME,
DOMAIN,
RECOMMENDED_CHAT_MODEL,
RECOMMENDED_MAX_TOKENS,
@@ -72,7 +74,7 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> None:
class AnthropicConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Anthropic."""
VERSION = 1
VERSION = 2
async def async_step_user(
self, user_input: dict[str, Any] | None = None
@@ -81,6 +83,7 @@ class AnthropicConfigFlow(ConfigFlow, domain=DOMAIN):
errors = {}
if user_input is not None:
self._async_abort_entries_match(user_input)
try:
await validate_input(self.hass, user_input)
except anthropic.APITimeoutError:
@@ -102,57 +105,93 @@ class AnthropicConfigFlow(ConfigFlow, domain=DOMAIN):
return self.async_create_entry(
title="Claude",
data=user_input,
options=RECOMMENDED_OPTIONS,
subentries=[
{
"subentry_type": "conversation",
"data": RECOMMENDED_OPTIONS,
"title": DEFAULT_CONVERSATION_NAME,
"unique_id": None,
}
],
)
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors or None
)
@staticmethod
def async_get_options_flow(
config_entry: ConfigEntry,
) -> OptionsFlow:
"""Create the options flow."""
return AnthropicOptionsFlow(config_entry)
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: ConfigEntry
) -> dict[str, type[ConfigSubentryFlow]]:
"""Return subentries supported by this integration."""
return {"conversation": ConversationSubentryFlowHandler}
class AnthropicOptionsFlow(OptionsFlow):
"""Anthropic config flow options handler."""
class ConversationSubentryFlowHandler(ConfigSubentryFlow):
"""Flow for managing conversation subentries."""
def __init__(self, config_entry: ConfigEntry) -> None:
"""Initialize options flow."""
self.last_rendered_recommended = config_entry.options.get(
CONF_RECOMMENDED, False
)
last_rendered_recommended = False
async def async_step_init(
@property
def _is_new(self) -> bool:
"""Return if this is a new subentry."""
return self.source == "user"
async def async_step_set_options(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Manage the options."""
options: dict[str, Any] | MappingProxyType[str, Any] = self.config_entry.options
) -> SubentryFlowResult:
"""Set conversation options."""
# abort if entry is not loaded
if self._get_entry().state != ConfigEntryState.LOADED:
return self.async_abort(reason="entry_not_loaded")
errors: dict[str, str] = {}
if user_input is not None:
if user_input[CONF_RECOMMENDED] == self.last_rendered_recommended:
if not user_input.get(CONF_LLM_HASS_API):
user_input.pop(CONF_LLM_HASS_API, None)
if user_input.get(
CONF_THINKING_BUDGET, RECOMMENDED_THINKING_BUDGET
) >= user_input.get(CONF_MAX_TOKENS, RECOMMENDED_MAX_TOKENS):
errors[CONF_THINKING_BUDGET] = "thinking_budget_too_large"
if not errors:
return self.async_create_entry(title="", data=user_input)
if user_input is None:
if self._is_new:
options = RECOMMENDED_OPTIONS.copy()
else:
# Re-render the options again, now with the recommended options shown/hidden
self.last_rendered_recommended = user_input[CONF_RECOMMENDED]
# If this is a reconfiguration, we need to copy the existing options
# so that we can show the current values in the form.
options = self._get_reconfigure_subentry().data.copy()
options = {
CONF_RECOMMENDED: user_input[CONF_RECOMMENDED],
CONF_PROMPT: user_input[CONF_PROMPT],
CONF_LLM_HASS_API: user_input.get(CONF_LLM_HASS_API),
}
self.last_rendered_recommended = cast(
bool, options.get(CONF_RECOMMENDED, False)
)
elif user_input[CONF_RECOMMENDED] == self.last_rendered_recommended:
if not user_input.get(CONF_LLM_HASS_API):
user_input.pop(CONF_LLM_HASS_API, None)
if user_input.get(
CONF_THINKING_BUDGET, RECOMMENDED_THINKING_BUDGET
) >= user_input.get(CONF_MAX_TOKENS, RECOMMENDED_MAX_TOKENS):
errors[CONF_THINKING_BUDGET] = "thinking_budget_too_large"
if not errors:
if self._is_new:
return self.async_create_entry(
title=user_input.pop(CONF_NAME),
data=user_input,
)
return self.async_update_and_abort(
self._get_entry(),
self._get_reconfigure_subentry(),
data=user_input,
)
options = user_input
self.last_rendered_recommended = user_input[CONF_RECOMMENDED]
else:
# Re-render the options again, now with the recommended options shown/hidden
self.last_rendered_recommended = user_input[CONF_RECOMMENDED]
options = {
CONF_RECOMMENDED: user_input[CONF_RECOMMENDED],
CONF_PROMPT: user_input[CONF_PROMPT],
CONF_LLM_HASS_API: user_input.get(CONF_LLM_HASS_API),
}
suggested_values = options.copy()
if not suggested_values.get(CONF_PROMPT):
@@ -163,19 +202,25 @@ class AnthropicOptionsFlow(OptionsFlow):
suggested_values[CONF_LLM_HASS_API] = [suggested_llm_apis]
schema = self.add_suggested_values_to_schema(
vol.Schema(anthropic_config_option_schema(self.hass, options)),
vol.Schema(
anthropic_config_option_schema(self.hass, self._is_new, options)
),
suggested_values,
)
return self.async_show_form(
step_id="init",
step_id="set_options",
data_schema=schema,
errors=errors or None,
)
async_step_user = async_step_set_options
async_step_reconfigure = async_step_set_options
def anthropic_config_option_schema(
hass: HomeAssistant,
is_new: bool,
options: Mapping[str, Any],
) -> dict:
"""Return a schema for Anthropic completion options."""
@@ -187,15 +232,24 @@ def anthropic_config_option_schema(
for api in llm.async_get_apis(hass)
]
schema = {
vol.Optional(CONF_PROMPT): TemplateSelector(),
vol.Optional(
CONF_LLM_HASS_API,
): SelectSelector(SelectSelectorConfig(options=hass_apis, multiple=True)),
vol.Required(
CONF_RECOMMENDED, default=options.get(CONF_RECOMMENDED, False)
): bool,
}
if is_new:
schema: dict[vol.Required | vol.Optional, Any] = {
vol.Required(CONF_NAME, default=DEFAULT_CONVERSATION_NAME): str,
}
else:
schema = {}
schema.update(
{
vol.Optional(CONF_PROMPT): TemplateSelector(),
vol.Optional(
CONF_LLM_HASS_API,
): SelectSelector(SelectSelectorConfig(options=hass_apis, multiple=True)),
vol.Required(
CONF_RECOMMENDED, default=options.get(CONF_RECOMMENDED, False)
): bool,
}
)
if options.get(CONF_RECOMMENDED):
return schema

View File

@@ -5,6 +5,8 @@ import logging
DOMAIN = "anthropic"
LOGGER = logging.getLogger(__package__)
DEFAULT_CONVERSATION_NAME = "Claude conversation"
CONF_RECOMMENDED = "recommended"
CONF_PROMPT = "prompt"
CONF_CHAT_MODEL = "chat_model"
@@ -17,4 +19,11 @@ CONF_THINKING_BUDGET = "thinking_budget"
RECOMMENDED_THINKING_BUDGET = 0
MIN_THINKING_BUDGET = 1024
THINKING_MODELS = ["claude-3-7-sonnet-20250219", "claude-3-7-sonnet-latest"]
THINKING_MODELS = [
"claude-3-7-sonnet-20250219",
"claude-3-7-sonnet-latest",
"claude-opus-4-20250514",
"claude-opus-4-0",
"claude-sonnet-4-20250514",
"claude-sonnet-4-0",
]

View File

@@ -38,7 +38,7 @@ from anthropic.types import (
from voluptuous_openapi import convert
from homeassistant.components import conversation
from homeassistant.config_entries import ConfigEntry
from homeassistant.config_entries import ConfigEntry, ConfigSubentry
from homeassistant.const import CONF_LLM_HASS_API, MATCH_ALL
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
@@ -72,8 +72,14 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up conversation entities."""
agent = AnthropicConversationEntity(config_entry)
async_add_entities([agent])
for subentry in config_entry.subentries.values():
if subentry.subentry_type != "conversation":
continue
async_add_entities(
[AnthropicConversationEntity(config_entry, subentry)],
config_subentry_id=subentry.subentry_id,
)
def _format_tool(
@@ -294,6 +300,8 @@ async def _transform_stream( # noqa: C901 - This is complex, but better to have
elif isinstance(response, RawMessageDeltaEvent):
if (usage := response.usage) is not None:
chat_log.async_trace(_create_token_stats(input_usage, usage))
if response.delta.stop_reason == "refusal":
raise HomeAssistantError("Potential policy violation detected")
elif isinstance(response, RawMessageStopEvent):
if current_message is not None:
messages.append(current_message)
@@ -324,21 +332,22 @@ class AnthropicConversationEntity(
):
"""Anthropic conversation agent."""
_attr_has_entity_name = True
_attr_name = None
_attr_supports_streaming = True
def __init__(self, entry: AnthropicConfigEntry) -> None:
def __init__(self, entry: AnthropicConfigEntry, subentry: ConfigSubentry) -> None:
"""Initialize the agent."""
self.entry = entry
self._attr_unique_id = entry.entry_id
self.subentry = subentry
self._attr_name = subentry.title
self._attr_unique_id = subentry.subentry_id
self._attr_device_info = dr.DeviceInfo(
identifiers={(DOMAIN, entry.entry_id)},
identifiers={(DOMAIN, subentry.subentry_id)},
name=subentry.title,
manufacturer="Anthropic",
model="Claude",
entry_type=dr.DeviceEntryType.SERVICE,
)
if self.entry.options.get(CONF_LLM_HASS_API):
if self.subentry.data.get(CONF_LLM_HASS_API):
self._attr_supported_features = (
conversation.ConversationEntityFeature.CONTROL
)
@@ -361,18 +370,38 @@ class AnthropicConversationEntity(
chat_log: conversation.ChatLog,
) -> conversation.ConversationResult:
"""Call the API."""
options = self.entry.options
options = self.subentry.data
try:
await chat_log.async_update_llm_data(
DOMAIN,
user_input,
await chat_log.async_provide_llm_data(
user_input.as_llm_context(DOMAIN),
options.get(CONF_LLM_HASS_API),
options.get(CONF_PROMPT),
user_input.extra_system_prompt,
)
except conversation.ConverseError as err:
return err.as_conversation_result()
await self._async_handle_chat_log(chat_log)
response_content = chat_log.content[-1]
if not isinstance(response_content, conversation.AssistantContent):
raise TypeError("Last message must be an assistant message")
intent_response = intent.IntentResponse(language=user_input.language)
intent_response.async_set_speech(response_content.content or "")
return conversation.ConversationResult(
response=intent_response,
conversation_id=chat_log.conversation_id,
continue_conversation=chat_log.continue_conversation,
)
async def _async_handle_chat_log(
self,
chat_log: conversation.ChatLog,
) -> None:
"""Generate an answer for the chat log."""
options = self.subentry.data
tools: list[ToolParam] | None = None
if chat_log.llm_api:
tools = [
@@ -422,7 +451,7 @@ class AnthropicConversationEntity(
[
content
async for content in chat_log.async_add_delta_content_stream(
user_input.agent_id,
self.entity_id,
_transform_stream(chat_log, stream, messages),
)
if not isinstance(content, conversation.AssistantContent)
@@ -433,17 +462,6 @@ class AnthropicConversationEntity(
if not chat_log.unresponded_tool_results:
break
response_content = chat_log.content[-1]
if not isinstance(response_content, conversation.AssistantContent):
raise TypeError("Last message must be an assistant message")
intent_response = intent.IntentResponse(language=user_input.language)
intent_response.async_set_speech(response_content.content or "")
return conversation.ConversationResult(
response=intent_response,
conversation_id=chat_log.conversation_id,
continue_conversation=chat_log.continue_conversation,
)
async def _async_entry_update_listener(
self, hass: HomeAssistant, entry: ConfigEntry
) -> None:

View File

@@ -8,5 +8,5 @@
"documentation": "https://www.home-assistant.io/integrations/anthropic",
"integration_type": "service",
"iot_class": "cloud_polling",
"requirements": ["anthropic==0.47.2"]
"requirements": ["anthropic==0.52.0"]
}

View File

@@ -12,28 +12,44 @@
"timeout_connect": "[%key:common::config_flow::error::timeout_connect%]",
"authentication_error": "[%key:common::config_flow::error::invalid_auth%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]"
}
},
"options": {
"step": {
"init": {
"data": {
"prompt": "Instructions",
"chat_model": "[%key:common::generic::model%]",
"max_tokens": "Maximum tokens to return in response",
"temperature": "Temperature",
"llm_hass_api": "[%key:common::config_flow::data::llm_hass_api%]",
"recommended": "Recommended model settings",
"thinking_budget_tokens": "Thinking budget"
},
"data_description": {
"prompt": "Instruct how the LLM should respond. This can be a template.",
"thinking_budget_tokens": "The number of tokens the model can use to think about the response out of the total maximum number of tokens. Set to 1024 or greater to enable extended thinking."
"config_subentries": {
"conversation": {
"initiate_flow": {
"user": "Add conversation agent",
"reconfigure": "Reconfigure conversation agent"
},
"entry_type": "Conversation agent",
"step": {
"set_options": {
"data": {
"name": "[%key:common::config_flow::data::name%]",
"prompt": "Instructions",
"chat_model": "[%key:common::generic::model%]",
"max_tokens": "Maximum tokens to return in response",
"temperature": "Temperature",
"llm_hass_api": "[%key:common::config_flow::data::llm_hass_api%]",
"recommended": "Recommended model settings",
"thinking_budget_tokens": "Thinking budget"
},
"data_description": {
"prompt": "Instruct how the LLM should respond. This can be a template.",
"thinking_budget_tokens": "The number of tokens the model can use to think about the response out of the total maximum number of tokens. Set to 1024 or greater to enable extended thinking."
}
}
},
"abort": {
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
"entry_not_loaded": "Cannot add things while the configuration is disabled."
},
"error": {
"thinking_budget_too_large": "Maximum tokens must be greater than the thinking budget."
}
},
"error": {
"thinking_budget_too_large": "Maximum tokens must be greater than the thinking budget."
}
}
}

View File

@@ -46,11 +46,7 @@ class ConfigFlowHandler(ConfigFlow, domain=DOMAIN):
return self.async_show_form(step_id="user", data_schema=_SCHEMA)
host, port = user_input[CONF_HOST], user_input[CONF_PORT]
# Abort if an entry with same host and port is present.
self._async_abort_entries_match({CONF_HOST: host, CONF_PORT: port})
# Test the connection to the host and get the current status for serial number.
try:
async with asyncio.timeout(CONNECTION_TIMEOUT):
data = APCUPSdData(await aioapcaccess.request_status(host, port))
@@ -67,3 +63,30 @@ class ConfigFlowHandler(ConfigFlow, domain=DOMAIN):
title = data.name or data.model or data.serial_no or "APC UPS"
return self.async_create_entry(title=title, data=user_input)
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle reconfiguration of an existing entry."""
if user_input is None:
return self.async_show_form(step_id="reconfigure", data_schema=_SCHEMA)
host, port = user_input[CONF_HOST], user_input[CONF_PORT]
self._async_abort_entries_match({CONF_HOST: host, CONF_PORT: port})
try:
async with asyncio.timeout(CONNECTION_TIMEOUT):
data = APCUPSdData(await aioapcaccess.request_status(host, port))
except (OSError, asyncio.IncompleteReadError, TimeoutError):
errors = {"base": "cannot_connect"}
return self.async_show_form(
step_id="reconfigure", data_schema=_SCHEMA, errors=errors
)
await self.async_set_unique_id(data.serial_no)
self._abort_if_unique_id_mismatch(reason="wrong_apcupsd_daemon")
return self.async_update_reload_and_abort(
self._get_reconfigure_entry(),
data_updates=user_input,
)

View File

@@ -12,6 +12,7 @@ from homeassistant.components.sensor import (
)
from homeassistant.const import (
PERCENTAGE,
EntityCategory,
UnitOfApparentPower,
UnitOfElectricCurrent,
UnitOfElectricPotential,
@@ -35,6 +36,7 @@ SENSORS: dict[str, SensorEntityDescription] = {
"alarmdel": SensorEntityDescription(
key="alarmdel",
translation_key="alarm_delay",
entity_category=EntityCategory.DIAGNOSTIC,
),
"ambtemp": SensorEntityDescription(
key="ambtemp",
@@ -47,15 +49,18 @@ SENSORS: dict[str, SensorEntityDescription] = {
key="apc",
translation_key="apc_status",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"apcmodel": SensorEntityDescription(
key="apcmodel",
translation_key="apc_model",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"badbatts": SensorEntityDescription(
key="badbatts",
translation_key="bad_batteries",
entity_category=EntityCategory.DIAGNOSTIC,
),
"battdate": SensorEntityDescription(
key="battdate",
@@ -82,6 +87,7 @@ SENSORS: dict[str, SensorEntityDescription] = {
key="cable",
translation_key="cable_type",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"cumonbatt": SensorEntityDescription(
key="cumonbatt",
@@ -94,52 +100,63 @@ SENSORS: dict[str, SensorEntityDescription] = {
key="date",
translation_key="date",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"dipsw": SensorEntityDescription(
key="dipsw",
translation_key="dip_switch_settings",
entity_category=EntityCategory.DIAGNOSTIC,
),
"dlowbatt": SensorEntityDescription(
key="dlowbatt",
translation_key="low_battery_signal",
entity_category=EntityCategory.DIAGNOSTIC,
),
"driver": SensorEntityDescription(
key="driver",
translation_key="driver",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"dshutd": SensorEntityDescription(
key="dshutd",
translation_key="shutdown_delay",
entity_category=EntityCategory.DIAGNOSTIC,
),
"dwake": SensorEntityDescription(
key="dwake",
translation_key="wake_delay",
entity_category=EntityCategory.DIAGNOSTIC,
),
"end apc": SensorEntityDescription(
key="end apc",
translation_key="date_and_time",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"extbatts": SensorEntityDescription(
key="extbatts",
translation_key="external_batteries",
entity_category=EntityCategory.DIAGNOSTIC,
),
"firmware": SensorEntityDescription(
key="firmware",
translation_key="firmware_version",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"hitrans": SensorEntityDescription(
key="hitrans",
translation_key="transfer_high",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
),
"hostname": SensorEntityDescription(
key="hostname",
translation_key="hostname",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"humidity": SensorEntityDescription(
key="humidity",
@@ -163,10 +180,12 @@ SENSORS: dict[str, SensorEntityDescription] = {
key="lastxfer",
translation_key="last_transfer",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"linefail": SensorEntityDescription(
key="linefail",
translation_key="line_failure",
entity_category=EntityCategory.DIAGNOSTIC,
),
"linefreq": SensorEntityDescription(
key="linefreq",
@@ -198,15 +217,18 @@ SENSORS: dict[str, SensorEntityDescription] = {
translation_key="transfer_low",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
),
"mandate": SensorEntityDescription(
key="mandate",
translation_key="manufacture_date",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"masterupd": SensorEntityDescription(
key="masterupd",
translation_key="master_update",
entity_category=EntityCategory.DIAGNOSTIC,
),
"maxlinev": SensorEntityDescription(
key="maxlinev",
@@ -217,11 +239,13 @@ SENSORS: dict[str, SensorEntityDescription] = {
"maxtime": SensorEntityDescription(
key="maxtime",
translation_key="max_time",
entity_category=EntityCategory.DIAGNOSTIC,
),
"mbattchg": SensorEntityDescription(
key="mbattchg",
translation_key="max_battery_charge",
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
),
"minlinev": SensorEntityDescription(
key="minlinev",
@@ -232,41 +256,48 @@ SENSORS: dict[str, SensorEntityDescription] = {
"mintimel": SensorEntityDescription(
key="mintimel",
translation_key="min_time",
entity_category=EntityCategory.DIAGNOSTIC,
),
"model": SensorEntityDescription(
key="model",
translation_key="model",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"nombattv": SensorEntityDescription(
key="nombattv",
translation_key="battery_nominal_voltage",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
),
"nominv": SensorEntityDescription(
key="nominv",
translation_key="nominal_input_voltage",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
),
"nomoutv": SensorEntityDescription(
key="nomoutv",
translation_key="nominal_output_voltage",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
),
"nompower": SensorEntityDescription(
key="nompower",
translation_key="nominal_output_power",
native_unit_of_measurement=UnitOfPower.WATT,
device_class=SensorDeviceClass.POWER,
entity_category=EntityCategory.DIAGNOSTIC,
),
"nomapnt": SensorEntityDescription(
key="nomapnt",
translation_key="nominal_apparent_power",
native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
device_class=SensorDeviceClass.APPARENT_POWER,
entity_category=EntityCategory.DIAGNOSTIC,
),
"numxfers": SensorEntityDescription(
key="numxfers",
@@ -291,21 +322,25 @@ SENSORS: dict[str, SensorEntityDescription] = {
key="reg1",
translation_key="register_1_fault",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"reg2": SensorEntityDescription(
key="reg2",
translation_key="register_2_fault",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"reg3": SensorEntityDescription(
key="reg3",
translation_key="register_3_fault",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"retpct": SensorEntityDescription(
key="retpct",
translation_key="restore_capacity",
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
),
"selftest": SensorEntityDescription(
key="selftest",
@@ -315,20 +350,24 @@ SENSORS: dict[str, SensorEntityDescription] = {
key="sense",
translation_key="sensitivity",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"serialno": SensorEntityDescription(
key="serialno",
translation_key="serial_number",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"starttime": SensorEntityDescription(
key="starttime",
translation_key="startup_time",
entity_category=EntityCategory.DIAGNOSTIC,
),
"statflag": SensorEntityDescription(
key="statflag",
translation_key="online_status",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"status": SensorEntityDescription(
key="status",
@@ -337,6 +376,7 @@ SENSORS: dict[str, SensorEntityDescription] = {
"stesti": SensorEntityDescription(
key="stesti",
translation_key="self_test_interval",
entity_category=EntityCategory.DIAGNOSTIC,
),
"timeleft": SensorEntityDescription(
key="timeleft",
@@ -360,23 +400,28 @@ SENSORS: dict[str, SensorEntityDescription] = {
key="upsname",
translation_key="ups_name",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"version": SensorEntityDescription(
key="version",
translation_key="version",
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
"xoffbat": SensorEntityDescription(
key="xoffbat",
translation_key="transfer_from_battery",
entity_category=EntityCategory.DIAGNOSTIC,
),
"xoffbatt": SensorEntityDescription(
key="xoffbatt",
translation_key="transfer_from_battery",
entity_category=EntityCategory.DIAGNOSTIC,
),
"xonbatt": SensorEntityDescription(
key="xonbatt",
translation_key="transfer_to_battery",
entity_category=EntityCategory.DIAGNOSTIC,
),
}

View File

@@ -1,7 +1,9 @@
{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"wrong_apcupsd_daemon": "The reconfigured APC UPS Daemon is not the same as the one already configured.",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"

View File

@@ -62,6 +62,8 @@ async def async_setup_entry(
target_humidity_key=Attribute.HUMIDIFICATION_SETPOINT,
min_humidity=10,
max_humidity=50,
auto_status_key=Attribute.HUMIDIFICATION_AVAILABLE,
auto_status_value=1,
default_humidity=30,
set_humidity_fn=coordinator.client.set_humidification_setpoint,
)
@@ -77,6 +79,8 @@ async def async_setup_entry(
action_map=DEHUMIDIFIER_ACTION_MAP,
current_humidity_key=Attribute.INDOOR_HUMIDITY_CONTROLLING_SENSOR_VALUE,
target_humidity_key=Attribute.DEHUMIDIFICATION_SETPOINT,
auto_status_key=None,
auto_status_value=None,
min_humidity=40,
max_humidity=90,
default_humidity=60,
@@ -100,6 +104,8 @@ class AprilaireHumidifierDescription(HumidifierEntityDescription):
target_humidity_key: str
min_humidity: int
max_humidity: int
auto_status_key: str | None
auto_status_value: int | None
default_humidity: int
set_humidity_fn: Callable[[int], Awaitable]
@@ -163,14 +169,31 @@ class AprilaireHumidifierEntity(BaseAprilaireEntity, HumidifierEntity):
def min_humidity(self) -> float:
"""Return the minimum humidity."""
if self.is_auto_humidity_mode():
return 1
return self.entity_description.min_humidity
@property
def max_humidity(self) -> float:
"""Return the maximum humidity."""
if self.is_auto_humidity_mode():
return 7
return self.entity_description.max_humidity
def is_auto_humidity_mode(self) -> bool:
"""Return whether the humidifier is in auto mode."""
if self.entity_description.auto_status_key is None:
return False
return (
self.coordinator.data.get(self.entity_description.auto_status_key)
== self.entity_description.auto_status_value
)
async def async_set_humidity(self, humidity: int) -> None:
"""Set the humidity."""

View File

@@ -7,5 +7,5 @@
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["pyaprilaire"],
"requirements": ["pyaprilaire==0.9.0"]
"requirements": ["pyaprilaire==0.9.1"]
}

View File

@@ -7,5 +7,5 @@
"integration_type": "device",
"iot_class": "local_polling",
"loggers": ["APsystemsEZ1"],
"requirements": ["apsystems-ez1==2.6.0"]
"requirements": ["apsystems-ez1==2.7.0"]
}

View File

@@ -1,6 +1,9 @@
{
"entity": {
"sensor": {
"last_update": {
"default": "mdi:update"
},
"salt_left_side_percentage": {
"default": "mdi:basket-fill"
},

View File

@@ -4,6 +4,7 @@ from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime
from aioaquacell import Softener
@@ -28,7 +29,7 @@ PARALLEL_UPDATES = 1
class SoftenerSensorEntityDescription(SensorEntityDescription):
"""Describes Softener sensor entity."""
value_fn: Callable[[Softener], StateType]
value_fn: Callable[[Softener], StateType | datetime]
SENSORS: tuple[SoftenerSensorEntityDescription, ...] = (
@@ -77,6 +78,12 @@ SENSORS: tuple[SoftenerSensorEntityDescription, ...] = (
"low",
],
),
SoftenerSensorEntityDescription(
key="last_update",
translation_key="last_update",
device_class=SensorDeviceClass.TIMESTAMP,
value_fn=lambda softener: softener.lastUpdate,
),
)
@@ -111,6 +118,6 @@ class SoftenerSensor(AquacellEntity, SensorEntity):
self.entity_description = description
@property
def native_value(self) -> StateType:
def native_value(self) -> StateType | datetime:
"""Return the state of the sensor."""
return self.entity_description.value_fn(self.softener)

View File

@@ -21,6 +21,9 @@
},
"entity": {
"sensor": {
"last_update": {
"name": "Last update"
},
"salt_left_side_percentage": {
"name": "Salt left side percentage"
},

View File

@@ -89,7 +89,7 @@ class ArubaDeviceScanner(DeviceScanner):
def get_aruba_data(self) -> dict[str, dict[str, str]] | None:
"""Retrieve data from Aruba Access Point and return parsed result."""
connect = f"ssh {self.username}@{self.host} -o HostKeyAlgorithms=ssh-rsa"
connect = f"ssh {self.username}@{self.host}"
ssh: pexpect.spawn[str] = pexpect.spawn(connect, encoding="utf-8")
query = ssh.expect(
[

View File

@@ -1178,32 +1178,60 @@ class PipelineRun:
if role := delta.get("role"):
chat_log_role = role
# We are only interested in assistant deltas with content
if chat_log_role != "assistant" or not (
content := delta.get("content")
):
# We are only interested in assistant deltas
if chat_log_role != "assistant":
return
tts_input_stream.put_nowait(content)
if content := delta.get("content"):
tts_input_stream.put_nowait(content)
if self._streamed_response_text:
return
nonlocal delta_character_count
delta_character_count += len(content)
if delta_character_count < STREAM_RESPONSE_CHARS:
# Streamed responses are not cached. That's why we only start streaming text after
# we have received enough characters that indicates it will be a long response
# or if we have received text, and then a tool call.
# Tool call after we already received text
start_streaming = delta_character_count > 0 and delta.get("tool_calls")
# Count characters in the content and test if we exceed streaming threshold
if not start_streaming and content:
delta_character_count += len(content)
start_streaming = delta_character_count > STREAM_RESPONSE_CHARS
if not start_streaming:
return
# Streamed responses are not cached. We only start streaming text after
# we have received a couple of words that indicates it will be a long response.
self._streamed_response_text = True
self.process_event(
PipelineEvent(
PipelineEventType.INTENT_PROGRESS,
{
"tts_start_streaming": True,
},
)
)
async def tts_input_stream_generator() -> AsyncGenerator[str]:
"""Yield TTS input stream."""
while (tts_input := await tts_input_stream.get()) is not None:
yield tts_input
# Concatenate all existing queue items
parts = []
while not tts_input_stream.empty():
parts.append(tts_input_stream.get_nowait())
tts_input_stream.put_nowait(
"".join(
# At this point parts is only strings, None indicates end of queue
cast(list[str], parts)
)
)
assert self.tts_stream is not None
self.tts_stream.async_set_message_stream(tts_input_stream_generator())

View File

@@ -1,13 +1,23 @@
"""Base class for assist satellite entities."""
from dataclasses import asdict
import logging
from pathlib import Path
from typing import Any
from hassil.util import (
PUNCTUATION_END,
PUNCTUATION_END_WORD,
PUNCTUATION_START,
PUNCTUATION_START_WORD,
)
import voluptuous as vol
from homeassistant.components.http import StaticPathConfig
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant, ServiceCall, SupportsResponse
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.typing import ConfigType
@@ -23,6 +33,7 @@ from .const import (
)
from .entity import (
AssistSatelliteAnnouncement,
AssistSatelliteAnswer,
AssistSatelliteConfiguration,
AssistSatelliteEntity,
AssistSatelliteEntityDescription,
@@ -34,6 +45,7 @@ from .websocket_api import async_register_websocket_api
__all__ = [
"DOMAIN",
"AssistSatelliteAnnouncement",
"AssistSatelliteAnswer",
"AssistSatelliteConfiguration",
"AssistSatelliteEntity",
"AssistSatelliteEntityDescription",
@@ -86,6 +98,62 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"async_internal_start_conversation",
[AssistSatelliteEntityFeature.START_CONVERSATION],
)
async def handle_ask_question(call: ServiceCall) -> dict[str, Any]:
"""Handle a Show View service call."""
satellite_entity_id: str = call.data[ATTR_ENTITY_ID]
satellite_entity: AssistSatelliteEntity | None = component.get_entity(
satellite_entity_id
)
if satellite_entity is None:
raise HomeAssistantError(
f"Invalid Assist satellite entity id: {satellite_entity_id}"
)
ask_question_args = {
"question": call.data.get("question"),
"question_media_id": call.data.get("question_media_id"),
"preannounce": call.data.get("preannounce", False),
"answers": call.data.get("answers"),
}
if preannounce_media_id := call.data.get("preannounce_media_id"):
ask_question_args["preannounce_media_id"] = preannounce_media_id
answer = await satellite_entity.async_internal_ask_question(**ask_question_args)
if answer is None:
raise HomeAssistantError("No answer from satellite")
return asdict(answer)
hass.services.async_register(
domain=DOMAIN,
service="ask_question",
service_func=handle_ask_question,
schema=vol.All(
{
vol.Required(ATTR_ENTITY_ID): cv.entity_domain(DOMAIN),
vol.Optional("question"): str,
vol.Optional("question_media_id"): str,
vol.Optional("preannounce"): bool,
vol.Optional("preannounce_media_id"): str,
vol.Optional("answers"): [
{
vol.Required("id"): str,
vol.Required("sentences"): vol.All(
cv.ensure_list,
[cv.string],
has_one_non_empty_item,
has_no_punctuation,
),
}
],
},
cv.has_at_least_one_key("question", "question_media_id"),
),
supports_response=SupportsResponse.ONLY,
)
hass.data[CONNECTION_TEST_DATA] = {}
async_register_websocket_api(hass)
hass.http.register_view(ConnectionTestView())
@@ -110,3 +178,29 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.data[DATA_COMPONENT].async_unload_entry(entry)
def has_no_punctuation(value: list[str]) -> list[str]:
"""Validate result does not contain punctuation."""
for sentence in value:
if (
PUNCTUATION_START.search(sentence)
or PUNCTUATION_END.search(sentence)
or PUNCTUATION_START_WORD.search(sentence)
or PUNCTUATION_END_WORD.search(sentence)
):
raise vol.Invalid("sentence should not contain punctuation")
return value
def has_one_non_empty_item(value: list[str]) -> list[str]:
"""Validate result has at least one item."""
if len(value) < 1:
raise vol.Invalid("at least one sentence is required")
for sentence in value:
if not sentence:
raise vol.Invalid("sentences cannot be empty")
return value

View File

@@ -4,12 +4,16 @@ from abc import abstractmethod
import asyncio
from collections.abc import AsyncIterable
import contextlib
from dataclasses import dataclass
from dataclasses import dataclass, field
from enum import StrEnum
import logging
import time
from typing import Any, Literal, final
from hassil import Intents, recognize
from hassil.expression import Expression, ListReference, Sequence
from hassil.intents import WildcardSlotList
from homeassistant.components import conversation, media_source, stt, tts
from homeassistant.components.assist_pipeline import (
OPTION_PREFERRED,
@@ -105,6 +109,20 @@ class AssistSatelliteAnnouncement:
"""Media ID to be played before announcement."""
@dataclass
class AssistSatelliteAnswer:
"""Answer to a question."""
id: str | None
"""Matched answer id or None if no answer was matched."""
sentence: str
"""Raw sentence text from user response."""
slots: dict[str, Any] = field(default_factory=dict)
"""Matched slots from answer."""
class AssistSatelliteEntity(entity.Entity):
"""Entity encapsulating the state and functionality of an Assist satellite."""
@@ -122,6 +140,7 @@ class AssistSatelliteEntity(entity.Entity):
_wake_word_intercept_future: asyncio.Future[str | None] | None = None
_attr_tts_options: dict[str, Any] | None = None
_pipeline_task: asyncio.Task | None = None
_ask_question_future: asyncio.Future[str | None] | None = None
__assist_satellite_state = AssistSatelliteState.IDLE
@@ -309,6 +328,112 @@ class AssistSatelliteEntity(entity.Entity):
"""Start a conversation from the satellite."""
raise NotImplementedError
async def async_internal_ask_question(
self,
question: str | None = None,
question_media_id: str | None = None,
preannounce: bool = True,
preannounce_media_id: str = PREANNOUNCE_URL,
answers: list[dict[str, Any]] | None = None,
) -> AssistSatelliteAnswer | None:
"""Ask a question and get a user's response from the satellite.
If question_media_id is not provided, question is synthesized to audio
with the selected pipeline.
If question_media_id is provided, it is played directly. It is possible
to omit the message and the satellite will not show any text.
If preannounce is True, a sound is played before the start message or media.
If preannounce_media_id is provided, it overrides the default sound.
Calls async_start_conversation.
"""
await self._cancel_running_pipeline()
if question is None:
question = ""
announcement = await self._resolve_announcement_media_id(
question,
question_media_id,
preannounce_media_id=preannounce_media_id if preannounce else None,
)
if self._is_announcing:
raise SatelliteBusyError
self._is_announcing = True
self._set_state(AssistSatelliteState.RESPONDING)
self._ask_question_future = asyncio.Future()
try:
# Wait for announcement to finish
await self.async_start_conversation(announcement)
# Wait for response text
response_text = await self._ask_question_future
if response_text is None:
raise HomeAssistantError("No answer from question")
if not answers:
return AssistSatelliteAnswer(id=None, sentence=response_text)
return self._question_response_to_answer(response_text, answers)
finally:
self._is_announcing = False
self._set_state(AssistSatelliteState.IDLE)
self._ask_question_future = None
def _question_response_to_answer(
self, response_text: str, answers: list[dict[str, Any]]
) -> AssistSatelliteAnswer:
"""Match text to a pre-defined set of answers."""
# Build intents and match
intents = Intents.from_dict(
{
"language": self.hass.config.language,
"intents": {
"QuestionIntent": {
"data": [
{
"sentences": answer["sentences"],
"metadata": {"answer_id": answer["id"]},
}
for answer in answers
]
}
},
}
)
# Assume slot list references are wildcards
wildcard_names: set[str] = set()
for intent in intents.intents.values():
for intent_data in intent.data:
for sentence in intent_data.sentences:
_collect_list_references(sentence, wildcard_names)
for wildcard_name in wildcard_names:
intents.slot_lists[wildcard_name] = WildcardSlotList(wildcard_name)
# Match response text
result = recognize(response_text, intents)
if result is None:
# No match
return AssistSatelliteAnswer(id=None, sentence=response_text)
assert result.intent_metadata
return AssistSatelliteAnswer(
id=result.intent_metadata["answer_id"],
sentence=response_text,
slots={
entity_name: entity.value
for entity_name, entity in result.entities.items()
},
)
async def async_accept_pipeline_from_satellite(
self,
audio_stream: AsyncIterable[bytes],
@@ -351,6 +476,11 @@ class AssistSatelliteEntity(entity.Entity):
self._internal_on_pipeline_event(PipelineEvent(PipelineEventType.RUN_END))
return
if (self._ask_question_future is not None) and (
start_stage == PipelineStage.STT
):
end_stage = PipelineStage.STT
device_id = self.registry_entry.device_id if self.registry_entry else None
# Refresh context if necessary
@@ -433,6 +563,16 @@ class AssistSatelliteEntity(entity.Entity):
self._set_state(AssistSatelliteState.IDLE)
elif event.type is PipelineEventType.STT_START:
self._set_state(AssistSatelliteState.LISTENING)
elif event.type is PipelineEventType.STT_END:
# Intercepting text for ask question
if (
(self._ask_question_future is not None)
and (not self._ask_question_future.done())
and event.data
):
self._ask_question_future.set_result(
event.data.get("stt_output", {}).get("text")
)
elif event.type is PipelineEventType.INTENT_START:
self._set_state(AssistSatelliteState.PROCESSING)
elif event.type is PipelineEventType.TTS_START:
@@ -443,6 +583,12 @@ class AssistSatelliteEntity(entity.Entity):
if not self._run_has_tts:
self._set_state(AssistSatelliteState.IDLE)
if (self._ask_question_future is not None) and (
not self._ask_question_future.done()
):
# No text for ask question
self._ask_question_future.set_result(None)
self.on_pipeline_event(event)
@callback
@@ -577,3 +723,15 @@ class AssistSatelliteEntity(entity.Entity):
media_id_source=media_id_source,
preannounce_media_id=preannounce_media_id,
)
def _collect_list_references(expression: Expression, list_names: set[str]) -> None:
"""Collect list reference names recursively."""
if isinstance(expression, Sequence):
seq: Sequence = expression
for item in seq.items:
_collect_list_references(item, list_names)
elif isinstance(expression, ListReference):
# {list}
list_ref: ListReference = expression
list_names.add(list_ref.slot_name)

View File

@@ -10,6 +10,9 @@
},
"start_conversation": {
"service": "mdi:forum"
},
"ask_question": {
"service": "mdi:microphone-question"
}
}
}

View File

@@ -5,5 +5,6 @@
"dependencies": ["assist_pipeline", "http", "stt", "tts"],
"documentation": "https://www.home-assistant.io/integrations/assist_satellite",
"integration_type": "entity",
"quality_scale": "internal"
"quality_scale": "internal",
"requirements": ["hassil==2.2.3"]
}

View File

@@ -54,3 +54,35 @@ start_conversation:
required: false
selector:
text:
ask_question:
fields:
entity_id:
required: true
selector:
entity:
domain: assist_satellite
supported_features:
- assist_satellite.AssistSatelliteEntityFeature.START_CONVERSATION
question:
required: false
example: "What kind of music would you like to play?"
default: ""
selector:
text:
question_media_id:
required: false
selector:
text:
preannounce:
required: false
default: true
selector:
boolean:
preannounce_media_id:
required: false
selector:
text:
answers:
required: false
selector:
object:

View File

@@ -59,6 +59,36 @@
"description": "Custom media ID to play before the start message or media."
}
}
},
"ask_question": {
"name": "Ask question",
"description": "Asks a question and gets the user's response.",
"fields": {
"entity_id": {
"name": "Entity",
"description": "Assist satellite entity to ask the question on."
},
"question": {
"name": "Question",
"description": "The question to ask."
},
"question_media_id": {
"name": "Question media ID",
"description": "The media ID of the question to use instead of text-to-speech."
},
"preannounce": {
"name": "Preannounce",
"description": "Play a sound before the start message or media."
},
"preannounce_media_id": {
"name": "Preannounce media ID",
"description": "Custom media ID to play before the start message or media."
},
"answers": {
"name": "Answers",
"description": "Possible answers to the question."
}
}
}
}
}

View File

@@ -6,6 +6,7 @@ from homeassistant.components.water_heater import (
STATE_ECO,
STATE_PERFORMANCE,
WaterHeaterEntity,
WaterHeaterEntityFeature,
)
from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF, Platform, UnitOfTemperature
from homeassistant.core import HomeAssistant
@@ -32,6 +33,7 @@ class AtagWaterHeater(AtagEntity, WaterHeaterEntity):
"""Representation of an ATAG water heater."""
_attr_operation_list = OPERATION_LIST
_attr_supported_features = WaterHeaterEntityFeature.TARGET_TEMPERATURE
_attr_temperature_unit = UnitOfTemperature.CELSIUS
@property

View File

@@ -12,7 +12,7 @@ DATA_BLUEPRINTS = "automation_blueprints"
def _blueprint_in_use(hass: HomeAssistant, blueprint_path: str) -> bool:
"""Return True if any automation references the blueprint."""
from . import automations_with_blueprint # pylint: disable=import-outside-toplevel
from . import automations_with_blueprint # noqa: PLC0415
return len(automations_with_blueprint(hass, blueprint_path)) > 0
@@ -28,8 +28,7 @@ async def _reload_blueprint_automations(
@callback
def async_get_blueprints(hass: HomeAssistant) -> blueprint.DomainBlueprints:
"""Get automation blueprints."""
# pylint: disable-next=import-outside-toplevel
from .config import AUTOMATION_BLUEPRINT_SCHEMA
from .config import AUTOMATION_BLUEPRINT_SCHEMA # noqa: PLC0415
return blueprint.DomainBlueprints(
hass,

View File

@@ -11,7 +11,7 @@ from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac
from homeassistant.helpers.dispatcher import async_dispatcher_send
from ..const import ATTR_MANUFACTURER, DOMAIN as AXIS_DOMAIN
from ..const import ATTR_MANUFACTURER, DOMAIN
from .config import AxisConfig
from .entity_loader import AxisEntityLoader
from .event_source import AxisEventSource
@@ -79,7 +79,7 @@ class AxisHub:
config_entry_id=self.config.entry.entry_id,
configuration_url=self.api.config.url,
connections={(CONNECTION_NETWORK_MAC, self.unique_id)},
identifiers={(AXIS_DOMAIN, self.unique_id)},
identifiers={(DOMAIN, self.unique_id)},
manufacturer=ATTR_MANUFACTURER,
model=f"{self.config.model} {self.product_type}",
name=self.config.name,

Some files were not shown because too many files have changed in this diff Show More