Compare commits

..

657 Commits

Author SHA1 Message Date
J. Nick Koston 582761a6ec Merge branch 'dev' into ingress_dropping_close 2025-03-26 10:51:06 -10:00
Andrew Sayre 6bfd39f094 Add play queue item to HEOS (#141480)
Add ability to play specific queue item
2025-03-26 15:47:10 -05:00
Robert Resch 002ca9611d Add test for invalid mean type in StatisticsMeta (#141475) 2025-03-26 21:40:02 +01:00
Joost Lekkerkerker 46ee3d2b26 Sort SmartThings devices to be created by parent device id (#141515) 2025-03-26 20:52:39 +01:00
Franck Nijhof eb901bcf3a Bump version to 2025.5.0dev0 (#141507) 2025-03-26 20:30:03 +01:00
Norbert Rittel 930b4a2c81 Capitalize "Ethernet" in roku sensor name (#141509)
* Capitalize "Ethernet" in `roku` sensor name

* Update test_binary_sensor.py
2025-03-26 21:18:52 +02:00
Robert Resch 22d1b8e1cd Bump deebot-client to 12.4.0 (#141501) 2025-03-26 19:36:04 +01:00
Joost Lekkerkerker 2e3853dd7d Deprecate SmartThings media player switch (#141467)
* Deprecate SmartThings media player switch

* Fix

* Fix

* Update homeassistant/components/smartthings/strings.json

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

* Fix

---------

Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-03-26 18:40:11 +01:00
Joost Lekkerkerker fe99c39e25 Deprecate media player sensors for SmartThings (#141469)
* Deprecate media player sensors for SmartThings

* Deprecate media player sensors
2025-03-26 18:21:49 +01:00
Maciej Bieniek c8ab5bc796 Bump IMGW-PIB library to 1.0.10 (#141491) 2025-03-26 17:57:27 +01:00
Álvaro Fernández Rojas 4f3b36c2e1 Update aioairzone-cloud to v0.6.11 (#141488)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
2025-03-26 17:57:15 +01:00
Marc Mueller 222d89a84c Update meteofrance-api to 1.4.0 (#141490) 2025-03-26 17:56:45 +01:00
Joost Lekkerkerker eb3cb0e0c7 Bump yt-dlp to 2025.03.26 (#141484) 2025-03-26 11:49:29 -05:00
Joost Lekkerkerker 69c8f4fbb6 Add button to reset the water filter in SmartThings (#141493)
* Add button to reset the water filter in SmartThings

* Add button to reset the water filter in SmartThings
2025-03-26 11:48:03 -05:00
Jan Bouwhuis 3bcf1c942c Cleanup missed QoS translation string for MQTT subentries (#141485) 2025-03-26 17:40:22 +01:00
Michael Hansen 220aaf93c6 Add preannounce media id support for ESPHome (#141474)
* Working on preannounce media id support for ESPHome

* Fix test

* Update tests
2025-03-26 11:31:05 -05:00
Jan Bouwhuis febc455bc5 Add switch as entity platform on MQTT subentries (#140658) 2025-03-26 16:46:44 +01:00
Marc Mueller 57f65c205e Use SPDX identifier for container license (#141477) 2025-03-26 16:31:28 +01:00
Erik Montnemery 6e56486294 Bump pychromecast to 14.0.7 (#141479) 2025-03-26 16:30:37 +01:00
Joost Lekkerkerker 3a1e1684ea Add power binary sensor for Cooktop in SmartThings (#141482) 2025-03-26 16:29:02 +01:00
Bram Kragten 9d63a49812 Update frontend to 20250326.0 (#141481) 2025-03-26 16:27:43 +01:00
Markus Adrario 7a4ca6dcdc Add Homee lock platform (#140893)
* Add homee lock platform

* finish tests

* add locking & unlocking

* add PARALLEL_UPDATES

* fix review comments

* fix test review comment.

* fix another review comment
2025-03-26 09:46:21 -05:00
Marc Mueller 1622638f10 Update mypy-dev to 1.16.0a7 (#141472) 2025-03-26 15:21:38 +01:00
Jan Bouwhuis 0de3549e6e Move QoS setting to shared device properties in MQTT device subentries configuration (#141369)
* Move QoS setting to shared device properties in MQTT device subentries configuration

* Use kwargs for validate_user_input helper
2025-03-26 15:20:08 +01:00
Joost Lekkerkerker 63d4efda2e Deprecate switch entity for airdresser (#141470)
* Deprecate switch entity for airdresser

* Deprecate switch entity for airdresser
2025-03-26 15:06:13 +01:00
J. Diego Rodríguez Royo b5910dd7d6 Move Home Connect alarm clock entity from time platform to number platform (#141400)
* Move alarm clock entity from time platform to number platform

* Deprecate alarm clock time entity

* Don't update unique id

* Fix tests

* Fixable issues

* improvement

* Make the issues persistent
2025-03-26 14:46:07 +01:00
Denis Shulyaka c974285490 Add Web search to OpenAI Conversation integration (#141426)
* Add Web search to OpenAI Conversation integration

* Limit search for gpt-4o models

* Add more tests
2025-03-26 09:36:05 -04:00
Michael Hansen 8db91623ec Add language scores websocket command (#140480)
* Add language scores websocket command

* Don't store language scores in snapshot

* Add language/country args for preferred lang

* Bump intents to 2025.3.24 for dash lang code
2025-03-26 14:07:15 +01:00
Michael Hansen 3eda5333b0 Add info websocket command to wyoming integration (#139982)
* Add info websocket command to wyoming integration

* Add snapshot

* Add config schema

* Remove snapshots because of changing config entry ids
2025-03-26 14:06:51 +01:00
Robert Resch 3aaf859985 Add state class MEASUREMENT_ANGLE to wind direction sensor (#141392)
* Add state class MEASUREMENT_ANGLE to wind direction sensor

* Update snapshots

* Add some more
2025-03-26 13:58:23 +01:00
Sanjay Govind dba4c197c8 Add bosch_alarm integration (#138497)
* Add bosch_alarm integration

* Remove other platforms for now

* update some strings not being consistant

* fix sentence-casing for strings

* remove options flow and versioning

* clean up config flow

* Add OSI license + tagged releases + ci to bosch-alarm-mode2

* Apply suggestions from code review

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

* apply changes from review

* apply changes from review

* remove options flow

* work on fixtures

* work on fixtures

* fix errors and complete flow

* use fixtures for alarm config

* Update homeassistant/components/bosch_alarm/manifest.json

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

* fix missing type

* mock setup entry

* remove use of patch in config flow test

* Use coordinator for managing panel data

* Use coordinator for managing panel data

* Coordinator cleanup

* remove unnecessary observers

* update listeners when error state changes

* Update homeassistant/components/bosch_alarm/coordinator.py

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

* Update homeassistant/components/bosch_alarm/quality_scale.yaml

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

* Update homeassistant/components/bosch_alarm/config_flow.py

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

* rename config flow

* Update homeassistant/components/bosch_alarm/quality_scale.yaml

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

* add missing types

* fix quality_scale.yaml

* enable strict typing

* enable strict typing

* Add test for alarm control panel

* add more tests

* add more tests

* Update homeassistant/components/bosch_alarm/coordinator.py

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

* Update homeassistant/components/bosch_alarm/coordinator.py

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

* Update homeassistant/components/bosch_alarm/alarm_control_panel.py

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

* Update homeassistant/components/bosch_alarm/alarm_control_panel.py

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

* Update homeassistant/components/bosch_alarm/alarm_control_panel.py

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

* Add snapshot test

* add snapshot test

* add snapshot test

* update quality scale

* update quality scale

* update quality scale

* update quality scale

* Apply suggestions from code review

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

* apply changes from code review

* apply changes from code review

* apply changes from code review

* Apply suggestions from code review

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

* apply changes from code review

* apply changes from code review

* Fix alarm control panel device name

* Fix

* Fix

* Fix

* Fix

---------

Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-03-26 13:56:44 +01:00
Robert Resch f842640249 Add check that sensor state classes are used only with valid unit of measurements (#141444) 2025-03-26 13:52:00 +01:00
Robert Resch aa493ff97d Correct device class and state class for wind direction sensors (#141393)
* Fix state class on wind direction sensors

* Update snapshots
2025-03-26 13:48:08 +01:00
Joost Lekkerkerker 21d5885ded Add select entity for dishwasher operating state in SmartThings (#141468)
* Add select entity for dishwasher operating state in SmartThings

* Add select entity for dishwasher operating state in SmartThings
2025-03-26 13:39:36 +01:00
Tsvi Mostovicz 054b3bb26c Add service for counting the omer (#141008)
* Add service for counting the omer

* Add description and strings. Expect string from user

* Fix constraints on nusach and language + Make independent of config_entry

* Provide config schema

* Fix services.yaml and strings.json to match updated service.py

* Use LanguageSelector and some constants

* Action description -> third-person singular

* Use built-in language selector in yaml

* Fix schema

* Show the hebrew date in the correct language in the response

* Revert "Show the hebrew date in the correct language in the response"

This reverts commit 59442d16c531e4bd54028dea3fb9ae6a7312af7b.

Requires a bugfix in the original library

* Don't return the hebrew date as it doesn't return correctly
2025-03-26 13:38:58 +01:00
Jan Bouwhuis 77bf977d63 Add sensor as entity platform on MQTT subentries (#139899)
* Add sensor as entity platform on MQTT subentries

* Fix typo

* Improve device class data description

* Tweak

* Rework reconfig calculation

* Filter out last_reset_value_template if state class is not total

* Collapse expire after as advanced setting

* Update suggested_display_precision translation strings

* Make options and last_reset_template conditional, use sections for advanced settings

* Ensure options are removed properly

* Improve sensor options label, ensure UOM is set when device class has units

* Use helper to apply suggested values from component config

* Rename to `Add option`

* Fix schema builder not hiding empty sections and removing fields excluded from reconfig

* Do not hide advanced settings if values are available or are defaults

* Improve spelling and Learn more links

* Improve unit of measurement validation

* Fix UOM selector and translation strings

* Address comments from code review

* Remove stale comment

* Rename selector constant, split validator

* Simplify config validator

* Return tuple with config and errors for config validation
2025-03-26 13:34:24 +01:00
Robert Resch 3f68e327f3 Bump uv to 0.6.10 (#141464) 2025-03-26 13:30:57 +01:00
Marc Mueller 82db1ffd12 Update typing-extensions to 4.13.0 (#141465) 2025-03-26 13:28:46 +01:00
Allen Porter 06f6c86ba5 Simplify roborock map storage test fixture (#141430) 2025-03-26 08:19:48 -04:00
Robert Resch e3f2f30395 Add circular mean statistics and sensor state class MEASUREMENT_ANGLE (#138453)
* Add circular mean statistics

* fixes

* Add has_circular_mean and fix tests

* Fix mypy

* Rename to MEASUREMENT_ANGLE

* Fix kitchen_sink tests

* Fix sensor tests

* for testing only

* Revert ws command change

* Apply suggestions

* test only

* add custom handling for postgres

* fix recursion limit

* Check if column is already available

* Set default false and not nullable for has_circular_mean

* Proper fix to be backwards compatible

* Fix value is None

* Align with schema

* Remove has_circular_mean from test schemas as it's not required anymore

* fix wrong column type

* Use correct variable to reduce stats

* Add guard that the uom is matching a valid one from the state class

* Add some tests

* Fix tests again

* Use mean_type in StatisticsMetato difference between different mean type algorithms

* Fix leftovers

* Fix kitchen_sink tests

* Fix postgres

* Add circular mean test

* Add mean_type_changed stats issue

* Align the attributes with unit_changed

* Fix mean_type_change stats issue

* Add missing sensor recorder tests

* Add test_statistic_during_period_circular_mean

* Add mean_weight

* Add test_statistic_during_period_hole_circular_mean

* Use seperate migration step to null has_mean

* Typo ARITHMETIC

* Implement requested changes

* Implement requested changes

* Split into #141444

* Add StatisticMeanType.NONE and forbid that mean_type can be None

* Fix mean_type

* Implement requested changes

* Small leftover of latest StatisticMeanType changes
2025-03-26 13:15:58 +01:00
Brett Adams 4a6d2c91da Bump tesla-fleet-api to v1.0.16 (#140869)
* Add streaming climate

* fixes

* Add missing changes

* Fix restore

* Update homeassistant/components/teslemetry/climate.py

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

* Use dict

* Add fan mode translations

* Infer side

* WIP

* fix deps

* Migration in progress

* Working

* tesla-fleet-api==1.0.15

* tesla-fleet-api==1.0.16

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-03-26 12:28:16 +01:00
Simone Chemelli d7de8c5f68 Add full test coverage for Comelit coordinator (#141321)
* Add full test coverage for Comelit coordinator

* add common const

* apply review comment
2025-03-26 13:21:58 +02:00
Norbert Rittel 7bcba2b639 Fix online docs URL in motionblinds plus gateway naming (#141453)
* Fix online docs URL in `motionblinds` plus gateway naming

- add missing "api" to the online docs URL to make it work
- fix sentence-casing of "API key"
- replace "Motion Gateway" with "Motionblinds gateway" as there is no brand "Motion" and the list of compatible bridges cover a lot more brands

* Replace comma with period to improve readability
2025-03-26 13:11:49 +02:00
Maciej Bieniek 53990f8fad Do not show the firmware changelog for Shelly Wall Display X2 update entities (#141457)
There is no firmware changelog for Wall Display X2
2025-03-26 12:11:09 +01:00
Joost Lekkerkerker ed7c864869 Add switch for icemaker in SmartThings (#141313)
* Add switch for icemaker in SmartThings

* Fix
2025-03-26 12:10:44 +01:00
Joost Lekkerkerker 74ff40e253 Deprecate SmartThings machine state sensors (#141363)
* Deprecate SmartThings machine state sensors

* Fix
2025-03-26 11:46:50 +01:00
TimL 57d02d7a17 Cleanups related to improved typing on radios objects (#141455)
* Improved handling of radio objects

* Drop get_radio helper

* Remove mock of get_radio in tests
2025-03-26 11:45:07 +01:00
TimL 043603c9be Add SMLIGHT sensor entities for second radio (#137403)
* Add sensors for second radio

* Add test for zigbee2 sensor

* Update homeassistant/components/smlight/sensor.py

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

* drop useless replace

* Fix test failure

* Fix code coverage in config flow

* Update homeassistant/components/smlight/sensor.py

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

* fix conversion of iterator to list

* Remove assert on radios

* simplify handling of radios further

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2025-03-26 11:34:44 +01:00
TimL e10801af80 Bump pysmlight to v0.2.4 (#141450) 2025-03-26 11:28:25 +01:00
Simone Chemelli f4fa4056ac Make BT support detection dynamic for Shelly RPC devices (#137323) 2025-03-26 11:17:54 +01:00
Joost Lekkerkerker 208e8ae451 Deprecate SmartThings switch entity (#141360)
* Deprecate SmartThings switch entity

* Apply suggestions from code review

Co-authored-by: Robert Resch <robert@resch.dev>

* Fix

* Revert "Apply suggestions from code review"

This reverts commit c6d39d38de1c8b8cc1a95d79a62b6658776375cc.

* Revert "Revert "Apply suggestions from code review""

This reverts commit d92411c1560b031eb44679c3f24f3a6835279570.

* Fix

* Fix

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2025-03-26 11:05:31 +01:00
TheJulianJES 02f8322ac1 Bump ZHA to 0.0.54 (#141447)
* Bump ZHA to 0.0.54

* Add strings for v2 quirk entities

* Adjust cover tests for new ZHA behavior

* Improve cover tests further
2025-03-26 11:55:18 +02:00
Norbert Rittel e8158234a9 Fix grammar in spotify reauthentication error (#141451) 2025-03-26 11:45:55 +02:00
Norbert Rittel 7848c3cd79 Fixes to user-facing strings of cloudflare integration (#141452)
- fix sentence-casing of a few strings
- fix grammar of action description
2025-03-26 11:45:05 +02:00
Norbert Rittel 2d8420b656 Fix spelling of "serial number" in smappee (#141449) 2025-03-26 10:25:12 +01:00
Joost Lekkerkerker 63a86763b1 Migrate unique ids in SmartThings (#141308)
* Migrate unique ids in SmartThings

* Migrate

* Migrate

* Migrate

* Fix

* Fix
2025-03-26 10:23:20 +01:00
Michael b5117eb071 Proper handling of unavailable Synology DSM nas during backup (#140721)
* raise BackupAgentUnreachableError when NAS is unavailable

* also raise BackupAgentUnreachableError during upload when nas unavailable

* Revert "also raise BackupAgentUnreachableError during upload when nas unavailable"

This reverts commit 38877d8540aa3c61c366069dc063bb9b4d866c48.

* Revert "raise BackupAgentUnreachableError when NAS is unavailable"

This reverts commit 4d8cfae396ea3be3409ed8f4784b9e2448954a04.

* check last_update_success of  coordinator_central to get backup agents

* consider last_update_success before notify backup listeners

* add test

* use walrus :=  :)
2025-03-26 10:22:43 +01:00
Norbert Rittel f0c774a4bd Small grammar fixes in hue user strings (#141446)
… including proper sentence-casing
2025-03-26 11:16:10 +02:00
Simone Chemelli 8bedf97382 Remove helpers and align coding style in Shelly tests (#140080)
* Cleanup hass.states method in Shelly tests (part 1)

* remove helper functions and align coding style

* missed

* revert unwanted changes

* apply review comment

* apply review comment

* apply review comment

* apply ATTR where missing

* apply walrus

* add missed walrus

* add walrus to entity_registry.async_get

* minor tweak

* align after merge
2025-03-26 10:05:42 +01:00
Robert Resch 65c05d66c0 Use a constant for sensor statistics issues (#141441) 2025-03-26 09:43:09 +01:00
Norbert Rittel 1cb4332a3c Fix sentence-case and naming of "Security code" in tradfri (#141440) 2025-03-26 10:07:30 +02:00
Robert Resch 18dfd3db88 Simplify Reolink exception handling (#141427) 2025-03-26 08:53:46 +01:00
Luke Lashley dd914deb47 Bump roborock to silver (#141433) 2025-03-26 08:36:07 +01:00
Michael d954d04d12 Add diagnostics for Home Assistant Backup integration (#141407)
add diagnostics platform
2025-03-26 08:34:15 +01:00
Erik Montnemery e95f2c4282 Fix log level of cast print informing users to contribute model number (#141438) 2025-03-26 08:28:57 +01:00
Franck Nijhof eb1caeb770 Add template list functions: intersect, difference, symmetric_difference, union (#141420) 2025-03-26 07:51:25 +01:00
Ivan Lopez Hernandez 56cc4044e4 Fix a type error when using google-genai==1.7.0 (#141431)
* Fix parts

* Fix the type being sent to the SDK

* Revert changes to __init__

* Test fixes

* Bump version back to 1.7
2025-03-25 19:59:21 -07:00
Thomas D 2208650fde Add climate platform to qbus (#139327)
* Add climate platform

* Add unit tests for climate platform

* Use setup_integration fixture

* Apply new import order

* Undo import order

* Code review

* Throw an exception on invalid preset mode

* Let device response determine state

* Remove hvac mode OFF

* Remove hvac mode OFF

* Setup debouncer when being added to hass

* Fix typo
2025-03-26 00:25:05 +00:00
Tsvi Mostovicz e2a3bfca9a Jewish calendar migration bugfix (#141425)
Fix migration of Jewish calendar
2025-03-26 01:33:38 +02:00
starkillerOG 840613f43d Add mac to Reolink IPC cam device info (#140822)
* Add mac to Reolink IPC cams

* Add test

* check mac none
2025-03-26 00:31:01 +01:00
starkillerOG e78a19ae3e Reolink translate key (#140821)
* Add firmware exception translations

* Add test

* Much nicer syntax

* Check if translation key is present in string.json

* fix tests

* fix typo
2025-03-26 00:30:02 +01:00
Norbert Rittel 07bce8850f Capitalize one occurrence of "bluetooth" in idasen_desk (#141423)
All others are correct in the integration.

And (according to Lokalise) in Home Assistant now, too. :-)
2025-03-25 22:53:32 +00:00
Alexey ALERT Rubashёff 25a36c1588 Add AtlanticDomesticHotWaterProductionV2IOComponent to Overkiz (#139524) 2025-03-25 23:05:14 +01:00
Andrew Sayre ab709aeb46 Add Get Queue HEOS entity service (#141150) 2025-03-25 16:55:44 -05:00
J. Diego Rodríguez Royo f3bcb96b41 Tiny Home Connect tweaks (#141403) 2025-03-25 22:06:38 +01:00
Norbert Rittel 56a8c74e87 Capitalize "Bluetooth proxy" in private_ble_device integration (#141418) 2025-03-25 22:05:24 +01:00
Norbert Rittel cec21b5507 Capitalize "Bluetooth" in motionblinds_ble user strings (#141419) 2025-03-25 22:03:32 +01:00
Joost Lekkerkerker 3a62095af2 Add power binary sensor for dishwasher in SmartThings (#141417)
Add power binary sensor for dishwasher
2025-03-25 21:49:38 +01:00
Shay Levy 8dd179c9e0 Fix Ecoforest spelling of "convector" air flow sensor (#141414) 2025-03-25 21:24:44 +01:00
Joost Lekkerkerker c29ca4c50a Add power binary sensor for microwave in SmartThings (#141415)
Add power binary sensor for microwave
2025-03-25 21:24:01 +01:00
Brett Adams 013439f7c6 Add streaming to Climate platform in Teslemetry (#138689)
* Add streaming climate

* fixes

* Add missing changes

* Fix restore

* Update homeassistant/components/teslemetry/climate.py

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

* Use dict

* Add fan mode translations

* Infer side

* Apply suggestions from code review

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

* Update homeassistant/components/teslemetry/climate.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-03-25 21:09:45 +01:00
Norbert Rittel 646c97a26c Fix spelling / grammar in sensibo strings (#141130)
- capitalize "ID"
- remove excessive space and comma
- remove excessive "the"
2025-03-25 21:06:44 +01:00
elmurato e853df4fb0 Add Pterodactyl integration (#141197)
* Add Pterodactyl integration

* Remove translation for unavailable platform sensor, use constant for host

* Improve data descriptions

* Replace index based handling of data (list) with dict[str, PterodactylData]

* Replace CONF_HOST with CONF_URL

* Parse URL with YARL

* Set proper availability in binary sensor

* Remove storage of data within api.py

* Fix some review findings

* Use better unique ID for binary_sensor

* Fix more review findings

* Fix remaining review findings

* Add wrapper for server and util API, use underscore in unique ID

* Reuse result in config flow tests

* Patch async_setup_entry in config_flow tests

* Move patching of library APIs to the fixture mock_pterodactyl
2025-03-25 20:50:03 +01:00
Norbert Rittel 4cd4201a31 Add missing "r" in "Convector air flow" sensor of ecoforest (#141410)
Add lost "r" in "Convector air flow" sensor of `ecoforest`
2025-03-25 20:49:20 +01:00
Shay Levy 5db52cd5df Add data description for Shelly Bluetooth scanner mode (#141409) 2025-03-25 21:43:46 +02:00
Norbert Rittel 10d9e0c684 Fix missing capitalization in two strings of nobo_hub (#141404)
Fix missing capitalization of two strings in `nobo_hub`
2025-03-25 21:25:04 +02:00
tdfountain 8b9939c344 Remove invalid watts sensor from NUT (#141401) 2025-03-25 09:04:07 -10:00
Marc Mueller 746f49884c Update setuptools for build-system to 77.0.3 (#141394) 2025-03-25 18:39:06 +00:00
Michael Hansen ae18fa2e30 Add start conversation support to ESPHome (#141387) 2025-03-25 13:38:52 -05:00
Michael Hansen 7319637bd5 Set responding state in assist satellite start_conversation (#141388)
* Set responding state in async_start_conversation

* Check idle state
2025-03-25 14:30:44 -04:00
Simone Chemelli c8745cc339 Add full test coverage for Vodafone Station button platform (#141298) 2025-03-25 20:19:00 +02:00
G Johansson 44a02ac7a7 Bump holidays to 0.69 (#141391) 2025-03-25 18:52:31 +01:00
Joost Lekkerkerker 73642da7a4 Add sensor for brightness intensity to SmartThings (#141368) 2025-03-25 18:45:10 +01:00
J. Nick Koston e1eb031022 Bump orjson to 3.10.16 (#141339)
changelog: https://github.com/ijl/orjson/compare/3.10.15...3.10.16
2025-03-25 18:44:00 +01:00
G Johansson db66b4093a Bump psutil to 7.0.0 (#141390) 2025-03-25 07:27:17 -10:00
Maciej Bieniek ef531cec41 Add data description for Shelly config flow (#141383) 2025-03-25 17:26:13 +01:00
Huyuwei 1772348eef Add illuminance sensor to SwitchBot integration (#141382)
* Add illuminance sensor to SwitchBot integration

* Add WoHub2 sensor tests
2025-03-25 17:09:51 +01:00
Maciej Bieniek 0920d7d82d Set PARALLEL_UPDATES in IMGW-PIB sensor platform (#141386) 2025-03-25 16:09:33 +00:00
Joost Lekkerkerker 2cbe8a4a14 Add translations to Hue effects (#138990)
* Add translations to Hue effects

* Add translations to Hue effects

* Add more effects

* Fix

* Trigger build
2025-03-25 17:01:25 +01:00
Mick Vleeshouwer a2f92b1e28 Add battery discrete level sensor to Overkiz (#141328) 2025-03-25 17:19:06 +02:00
Norbert Rittel a2d9eb2a5b Sentence-case "TOTP secret" in opower config flow (#141384)
… and replace the second occurrence with a reference.
2025-03-25 17:17:57 +02:00
Huyuwei e72231037e Bump PySwitchBot to 0.58.0 (#141378) 2025-03-25 17:12:01 +02:00
starkillerOG 37aaf149f9 Bump reolink-aio to 0.13.0 (#141379)
* Bump reolink-aio to 0.13.0

* Add push cmd_id 588
2025-03-25 17:09:51 +02:00
Joost Lekkerkerker 83c21570c8 Support TVs in SmartThings (#141366) 2025-03-25 17:05:35 +02:00
Marc Mueller 42566b7378 Update pytest-asyncio to 0.26.0 (#141365) 2025-03-25 17:03:10 +02:00
Maciej Bieniek 735f877cf1 Add data description for IMGW-PIB config flow (#141381)
* Add data description for IMGW-PIB config flow

* Better wording
2025-03-25 16:57:37 +02:00
Simone Chemelli 8f000f222d Bump aiocomelit to 0.11.3 (#141375) 2025-03-25 15:50:40 +01:00
Shay Levy 05ead4d1f5 Initialize Shelly runtime_data in async_setup_entry (#141315) 2025-03-25 16:43:48 +02:00
Maikel Punie 3775f15461 Fix Velbus translations (#141372) 2025-03-25 14:37:21 +01:00
Joost Lekkerkerker 20a2fdb660 Create separate httpx client for Discovergy (#141374) 2025-03-25 09:32:25 -04:00
David Badura e49b105724 Align Matter eve thermo offset max range with eve app (#140579)
* align eve thermo offset max range with eve app

* fix tests
2025-03-25 14:22:32 +01:00
Noah Groß 19bc54c1de Bump python-picnic-api2 from 1.2.2 to 1.2.4 (#141353) 2025-03-25 14:12:07 +01:00
dependabot[bot] 3e018f2523 Bump home-assistant/wheels from 2025.02.0 to 2025.03.0 (#141359) 2025-03-25 13:51:11 +01:00
Piotr Machowski f00fb1d9a3 Add media_player support to SmartThings integration (#141296)
* Initial soundbar support

* Soundbar support

* Add SAMSUNG_VD_AUDIO_INPUT_SOURCE capability

* Adjust setting input source

* Add unit tests for media_player platform

* Adjust code after merge

* Adjust code after merge

* Adjust code style

* Adjust code style

* Fix

* Fix

---------

Co-authored-by: Piotr Machowski <PiotrMachowski@users.noreply.github.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2025-03-25 13:34:19 +01:00
jukrebs 0ddf3c794b Add attachment and connection status for IOmeter (#140998)
* add binary sensors

* fix: suggestion value_fn

* add snapshot test and split cases
2025-03-25 13:26:07 +01:00
Maikel Punie 77c210fb87 Velbus add missing translations (#141358)
Fix the translation items for Velbus
2025-03-25 13:05:46 +01:00
Norbert Rittel 17efff940a Fix missing capitalization of two strings in mysensors (#141356)
… and replace both duplicates with identical references.
2025-03-25 12:49:43 +01:00
Shay Levy 32a16ae0f0 Make UnitSystem a frozen dataclass (#140954)
* Make UnitSystem a frozen dataclass

* Use super() for attribute setting in UnitSystem class
2025-03-25 11:45:54 +01:00
Artur Pragacz 3766040960 Promote after dependencies in bootstrap (#140352) 2025-03-25 11:34:53 +01:00
adam-the-hero a1a808b843 Add EventEntity for Auto Shut Off events in Watergate integration (#135675)
* Add EventEntity for Auto Shut Off events in Watergate integration

* Split events into two: volume and duration

* Add icons to json. Extract some common translation keys. Simplify tests

* Apply suggestions from code review

* Fix

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-03-25 10:53:36 +01:00
starkillerOG e7eb173e07 Add Reolink smart ai number entities (#140417) 2025-03-25 10:49:10 +01:00
Joost Lekkerkerker 615afeb4d5 Log bare exceptions in the config flow (#135584)
* Log bare exceptions in the config flow

* add more

* Fix
2025-03-25 10:34:05 +01:00
Manu 348ebe1402 Adds create_daily action to Habitica integration (#140684)
Add create_daily action
2025-03-25 10:27:21 +01:00
J. Diego Rodríguez Royo d20fc30409 Add missing events to Home Connect (#141323)
* Add missing events to Home Connect

* Unsort

* Unsort strings also
2025-03-25 10:11:35 +01:00
pglab-electronics 13f306ddbc Add cover support to PG LAB integration (#140290)
* Add cover support to PG LAB Electronics integration

* check shutter none state in is_closing and is_opening

* adding a loop instead of test test single cover individually
2025-03-25 09:55:11 +01:00
Erik Montnemery 36d32eaabc Improve backup exclude filters (#141311)
* Improve backup exclude filters

* Add comment
2025-03-25 09:52:45 +01:00
Jan Bouwhuis 4f6daa227a Move MQTT light constants to const module (#140945) 2025-03-25 09:34:44 +01:00
Ted van den Brink b3e054d5a7 Fix for whois - quota exceeded and private registry (#141060)
* Fix for quota exceeded and private registry

* Add tests
2025-03-25 09:24:32 +01:00
Abílio Costa 5fd219fc9e Add Motionblinds Matter virtual integration (#140812)
* Add Motionblinds Matter virtual integration

* Change to iot_standards instead of virtual integration
2025-03-25 08:41:02 +01:00
Matrix 4e266fe56e Bump YoLink API to 0.4.9 fix fob event (#141343)
Fix Fob Event
2025-03-25 08:39:58 +01:00
dependabot[bot] c7e2acb4bf Bump actions/setup-python from 5.4.0 to 5.5.0 (#141342)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.4.0 to 5.5.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.4.0...v5.5.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 08:38:13 +01:00
dependabot[bot] 9888385dbe Bump github/codeql-action from 3.28.12 to 3.28.13 (#141344)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.12 to 3.28.13.
- [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.12...v3.28.13)

---
updated-dependencies:
- dependency-name: github/codeql-action
  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-03-25 08:37:55 +01:00
Joost Lekkerkerker 11877a3b12 Bump pysmartthings to 3.0.0 (#141058)
* Bump pysmartthings to 2.7.5

* Bump to pysmartthings 3.0.0
2025-03-25 08:37:32 +01:00
tdfountain ee3b31c01f Improve default icons for sensors in NUT (#141255) 2025-03-24 19:12:26 -10:00
tdfountain 598a75379b Add sensor native unit of measure in NUT (#141338) 2025-03-24 19:11:13 -10:00
Allen Porter f864f71028 Remove nest event media files that are no longer referenced (#141295)
* Remove nest event media files that are no longer referenced

* Fix double glob
2025-03-24 21:08:54 -04:00
Allen Porter 204b1e1f24 Add a Google Calendar birthdays calendar (#141300) 2025-03-24 21:06:45 -04:00
Mick Vleeshouwer b2377d6da3 Bump pyOverkiz to version 1.16.5 (#141326)
Bump pyoverkiz to version 1.16.5
2025-03-24 23:28:37 +00:00
J. Nick Koston d657809ffe Bump annotatedyaml to 0.4.5 (#141316) 2025-03-24 11:04:54 -10:00
Michael Hansen 33198cd704 Add preannounce_media_id to Assist Satellite (#141317)
Add preannounce_media_id
2025-03-24 17:04:13 -04:00
Andrew Scott 61a76b4064 Jellyfin: display album primary art instead of artist backdrop (#141246)
* Jellyfin: Properly display album primary art instead of artist backdrop when playing music

* add test for album art urls, fix existing tests that broke because they have extraneous "album*" fields for non-album items.

* fix snapshot test
2025-03-24 21:33:34 +01:00
Thomas D 0e6d72dcc8 Let device response determine state in Qbus (#141302)
Let device response determine state
2025-03-24 19:26:02 +00:00
SLaks c8f839068c Bump google-genai to 1.7.0 (#140770)
Gemini: Upgrade google-genai to support generating images
2025-03-24 10:52:16 -07:00
Erik Montnemery 3132cba51f Improve tests of backup exclusion (#141303) 2025-03-24 18:10:08 +01:00
Simone Chemelli 6661218220 Add device reconfigure to Vodafone Station config flow (#141221)
* Add device reconfigure to Vodafone Station config flow

* remove unreachable code

* apply review comment
2025-03-24 12:03:29 -05:00
Artur Pragacz 8904f174d2 Remove unused util module in conversation (#141293) 2025-03-24 17:27:27 +01:00
Michael Hansen 4472dc533d Don't filter nevermind for fallback (#141294) 2025-03-24 17:26:35 +01:00
Erik Montnemery 9fdb69c558 Remove the zengge integration (#141283) 2025-03-24 17:22:52 +01:00
Artur Pragacz 93561543ff Improve code quality of condition validation (#141292)
Streamline condition validation
2025-03-24 17:21:32 +01:00
Maciej Bieniek 1166c9d927 Do not return router as source_type for Tractive device_tracker entity (#141188)
* Do not return router as source_type

* Add test

* Update stale docstring

---------

Co-authored-by: Andrew Sayre <6730289+andrewsayre@users.noreply.github.com>
2025-03-24 17:16:59 +01:00
Maciej Bieniek 95cc3e31f5 Add exceptions translations for Shelly integration (#141071)
* Add exceptions translations

* Improve exception strings for update platform

* Fix tests

* Improve device_communication_error

* Remove error placeholder

* Improve tests

* Fix test_rpc_set_state_errors

* Strings improvement

* Remove `device`

* Remove `entity`

* Fix tests
2025-03-24 17:16:29 +01:00
puddly 5f093180ab Include hardware integrations in the cached integrations.json (#139001)
Include hardware integrations in the cached integrations JSON
2025-03-24 17:15:02 +01:00
Thomas55555 c3bab1f316 Add downtime and uptime sensors for Husqvarna Automower (#140804)
* Add downtime and uptime sensors for Husqvarna Automower

* add strings
2025-03-24 11:08:39 -05:00
Norbert Rittel e9cf4a209e Fix typos in smartthings binary sensor deprecation messages (#141299)
Fix typos in 'smartthings` binary sensor deprecation messages
2025-03-24 18:01:19 +02:00
Denis Shulyaka cb9692f3fb Raise error when max tokens reached for openai_conversation (#140214)
* Handle ResponseIncompleteEvent

* Updated error text

* Fix tests

* Update conversation.py

* ruff

* More tests

* Handle ResponseFailed and ResponseError

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2025-03-24 15:49:34 +01:00
Joost Lekkerkerker 90623bbaff Deprecate fridge door sensor in SmartThings (#141275) 2025-03-24 15:49:10 +01:00
Joost Lekkerkerker 69a375776a Add wrinkle prevent binary sensor active to SmartThings (#141289)
* Add wrinkle prevent binary sensor active to SmartThings

* Fix
2025-03-24 15:48:18 +01:00
Joost Lekkerkerker 06382f33e0 Add command to SmartThings button unique id (#141281)
* Add command to SmartThings button unique id

* Add command to SmartThings button unique id
2025-03-24 15:42:26 +01:00
Norbert Rittel b3e3d77d7c Fix spelling of "Power factor" and capitalization in enphase_envoy (#141285)
* Fix spelling of "Power factor" and capitalization in `enphase_envoy`

* Update test_sensor.ambr
2025-03-24 15:38:59 +01:00
Jan Bouwhuis e192bfb62e Do not deepcopy section schema when applying suggested values (#141280)
Do not deep copy section schema when appying suggested values
2025-03-24 15:32:57 +01:00
Erwin Douna 358f78c7cd Tado migrate to OAuth Device Flow (#140761)
* Bump PyTado 0.19.0

* Initial setup

* Current state

* Update to PyTado 0.18.8

* First concept for review

* Fix

* Fix

* Fix

* First concept for review

* Bump PyTado to 0.18.9

* Remove redundant part

* Initial test setup

* Authentication exceptions

* Fix

* Fix

* Fix

* Update version to 2

* All migration code

* Small tuning

* Add reauth unique ID check

* Add reauth test

* 100% on config flow

* Making tests working on new device flow

* Fix

* Fix

* Fix

* Update homeassistant/components/tado/strings.json

* Update homeassistant/components/tado/strings.json

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-03-24 14:28:12 +01:00
Simone Chemelli 83a0ed4250 Update Vodafone Station quality scale (#141196) 2025-03-24 13:57:08 +01:00
Franck Nijhof fa526552dc Merge branch 'master' into dev 2025-03-24 12:08:05 +00:00
Michael e96e95c32d Add sensor platform to backup integration (#138663)
* add sensor platform to backup integration

* adjust namings, remove system integration flag

* add first simple test

* apply review comments

* fix test

* add sensor tests

* adjustements to use backup helper

* remove obsolet async_get_manager from init

* unsubscribe from events on entry unload

* add configuration_url

* fix doc string

* fix sensor tests

* mark async_unsubscribe as callback

* set integration_type service

* extend sensor test

* set integration_type on correct integration :)

* fix after online conflict resolution

* add sensor update tests

* simplify the sensor update tests

* avoid io during tests

* Add comment

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-24 12:54:16 +01:00
Joost Lekkerkerker 265a2ace90 Add Bubble soak switch to SmartThings (#141139)
* Add Bubble soak switch to SmartThings

* Fix
2025-03-24 12:43:53 +01:00
karwosts 1ae2cebeb1 Support for hierarchy of individual energy devices (#132616)
* Support for hierarchy of individual energy devices

* update DeviceConsumption dict

* change name parent to 'included_in'

* Break comment

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-24 12:37:55 +01:00
Martin Hjelmare 75cd32b742 Fix backup tests typing warnings (#141274) 2025-03-24 12:36:57 +01:00
Martin Hjelmare 86ff540db9 Patch Z-Wave platforms in custom event tests (#141268)
Patch Z-Wave platforms in custom events tests
2025-03-24 12:19:29 +01:00
tronikos f4bc1a3545 Bump androidtvremote2 to 0.2.1 (#141259) 2025-03-24 13:04:47 +02:00
tronikos 4e6eecf11b Retry Google Cloud exceptions (#141266) 2025-03-24 11:27:59 +01:00
Jan Bouwhuis 0f60fd8c40 Test data entry flow form showing suggested values (#141249)
Add test with from showing suggested values to data entry flow tests
2025-03-24 10:36:02 +01:00
Simon Lamon b4fd5339c6 Bump linkplay to v0.2.1 (#141260) 2025-03-24 10:45:09 +02:00
Erik Montnemery ab9d29bf9d Remove reauth persistent notification (#140932)
* Remove persistent notification created when starting reauth

* Update netatmo tests
2025-03-24 09:29:14 +01:00
Joost Lekkerkerker 12e001cf2b Add binary sensors for fridge doors in SmartThings (#141252)
* Add binary sensors for fridge doors

* Add binary sensors for fridge doors

* Add binary sensors for fridge doors

* Add binary sensors for fridge doors
2025-03-24 10:28:10 +02:00
Norbert Rittel 590c588557 Fix sentence-casing and change to "1-Wire" in onewire strings (#141265)
* Fix sentence-casing in a few `onewire` strings

* Change "OneWire" to "1-Wire"
2025-03-24 10:25:13 +02:00
Pieter Viljoen d65392a374 ConfigSubEntryFlow _get_reconfigure_entry() -> _get_entry() (#141017)
* ConfigSubEntryFlow _get_reconfigure_entry() -> _get_entry()

* Update MQTT test

* Fix test_config_entries

* Minimize changes to keep existing tests working

* Re-revert and update negative test instead
2025-03-24 09:24:43 +01:00
Simon Lamon 0514de3e16 Remove manufacturer data for linkplay (#141261)
Remove manufacturer data
2025-03-24 09:13:06 +01:00
tronikos 59190786f9 Bump gassist-text to 0.0.12 (#141244) 2025-03-24 00:46:30 -07:00
Erik Montnemery f4d57e3722 Add cloud onboarding views (#139422)
* Add cloud onboarding views

* Break import cycle when running hassfest

* Add exemption to hassfest for onboarding using cloud

* Adjust according to discussion

* Fix copy-paste errors

* Add tests

* Fix stale docstring

* Import cloud loally
2025-03-24 08:41:19 +01:00
Mirko Liebender d3b8dbb76c Google gen ai fix for empty chat log messages (#136019) (#140315)
* Google gen ai fix for empty chat log messages (#136019)

* Google gen ai test for empty chat history fields (#136019)
2025-03-23 22:27:35 -07:00
Ivan Lopez Hernandez 6a7fa3769d Add Google Search tool in Google Generative AI (#140772)
* Added Google Search grounding

* Added testing
2025-03-23 22:23:52 -07:00
tdfountain af96fedc0f Alphabetize key lists for strings, icons and sensors in NUT (#141254) 2025-03-23 15:58:41 -10:00
Joost Lekkerkerker 174515d197 Use common translation string in SmartThings (#141250) 2025-03-23 23:18:40 +01:00
Norbert Rittel 693de289a2 Fix descriptions of virtualkey and set_variable_value actions (#141175)
- fix the broken grammar ("presses" vs. "simulate") in the description of the `virtualkey` action by using the wording from the online docs instead
- fix the wrong description of the `set_variable_value` action by replacing it with the right one from the online docs
2025-03-23 23:03:58 +01:00
Thomas55555 b171439098 Bump aioautomower to 2025.3.2 (#141211)
* Bump aioautomower to 2025.3.2

* requirements

* adjust test
2025-03-23 22:19:16 +01:00
Jan Bouwhuis 93010ab5c9 Ensure suggested values are added to section schema in data entry fow (#141227) 2025-03-23 22:14:06 +01:00
Allen Porter 842356877e Bump mcp to 1.5.0 (#141219)
* Bump mcp to 1.5.0

* Add required server lifespan typing

* Remove comment about typing
2025-03-23 22:12:44 +01:00
Michael Hansen 2883f0a1e8 Bump intents to 2025.3.23 (#141241) 2025-03-23 22:12:05 +01:00
Patrick ZAJDA 27f529622c Switchbot: revert name set to none for temperature sensor (#141149) 2025-03-23 10:51:13 -10:00
J. Nick Koston 3917b460f4 Bump dbus-fast to 2.43.0 (#141240) 2025-03-23 10:48:34 -10:00
Norbert Rittel ec5139eb94 Fix typo "to setup" in slide_local (#141216) 2025-03-23 21:12:45 +01:00
Robert Svensson 5d16a23d79 Bump pydeconz to v120 (#141239) 2025-03-23 10:00:27 -10:00
tdfountain 56cb54588e Set parallel updates in NUT (#141225) 2025-03-23 09:35:58 -10:00
Norbert Rittel e2f7133d00 Fix spelling of "breadcrumbs" in sentry integration (#141189)
Replace "breadcrums" with "breadcrumps" as this is the spelling  that both Sentry and the HA online docs use.

Also use "events" instead of "logs" as the log is the whole and the events are its parts.
2025-03-23 21:26:45 +02:00
Maciej Bieniek 1f122ea54d Improve error handling and add exception translations for Nettigo Air Monitor integration (#141183)
* Add update_error

* Add device_communication_error

* Add auth_error

* Add device_communication_action_error

* Coverage
2025-03-23 21:23:11 +02:00
Norbert Rittel ef84fc52af Clarify the meaning of "recorder" in energy issue description (#141228)
Clarify the meaning of "The recorder" in `energy` issue description

"The recorder" has resulted in a bunch of overtranslations that make this alert useless.

By using "Home Assistant Recorder" instead this should get fixed.
2025-03-23 21:21:18 +02:00
Norbert Rittel 9677b0d254 Capitalize "Recorder" as the component name in Home Assistant (#141226) 2025-03-23 21:09:52 +02:00
Norbert Rittel 1d36279e79 Use correct unit symbol "min" for minutes in systemmonitor integration (#141236)
* Use correct unit symbol "min" for minutes in `systemmonitor` integration

* Update test_sensor.ambr

* Remove accidentially added, excessive space character
2025-03-23 21:08:25 +02:00
Norbert Rittel c2057d19c0 Capitalize "ID" and "URL" abbreviations in trafikverket_camera (#141238)
Make the spelling consistent throughout Home Assistant.
2025-03-23 21:05:15 +02:00
Norbert Rittel d23a724f79 Fix typo "to setup" in reolink (#141214) 2025-03-23 19:28:45 +01:00
Allen Porter 28ef0a33ad Update MCP to reconnect to the server on demand (#141215)
* Reconnect to the MCP client on deman

* Remove debug log

* Update log messages
2025-03-23 12:11:40 -04:00
Allen Porter c451518959 Fix google calendar working location event filtering (#141222) 2025-03-23 09:07:42 -07:00
Allen Porter f14b76c54b Add Gemini/OpenAI token stats to the conversation trace (#141118)
* Add gemini token status to the conversation trace

* Add OpenAI Token Stats

* Revert input_tokens_details since its not in the openai version yet

* Fix ruff lint errors
2025-03-23 12:03:06 -04:00
Artur Pragacz 663a204c04 Fix Python path for vscode run core task (#141090)
Fix Python path for vscode launch core task
2025-03-23 12:01:35 -04:00
Norbert Rittel a6ff5391e5 Fix typo "to setup" in homeassistant_hardware (#141212)
Fix typo "to setup" in multiple integrations
2025-03-23 17:26:28 +02:00
Norbert Rittel 3df1ebf2fc Fix typo "to setup" and sentence-casing in twilio (#141218) 2025-03-23 17:25:05 +02:00
Simon Lamon 5f3344cd3d Bump linkplay to v0.2.0 (#141098)
* Bump linkplay to v0.2.0

* Fix invalid reference on items()

* Ruff
2025-03-23 16:27:40 +02:00
Norbert Rittel 56f553e352 Clarify meaning of "level" in dynalite.request_channel_level action (#141184)
Without context it's very difficult to come up with a good translation of "level" as there are many different words for this in other languages.

This commit adds "brightness" to explain the meaning of "channel level" in `dynalite`.
2025-03-23 16:26:44 +02:00
J. Nick Koston 8869236e9c Bump google-cloud-pubsub to 2.29.0 (#141178)
changelog: https://github.com/googleapis/python-pubsub/compare/v2.28.0...v2.29.0
2025-03-23 16:26:14 +02:00
Norbert Rittel f94b55b608 Fixes to user-facing strings of azure_devops integration (#141208)
* Fixes to user-facing strings of `azure_devops` integration

- capitalize abbreviations "ID" and "URL"
- sentence-case "project"
- consistently capitalize "Personal Access Token" as a name

* Update test_sensor.ambr
2025-03-23 16:22:57 +02:00
Martin Hjelmare fdaba003ce Patch Z-Wave platforms in event tests (#141209) 2025-03-23 16:22:18 +02:00
Norbert Rittel 703848766a Capitalize "URL" in feedreader error message (#141210) 2025-03-23 16:21:48 +02:00
Shay Levy ba8ec22587 Add Switcher missing data descriptions (#141077) 2025-03-23 16:20:37 +02:00
Michael 6b724603c8 Remove orphan fuel type settings from Tankerkoening (#141207)
remove orphan fule type settings
2025-03-23 15:01:53 +01:00
Simone Chemelli 2465d0db7b Cleanup Vodafone Station strings (#141202) 2025-03-23 14:52:22 +01:00
Norbert Rittel 4758452e92 Use correct unit symbol "min" for minutes in asuswrt integration (#141206)
* Use correct unit symbol "min" for minutes in `asuswrt` integration

* Sentence-case all "temperature" sensors
2025-03-23 15:35:59 +02:00
Martin Hjelmare 588d6ad4cf Patch Z-Wave platforms in cover tests (#141205) 2025-03-23 15:35:29 +02:00
Norbert Rittel c7d1e5a28c Fix spelling of "Do you want to set up?" in airgradient (#141199) 2025-03-23 15:17:32 +02:00
Norbert Rittel 8874fbe9c7 Fix sentence-casing of "Station radius" in airnow (#141200) 2025-03-23 15:16:54 +02:00
Norbert Rittel ef2485be3b Fix sentence-casing in part of airq sensor names (#141203) 2025-03-23 15:15:41 +02:00
Martin Hjelmare 34504f45a5 Patch Z-Wave platforms in climate tests (#141204) 2025-03-23 15:15:09 +02:00
Artur Pragacz 798ee60ae5 Make variables action not restricted to local scopes (#141114)
Make variables action in scripts not restricted to local scopes
2025-03-23 14:07:52 +01:00
Simone Chemelli ca10618dc7 Update strings for Comelit (#140925)
* Update strings for Comelit

* apply review comment

* apply review comment

* Update homeassistant/components/comelit/strings.json

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>

---------

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>
2025-03-23 12:50:02 +01:00
Simone Chemelli 77f8ddd948 Fix climate and humidifier platform for Comelit (#140611)
fix climate and humidifier platform for Comelit
2025-03-23 12:32:38 +01:00
Norbert Rittel 5c642ef626 Fix spelling of user-facing strings in adax integration (#141190)
- capitalize "Bluetooth" and "LED"
- sentence-case "Wi-Fi password"
2025-03-23 13:21:07 +02:00
Michael 489c486278 Rework Synology DSM to use config entry runtime_data (#141084)
rework to use config entry runtime_data
2025-03-23 12:05:40 +01:00
J. Diego Rodríguez Royo d8a5881eaa Home Connect test improvements (#141135)
* Home Connect test improvements

* Remove `appliance_ha_id` fixture in favour of `appliance` fixture
2025-03-23 11:33:55 +01:00
Nerdix 883ce6842d Fix icon for "Coffee and Milk counter" in HomeConnect (#141170)
fix coffee and milk counter
2025-03-23 10:28:10 +01:00
Allen Porter 3a80a2d5b9 Bump openai to 1.68.2 (#141154)
* Bump openai to 1.68.2

* Remove unused type ignore
2025-03-22 23:12:02 -10:00
Luke Lashley 65279c94ac Finish strict typing for Roborock (#141165)
Mark strict typing as done
2025-03-22 23:07:22 -10:00
J. Nick Koston 87db981712 Bump anyio to 4.9.0 (#141161)
changelog: https://github.com/agronholm/anyio/compare/4.8.0...4.9.0
2025-03-23 10:34:49 +02:00
J. Nick Koston 153ccf86b0 Bump dbus-fast to 2.41.1 (#141162)
* Bump dbus-fast to 2.41.0

changelog: https://github.com/Bluetooth-Devices/dbus-fast/compare/v2.39.6...v2.41.0

* Apply suggestions from code review
2025-03-23 10:33:44 +02:00
tdfountain 9e86ca2e9e Add Switch platform and PDU dynamic outlet switches to NUT (#141159) 2025-03-22 19:27:52 -10:00
Luke Lashley e2e80a850c Add dhcp discovery to Roborock (#141148)
* Add discovery to Roborock

* Update homeassistant/components/roborock/config_flow.py

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

* MR comments

* go back to removing the ":"

* change method of getting devices

---------

Co-authored-by: Allen Porter <allen.porter@gmail.com>
2025-03-22 21:21:43 -07:00
tdfountain ddd67a7e58 Add PDU dynamic outlet buttons to NUT (#140317) 2025-03-22 13:04:20 -10:00
tdfountain a9df341abf Optimize entity creation by storing device name as data in NUT (#141147) 2025-03-22 11:11:48 -10:00
Allen Porter 4e2dfba45f Omit state from the Assist LLM prompts (#141034)
* Omit state from the Assist LLM prompts

* Add back the stateful prompt
2025-03-22 15:41:51 -04:00
Thomas55555 61e30d0e91 Add diagnostics to remote calendar (#141111)
* Add diagnostics

* add diagnostics

* address review

* ruff

* ruff

* use raw ics data

* mypy

* mypy

* naming

* redact ics

* ruff

* simpify

* reduce data

* ruff
2025-03-22 12:27:48 -07:00
Luke Lashley 6d91bdb02e Inject websession for Roborock api client (#141141) 2025-03-22 12:19:54 -07:00
Andrew Sayre 7f640252a1 Use Debouncer helper in HEOS Coordinator (#141133)
Use Debouncer
2025-03-22 21:12:51 +02:00
Joost Lekkerkerker f245bbd8dd Add door state binary sensor to SmartThings (#141143) 2025-03-22 20:04:21 +01:00
Joost Lekkerkerker b47d3076cc Add oven stop button to SmartThings (#141142) 2025-03-22 20:51:41 +02:00
Mick Vleeshouwer 99d0449cbe Bump pyOverkiz to 1.16.4 in Overkiz (#141132)
* Bump Overkiz to 1.16.3

* Add missing generated files
2025-03-22 20:40:47 +02:00
Luke Lashley 1e0b89c381 Bump python Roborock to 2.16.1 (#141033)
* Bump python Roborock to 2.15.0

* Add aiohttp clientsession

* inject websession

* fix lint after merge

* bump to 2.16

* bump and revert

* revert formatting
2025-03-22 11:29:32 -07:00
Joost Lekkerkerker c56b087d0c Add Dryer Wrinkle Prevent switch to SmartThings (#141085)
* Add Dryer Wrinkle Prevent switch to SmartThings

* Fix
2025-03-22 19:05:21 +01:00
Joost Lekkerkerker 4b4d75063c Add number platform to SmartThings (#141063)
* Add select platform to SmartThings

* Add number platform to SmartThings

* Fix

* Fix

* Fix

* Fix
2025-03-22 19:03:26 +01:00
Joost Lekkerkerker 931ce8951e Use category to define SmartThings binary sensor device class (#141075)
* Use category to define SmartThings binary sensor device class

* Fix
2025-03-22 12:41:15 -05:00
tdfountain 92c619cdd6 Create new entity base class for NUT (#141122) 2025-03-22 07:40:47 -10:00
Andrew Sayre 436acaf3d0 Remove uncalled function in HEOS (#141134)
Remove uncalled function
2025-03-22 12:37:11 -05:00
Andrew Sayre ec4de0dcce Always allow browsing TuneIn for HEOS (#141131)
* Always allow browsing TuneIn

* Update test snapshots

* Retry CI
2025-03-22 18:14:42 +01:00
Joost Lekkerkerker 1b8b348eff Add select platform to SmartThings (#141115)
* Add select platform to SmartThings

* Add select platform to SmartThings
2025-03-22 18:03:50 +01:00
Joost Lekkerkerker 765691c84d Add power binary sensor for SmartThings (#141126) 2025-03-22 17:59:15 +01:00
Luke Lashley fc0dbcd600 Refresh coordinator after map sleep for Roborock (#141093)
Refresh coordinator after the map sleep
2025-03-22 09:01:57 -07:00
Matthew FitzGerald-Chamberlain b2942d61b3 Update pyaprilaire to 0.8.1 (#141094)
* Update pyaprilaire to 0.8.1

* Update requirements
2025-03-22 16:57:30 +02:00
Simone Chemelli 37a048a2ca Move Vodafone Station to silver quality scale (#141106) 2025-03-22 15:53:12 +01:00
Norbert Rittel 2453e7e686 Improve descriptions of fan_min_on_time in ecobee actions (#141086)
Add the explanations from the online docs to the `description` strings of both the `set_fan_min_on_time` action and its `fan_min_on_time` field.

Make the `fan_min_on_time` field of the `create_vacation` action consistent by dropping "(0 to 60)" from it (the UI takes care of that).

Fix sentence-casing of "Away indefinitely" state.
2025-03-22 16:30:24 +02:00
J. Diego Rodríguez Royo 4479b7b13d Add missing Home Connect chiller doors (#141105) 2025-03-22 14:31:28 +01:00
Joost Lekkerkerker 1492c59abe Delete deleted devices on runtime in SmartThings (#141080) 2025-03-22 13:12:37 +01:00
Joost Lekkerkerker 5961a46fc0 Start reauth for SmartThings if token expired (#141082) 2025-03-22 13:12:24 +01:00
J. Nick Koston b7d300b49f Bump habluetooth to 3.37.0 (#141088)
changelog: https://github.com/Bluetooth-Devices/habluetooth/compare/v3.36.0...v3.37.0
2025-03-22 14:06:49 +02:00
J. Diego Rodríguez Royo dc146e393c Add coordinator context override to Home Connect entity constructor (#141104)
* Improve Home Connect entity constructor to allow coordinator context override

* Simplify context usage at entity constructor
2025-03-22 12:42:54 +01:00
J. Diego Rodríguez Royo 9d9b352631 Move Home Connect service actions to a services.py (#141100)
* Move Home Connect service actions to a actions.py

* Rename actions.py to services.py

* Move more fuctions to module level
2025-03-22 12:35:46 +01:00
Maciej Bieniek c08cbf3763 Use ShellyConfigEntry type in Shelly config flow (#141103)
Use ShellyConfigEntry type in async_get_options_flow
2025-03-22 11:57:59 +02:00
J. Diego Rodríguez Royo ffd5c003cb Remove Home Connect service error string constants (#141102) 2025-03-22 10:48:35 +01:00
Andrew Sayre 34318ab655 Bump pyheos to 1.0.4 (#141091) 2025-03-21 12:19:05 -10:00
J. Nick Koston 6027a26761 Add SSLContext.set_default_verify_paths to asyncio blocking detection (#140648)
This one loads a significant number of files from /etc/ssl
2025-03-21 11:50:18 -10:00
tdfountain 2571725eb9 Add metered PDU dynamic outlet sensors to NUT (#140179)
* Add metered PDU dynamic outlet sensors

* Make deep copy and improve efficiency of loops

* Improve performance by creating new dict

Co-authored-by: J. Nick Koston <nick+github@koston.org>

* Remove unused import copy

* Use outlet name (if available) in friendly name and remove as separate sensor

---------

Co-authored-by: J. Nick Koston <nick+github@koston.org>
2025-03-21 11:41:43 -10:00
dependabot[bot] 84c6fa256c Bump home-assistant/builder from 2025.02.0 to 2025.03.0 (#141039)
Bumps [home-assistant/builder](https://github.com/home-assistant/builder) from 2025.02.0 to 2025.03.0.
- [Release notes](https://github.com/home-assistant/builder/releases)
- [Commits](https://github.com/home-assistant/builder/compare/2025.02.0...2025.03.0)

---
updated-dependencies:
- dependency-name: home-assistant/builder
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-21 21:44:33 +01:00
Franck Nijhof 2f244b2b66 2025.3.4 (#141081) 2025-03-21 21:21:43 +01:00
Martin Hjelmare 1b7e53fd01 Improve Home Connect appliances test fixture (#139787)
Improve Home Connect appliances fixture
2025-03-21 19:45:18 +00:00
Franck Nijhof bfabf972a8 Bump version to 2025.3.4 2025-03-21 19:35:24 +00:00
Luke Lashley c0c997eed8 Bump python-snoo to 0.6.4 (#141030) 2025-03-21 19:35:03 +00:00
Luke Lashley 14b07087dc Bump Python-Snoo to 0.6.3 (#140628)
Bump python-Snoo to 0.6.3
2025-03-21 19:34:59 +00:00
puddly f54a634563 Bump ZHA to 0.0.53 (#141025)
* Bump ZHA to 0.0.53

* Regenerate snapshot
2025-03-21 19:33:41 +00:00
J. Diego Rodríguez Royo e98d518b0b Fix some Home Connect options keys (#141023)
Fix some options keys
2025-03-21 19:33:38 +00:00
starkillerOG 121ee27105 Reolink fix playback headers (#141015) 2025-03-21 19:33:35 +00:00
Ivan Lopez Hernandez 5681f4f2ea Ensure file is correctly uploaded by the GenAI SDK (#140969)
Opened the file outside of the SDK
2025-03-21 19:33:32 +00:00
Joost Lekkerkerker 8a63fa3bb7 Log SmartThings subscription error on exception (#140939) 2025-03-21 19:33:28 +00:00
Josef Zweck 983a2f513d Bump pylamarzocco to 1.4.9 (#140916) 2025-03-21 19:33:24 +00:00
Joost Lekkerkerker aab349e787 Fix SmartThings ACs without supported AC modes (#140744) 2025-03-21 19:31:08 +00:00
Joost Lekkerkerker 21ced23c3c Bump pySmartThings to 2.7.4 (#140720)
* Bump pySmartThings to 2.7.3

* Bump pySmartThings to 2.7.3

* Fix

* Fix

* Fix
2025-03-21 19:25:33 +00:00
Josef Zweck a453e9d4c2 Don't reload onedrive on options flow (#140712) 2025-03-21 19:21:22 +00:00
Joost Lekkerkerker 1385bcdb90 Grade SmartThings on the integration quality scale (#141078) 2025-03-21 20:19:45 +01:00
Adam Feldman 3f493dce06 Fix broken core integration Smart Meter Texas by switching it to use HA's SSL Context (#140694)
* Update __init__.py to use HA's SSLContext

* Update config_flow.py to use HA's SSLContext

* Use default context for config_flow.py

* Use default context instead in __init__.py

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

* Fix import in __init__.py

* Fix import in config_flow.py

---------

Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-03-21 19:19:06 +00:00
Joost Lekkerkerker 403fe36489 Check Celsius in SmartThings oven setpoint (#140687) 2025-03-21 19:19:03 +00:00
J. Nick Koston 66fd7d9e8a Bump PySwitchBot to 0.57.1 (#140681)
changelog: https://github.com/sblibs/pySwitchbot/compare/0.56.1...0.57.1

fixes #140405
2025-03-21 19:19:00 +00:00
Glenn Waters c9ceade10d Fix Elk-M1 missing TLS 1.2 check (#140672)
* Fix for missing TLS 1.2 check

* Fix error message.

* combine startswith

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
2025-03-21 19:18:57 +00:00
Joost Lekkerkerker 85b6b3a360 Make Oven setpoint follow temperature UoM in SmartThings (#140666) 2025-03-21 19:18:08 +00:00
Maikel Punie a2102f9b98 Fix optional password in Velbus config flow (#140615)
* Fix velbusconfigflow

* add tests

* Paramtize the tests

* Removed duplicate test in favor of another case

* more comments
2025-03-21 19:12:20 +00:00
J. Diego Rodríguez Royo 28cad1d085 Handle non documented options at Home Connect select entities (#140608)
* Allow non documented options at select entities

* Don't allow undocumented options
2025-03-21 19:12:17 +00:00
J. Diego Rodríguez Royo 9d8dbfbf3f Add 700 RPM option to washer spin speed options at Home Connect (#140607)
Add 700 RPM option to washer spin speed options
2025-03-21 19:12:14 +00:00
Hessel 1382a001e3 Change max ICP value to fixed value for Wallbox Integration (#140592)
change max ICP value to fixed value

Co-authored-by: Hessel van Es <hessel@datadragons.nl>
2025-03-21 19:12:10 +00:00
Pete Sage 88e3dcccda Album art not available for Sonos media library favorites (#140557)
* get album art uri for favorites

* add tests

* update typing

* update typing

* update typing

* simplify
2025-03-21 19:12:07 +00:00
J. Diego Rodríguez Royo 43e24cf833 Handle API rate limit error on Home Connect entities fetch (#139384)
* Handle API rate limit error on entities fetch

* Apply suggestions

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

* Add decorator (does not work)

* Fix decorator

* Apply suggestions

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

* Add test

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-21 19:12:03 +00:00
J. Diego Rodríguez Royo 65aef40a3f Fix initial fetch of Home Connect appliance data to handle API rate limit errors (#139379)
* Fix initial fetch of appliance data to handle API rate limit errors

* Apply comments

* Delete stale function

* Handle api rate limit error at options fetching

* Update appliances after stream non-breaking error

* Always initialize coordinator data

* Improve device update

* Update test description

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

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-21 19:11:58 +00:00
Joost Lekkerkerker 276e2e8f59 Move device creation in SmartThings (#141074)
Move device creation
2025-03-21 19:32:05 +02:00
Joost Lekkerkerker 5f67623214 Deprecate SmartThings events (#141073) 2025-03-21 18:26:17 +01:00
Joost Lekkerkerker e78e873892 Add update platform to SmartThings (#141070)
* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* fix

* fix

* Add AC tests

* Add thermostat tests

* Add cover tests

* Add device tests

* Add light tests

* Add rest of the tests

* Add update

* Add oauth

* Add oauth tests

* Add oauth tests

* Add oauth tests

* Add oauth tests

* Bump version

* Add rest of the tests

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Add test fixtures

* Add test fixtures
2025-03-21 17:01:13 +01:00
G Johansson 16d335efc0 Update quality scale for Sensibo (#135924)
* Update quality scale for Sensibo

* platinum
2025-03-21 16:59:03 +01:00
Joost Lekkerkerker 74ed0e8011 Add support for PM1.0 in SmartThings (#141061)
* Add support for PM1.0 in SmartThings

* Add test fixtures

* Add test fixtures
2025-03-21 16:29:00 +01:00
Simone Chemelli c1753631b1 Handle button presses exceptions for Vodafone Station (#140953)
* Handle button presses execeptions for Vodafone Station

* apply review comment
2025-03-21 16:26:51 +01:00
Joost Lekkerkerker f84a46680d Add event platform to SmartThings (#141066)
* Add event platform to SmartThings

* Add event platform to SmartThings

* Fix
2025-03-21 16:20:42 +01:00
Joost Lekkerkerker a9cbc72ce5 Add child lock to SmartThings (#140200)
* Add kids lock to SmartThings

* Add kids lock to SmartThings

* Fix

* Fix
2025-03-21 14:03:44 +01:00
Luke Lashley 466ec0b596 Fix failing Roborock test (#141059)
Fix the falky test
2025-03-21 05:31:17 -07:00
Wouter 858f0e6657 Fixed issue where the device was already disconnected when setting up the event platform (#140722)
* Changed where the script events are collected to remove any device communication from async_setup_entry

* Implemented improvements and added a test to test whats happends when script_getcode fails

* Renamed script_events to rpc_script_event to make clear this is only for RPC devices

Co-authored-by: Shay Levy <levyshay1@gmail.com>

---------

Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-03-21 14:13:56 +02:00
Jan-Philipp Benecke 4ed2689678 Handle wrong WebDAV URL more gracefully in config flow (#141040) 2025-03-21 12:25:26 +02:00
fwestenberg 1fafe81d20 Update Stookwijzer diagnostics and description (#141041)
Update diagnostics and description
2025-03-21 12:20:15 +02:00
Norbert Rittel 3101d9099b Fix spelling of "mDNS" in esphome (#141052)
Change "MDNS" to the correct "mDNS".
2025-03-21 12:19:07 +02:00
Maciej Bieniek 2785688f57 Add calibrate button for Shelly BLU TRV (#140578)
* Initial commit

* Refactor

* Call async_add_entities() once

* Type

* Cleaning

* `supported` is not needed here

* Add error handling

* Add test

* Fix name

* Change class name

* Change method name

* Move BLU_TRV_TIMEOUT

* Fix BLU_TRV_TIMEOUT import

* Coverage

* Use test snapshots

* Support error translations

* Fix tests

* Introduce ShellyBaseButton class

* Rename press_method to _press_method

* Improve exception strings
2025-03-21 10:14:20 +01:00
Norbert Rittel bce7fcc3c6 Capitalize "DIP" abbreviation in apcupsd (#141048)
As "DIP" stands for "dual in-line package" it becomes capitalized as an abbreviation.
2025-03-21 09:44:02 +01:00
J. Nick Koston 021e4fab8c Bump habluetooth to 3.36.0 (#141037)
* Bump habluetooth to 3.35.0

changelog: https://github.com/Bluetooth-Devices/habluetooth/compare/v3.32.0...v3.35.0

* adjust
2025-03-21 08:12:55 +01:00
puddly 110500b860 Bump ZHA to 0.0.53 (#141025)
* Bump ZHA to 0.0.53

* Regenerate snapshot
2025-03-21 07:44:57 +01:00
Luke Lashley e388d0c344 Bump python-snoo to 0.6.4 (#141030) 2025-03-21 07:42:02 +01:00
Allen Porter a83bf4f514 Add a GetHomeState tool to return the current state of the home (#140971)
* Add a GetHomeState tool to return the current state of the home

* Fix check for exposing entities

* Add "all" to get home state description
2025-03-20 19:37:54 -07:00
Luke Lashley a388863e62 Remove stale devices automatically for Roborock (#140991)
* Remove stale devices

* Add test

* extra test + fix networking patch bug
2025-03-20 18:28:37 -07:00
Abílio Costa d12b4a1460 Log a warning for modules that log too often (#139708)
* Log a warning for modules that log too often

* Improve var naming

* Increase time window; improve log info

* Fix zha type

* Fix typo

* Ignore debug logs

* Use timer to avoid now() calls

* Switch to async_track_time_interval

* Allow using base QueueLister

* Add test for counters reset

* Make var names consistent; reduce message/time ratio

* Use log times instead of timer

* Simplify reset test

* Warn only once per module

* Remove uneeded counter reset
2025-03-20 14:53:53 -10:00
puddly 87c8234cdc Allow USB polling monitor on macOS for development (#141029)
* Allow USB polling on macOS

* Remove `_async_supports_monitoring`
2025-03-20 14:43:29 -10:00
dependabot[bot] 72645dff8b Bump actions/cache from 4.2.2 to 4.2.3 (#140977) 2025-03-21 00:34:48 +01:00
Marc Mueller b936739917 Update pylint to 3.3.6 (#141028) 2025-03-21 00:33:16 +01:00
J. Diego Rodríguez Royo a45c8d2820 Fix some Home Connect options keys (#141023)
Fix some options keys
2025-03-20 22:52:46 +01:00
Norbert Rittel 98f7193986 Apply sentence-casing to all status codes in litterrobot (#141020) 2025-03-20 21:23:35 +01:00
starkillerOG 5d1c8ea537 Reolink fix playback headers (#141015) 2025-03-20 20:45:07 +01:00
Norbert Rittel 95014dfdd8 Fix name of energenie_power_sockets integration (#141014)
* Fix name of `energenie_power_sockets` integration

Remove "integration." from the integration name.

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-03-20 21:43:13 +02:00
Maciej Bieniek 53f1dd8adf Improve error handling and add exception translations for NextDNS integration (#141005)
* Add exception translations

* Coverage

* Add missing auth_error

* Coverage

* Use async_start_reauth

* Fix test

* Remove method placeholder
2025-03-20 20:33:45 +02:00
Norbert Rittel a338205b73 Fix sentence-casing of "round-trip time" sensors in ping (#141012)
* Fix sentence-casing of "round-trip time" sensors in `ping`

Also add a hyphen for better English grammar.

* Update test_sensor.ambr
2025-03-20 20:30:28 +02:00
poucz a030502489 Add MQTT cover stop tilt (#139912)
* Stop tilt move.

Stop tilt use same payload as cover - payload_stop

* Add test for STOP_TILT

* Tilt action

* Revert "Tilt action"

This reverts commit 7ce4fbb086616a900fc53277d379cbf03e9e0339.

* Update tests/components/mqtt/test_cover.py

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

* Update homeassistant/components/mqtt/cover.py

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

* Append CONF_PAYLOAD_STOP_TILT

* Update homeassistant/components/mqtt/cover.py

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>

* Test for new payload

* Update tests/components/mqtt/test_cover.py

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>

* Update tests/components/mqtt/test_cover.py

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>

* Ruff format

* abbreviation

---------

Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
2025-03-20 18:20:12 +00:00
EnjoyingM f9bb250621 Wolf Smartset: Adding Heatpump Parameters: Frequency, RPM and Flow rate (#140844)
* Add missing Heatpump parameters and units

* Fix merge issue

* Fix snapshot

* Removing bundle_id as extra state attribute till functionality is needed and updating api translation with missing phrase

* Fix translations for listparameters

* Fix translations for listparameters
2025-03-20 18:46:04 +01:00
Abílio Costa eca10ea591 Improve Withings sleep and weight default units (#140665) 2025-03-20 18:45:52 +01:00
Robert Resch 32c6fb8629 Bump uv to 0.6.8 (#141007) 2025-03-20 19:20:40 +02:00
Norbert Rittel 4bbd49af53 Capitalize "PIN to Drive" feature name in teslemetry (#141011)
* Capitalize "PIN to Drive" as feature name in `teslemetry`

Fixes the spelling of "PIN" for consistency and turns "PIN to Drive" into the feature name that Tesla uses (in English).

* Update test_binary_sensor.ambr
2025-03-20 19:20:08 +02:00
peteS-UK e48a25e952 Add button platform for Squeezebox integration (#140697)
* initial

* trans key correction

* base class updates

* model tidy up

* Update homeassistant/components/squeezebox/strings.json

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

* Update homeassistant/components/squeezebox/entity.py

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

* Update homeassistant/components/squeezebox/media_player.py

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

* Update homeassistant/components/squeezebox/media_player.py

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

* Update homeassistant/components/squeezebox/button.py

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

* review updates

* update

* move manufacturer to library

* updates

* list concat

* review updates

* Update tests/components/squeezebox/test_button.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-03-20 17:18:08 +01:00
Maciej Bieniek 70ed120c6e Add exception translations for GIOS integration (#141006)
Add exception translations
2025-03-20 16:58:49 +01:00
Martin Hjelmare a835c85f59 Patch Z-Wave platforms in button tests (#141001) 2025-03-20 16:37:02 +02:00
Luke Lashley 2a4ed9ace7 Add translations for Roborock Exceptions (#140964)
* Add translations to a few exceptions

* match existing wording

* fix regex

* consolidate errors

* fix test
2025-03-20 07:14:45 -07:00
Petro31 212d39ba19 Migrate template switch to new style (#140324)
* Migrate template switch to new style

* update tests

* Update tests

* Add config flow migration

* comment fixes

* revert entity config migration
2025-03-20 15:12:43 +01:00
Martin Hjelmare 5f84fc3ee5 Patch Z-Wave platforms in binary sensor tests (#140992) 2025-03-20 16:06:21 +02:00
Artur Pragacz c9b27cf26e Detect early base platforms in bootstrap (#140359)
* Detect early base platforms in bootstrap

* Address feedback

* Address feedback
2025-03-20 12:56:45 +01:00
Martin Hjelmare df0125abdd Patch Z-Wave platforms in api tests (#140988) 2025-03-20 12:54:40 +01:00
Martin Hjelmare d8a4a97ee0 Allow patching Z-Wave platforms specifically in tests (#140987) 2025-03-20 12:19:14 +01:00
starkillerOG a20601a1f0 Bump reolink-aio to 0.12.3 (#140789)
* Add password length restriction

* Bump reolink-aio to 0.12.3

* Add repair issue for too long password

* finish password too long repair issue

* add test
2025-03-20 11:39:57 +01:00
Franck Nijhof d3c40939f6 Reorder template extensions (#140985) 2025-03-20 11:34:02 +01:00
Marc Mueller 56e966a980 Update project metadata for PEP 639 (#140960) 2025-03-20 11:04:49 +01:00
Joost Lekkerkerker 827d5256c6 Bump pySmartThings to 2.7.4 (#140720)
* Bump pySmartThings to 2.7.3

* Bump pySmartThings to 2.7.3

* Fix

* Fix

* Fix
2025-03-20 11:02:51 +01:00
Franck Nijhof c6d3928ed1 Add template function: combine (#140948)
* Add template function: combine

* Add test to take away concern raised
2025-03-20 10:29:40 +01:00
Petar Petrov 3fb0290fba Remove unused params in "zwave_js/provision_smart_start_node" API (#140982) 2025-03-20 10:19:26 +01:00
Martin Hjelmare 2674b02bfa Refactor zwave_js config entry setup (#107635)
* Refactor zwave_js config entry setup

* Fix blocking update test

* Address timeout comment

* Remove platform tasks

* Replace deprecated async_add_job

* Use ConfigEntry.async_on_state_change

* Use modern config entry methods

* Clarify exception message

* Test listen error after config entry setup

* Test listen failure during setup after forward entry

* Test not reloading when hass is stopping

* Test client disconnect is called on entry unload

* Fix and test client not connected during driver setup

* Fix and test driver ready timeout

* Stringify listen task exception when logging

* Use identity compare

* Guard for closed connection

* Consolidate listen task checking and tests
2025-03-20 10:16:48 +01:00
Simone Chemelli 32f9c07254 Add missing exception translation in Vodafone Station (#140951)
* Add missing exception translation in Vodafone Station

* strings
2025-03-20 09:47:02 +01:00
J. Diego Rodríguez Royo 2ec80fd1ca Fix initial fetch of Home Connect appliance data to handle API rate limit errors (#139379)
* Fix initial fetch of appliance data to handle API rate limit errors

* Apply comments

* Delete stale function

* Handle api rate limit error at options fetching

* Update appliances after stream non-breaking error

* Always initialize coordinator data

* Improve device update

* Update test description

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

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-20 09:39:28 +01:00
dependabot[bot] adf3e4fcca Bump actions/download-artifact from 4.2.0 to 4.2.1 (#140974)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4.2.0...v4.2.1)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  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-03-20 09:30:59 +01:00
dependabot[bot] 03bd8cd251 Bump github/codeql-action from 3.28.11 to 3.28.12 (#140975)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.11 to 3.28.12.
- [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.11...v3.28.12)

---
updated-dependencies:
- dependency-name: github/codeql-action
  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-03-20 09:30:36 +01:00
Norbert Rittel 006dde435e Clarify descriptions of lcn.address_to_device_id action (#140979)
Clarify descriptions of `lcn.address_to_device` action

Changes the wording of the action and field descriptions so there is less ambiguity for translations.
2025-03-20 10:26:39 +02:00
dependabot[bot] 9f68ac575d Bump actions/upload-artifact from 4.6.1 to 4.6.2 (#140976)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.1 to 4.6.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4.6.1...v4.6.2)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  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-03-20 09:20:33 +01:00
Ivan Lopez Hernandez d9cf2750d5 Ensure file is correctly uploaded by the GenAI SDK (#140969)
Opened the file outside of the SDK
2025-03-19 22:58:19 -07:00
J. Nick Koston a600bc5e57 Add turn on/off support to HomeKit TVs (#140957)
* Add turn on/off support to HomeKit TVs

* 0 = off, 1 = on, not a bool

* add coverage

* update snapshot
2025-03-19 11:19:04 -10:00
Joost Lekkerkerker 100e4425e4 Log SmartThings subscription error on exception (#140939) 2025-03-19 20:13:46 +01:00
Joost Lekkerkerker 4344e9d604 Add remote control status to SmartThings (#140197)
* Add remote control status to SmartThings

* Add remote control status to SmartThings

* Fix
2025-03-19 18:23:15 +00:00
Norbert Rittel 2ffec3415c Use official spelling "FFmpeg" in ezviz / canary / onvif (#140938)
* Use official spelling "FFmpeg" in `ezviz`

* Use official spelling "FFmpeg" in `canary`

Fix sentence-casing along the way.

* Use official spelling "FFmpeg" in `onvif`

Fix sentence-casing along the way
2025-03-19 18:17:42 +00:00
J. Diego Rodríguez Royo 8afd9c0c44 Handle API rate limit error on Home Connect entities fetch (#139384)
* Handle API rate limit error on entities fetch

* Apply suggestions

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

* Add decorator (does not work)

* Fix decorator

* Apply suggestions

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

* Add test

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-19 18:53:14 +01:00
Norbert Rittel d99df8701c Use official spelling "FFmpeg" in user-facing strings (#140937)
* Use official spelling "FFmpeg" in user-facing strings

* Replace "a" with "an"
2025-03-19 18:50:19 +01:00
Erik Montnemery 05c61b7ec3 Rename BackupManager last_non_idle_event to last_action_event (#140291)
* Rename BackupManager last_non_idle_event to last_action_event

* Update snapshots
2025-03-19 17:28:40 +01:00
jukrebs 2c9eb288e3 Add capability to display updated firmware versions in Home Assistant (#140524)
* add firmware version update

* incoperate review feedback
2025-03-19 16:51:39 +01:00
Erik Montnemery 6b9c1e17e0 Fix docstring in selector helper (#140929) 2025-03-19 16:37:07 +01:00
Maciej Bieniek 4a5567806b Add exception translations for IMGW-PIB integration (#140936)
Add exception translations
2025-03-19 17:14:02 +02:00
Erik Montnemery 6211e378c3 Fix flaky cast tests (#140928) 2025-03-19 16:50:09 +02:00
Simone Chemelli 6af23d2348 Add quality scale to Vodafone Station (#139444)
* Add quality scale and strict typing to Vodafone Station

* mypy and hassfest

* tweek

* parallel-updates

* update

* update manifest

* apply review comment
2025-03-19 15:35:47 +01:00
Erik Montnemery 6434befdcd Fix misleading airthings_ble test (#140933) 2025-03-19 15:12:43 +01:00
dontinelli a2f0970dfc Bump fyta_cli to 0.7.2 (#140930) 2025-03-19 14:09:10 +00:00
starkillerOG 334359871d Add Reolink home hub scene select entity (#140823) 2025-03-19 14:34:49 +01:00
Erik Montnemery 245f0a1958 Minor typing tweak in cast (#140911) 2025-03-19 12:52:27 +00:00
Simone Chemelli adc3f542cf Update strings for Vodafone Station (#140919) 2025-03-19 13:11:29 +01:00
Josef Zweck 3fd17c802c Bump pylamarzocco to 1.4.9 (#140916) 2025-03-19 11:25:12 +01:00
Norbert Rittel f79aa2f73e Fix typos in nibe_heatpump strings (#140917)
* Fix typo in `nibe_heatpump` strings

* Also capitalize "Telnet"
2025-03-19 11:02:37 +01:00
Norbert Rittel f28b9ba961 Fix sentence-casing in nibe_heatpump strings (#140915) 2025-03-19 11:36:49 +02:00
Erik Montnemery 793e36635b Improve google cast known hosts configuration (#140913) 2025-03-19 10:07:47 +01:00
Norbert Rittel 7c6abe17a2 Clarify description of speed field in omnilogic.set_pump_speed action (#140912)
Replace "VSP" (for variable speed pump) with just "pump" so it can be properly translated.
2025-03-19 10:55:49 +02:00
J. Nick Koston f4fe234279 Bump annotatedyaml to 0.4.4 (#140861)
* Bump annotatedyaml to 0.4.2

changelog: https://github.com/home-assistant-libs/annotatedyaml/compare/v0.2.0...v0.4.2

~10-11% performance improvement

* tweak imports

* bump to .3 to make pylint happy

* bump again for fixes

---------

Co-authored-by: Shay Levy <levyshay1@gmail.com>
2025-03-18 22:26:23 -10:00
dependabot[bot] d37783fb21 Bump actions/download-artifact from 4.1.9 to 4.2.0 (#140907)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.1.9 to 4.2.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4.1.9...v4.2.0)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 09:53:00 +02:00
Manu caf81eecd3 Bump bring-api to v1.1.0 (#140906) 2025-03-18 20:25:41 -10:00
Luke Lashley 254622878a Add Roborock entity with the name of the current room (#140895)
* Add current room entity

* Update homeassistant/components/roborock/models.py

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

* Update homeassistant/components/roborock/models.py

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

* use current_room property

* remove select changes

---------

Co-authored-by: Allen Porter <allen.porter@gmail.com>
2025-03-18 18:48:34 -07:00
Erik Montnemery c41d5f2577 Fix cast.show_lovelace_view service description (#140859) 2025-03-18 23:13:08 +01:00
Maciej Bieniek 3ce9d47d7d Add exception translations for Airly integration (#140864)
* Add exception translations

* Improve error strings
2025-03-18 21:27:36 +02:00
Norbert Rittel 07302ea178 Fix duplicate descriptions of homematicip_cloud.activate_eco_mode_with_… actions (#140885)
Update strings.json

Currently both the `activate_eco_mode_with_duration` and the `activate_eco_mode_with_period` actions have the identical description:

"Activates eco mode with period."

To resolve this confusing duplicate, both actions get their own descriptions, making the latter consistent with that of the `activate_vacation` action.
2025-03-18 21:27:21 +02:00
Norbert Rittel 2d82a12e0a Make description of homeassistant.reload_all action consistent (#140887)
Change it to "Reloads …" like all other `homeassistant.reload_xyz` actions.
2025-03-18 18:47:14 +00:00
starkillerOG f8ab4d0238 Fix warnings in Reolink tests (#140878) 2025-03-18 16:47:33 +01:00
Maciej Bieniek 11e02f89cf Add exception translations for Brother integration (#140868)
Add exception translations
2025-03-18 17:40:47 +02:00
starkillerOG 4564d2537b Fix flakey reolink test (#140877) 2025-03-18 17:38:34 +02:00
Markus Adrario e2460a4393 bump pyHomee to 1.2.8 (#140870) 2025-03-18 17:32:14 +02:00
Simone Chemelli a170e32852 Deprecate Shelly state attributes (#140791) 2025-03-18 17:29:21 +02:00
Maikel Punie 4176776d70 Fix optional password in Velbus config flow (#140615)
* Fix velbusconfigflow

* add tests

* Paramtize the tests

* Removed duplicate test in favor of another case

* more comments
2025-03-18 14:49:27 +00:00
Luke Lashley 1cae866da9 Update Roborock Map on status change (#140873)
* update map on status change

* Update tests/components/roborock/test_image.py

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

* update code to handle state logic within async_update_data

* Update homeassistant/components/roborock/coordinator.py

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

* move previous_state and allow update on None

---------

Co-authored-by: Allen Porter <allen.porter@gmail.com>
2025-03-18 07:34:02 -07:00
Norbert Rittel de1823070f Replace unsupported markup of examples in humidifier.set_mode action (#140824)
Markup language is not supported in the action UI. Thus the underscores for italics are replaced with quote marks.
2025-03-18 12:55:32 +01:00
Maciej Bieniek 29f03f5b87 Add exception translations for AccuWeather integration (#140863)
* Add exception translations

* Improve error strings
2025-03-18 13:23:51 +02:00
Petar Petrov 516aaa741d Add Z-Wave JS lookup_device API (#140802)
* ZwaveJS lookup_device API

* add FailedCommand test

* test tweak
2025-03-18 12:05:10 +01:00
Simone Chemelli 12f5bd2aea Add dedicated sensors for extra_state_attributes in Shelly integration (#140793)
* Add dedicated sensors for extra_state_attributes in Shelly integration

* add tests

* apply review comment

* fix text syntax

* add gas test

* update strings

* add icons
2025-03-18 11:48:18 +01:00
Dan Raper 30c19ec373 Add reconfigure flow to Ohme (#140835)
* Add reconfigure flow to Ohme

* Remove incorrect unique ID check from ohme reconfig
2025-03-18 10:36:21 +01:00
EnjoyingM 5438532780 Bump wolf-comm to 0.0.23 (#140840)
* Bump wolf-comm to 0.0.23

* fix test for new lib
2025-03-18 11:22:32 +02:00
starkillerOG fdd36e457d Add Reolink day night state sensor (#140825)
* Add day night state sensor

* Update test_diagnostics.ambr
2025-03-18 11:19:45 +02:00
Norbert Rittel 603557af73 Improve description of vicare.set_vicare_mode action (#140826)
Add some additional information from the online docs so they get included in translations.
2025-03-18 11:16:21 +02:00
Norbert Rittel 36d42760a4 Fix capitalization in nextcloud entity names (#140856)
* Fix capitalization in `nextcloud` entity names

Use uppercase for abbreviations, sentence-case for words.

* Update test_sensor.ambr
2025-03-18 11:07:05 +02:00
Luke Lashley ea259ffa66 Add event to Snoo (#140827) 2025-03-18 09:35:57 +01:00
Jan Schneider 52054d69c7 Update moehlenhoff-alpha2 to 1.4.0 (#140829)
* Update moehlenhoff-alpha2 to 1.4.0

* Fix test
2025-03-18 09:32:28 +01:00
Dan Raper 74992344d5 Add diagnostics for Ohme (#140833) 2025-03-18 09:31:08 +01:00
Adam Feldman 776495dfa2 Fix broken core integration Smart Meter Texas by switching it to use HA's SSL Context (#140694)
* Update __init__.py to use HA's SSLContext

* Update config_flow.py to use HA's SSLContext

* Use default context for config_flow.py

* Use default context instead in __init__.py

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

* Fix import in __init__.py

* Fix import in config_flow.py

---------

Co-authored-by: Josef Zweck <josef@zweck.dev>
2025-03-18 09:24:05 +01:00
Norbert Rittel 426be3c11b Capitalize "ZIP" as abbreviation in rova integration strings (#140852)
Capitalized "ZIP" as abbreviation in `rova`
2025-03-18 09:21:28 +02:00
Norbert Rittel a93ab74e40 Sentence-case "Zip code" in iqvia integration strings (#140853) 2025-03-18 09:21:06 +02:00
Luke Lashley 0eac679a5a Move MapData to Coordinator for Roborock (#140766)
* Move MapData to Coordinator

* seeing if mypy likes this

* delete dead code

* Some MR comments

* remove MapData and always update on startup if we don't have a stored map.

* don't do on demand updates

* remove unneeded logic and pull out map save

* Apply suggestions from code review

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

* see if mypy is happy

---------

Co-authored-by: Allen Porter <allen.porter@gmail.com>
2025-03-17 19:34:47 -07:00
Luke Lashley 73a24bf799 Set Parallel updates to 0 in Roborock (#140837)
roborock set parallel updates to 0
2025-03-17 18:39:48 -07:00
Allen Porter 412705302d Update MCP server to make the stateless API implicit (#140753)
* Update MCP server to not register the stateless API, but use it implicitly as an Assist API replacement

* Ensure backwards compatibility with old registration
2025-03-17 16:38:21 -05:00
LG-ThinQ-Integration c9276aedde Bump thinqconnect to 1.0.5 (#140577)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
2025-03-17 21:38:37 +01:00
Norbert Rittel eafea6070d Improve action description in mealie integration (#140817)
- change all action descriptions to third-person singular
- use neutral wording for the description of `config_entry_id` so it works with all the different action contexts.
2025-03-17 21:45:17 +02:00
Norbert Rittel 539a28dcba Make all action descriptions in rachio consistent (#140816)
Changes 4 of the 6 action descriptions in the `rachio` integration to also use the descriptive style of Home Assistant.

In addition "API key" is sentence-cased to match the common string used in the same dialog.
2025-03-17 21:19:38 +02:00
Andrew Sayre 52d86ede3e Add ability to browse (and play) HEOS media (#140433)
* Add browse and play

* Tests

* Add tests involving media source
2025-03-17 14:10:56 -05:00
starkillerOG 4dfb56a2f7 Bump reolink-aio to 0.12.3b1 (#140811) 2025-03-17 20:06:49 +01:00
Erik Montnemery 290dab25bf Don't raise in ConfigFlow.async_set_unique_id if the other flow is a reauth flow (#140723)
* Don't raise in ConfigFlow.async_set_unique_id if the other flow is a reauth flow

* Improve test
2025-03-17 09:04:30 -10:00
Norbert Rittel e16f0e9af3 Clarify action descriptions of smarttub.snooze_reminder / reset_reminder (#140810)
- change both descriptions to descriptive HA style
- change "reminder" to "maintenance reminder" (helps translators a lot)
- use more of the wording from the online documentation
2025-03-17 20:03:05 +02:00
Norbert Rittel a2fec8c2ce Fix inconsistent capitalization in growatt_server entities (#140803)
* Fix inconsistent capitalization in `growatt_server` entities

* Makes "amperage" and "wattage" consistent (with "voltage")
2025-03-17 19:21:56 +02:00
Thomas55555 9a0837593a Improve test coverage and add comment for loading in executor for remote calendar (#140807)
Improve calendar loading by executing in a separate thread and add test for CalendarParseError
2025-03-17 17:38:40 +01:00
Simone Chemelli f4787d469a Remove Shelly extra_attributes for RPC & REST devices (#140792)
* Remove Shelly extra_attributes for RPC devices

* apply review comment
2025-03-17 17:27:01 +01:00
Thomas55555 a252c19e7c Use MowerDictionary in Husqvarna Automower (#140805) 2025-03-17 16:57:03 +01:00
Shay Levy 9b57a831f7 Fix Shelly Air lamp life sensor (#140799) 2025-03-17 17:33:11 +02:00
starkillerOG 18bd8b561a Add Reolink smart ai binary sensors (#140408)
* Add Crossline smart AI binary sensor

* Add intrusion, lingering, forgotten item, item taken detection

* Use unique_index instead of location for unique_id

* Add test

* Apply suggestions from code review

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

* Name changes

* Update homeassistant/components/reolink/binary_sensor.py

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

* Use smart_type instead of key

* Use occupancy translation instead of gas (point to the same thing).

* Revert "Use occupancy translation instead of gas (point to the same thing)."

This reverts commit 9caf796585e1cffdea6e66f16824fe8e34d03276.

* fix styling

---------

Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>
2025-03-17 14:49:13 +00:00
Stephan van Rooij 76aef5be9f Add PKCE implementation in oauth2 helper (#139509)
* Update config_entry_oauth2_flow.py

* Specify type on request_data

* Added LocalOAuth2ImplementationWithPkce

* LocalOAuth2ImplementationWithPkce works more like specs

* fix: Adding tests for pkce flow and feedback applied

* fix last test for pkce

* Clean test_abort_if_oauth_with_pkce_rejected

* Improve assertion of code verifier and code challenge

* Break long docstrings

* Shorten docstring

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-17 14:16:52 +01:00
Erik Montnemery fb2b3ce7d2 Bump pychromecast to 14.0.6 (#140794) 2025-03-17 13:19:27 +01:00
Petar Petrov 0d1c79b427 Bump zwave-js-server-python to 0.62.0 (#140796)
* Bump zwave-js-server-python to 0.62.0

* fix breaking change
2025-03-17 13:18:15 +01:00
Indu Prakash a5913147e7 Add support for fan night light in VeSync (#140637)
* style: rename humidifier night const

* fix: separate night light for fan and humidifier

Check for the presence of set_night_light_brightness and
set_night_light to indentify humidifier and fan devices.

set_night_light is defined on VeSyncAirBypass and
set_night_light_brightness is defined on VeSyncHumid200300S.

update test
2025-03-17 10:32:52 +01:00
Ivan Lopez Hernandez 110e827ede Add @IvanLH to owners of google_generative_ai_conversation (#140764)
Update CODEOWNERS
2025-03-17 09:12:22 +01:00
dependabot[bot] 74ce703755 Bump docker/login-action from 3.3.0 to 3.4.0 (#140780)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3.3.0...v3.4.0)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-17 09:08:47 +01:00
J. Diego Rodríguez Royo 4baf72d80b Call only required listeners on CONNECT/PAIRED in Home Connect (#140765)
Call only to the required listeners on CONNECT/PAIRED
2025-03-17 07:43:02 +01:00
J. Nick Koston ab6c5af374 Bump aiohttp to 3.11.14 (#140773)
changelog: https://github.com/aio-libs/aiohttp/compare/v3.11.13...v3.11.14
2025-03-17 07:36:43 +01:00
J. Nick Koston 5fb03114b5 Bump dbus-fast to 2.39.6 (#140775)
changelog: https://github.com/Bluetooth-Devices/dbus-fast/compare/v2.39.5...v2.39.6
2025-03-17 07:35:49 +01:00
Marc Mueller bddec1168b Bump ci cache version (#140767) 2025-03-17 01:38:05 +01:00
Norbert Rittel f19a5b28f7 Update description of evaluate_payload to use friendly name (#140736)
* Update description of `evaluate_payload` to use friendly name

For the graphical UI the action descriptions need to refer to the friendly names of other fields so these can be translated to match.

Small change from `payload` to 'Payload'.

* Replace "When …" with "If …"
2025-03-16 22:38:25 +01:00
Johnny Willemsen a9949aece0 Fix typo in Homee (#140759)
* Update strings.json

Fixed typo

* Update homeassistant/components/homee/strings.json

* Fix

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-03-16 22:27:35 +01:00
Luke Lashley 15e983e997 Add snoo switches (#140748)
* Add snoo switches

* change naming

* change wording
2025-03-16 22:24:49 +01:00
Luke Lashley a40bb2790e Move Roborock map refresh to coordinator (#140758)
Move refresh coordinator to coordinator
2025-03-16 14:15:04 -07:00
Ivaylo Iliev 1b91240d54 Bump nibe_heatpump component version to add S332/S330 model (#140741) 2025-03-16 21:31:34 +01:00
Joost Lekkerkerker bbe2a95b3d Deprecate Valve binary sensor in SmartThings (#140751)
Deprecate Valve binary sensor
2025-03-16 22:29:03 +02:00
mbraem 5351fe3f9b Add specific sensor device_class, state_class and unit_of_measurement (#137038)
Support additional units in the coil unit descriptions: min, s, Pa, kPa, bar,
l/m, m³/h and %RH.

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-03-16 21:06:49 +01:00
Luke Lashley b0db7b432e Move Roborock MapParser to coordinator (#140750)
Move MapParser to coordinator
2025-03-16 12:55:00 -07:00
Joost Lekkerkerker 784381a25f Deprecate SmartThings cover battery state attribute (#140752) 2025-03-16 20:45:46 +01:00
Markus Adrario 42f0e70cde Add Homee binary sensor platform (#140088)
* binary-sensor initial

* Add binary sensor tests

* small string changes

* fix review comments

* review change 1
2025-03-16 20:13:36 +01:00
Allen Porter 1ee4f02e70 Bump ical to 9.0.1 (#140726) 2025-03-16 21:10:40 +02:00
Joost Lekkerkerker d061f4ee05 Fix SmartThings ACs without supported AC modes (#140744) 2025-03-16 20:06:50 +01:00
MarkGodwin 56fe4319a0 Bump TP-Link Omada API to 1.4.4 (#140738) 2025-03-16 21:04:58 +02:00
Thomas55555 a7b6bcf1d6 Address post merge comments for remote calendar (#140735) 2025-03-16 20:03:02 +01:00
Manu 46973f0446 Redact emails and names in Bring! diagnostics (#140746) 2025-03-16 20:00:10 +01:00
Joost Lekkerkerker 735c98cb86 Set Home Connect button unique id to shorthand attribute (#140745) 2025-03-16 19:54:00 +01:00
starkillerOG b5fa3e74c0 Add option to specify Reolink Basic Service Port (#137603)
* Allow changing the baichuan port

* styling

* Add description

* Add tests

* Review feedback

* capital letters

Co-authored-by: Robert Resch <robert@resch.dev>

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2025-03-16 19:51:06 +01:00
Manu 8a552aef9d Adjusts strings in create actions in Habitica integration (#140742)
Adjusts strings in create actions
2025-03-16 19:33:28 +01:00
Thomas55555 2ece7fbc11 Add strict typing to remote_calendar (#140734) 2025-03-16 19:32:59 +01:00
Luke Lashley 2424d1c615 bump Python-Roborock to 2.14.0 (#140727)
bump Python Roborock to 2.14.0
2025-03-16 10:19:32 -07:00
Denis Shulyaka bb7b5b9ccb OpenAI Responses API (#140713) 2025-03-16 13:18:18 -04:00
Luke Lashley 214d14b06b Add binary sensor to Snoo (#140729)
* Add binary sensor

* Update homeassistant/components/snoo/binary_sensor.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-03-16 16:57:21 +01:00
Denis Shulyaka 056616f9c5 Stronger type annotations for conversation content (#140725)
stronger type annotations for conversation content
2025-03-16 10:59:25 -04:00
Josef Zweck 012b4645f3 Don't reload onedrive on options flow (#140712) 2025-03-16 09:51:53 -04:00
Jan-Philipp Benecke 4ca31da0a5 Bump annotatedyaml to 0.2.0 (#140715) 2025-03-16 09:51:36 -04:00
Pete Sage d560083e15 Album art not available for Sonos media library favorites (#140557)
* get album art uri for favorites

* add tests

* update typing

* update typing

* update typing

* simplify
2025-03-16 14:09:21 +01:00
Dan Raper d365092bcc Add price cap support to Ohme (#140537)
* Add price cap support

* Change service input to box mode

* Add icon for set_price_cap service

* Improve test coverage

* Change ohme service description wording
2025-03-16 14:05:08 +01:00
Luke Lashley 4e0985e1a7 Add Select entity to Snoo (#140638) 2025-03-16 14:00:43 +01:00
Brett Adams 011a076155 Fix auto seat heater in Teslemetry (#140703)
Fix auto seat heater
2025-03-16 10:16:21 +01:00
Pete Sage 5f8564bfc5 Fix audiobooks always start from beginning on Sonos (#140663)
* play audible favorite

* play audible favorite

* simplify tests
2025-03-16 10:11:08 +01:00
Serge Wagener 6b6470f345 Update knx-frontend and increase BinarySensor reset_after limit (#140196)
Bumped to newest knx-frontend version and adapt knx ui schema
2025-03-16 08:29:44 +01:00
Jan-Philipp Benecke 7b9ea63f17 Split out yaml loading into own package (#140683)
* Split out yaml loading into library

* Code review

* Code review

* Fix check config script
2025-03-15 22:26:18 -04:00
Denis Shulyaka 3a6ddcf428 Bump openai to 1.66.3 (#140690) 2025-03-15 22:24:27 -04:00
Thomas55555 4050c216ed Add Remote calendar integration (#138862)
* Add remote_calendar with storage

* Use coordinator and remove storage

* cleanup

* cleanup

* remove init from config_flow

* add some tests

* some fixes

* test-before-setup

* fix error handling

* remove unneeded code

* fix updates

* load calendar in the event loop

* allow redirects

* test_update_failed

* tests

* address review

* use error from local_calendar

* adress more comments

* remove unique_id

* add unique entity_id

* add excemption

* abort_entries_match

* unique_id

* add ,

* cleanup

* deduplicate call

* don't raise for status end de-nest

* multiline

* test

* tests

* use raise_for_status again

* use respx

* just use config_entry argument that already is defined

* Also assert on the config entry result title and data

* improve config_flow

* update quality scale

* address review

---------

Co-authored-by: Allen Porter <allen@thebends.org>
2025-03-15 18:57:45 -07:00
IceBotYT 91e0f1cb46 Add voip_utils to voip loggers (#140695)
* Add voip_utils to voip loggers

* Sort
2025-03-15 23:40:02 +01:00
Joost Lekkerkerker 675b684290 Check Celsius in SmartThings oven setpoint (#140687) 2025-03-15 23:09:55 +01:00
J. Nick Koston d69bcc02b0 Pass scanner mode to shelly Bluetooth scanner (#140689)
habluetooth will eventually be able to make better decisions
on how to route data based on the scanning mode.
2025-03-15 12:00:23 -10:00
Glenn Waters 76244e0d6b Fix Elk-M1 missing TLS 1.2 check (#140672)
* Fix for missing TLS 1.2 check

* Fix error message.

* combine startswith

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
2025-03-15 11:07:45 -10:00
Thomas55555 ed0b1f58dc Bump aioautomower to 2025.3.1 (#140682) 2025-03-15 21:30:19 +01:00
J. Nick Koston 16556fa2a9 Bump PySwitchBot to 0.57.1 (#140681)
changelog: https://github.com/sblibs/pySwitchbot/compare/0.56.1...0.57.1

fixes #140405
2025-03-15 21:06:00 +01:00
Joost Lekkerkerker 43898d7845 Add valve platform to SmartThings (#140195)
* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* Refactor SmartThings

* fix

* fix

* Add AC tests

* Add thermostat tests

* Add cover tests

* Add device tests

* Add light tests

* Add rest of the tests

* Add valve

* Add oauth

* Add oauth tests

* Add oauth tests

* Add oauth tests

* Add oauth tests

* Bump version

* Add rest of the tests

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Finalize

* Fix

* Fix
2025-03-15 20:28:51 +01:00
Joost Lekkerkerker bff73ee5f8 Add EHS test fixture to SmartThings (#140199) 2025-03-15 20:28:04 +01:00
Jeff Terrace 02a75edf1d Add onvif parser support for reolink package and hikvision alarm (#140669) 2025-03-15 09:03:40 -10:00
EnjoyingM c1c8deed0c Fix sensor values for Power and Energy for Wolf Heatpumps (#139007)
* Add sensor values for Power and Energy

* test

* test

* Sensor test

* Fix test

* fix test

* Fixing test coverage

* refactored

* WolfllinkSensorEntityDescriptions and updated tests

* fix test

* Add name_fn and test_sensor adoptions

* fix test coverage

* Revert "fix test coverage"

This reverts commit 2405751f5a9d0d5be67b78b39a510240a794a7e5.

* resolve requested changes and fix test

* Fix Snapshot

* clean up

* Fixed unknown state in snapshot test
2025-03-15 19:56:45 +01:00
Simone Chemelli 2fd91e7f9c Remove unknown from Shelly sensor state (#140597) 2025-03-15 18:10:35 +01:00
Maciej Bieniek 58ff593f96 Bump aioshelly to version 13.4.0 (#140671)
Bump aioshelly to version 13.4.0
2025-03-15 18:11:04 +02:00
Maciej Bieniek 89e7536731 Add missing translations for options attribute in Nettigo Air Monitor integration (#140662)
Add missing translations for options attribute
2025-03-15 15:38:45 +01:00
Joost Lekkerkerker b7e2e041bc Make Oven setpoint follow temperature UoM in SmartThings (#140666) 2025-03-15 15:08:21 +01:00
J. Diego Rodríguez Royo 940625505f Handle non documented options at Home Connect select entities (#140608)
* Allow non documented options at select entities

* Don't allow undocumented options
2025-03-15 14:17:16 +01:00
J. Nick Koston f801cfee7e Bump habluetooth to 3.32.0 (#140640)
changelog: https://github.com/Bluetooth-Devices/habluetooth/compare/v3.27.0...v3.32.0
2025-03-15 12:27:21 +02:00
J. Nick Koston 99f661538d Bump aioesphomeapi to 29.7.0 (#140641)
changelog: https://github.com/esphome/aioesphomeapi/compare/v29.6.0...v29.7.0
2025-03-15 12:27:06 +02:00
Tim Laing 13b6cfa438 Add generate content service for OpenAI to match Google AI (#122818)
* Aded Generate Content Service for OpenAI to match Google AI

* Fixed code for commit checks

* Addressed code review comments

* Address review comments

* Addressed @balloob review comments.

* Address futher review comments from @balloob
2025-03-14 22:54:49 -04:00
J. Nick Koston 5dc1a321dd Rework cover reproduce_state to consider supported features (#140558)
* Handle open/closed state in reproduce_state for tilt only covers

fixes #137144

* cleanups

* cleanups

* cleanups

* cleanups

* cleanups

* cleanups

* cleanups

* cleanups

* cleanups

* cleanups

* cleanups

* cleanups

* rework

* rework

* rework

* rework

* more coverage

* more coverage

* more coverage

* more coverage

* more coverage

* more coverage

* more coverage

* more coverage

* more coverage

* more coverage

* more coverage

* back compat

* back compat

* back compat

* cleanups

* cleanups

* cleanups

* cleanups

* comments

* comments
2025-03-14 22:14:09 -04:00
Denis Shulyaka 07e7672b78 Anthropic conversation extended thinking support (#139662)
* Anthropic conversation extended thinking support

* update conversation snapshots

* Add conversation test

* Update openai_conversation snapshots

* Removed metadata

* Removed metadata

* Removed thinking

* cosmetic fix

* combine user messages

* Apply suggestions from code review

* Add tests for chat_log messages conversion

* s/THINKING_BUDGET_TOKENS/THINKING_BUDGET/

* Apply suggestions from code review

* Update tests

* Update homeassistant/components/anthropic/strings.json

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>

* apply suggestions from code review

---------

Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2025-03-14 22:07:59 -04:00
Luke Lashley baafcf48dc Separate Roborock entities to a new dock device (#140612)
* Seperate entities to a new dock device

* update entity names

* Update homeassistant/components/roborock/coordinator.py

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2025-03-14 22:06:09 -04:00
Luke Lashley ed2ef04b98 Bump Python-Snoo to 0.6.3 (#140628)
Bump python-Snoo to 0.6.3
2025-03-14 21:48:47 -04:00
J. Nick Koston c54a2e7338 Bump nexia to 2.4.0 (#140634)
changelog: https://github.com/bdraco/nexia/compare/2.2.2...2.4.0
2025-03-14 15:27:51 -10:00
J. Nick Koston fa836118b2 Bump bluetooth-data-tools to 1.26.1 (#140635)
changelog: https://github.com/Bluetooth-Devices/bluetooth-data-tools/compare/v1.26.0...v1.26.1
2025-03-14 15:24:55 -10:00
Jeff Terrace 11e15b1405 Move redundant attribute and key error handling to event parser caller (#140630) 2025-03-14 14:16:35 -10:00
puddly 537302ce56 ZBT-1 and Yellow firmware update entities for Zigbee/Thread (#138505)
* Initial implementation of hardware update model

* Fixes

* WIP: change the `homeassistant_sky_connect` integration type

* More fixes

* WIP

* Display firmware info in the device page

* Make progress more responsive

* WIP: Yellow

* Abstract the bootloader reset type

* Clean up comments

* Make the Yellow integration non-hardware

* Use the correct radio device for Yellow

* Avoid hardcoding strings

* Use `FIRMWARE_VERSION` within config flows

* Fix up unit tests

* Revert integration type changes

* Rewrite hardware ownership context manager name, for clarity

* Move manifest parsing logic into a new package

Pass the correct type to the firmware API library

* Create and delete entities instead of mutating the entity description

* Move entity replacement into a `async_setup_entry` callback

* Change update entity category from "diagnostic" to "config"

* Have the client library handle firmware fetching

* Switch from dispatcher to `async_on_state_change`

* Remove unnecessary type annotation on base update entity

* Simplify state recomputation

* Remove device registry code, since the devices will not be visible

* Further simplify state computation

* Give the device-less update entity a more descriptive name

* Limit state changes to integer increments when sending firmware update progress

* Re-raise `HomeAssistantError` if there is a problem during flashing

* Remove unnecessary state write during entity creation

* Rename `_maybe_recompute_state` to `_update_attributes`

* Bump the flasher to 0.0.30

* Add some tests

* Ensure the update entity has a sensible name

* Initial ZBT-1 unit tests

* Replace `_update_config_entry_after_install` with a more explicit `_firmware_info_callback` override

* Write the firmware version to the config entry as well

* Test the hardware update platform independently

* Add unit tests to the Yellow and ZBT-1 integrations

* Load firmware info from the config entry when creating the update entity

* Test entity state restoration

* Test the reloading of integrations marked as "owning"

* Test installation failure cases

* Test firmware type change callback failure case

* Address review comments
2025-03-15 00:28:02 +01:00
Mick Vleeshouwer b07c28126a Bump pyOverkiz to 1.16.3 (#140621)
Bump Overkiz to 1.16.3
2025-03-15 00:42:10 +02:00
J. Diego Rodríguez Royo 59cab7cd58 Add 700 RPM option to washer spin speed options at Home Connect (#140607)
Add 700 RPM option to washer spin speed options
2025-03-14 19:35:13 +01:00
Maciej Bieniek 8964af428a Add missing translations for options attribute in AccuWeather integration (#140610)
Add missing translations for options attribute
2025-03-14 19:20:18 +01:00
Michel van de Wetering 160b98bd28 Fix media_player Toggle when in idle (#78192)
* Remove idle as off state

* Fix merge mistake

* Fix merge mistake

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-03-14 17:24:39 +01:00
Marc Mueller 2951eb5cc8 Fix len-test (PLC1802) (#140600) 2025-03-14 17:03:42 +01:00
Erik Montnemery 588366a514 Add setup function to improv_ble (#140594) 2025-03-14 16:55:42 +01:00
Manu 78a04776e4 Add update_daily action to Habitica integration (#140328)
* add update_daily action

* day strings
2025-03-14 16:49:56 +01:00
Paul Bottein 324f208d68 Add lawn mower support to Google Assistant (#140530)
* Add lawn mower support to google assistant

* Update snapshots

* Sort alphabetically

* Refactor service call

* Refactor service call

* Feedback
2025-03-14 15:22:23 +00:00
Hessel e740e341c8 Change max ICP value to fixed value for Wallbox Integration (#140592)
change max ICP value to fixed value

Co-authored-by: Hessel van Es <hessel@datadragons.nl>
2025-03-14 16:13:07 +01:00
Joost Lekkerkerker 532c860bf0 Bump ruff to 0.11.0 (#140598) 2025-03-14 16:04:11 +01:00
Brett Adams 251bb30dc7 Add streaming media platform to Teslemetry (#140482)
* Update media player

* Add media player platform with tests and bump firmware
2025-03-14 15:27:18 +01:00
Petar Petrov de0efd61d1 Add Z-Wave JS NVM backup and restore API (#139233)
* ZWaveJS: NVM backup and restore API

* remove unused const

* test fix

* switch to WS commands

* Backup & restore MVP

* Use base64 data directly

* update tests

* fix mistake

* Apply suggestions from code review

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

* PR comments

* update tests

* more tests

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-14 15:17:23 +01:00
J. Nick Koston e9c8b3acfc Bump aioharmony to 0.5.2 (#140589)
mostly logging fixes (some format stings were missing values)

related issue #139126
2025-03-14 16:07:32 +02:00
Erik Montnemery 08fc6dcff6 Allow configuring ignored devices from improve_ble user flow (#140595) 2025-03-14 16:05:58 +02:00
Erik Montnemery 96a6d88dca Allow configuring ignored devices from dormakaba_dkey user flow (#140596) 2025-03-14 16:01:43 +02:00
Luke Lashley 1bd8ff884e Improve Snoo testing (#139302)
* improve snoo testing

* change to asyncMock method of testing

* Apply suggestions from code review

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

* address comments

* Apply suggestions from code review

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

* adress comments

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-03-14 14:58:55 +01:00
Jan Bouwhuis a8f1df3e55 Add availability support for MQTT subentries (#138673)
* Add availability support for MQTT subentries

* Update homeassistant/components/mqtt/config_flow.py

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

* Update homeassistant/components/mqtt/config_flow.py

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

* Update homeassistant/components/mqtt/config_flow.py

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

* Update homeassistant/components/mqtt/strings.json

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

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2025-03-14 14:56:27 +01:00
Luke Lashley 7ff842fc37 Add dynamic update interval to Roborock (#140563)
* Add dynamic update interval to Roborock

* mr comments

* update time intervals

* Set A01 to 1 minute

* set interval to 30
2025-03-14 06:55:18 -07:00
Brett Adams 220bd5a27f Fix time to full charge in Teslemetry (#137996)
* Fix streaming full charge

* ruff
2025-03-14 14:48:17 +01:00
Brett Adams 4e759e59a4 Add streaming switches to Teslemetry (#137145)
* Add streaming switches

* Add switch tests

* Update snapshot

* Fix sentry

* update test docstring
2025-03-14 14:41:09 +01:00
Jan Bouwhuis bd4d0ec4b8 Add initial MQTT subentry support for notify entities (#138461)
* Add initial MQTT subentry support for notify entities

* Fix componts assigment is reset on device config. Translation tweaks

* Rephrase

* Go to summary menu when components are set up already - add test

* Fix suggested device info on config flow

* Invert

* Simplify subentry config flow and omit menu

* Use constants instead of literals

* More constants

* Teak some translations

* Only show save when the the entry is dirty

* Do not trigger an entry reload twice

* Remove encoding, entity_category

* Remove icon from mqtt subentry flow

* Separate entity settings and MQTT specific settings

* Remove object_id and refactor

* Migrate translations

* Make subconfig flow test extensible

* Make sub reconfig flow tests extensible

* Rename entity_platform_config step to mqtt_platform_config

* Make component unique ID independent from the name

* Move code for update of component data to helper

* Follow up on code review

* Skip dirty stuff

* Fix rebase issues #1

* Do not allow reconfig for entity platform/name, default QoS and refactor tests

* Add entity platform and entity name label to basic entity config dialog

* Rename to exclude_from_reconfig and make reconfig option not optional
2025-03-14 14:00:07 +01:00
Joost Lekkerkerker dcc63a6f2e Bump ruff to 0.10.0 (#140541)
* Bump ruff to 0.10.0

* Bump ruff to 0.10.0

* Bump ruff to 0.10.0

* Bump ruff to 0.10.0

* Update pyproject.toml

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>

* Fix

---------

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2025-03-14 12:32:50 +00:00
Franck Nijhof 4d1c89f0d1 2025.3.3 (#140583) 2025-03-14 12:55:51 +01:00
Petar Petrov ae8709be21 Expose ZWaveJSsupports_long_range to the frontend (#140489)
* Expose ZWaveJS`supports_long_range` to the frontend

* update test
2025-03-14 12:19:49 +01:00
Maciej Bieniek 5ea7c113b0 Use test snapshots for Shelly climate (#140582) 2025-03-14 11:15:38 +01:00
Franck Nijhof 831f2dc30e Bump version to 2025.3.3 2025-03-14 09:56:13 +00:00
ashionky 1566ab3b28 Fix missing UnitOfPower.MILLIWATT in sensor and number allowed units (#140567)
* MILLIWATT

* MILLIWATT
2025-03-14 09:53:08 +00:00
Joost Lekkerkerker c852e1398c Set unit of measurement for SmartThings oven setpoint (#140560) 2025-03-14 09:53:05 +00:00
Joost Lekkerkerker 761be9342e Fix windowShadeLevel capability in SmartThings (#140552) 2025-03-14 09:52:58 +00:00
Maciej Bieniek 54ad44a574 Fix Shelly diagnostics for devices without WebSocket Outbound support (#140501)
* Don't assume that `ws` is always in config

* Fix device
2025-03-14 09:49:52 +00:00
Matthias Alphart fed4015bab Update xknxproject to 3.8.2 (#140499) 2025-03-14 09:49:49 +00:00
Brett Adams 019a0ebf9b Bump Tesla Fleet API to 0.9.13 (#140485) 2025-03-14 09:49:45 +00:00
Joost Lekkerkerker 7607b7d494 Mark value in number.set_value action as required (#140445) 2025-03-14 09:49:40 +00:00
Maikel Punie 8b96a9606d Bump velbusaio to 2025.3.1 (#140443) 2025-03-14 09:49:37 +00:00
Jan-Philipp Benecke 6349821037 Only do WebDAV path migration when path differs (#140402) 2025-03-14 09:49:33 +00:00
Louis Christ db26a42734 Use only IPv4 for zeroconf in bluesound integration (#140226)
* Use only ipv4 for zeroconf

* Fix tests

* Use only ip_address for ip version check

* Add test

* Reduce test
2025-03-14 09:49:30 +00:00
Glenn Waters 74fe35f44e Bump upb-lib to 0.6.1 (#140212) 2025-03-14 09:49:26 +00:00
jb101010-2 e648716ddf Bump pysuezV2 to 2.0.4 (#139824) 2025-03-14 09:49:23 +00:00
Luke Lashley 2e20245cdf Fix bug with all Roborock maps being set to the wrong map when empty (#138493)
* Fix bug with all maps being set to the same when empty

* fix parens

* fix other parens

* rework some of the logic

* few small updates

* Remove test that is no longer relevant

* remove updated time bump
2025-03-14 09:49:19 +00:00
Norbert Rittel 8726be31ff Use correct unit symbol "min" for minutes in webmin integration (#140448)
* Use correct unit symbol "min" for minutes in `webmin` integration

Replace the unit symbol "m" which stands for meter with the correct SI uni symbol "min".

* Update test_sensor.ambr

* Update test_sensor.ambr (2)
2025-03-14 10:28:37 +01:00
Jan-Philipp Benecke 99b140f73f Remove WebDAV properties and rely on metadata file (#140539) 2025-03-14 10:21:16 +01:00
Louis Christ d952e8186f Use only IPv4 for zeroconf in bluesound integration (#140226)
* Use only ipv4 for zeroconf

* Fix tests

* Use only ip_address for ip version check

* Add test

* Reduce test
2025-03-14 10:20:16 +01:00
ashionky 2b0a2e7644 Fix missing UnitOfPower.MILLIWATT in sensor and number allowed units (#140567)
* MILLIWATT

* MILLIWATT
2025-03-14 10:19:43 +01:00
Simone Chemelli 9820cbb036 Add exceptions translation for Comelit (#140404)
* Add exceptions translation for Comelit

* apply review comment

* Add climate tests for Comelit

* Revert "Add climate tests for Comelit"

This reverts commit 6d76d312a064491be4dbfb960a28b00f742f4186.
2025-03-14 10:17:10 +01:00
Marc Mueller f48d94ce34 Use TypeVar default for Generator (#140506) 2025-03-14 10:08:39 +01:00
Simone Chemelli 5daa3167ca Add parallel updates to Comelit (#140527) 2025-03-14 10:03:29 +01:00
J. Nick Koston 23f4f97603 Bump habluetooth to 3.27.0 (#140569)
changelog: https://github.com/Bluetooth-Devices/habluetooth/compare/v3.25.1...v3.27.0
2025-03-13 22:57:24 -10:00
J. Nick Koston 1e8f211725 Bump aioshelly to 13.3.0 (#140571)
changelog: https://github.com/home-assistant-libs/aioshelly/compare/13.2.0...13.3.0
2025-03-14 09:47:36 +01:00
Petro31 84667fd32d Migrate template light to new style (#140326)
* Migrate template light to new style

* add modern templates to tests

* fix comments
2025-03-14 09:00:46 +01:00
Norbert Rittel e42a6c5d4f Fix missing RGBW field description reference in Lokalise - step 2 (#140576)
Reverts step 1, re-adding the field reference.
2025-03-14 09:51:49 +02:00
Simone Chemelli 6f926d0a66 Add missing typing to Vodafone Station (#140562) 2025-03-14 08:28:56 +01:00
J. Nick Koston 9f801e7785 Bump dbus-fast to 2.39.5 (#140565) 2025-03-13 14:49:37 -10:00
J. Nick Koston f0b86c512d Bump habluetooth to 3.25.1 and bluetooth-auto-recovery to 1.4.5 (#140561)
habluetooth: https://github.com/Bluetooth-Devices/habluetooth/compare/v3.25.0...v3.25.1
bluetooth-auto-recovery: https://github.com/Bluetooth-Devices/bluetooth-auto-recovery/compare/v1.4.4...v1.4.5
2025-03-13 14:06:24 -10:00
Norbert Rittel 3383e8b70d Fix missing RGBW field description reference in Lokalise - step 1 (#140526)
Empties the string to trigger an export to Lokalise.
Will be followed up by a second PR to restore the reference.
2025-03-14 01:47:11 +02:00
Joost Lekkerkerker 058aed96d2 Fix windowShadeLevel capability in SmartThings (#140552) 2025-03-14 01:28:08 +02:00
Joost Lekkerkerker b1285fcc4e Set unit of measurement for SmartThings oven setpoint (#140560) 2025-03-14 01:28:01 +02:00
Joakim Plate d56680e05e Update to version 1.6.0 of gardena library (#140559) 2025-03-13 13:13:16 -10:00
Marc Mueller 5cf3bea8fe Fix unnecessary-dict-comprehension-for-iterable (C420) (#140555) 2025-03-13 23:32:00 +01:00
Marc Mueller b48ab77a38 Fix call on root logger (LOG015) (#140556) 2025-03-13 23:02:26 +01:00
Paul Bottein cdead8661d Add lawn mower support to HomeKit (#140438)
Add lawn mower support to homekit
2025-03-13 10:27:00 -10:00
J. Nick Koston 474d427b87 Bump bleak-esphome to 2.12.0 (#140543)
changelog: https://github.com/Bluetooth-Devices/bleak-esphome/compare/v2.11.0...v2.12.0
2025-03-13 21:01:41 +01:00
Shay Levy 87f726141a Fix ollama history trimming test (#140538) 2025-03-13 19:41:45 +00:00
Maciej Bieniek fa57d57215 Fix Shelly diagnostics for devices without WebSocket Outbound support (#140501)
* Don't assume that `ws` is always in config

* Fix device
2025-03-13 20:58:09 +02:00
Dan Raper 8ea2d40467 Bump ohmepy to 1.4.1 (#140535) 2025-03-13 20:57:05 +02:00
Simone Chemelli d5af542dd1 Add parallel updates to Vodafone Station (#140532) 2025-03-13 17:32:45 +00:00
Paulus Schoutsen 55895df54d Switch more TTS core to async generators (#140432)
* Switch more TTS core to async generators

* Document a design choice

* robust

* Add more tests

* Update comment

* Clarify and document TTSCache variables
2025-03-13 13:24:44 -04:00
Matthias Alphart b07ac301b9 Update xknxproject to 3.8.2 (#140499) 2025-03-13 15:57:22 +00:00
Marc Mueller 473a5559cc Improve tado typing (#140505) 2025-03-13 15:48:04 +00:00
Norbert Rittel c92ee120b6 Make actions in flo integration UI-friendly (#140522)
Makes actions in `flo` integration UI-friendly

- replace key name `sleep_minutes` with its friendly name to match the UI (in translations)
- replace "time" with "duration" to reduce the ambiguity
- use third-person singular for `run_health_test` description for consistency (in translations)
2025-03-13 16:39:12 +01:00
Simone Chemelli 3bba781554 Use runtime data in Vodafone Station (#140464)
* Use runtime data in Vodafone Station

* specialize config entry

* revert unwanted change
2025-03-13 15:53:01 +01:00
Norbert Rittel bc6eb94c0d Fix sentence-casing and spelling of "ID" in system_bridge integration (#140516) 2025-03-13 16:36:12 +02:00
Norbert Rittel 5526585eeb Fix spelling of "ID" and excessive colon in bang_olufsen integration (#140518) 2025-03-13 16:35:40 +02:00
Paulus Schoutsen f32bb1a318 Assist satellite to use TTS tokens for announcements (#140336)
* Migrate Assist Satellite to use token

* Fix tests

* Fix tests
2025-03-13 08:36:38 -05:00
Marc Mueller e710d3699c Improve frontend typing (#140503) 2025-03-13 13:23:52 +01:00
Marc Mueller 26e3624610 Update pipdeptree to 2.25.1 (#140507) 2025-03-13 13:23:00 +01:00
Erik Montnemery 427aa55789 Correct fallback to state in state machine when processing statistics (#140396) 2025-03-13 09:28:15 +01:00
Pieter Viljoen ffa6f42c0e Use runtime_data to store coordinator state (#140486)
Use runtime-data to save coordinator state
2025-03-13 08:52:42 +01:00
Brett Adams f5412dd209 Bump Tesla Fleet API to 0.9.13 (#140485) 2025-03-13 08:23:26 +01:00
Allen Porter 6d58dd541e Update roborock quality scale for docs items (#140483) 2025-03-12 22:50:42 -04:00
Allen Porter 6a743310bb Change the local to-do list creation button to 'Create' (#140484) 2025-03-12 22:38:50 -04:00
J. Nick Koston ab56a4ca69 Bump aioesphomeapi to 29.6.0 (#140481)
changelog: https://github.com/esphome/aioesphomeapi/compare/v29.5.1...v29.6.0
2025-03-12 22:15:28 -04:00
Jan-Philipp Benecke db9a805ff0 Add rain state binary sensor to ecowitt (#140463) 2025-03-12 23:32:55 +00:00
J. Nick Koston e78dc486f7 Bump SQLAlchemy to 2.0.39 (#140473)
* Bump SQLAlchemy to 2.0.39

changelog: https://docs.sqlalchemy.org/en/20/changelog/changelog_20.html#change-2.0.39

* fix typing
2025-03-12 13:09:41 -10:00
Pete Sage 1f6658fca0 Prevent ipv6 discovery messages for Sonos (#139648) 2025-03-12 15:19:09 -04:00
Joost Lekkerkerker bad109dec5 Mark value in number.set_value action as required (#140445) 2025-03-12 19:07:41 +01:00
Simone Chemelli 892b78a1f9 Add exceptions translation for Vodafone Station (#140410) 2025-03-12 16:12:27 +00:00
Maikel Punie 70c355b52e Bump velbusaio to 2025.3.1 (#140443) 2025-03-12 16:30:01 +01:00
dontinelli d3376f31d0 Bump fyta_cli to 0.7.1 (#140452) 2025-03-12 15:29:43 +01:00
J. Nick Koston 06019e7995 Split timeout in lutron_caseta to increase configure timeout (#138875) 2025-03-12 10:59:36 +00:00
Franck Nijhof a12915fc14 2025.3.2 (#140392)
* Don't allow creating backups if Home Assistant is not running (#139499)

* Don't allow creating backups if hass is not running

* Revert "Don't allow creating backups if hass is not running"

This reverts commit 1bf545eb25f20fc27fe161691a94531cba7e005c.

* Set backup manager to idle only after Home Assistant has started

* Update according to discussion, add tests

* Add more test

* Bump govee_ble to 0.43.1 (#139862)

Bump govee_ble to 0.43.0

* Label emergency heat switch (#139872)

* Add label to emergency heat switch

* Use sentence case names

Co-authored-by: Franck Nijhof <frenck@frenck.nl>

---------

Co-authored-by: Franck Nijhof <frenck@frenck.nl>

* Bump sense-energy lib to 0.13.7 (#140068)

* Update jinja to 3.1.6 (#140069)

* Update evohome-async to 1.0.3 (#140083)

bump client to 1.0.3

* Fix HEOS discovery error when previously ignored (#140091)

Abort ignored discovery

* Map prewash job state in SmartThings (#140097)

* Check support for thermostat operating state in SmartThings (#140103)

* Handle None options in SmartThings (#140110)

* Handle None options in SmartThings

* Handle None options in SmartThings

* Fix MQTT JSON light not reporting color temp status if color is not supported (#140113)

* Fix HEOS user initiated setup when discovery is waiting confirmation (#140119)

* Support null supported Thermostat modes in SmartThings (#140101)

* Set device class for Oven Completion time in SmartThings (#140139)

* Revert "Check if the unit of measurement is valid before creating the entity" (#140155)

Revert "Check if the unit of measurement is valid before creating the entity …"

This reverts commit 99e1a7a676.

* Fix the order of the group members attribute of the Music Assistant integration (#140204)

* Fix events without user in Bring integration (#140213)

Fix events without publicUserUuid

* Log broad exception in Electricity Maps config flow (#140219)

* Bump evohome-async to 1.0.4 to fix  #140194 (#140230)

bump client, add test for fix  #140194

* Refresh Home Connect token during config entry setup (#140233)

* Refresh token during config entry setup

* Test 500 error

---------

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

* Add 900 RPM option to washer spin speed options at Home Connect (#140234)

Add 900 RPM option to washer spin speed options

* Fix todo tool broken with Gemini 2.0 models. (#140246)

* Change tool name for addlist item

* Change to HasListAddItem

* extract to function

* Fix version not always available in onewire (#140260)

* Fix `client_id` not generated when connecting to the MQTT broker (#140264)

Fix client_id not generated when connecting to the MQTT broker

* Bump velbusaio to 2025.3.0 (#140267)

* Fix dryer operating state in SmartThings (#140277)

* FGLair : Upgrade to ayla-iot-unofficial 1.4.7 (#140296)

Upgrade to ayla-iot-unofficial 1.4.7

* Bump pyheos to v1.0.3 (#140310)

Bump pyheos v1.0.3

* Bump ZHA to 0.0.52 (#140325)

* Bump pydrawise to 2025.3.0 (#140330)

* Bump teslemetry-stream (#140335)

Bump

* Fix no temperature unit in SmartThings (#140363)

* Fix double space quoting in WebDAV (#140364)

* Bump python-roborock to 2.12.2 (#140368)

bump python roboorck to 2.12.2

* Handle incomplete power consumption reports in SmartThings (#140370)

* Fix browsing Audible Favorites in Sonos (#140378)

* initial commit

* updates

* update test data

* Make sure SmartThings light can deal with unknown states (#140190)

* Fix

* add comment

* Make light unknown

* Make light unknown

* Delete subscription on shutdown of SmartThings (#140135)

* Cache subscription url in SmartThings

* Cache subscription url in SmartThings

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Bump pysmartthings to 2.7.1

* 2.7.2

---------

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

* Bump version to 2025.3.2

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Evan Farrell <evan@evanfarrell.com>
Co-authored-by: John Hillery <34005807+jrhillery@users.noreply.github.com>
Co-authored-by: Keilin Bickar <TrumpetGod@gmail.com>
Co-authored-by: David Bonnes <zxdavb@bonnes.me>
Co-authored-by: Andrew Sayre <6730289+andrewsayre@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
Co-authored-by: msm595 <msm595@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Jan-Philipp Benecke <jan-philipp@bnck.me>
Co-authored-by: J. Diego Rodríguez Royo <jdrr1998@hotmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Luke Lashley <conway220@gmail.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: Maikel Punie <maikel.punie@gmail.com>
Co-authored-by: Antoine Reversat <a.reversat@gmail.com>
Co-authored-by: puddly <32534428+puddly@users.noreply.github.com>
Co-authored-by: David Knowles <dknowles2@gmail.com>
Co-authored-by: Brett Adams <Bre77@users.noreply.github.com>
Co-authored-by: Pete Sage <76050312+PeteRager@users.noreply.github.com>
2025-03-11 17:36:00 +01:00
Franck Nijhof 3d5e4b980f Bump version to 2025.3.2 2025-03-11 15:22:38 +00:00
Joost Lekkerkerker f2f653efcf Delete subscription on shutdown of SmartThings (#140135)
* Cache subscription url in SmartThings

* Cache subscription url in SmartThings

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix

* Bump pysmartthings to 2.7.1

* 2.7.2

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-11 15:21:27 +00:00
Joost Lekkerkerker b5c7bdd98f Make sure SmartThings light can deal with unknown states (#140190)
* Fix

* add comment

* Make light unknown

* Make light unknown
2025-03-11 14:58:36 +00:00
Pete Sage 38e6133202 Fix browsing Audible Favorites in Sonos (#140378)
* initial commit

* updates

* update test data
2025-03-11 14:58:02 +00:00
Joost Lekkerkerker 8541dc5bde Handle incomplete power consumption reports in SmartThings (#140370) 2025-03-11 14:57:58 +00:00
Luke Lashley 5327996bad Bump python-roborock to 2.12.2 (#140368)
bump python roboorck to 2.12.2
2025-03-11 14:57:55 +00:00
Jan-Philipp Benecke 4ddc43a9d9 Fix double space quoting in WebDAV (#140364) 2025-03-11 14:57:51 +00:00
Joost Lekkerkerker e6dea4179b Fix no temperature unit in SmartThings (#140363) 2025-03-11 14:57:47 +00:00
Brett Adams 0318b85517 Bump teslemetry-stream (#140335)
Bump
2025-03-11 14:57:43 +00:00
David Knowles 29987d443e Bump pydrawise to 2025.3.0 (#140330) 2025-03-11 14:57:27 +00:00
puddly cbfd8707b9 Bump ZHA to 0.0.52 (#140325) 2025-03-11 14:57:18 +00:00
Andrew Sayre 5f158f5c87 Bump pyheos to v1.0.3 (#140310)
Bump pyheos v1.0.3
2025-03-11 14:57:14 +00:00
Antoine Reversat d67ccd2fce FGLair : Upgrade to ayla-iot-unofficial 1.4.7 (#140296)
Upgrade to ayla-iot-unofficial 1.4.7
2025-03-11 14:57:10 +00:00
Joost Lekkerkerker 29c9d3804b Fix dryer operating state in SmartThings (#140277) 2025-03-11 14:57:07 +00:00
Maikel Punie 76d478c84f Bump velbusaio to 2025.3.0 (#140267) 2025-03-11 14:56:54 +00:00
Jan Bouwhuis 5d9d6f099c Fix client_id not generated when connecting to the MQTT broker (#140264)
Fix client_id not generated when connecting to the MQTT broker
2025-03-11 14:56:49 +00:00
epenet e4b31640b3 Fix version not always available in onewire (#140260) 2025-03-11 14:56:43 +00:00
Luke Lashley c43f6a67d0 Fix todo tool broken with Gemini 2.0 models. (#140246)
* Change tool name for addlist item

* Change to HasListAddItem

* extract to function
2025-03-11 14:55:51 +00:00
J. Diego Rodríguez Royo 0bbab63193 Add 900 RPM option to washer spin speed options at Home Connect (#140234)
Add 900 RPM option to washer spin speed options
2025-03-11 14:52:37 +00:00
J. Diego Rodríguez Royo 06188b8fbd Refresh Home Connect token during config entry setup (#140233)
* Refresh token during config entry setup

* Test 500 error

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2025-03-11 14:52:33 +00:00
David Bonnes bbbb5cadd4 Bump evohome-async to 1.0.4 to fix #140194 (#140230)
bump client, add test for fix  #140194
2025-03-11 14:52:29 +00:00
Jan-Philipp Benecke 52fcdda429 Log broad exception in Electricity Maps config flow (#140219) 2025-03-11 14:52:25 +00:00
Manu 7d93ceb0f0 Fix events without user in Bring integration (#140213)
Fix events without publicUserUuid
2025-03-11 14:52:22 +00:00
msm595 873e4b77eb Fix the order of the group members attribute of the Music Assistant integration (#140204) 2025-03-11 14:52:17 +00:00
Jan Bouwhuis 61f0eabcbb Revert "Check if the unit of measurement is valid before creating the entity" (#140155)
Revert "Check if the unit of measurement is valid before creating the entity …"

This reverts commit 99e1a7a676.
2025-03-11 14:50:10 +00:00
Joost Lekkerkerker 134b5319e1 Set device class for Oven Completion time in SmartThings (#140139) 2025-03-11 14:50:05 +00:00
Joost Lekkerkerker ee78e21950 Support null supported Thermostat modes in SmartThings (#140101) 2025-03-11 14:47:50 +00:00
Andrew Sayre 323bc54efc Fix HEOS user initiated setup when discovery is waiting confirmation (#140119) 2025-03-11 14:46:18 +00:00
Jan Bouwhuis fd2dee3c11 Fix MQTT JSON light not reporting color temp status if color is not supported (#140113) 2025-03-11 14:46:14 +00:00
Joost Lekkerkerker fc53322c07 Handle None options in SmartThings (#140110)
* Handle None options in SmartThings

* Handle None options in SmartThings
2025-03-11 14:46:08 +00:00
Joost Lekkerkerker faf9977abb Check support for thermostat operating state in SmartThings (#140103) 2025-03-11 14:46:03 +00:00
Joost Lekkerkerker 7336c8fc07 Map prewash job state in SmartThings (#140097) 2025-03-11 14:36:17 +00:00
Andrew Sayre 5cfaeda95b Fix HEOS discovery error when previously ignored (#140091)
Abort ignored discovery
2025-03-11 14:36:13 +00:00
David Bonnes a78e9039c6 Update evohome-async to 1.0.3 (#140083)
bump client to 1.0.3
2025-03-11 14:36:10 +00:00
Franck Nijhof 227f3cea25 Update jinja to 3.1.6 (#140069) 2025-03-11 14:36:06 +00:00
Keilin Bickar cab4890246 Bump sense-energy lib to 0.13.7 (#140068) 2025-03-11 14:36:03 +00:00
John Hillery 95fd096bdd Label emergency heat switch (#139872)
* Add label to emergency heat switch

* Use sentence case names

Co-authored-by: Franck Nijhof <frenck@frenck.nl>

---------

Co-authored-by: Franck Nijhof <frenck@frenck.nl>
2025-03-11 14:35:59 +00:00
Evan Farrell 91cf8cb547 Bump govee_ble to 0.43.1 (#139862)
Bump govee_ble to 0.43.0
2025-03-11 14:35:56 +00:00
Erik Montnemery 3ce4f3f918 Don't allow creating backups if Home Assistant is not running (#139499)
* Don't allow creating backups if hass is not running

* Revert "Don't allow creating backups if hass is not running"

This reverts commit 1bf545eb25f20fc27fe161691a94531cba7e005c.

* Set backup manager to idle only after Home Assistant has started

* Update according to discussion, add tests

* Add more test
2025-03-11 14:35:46 +00:00
J. Nick Koston a8bdf80044 Merge branch 'dev' into ingress_dropping_close 2025-03-09 10:08:20 -10:00
Franck Nijhof 4e89948b5c 2025.3.1 (#140061) 2025-03-07 18:54:39 +01:00
Franck Nijhof 9f95383201 Bump version to 2025.3.1 2025-03-07 17:03:29 +00:00
Joost Lekkerkerker 7e452521c8 Restore SmartThings button event (#140044)
* Restore SmartThings button event

* Fix
2025-03-07 17:03:16 +00:00
Michael 991de6f1d0 Bump py-synologydsm-api to 2.7.1 (#140052)
bump py-synologydsm-api to 2.7.1
2025-03-07 16:49:07 +00:00
Joost Lekkerkerker be32e3fe8f Only keep valid powerConsumptionReports in SmartThings (#140049)
* power consumption report

* Only keep valid powerConsumptionReports in SmartThings
2025-03-07 16:49:03 +00:00
Joost Lekkerkerker d6eb61e9ec Bump pysmartthings to 2.7.0 (#140047) 2025-03-07 16:49:00 +00:00
Joost Lekkerkerker e74fe69d65 Fix SmartThings thermostat climate check (#140046)
* Fix SmartThings thermostat climate check

* Add tests
2025-03-07 16:48:55 +00:00
Joost Lekkerkerker 208406123e Fix SmartThings disabling working capabilities (#140039) 2025-03-07 16:03:40 +00:00
David Bonnes 8bcd135f3d Fix evohome to gracefully handle null schedules (#140036)
* extend tests to catch null schedules

* add fixture with null schedule

* remove null schedules for now

* fic the typing for _schedule attr (is list, not dict)

* add valid schedule to fixture

* update ssetpoints only if there is a schedule

* snapshot to match last change

* refactor: dont update switchpoints if no schedule

* add in warnings for null schedules

* add fixture for DHW without schedule
2025-03-07 16:03:36 +00:00
hahn-th e7ea0e435e Add description for HomematicIP HCU1 in homematicip_cloud setup config flow (#140025)
add description for hcu1
2025-03-07 16:03:33 +00:00
Brett Adams b15b680cfe Fix shift state default in Teslemetry and Tessie (#140018)
* Fix again

* Fix Tessie

* Update snap
2025-03-07 16:03:29 +00:00
Brett Adams 5e26d98bdf Fix powerwall 0% in Tessie and Tesla Fleet (#140017)
Fix powerwall zero
2025-03-07 16:03:26 +00:00
Martin Hjelmare 9f94ee280a Bump aiohomeconnect to 0.16.3 (#140014) 2025-03-07 16:03:23 +00:00
J. Diego Rodríguez Royo efa98539fa Check operation state on Home Connect program sensor update (#140011)
Check operation state on program sensor update
2025-03-07 16:03:19 +00:00
David Bonnes 113cd4bfcc Fix regression to evohome debug logging (#140000)
* fix regression in debug logging

* lint
2025-03-07 16:03:15 +00:00
Ivan Lopez Hernandez ccbaf76e44 Correctly retrieve only loaded Google Generative AI config_entries (#139999)
* Correctly retrieve only loaded config_entries

* Ruff
2025-03-07 16:03:08 +00:00
Jan-Philipp Benecke 5d9d93d3a1 Bump aiowebdav2 to 0.4.1 (#139988) 2025-03-07 16:03:04 +00:00
J. Nick Koston c2c5274aac Bump nexia to 2.2.2 (#139986)
changelog: https://github.com/bdraco/nexia/compare/2.2.1...2.2.2
2025-03-07 16:03:01 +00:00
Joost Lekkerkerker 89756394c9 Fix SmartThings dust sensor UoM (#139977) 2025-03-07 16:02:57 +00:00
Bram Kragten 352aa88e79 Update frontend to 20250306.0 (#139965) 2025-03-07 16:02:54 +00:00
Joost Lekkerkerker 714962bd7a Fix SmartThings fan (#139962) 2025-03-07 16:02:50 +00:00
Luke Lashley fb4c50b5dc Bump to python-snoo 0.6.1 (#139954) 2025-03-07 16:02:47 +00:00
Jan-Philipp Benecke b4794b2029 Set content length when uploading files to WebDAV (#139950) 2025-03-07 16:02:43 +00:00
Joost Lekkerkerker 3a8c8accfe Add config entry level diagnostics to SmartThings (#139939)
* Add config entry level diagnostics to SmartThings

* Add config entry level diagnostics to SmartThings

* Add config entry level diagnostics to SmartThings
2025-03-07 16:02:40 +00:00
Jan-Philipp Benecke 844adfc590 Bump aiowebdav2 to 0.4.0 (#139938) 2025-03-07 16:02:36 +00:00
Joost Lekkerkerker a279e23fb5 Bump pysmartthings to 2.6.1 (#139936)
* Bump pysmartthings to 2.6.1

* Bump pysmartthings to 2.6.1
2025-03-07 15:58:00 +00:00
Jan Bouwhuis af9bbd0585 Check if the unit of measurement is valid before creating the entity (#139932) 2025-03-07 15:50:55 +00:00
Joost Lekkerkerker 1304194f09 Deduplicate climate modes in SmartThings (#139930)
* Deduplicate climate modes in SmartThings

* Deduplicate climate modes in SmartThings
2025-03-07 15:50:51 +00:00
J. Nick Koston e909417a3f Bump thermobeacon-ble to 0.8.1 (#139919)
changelog: https://github.com/Bluetooth-Devices/thermobeacon-ble/compare/v0.8.0...v0.8.1

fixes #139917
2025-03-07 15:50:48 +00:00
Ivan Lopez Hernandez 02706c116d Trim the Schema allowed keys to match the Public Gemini API docs. (#139876)
* Trim the Schema allowed types to match the Public API docs, not the SDK types as those do not match

* Testing
2025-03-07 15:50:43 +00:00
peteS-UK 3af6b5cb4c Fix Unit of Measurement for Squeezebox duration sensor entity on LMS service (#139861)
UOM Fix
2025-03-07 15:42:02 +00:00
Ishima 35c1bb1ec5 Check support for demand load control in SmartThings AC (#139616)
* Check support for demand load control in SmartThings AC

* Fix

---------

Co-authored-by: Joostlek <joostlek@outlook.com>
2025-03-07 15:41:52 +00:00
J. Nick Koston 14b16e298a Merge branch 'dev' into ingress_dropping_close 2025-01-08 07:26:39 -10:00
J. Nick Koston 75cf02cad8 Merge branch 'dev' into ingress_dropping_close 2024-11-08 23:24:44 +00:00
J. Nick Koston b2a737cf56 Merge branch 'dev' into ingress_dropping_close 2024-11-03 00:50:32 -05:00
J. Nick Koston 98601da3ea Fix ingress websocket forward not closing the websocket
Becuase the async iterator was used, it would stop iteration as soon
as a close message was seen. This meant we would never send close to
the other side
2024-09-25 07:56:47 -05:00
1190 changed files with 63707 additions and 13935 deletions
+13 -13
View File
@@ -32,7 +32,7 @@ jobs:
fetch-depth: 0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -69,7 +69,7 @@ jobs:
run: find ./homeassistant/components/*/translations -name "*.json" | tar zcvf translations.tar.gz -T -
- name: Upload translations
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: translations
path: translations.tar.gz
@@ -116,7 +116,7 @@ jobs:
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
if: needs.init.outputs.channel == 'dev'
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -175,7 +175,7 @@ jobs:
sed -i "s|pykrakenapi|# pykrakenapi|g" requirements_all.txt
- name: Download translations
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: translations
@@ -190,14 +190,14 @@ jobs:
echo "${{ github.sha }};${{ github.ref }};${{ github.event_name }};${{ github.actor }}" > rootfs/OFFICIAL_IMAGE
- name: Login to GitHub Container Registry
uses: docker/login-action@v3.3.0
uses: docker/login-action@v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build base image
uses: home-assistant/builder@2025.02.0
uses: home-assistant/builder@2025.03.0
with:
args: |
$BUILD_ARGS \
@@ -256,14 +256,14 @@ jobs:
fi
- name: Login to GitHub Container Registry
uses: docker/login-action@v3.3.0
uses: docker/login-action@v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build base image
uses: home-assistant/builder@2025.02.0
uses: home-assistant/builder@2025.03.0
with:
args: |
$BUILD_ARGS \
@@ -330,14 +330,14 @@ jobs:
- name: Login to DockerHub
if: matrix.registry == 'docker.io/homeassistant'
uses: docker/login-action@v3.3.0
uses: docker/login-action@v3.4.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
if: matrix.registry == 'ghcr.io/home-assistant'
uses: docker/login-action@v3.3.0
uses: docker/login-action@v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -457,12 +457,12 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
- name: Download translations
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: translations
@@ -502,7 +502,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to GitHub Container Registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
+59 -59
View File
@@ -37,10 +37,10 @@ on:
type: boolean
env:
CACHE_VERSION: 11
CACHE_VERSION: 12
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 9
HA_SHORT_VERSION: "2025.4"
HA_SHORT_VERSION: "2025.5"
DEFAULT_PYTHON: "3.13"
ALL_PYTHON_VERSIONS: "['3.13']"
# 10.3 is the oldest supported version
@@ -249,13 +249,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v4.2.2
uses: actions/cache@v4.2.3
with:
path: venv
key: >-
@@ -271,7 +271,7 @@ jobs:
uv pip install "$(cat requirements_test.txt | grep pre-commit)"
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache@v4.2.2
uses: actions/cache@v4.2.3
with:
path: ${{ env.PRE_COMMIT_CACHE }}
lookup-only: true
@@ -294,14 +294,14 @@ jobs:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -310,7 +310,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -334,14 +334,14 @@ jobs:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -350,7 +350,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -374,14 +374,14 @@ jobs:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
id: python
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -390,7 +390,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -484,7 +484,7 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
@@ -497,7 +497,7 @@ jobs:
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v4.2.2
uses: actions/cache@v4.2.3
with:
path: venv
key: >-
@@ -505,7 +505,7 @@ jobs:
needs.info.outputs.python_cache_key }}
- name: Restore uv wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v4.2.2
uses: actions/cache@v4.2.3
with:
path: ${{ env.UV_CACHE_DIR }}
key: >-
@@ -552,7 +552,7 @@ jobs:
python --version
uv pip freeze >> pip_freeze.txt
- name: Upload pip_freeze artifact
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: pip-freeze-${{ matrix.python-version }}
path: pip_freeze.txt
@@ -587,13 +587,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -620,13 +620,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -677,13 +677,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -695,7 +695,7 @@ jobs:
. venv/bin/activate
python -m script.licenses extract --output-file=licenses-${{ matrix.python-version }}.json
- name: Upload licenses
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: licenses-${{ github.run_number }}-${{ matrix.python-version }}
path: licenses-${{ matrix.python-version }}.json
@@ -720,13 +720,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -767,13 +767,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -812,7 +812,7 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -825,7 +825,7 @@ jobs:
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -833,7 +833,7 @@ jobs:
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Restore mypy cache
uses: actions/cache@v4.2.2
uses: actions/cache@v4.2.3
with:
path: .mypy_cache
key: >-
@@ -889,13 +889,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -907,7 +907,7 @@ jobs:
. venv/bin/activate
python -m script.split_tests ${{ needs.info.outputs.test_group_count }} tests
- name: Upload pytest_buckets
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: pytest_buckets
path: pytest_buckets.txt
@@ -949,13 +949,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -968,7 +968,7 @@ jobs:
run: |
echo "::add-matcher::.github/workflows/matchers/pytest-slow.json"
- name: Download pytest_buckets
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: pytest_buckets
- name: Compile English translations
@@ -1007,21 +1007,21 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${{ matrix.group }}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-full.conclusion == 'failure'
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{ matrix.group }}
path: pytest-*.txt
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
path: coverage.xml
overwrite: true
- name: Upload test results artifact
if: needs.info.outputs.skip_coverage != 'true' && !cancelled()
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: test-results-full-${{ matrix.python-version }}-${{ matrix.group }}
path: junit.xml
@@ -1074,13 +1074,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -1138,7 +1138,7 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${mariadb}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.mariadb }}
@@ -1146,7 +1146,7 @@ jobs:
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: coverage-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.mariadb }}
@@ -1154,7 +1154,7 @@ jobs:
overwrite: true
- name: Upload test results artifact
if: needs.info.outputs.skip_coverage != 'true' && !cancelled()
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: test-results-mariadb-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.mariadb }}
@@ -1208,13 +1208,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -1273,7 +1273,7 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${postgresql}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.postgresql }}
@@ -1281,7 +1281,7 @@ jobs:
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: coverage-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.postgresql }}
@@ -1289,7 +1289,7 @@ jobs:
overwrite: true
- name: Upload test results artifact
if: needs.info.outputs.skip_coverage != 'true' && !cancelled()
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: test-results-postgres-${{ matrix.python-version }}-${{
steps.pytest-partial.outputs.postgresql }}
@@ -1312,7 +1312,7 @@ jobs:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
- name: Download all coverage artifacts
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
pattern: coverage-*
- name: Upload coverage to Codecov
@@ -1359,13 +1359,13 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.2.2
uses: actions/cache/restore@v4.2.3
with:
path: venv
fail-on-cache-miss: true
@@ -1420,21 +1420,21 @@ jobs:
2>&1 | tee pytest-${{ matrix.python-version }}-${{ matrix.group }}.txt
- name: Upload pytest output
if: success() || failure() && steps.pytest-partial.conclusion == 'failure'
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: pytest-${{ github.run_number }}-${{ matrix.python-version }}-${{ matrix.group }}
path: pytest-*.txt
overwrite: true
- name: Upload coverage artifact
if: needs.info.outputs.skip_coverage != 'true'
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
path: coverage.xml
overwrite: true
- name: Upload test results artifact
if: needs.info.outputs.skip_coverage != 'true' && !cancelled()
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: test-results-partial-${{ matrix.python-version }}-${{ matrix.group }}
path: junit.xml
@@ -1454,7 +1454,7 @@ jobs:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.2
- name: Download all coverage artifacts
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
pattern: coverage-*
- name: Upload coverage to Codecov
@@ -1479,7 +1479,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Download all coverage artifacts
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
pattern: test-results-*
- name: Upload test results to Codecov
+2 -2
View File
@@ -24,11 +24,11 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.28.11
uses: github/codeql-action/init@v3.28.13
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.28.11
uses: github/codeql-action/analyze@v3.28.13
with:
category: "/language:python"
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
+14 -14
View File
@@ -36,7 +36,7 @@ jobs:
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -91,7 +91,7 @@ jobs:
) > build_constraints.txt
- name: Upload env_file
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: env_file
path: ./.env_file
@@ -99,14 +99,14 @@ jobs:
overwrite: true
- name: Upload build_constraints
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: build_constraints
path: ./build_constraints.txt
overwrite: true
- name: Upload requirements_diff
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: requirements_diff
path: ./requirements_diff.txt
@@ -118,7 +118,7 @@ jobs:
python -m script.gen_requirements_all ci
- name: Upload requirements_all_wheels
uses: actions/upload-artifact@v4.6.1
uses: actions/upload-artifact@v4.6.2
with:
name: requirements_all_wheels
path: ./requirements_all_wheels_*.txt
@@ -138,17 +138,17 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Download env_file
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: env_file
- name: Download build_constraints
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: build_constraints
- name: Download requirements_diff
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: requirements_diff
@@ -159,7 +159,7 @@ jobs:
sed -i "/uv/d" requirements_diff.txt
- name: Build wheels
uses: home-assistant/wheels@2025.02.0
uses: home-assistant/wheels@2025.03.0
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
@@ -187,22 +187,22 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Download env_file
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: env_file
- name: Download build_constraints
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: build_constraints
- name: Download requirements_diff
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: requirements_diff
- name: Download requirements_all_wheels
uses: actions/download-artifact@v4.1.9
uses: actions/download-artifact@v4.2.1
with:
name: requirements_all_wheels
@@ -219,7 +219,7 @@ jobs:
sed -i "/uv/d" requirements_diff.txt
- name: Build wheels
uses: home-assistant/wheels@2025.02.0
uses: home-assistant/wheels@2025.03.0
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
+1 -1
View File
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.10
rev: v0.11.0
hooks:
- id: ruff
args:
+2
View File
@@ -119,6 +119,7 @@ homeassistant.components.bluetooth_adapters.*
homeassistant.components.bluetooth_tracker.*
homeassistant.components.bmw_connected_drive.*
homeassistant.components.bond.*
homeassistant.components.bosch_alarm.*
homeassistant.components.braviatv.*
homeassistant.components.bring.*
homeassistant.components.brother.*
@@ -412,6 +413,7 @@ homeassistant.components.recollect_waste.*
homeassistant.components.recorder.*
homeassistant.components.remember_the_milk.*
homeassistant.components.remote.*
homeassistant.components.remote_calendar.*
homeassistant.components.renault.*
homeassistant.components.reolink.*
homeassistant.components.repairs.*
+1 -1
View File
@@ -4,7 +4,7 @@
{
"label": "Run Home Assistant Core",
"type": "shell",
"command": "hass -c ./config",
"command": "${command:python.interpreterPath} -m homeassistant -c ./config",
"group": "test",
"presentation": {
"reveal": "always",
Generated
+8 -2
View File
@@ -216,6 +216,8 @@ build.json @home-assistant/supervisor
/tests/components/bmw_connected_drive/ @gerard33 @rikroe
/homeassistant/components/bond/ @bdraco @prystupa @joshs85 @marciogranzotto
/tests/components/bond/ @bdraco @prystupa @joshs85 @marciogranzotto
/homeassistant/components/bosch_alarm/ @mag1024 @sanjay900
/tests/components/bosch_alarm/ @mag1024 @sanjay900
/homeassistant/components/bosch_shc/ @tschamm
/tests/components/bosch_shc/ @tschamm
/homeassistant/components/braviatv/ @bieniu @Drafteed
@@ -570,8 +572,8 @@ build.json @home-assistant/supervisor
/tests/components/google_cloud/ @lufton @tronikos
/homeassistant/components/google_drive/ @tronikos
/tests/components/google_drive/ @tronikos
/homeassistant/components/google_generative_ai_conversation/ @tronikos
/tests/components/google_generative_ai_conversation/ @tronikos
/homeassistant/components/google_generative_ai_conversation/ @tronikos @ivanlh
/tests/components/google_generative_ai_conversation/ @tronikos @ivanlh
/homeassistant/components/google_mail/ @tkdrob
/tests/components/google_mail/ @tkdrob
/homeassistant/components/google_photos/ @allenporter
@@ -1183,6 +1185,8 @@ build.json @home-assistant/supervisor
/tests/components/prusalink/ @balloob
/homeassistant/components/ps4/ @ktnrg45
/tests/components/ps4/ @ktnrg45
/homeassistant/components/pterodactyl/ @elmurato
/tests/components/pterodactyl/ @elmurato
/homeassistant/components/pure_energie/ @klaasnicolaas
/tests/components/pure_energie/ @klaasnicolaas
/homeassistant/components/purpleair/ @bachya
@@ -1252,6 +1256,8 @@ build.json @home-assistant/supervisor
/tests/components/refoss/ @ashionky
/homeassistant/components/remote/ @home-assistant/core
/tests/components/remote/ @home-assistant/core
/homeassistant/components/remote_calendar/ @Thomas55555
/tests/components/remote_calendar/ @Thomas55555
/homeassistant/components/renault/ @epenet
/tests/components/renault/ @epenet
/homeassistant/components/renson/ @jimmyd-be
Generated
+1 -1
View File
@@ -31,7 +31,7 @@ RUN \
&& go2rtc --version
# Install uv
RUN pip3 install uv==0.6.1
RUN pip3 install uv==0.6.10
WORKDIR /usr/src
+1 -1
View File
@@ -19,4 +19,4 @@ labels:
org.opencontainers.image.authors: The Home Assistant Authors
org.opencontainers.image.url: https://www.home-assistant.io/
org.opencontainers.image.documentation: https://www.home-assistant.io/docs/
org.opencontainers.image.licenses: Apache License 2.0
org.opencontainers.image.licenses: Apache-2.0
+9
View File
@@ -178,6 +178,15 @@ _BLOCKING_CALLS: tuple[BlockingCall, ...] = (
strict_core=False,
skip_for_tests=True,
),
BlockingCall(
original_func=SSLContext.set_default_verify_paths,
object=SSLContext,
function="set_default_verify_paths",
check_allowed=None,
strict=False,
strict_core=False,
skip_for_tests=True,
),
BlockingCall(
original_func=Path.open,
object=Path,
+11 -17
View File
@@ -859,8 +859,14 @@ async def _async_set_up_integrations(
integrations, all_integrations = await _async_resolve_domains_and_preload(
hass, config
)
all_domains = set(all_integrations)
domains = set(integrations)
# Detect all cycles
integrations_after_dependencies = (
await loader.resolve_integrations_after_dependencies(
hass, all_integrations.values(), set(all_integrations)
)
)
all_domains = set(integrations_after_dependencies)
domains = set(integrations) & all_domains
_LOGGER.info(
"Domains to be set up: %s | %s",
@@ -868,6 +874,8 @@ async def _async_set_up_integrations(
all_domains - domains,
)
async_set_domains_to_be_loaded(hass, all_domains)
# Initialize recorder
if "recorder" in all_domains:
recorder.async_initialize_recorder(hass)
@@ -900,24 +908,12 @@ async def _async_set_up_integrations(
stage_dep_domains_unfiltered = {
dep
for domain in stage_domains
for dep in all_integrations[domain].all_dependencies
for dep in integrations_after_dependencies[domain]
if dep not in stage_domains
}
stage_dep_domains = stage_dep_domains_unfiltered - hass.config.components
stage_all_domains = stage_domains | stage_dep_domains
stage_all_integrations = {
domain: all_integrations[domain] for domain in stage_all_domains
}
# Detect all cycles
stage_integrations_after_dependencies = (
await loader.resolve_integrations_after_dependencies(
hass, stage_all_integrations.values(), stage_all_domains
)
)
stage_all_domains = set(stage_integrations_after_dependencies)
stage_domains &= stage_all_domains
stage_dep_domains &= stage_all_domains
_LOGGER.info(
"Setting up stage %s: %s | %s\nDependencies: %s | %s",
@@ -928,8 +924,6 @@ async def _async_set_up_integrations(
stage_dep_domains_unfiltered - stage_dep_domains,
)
async_set_domains_to_be_loaded(hass, stage_all_domains)
if timeout is None:
await _async_setup_multi_components(hass, stage_all_domains, config)
continue
+2 -1
View File
@@ -1,5 +1,6 @@
{
"domain": "motionblinds",
"name": "Motionblinds",
"integrations": ["motion_blinds", "motionblinds_ble"]
"integrations": ["motion_blinds", "motionblinds_ble"],
"iot_standards": ["matter"]
}
@@ -75,7 +75,11 @@ class AccuWeatherObservationDataUpdateCoordinator(
async with timeout(10):
result = await self.accuweather.async_get_current_conditions()
except EXCEPTIONS as error:
raise UpdateFailed(error) from error
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="current_conditions_update_error",
translation_placeholders={"error": repr(error)},
) from error
_LOGGER.debug("Requests remaining: %d", self.accuweather.requests_remaining)
@@ -121,7 +125,11 @@ class AccuWeatherDailyForecastDataUpdateCoordinator(
language=self.hass.config.language
)
except EXCEPTIONS as error:
raise UpdateFailed(error) from error
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="forecast_update_error",
translation_placeholders={"error": repr(error)},
) from error
_LOGGER.debug("Requests remaining: %d", self.accuweather.requests_remaining)
@@ -106,6 +106,15 @@
"steady": "Steady",
"rising": "Rising",
"falling": "Falling"
},
"state_attributes": {
"options": {
"state": {
"falling": "[%key:component::accuweather::entity::sensor::pressure_tendency::state::falling%]",
"rising": "[%key:component::accuweather::entity::sensor::pressure_tendency::state::rising%]",
"steady": "[%key:component::accuweather::entity::sensor::pressure_tendency::state::steady%]"
}
}
}
},
"ragweed_pollen": {
@@ -220,6 +229,14 @@
}
}
},
"exceptions": {
"current_conditions_update_error": {
"message": "An error occurred while retrieving weather current conditions data from the AccuWeather API: {error}"
},
"forecast_update_error": {
"message": "An error occurred while retrieving weather forecast data from the AccuWeather API: {error}"
}
},
"system_health": {
"info": {
"can_reach_server": "Reach AccuWeather server",
+3 -3
View File
@@ -5,14 +5,14 @@
"data": {
"connection_type": "Select connection type"
},
"description": "Select connection type. Local requires heaters with bluetooth"
"description": "Select connection type. Local requires heaters with Bluetooth"
},
"local": {
"data": {
"wifi_ssid": "Wi-Fi SSID",
"wifi_pswd": "Wi-Fi Password"
"wifi_pswd": "Wi-Fi password"
},
"description": "Reset the heater by pressing + and OK until display shows 'Reset'. Then press and hold OK button on the heater until the blue led starts blinking before pressing Submit. Configuring heater might take some minutes."
"description": "Reset the heater by pressing + and OK until display shows 'Reset'. Then press and hold OK button on the heater until the blue LED starts blinking before pressing Submit. Configuring heater might take some minutes."
},
"cloud": {
"data": {
@@ -11,7 +11,7 @@
}
},
"discovery_confirm": {
"description": "Do you want to setup {model}?"
"description": "Do you want to set up {model}?"
}
},
"abort": {
+13 -2
View File
@@ -105,7 +105,14 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str | float | i
try:
await measurements.update()
except (AirlyError, ClientConnectorError) as error:
raise UpdateFailed(error) from error
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="update_error",
translation_placeholders={
"entry": self.config_entry.title,
"error": repr(error),
},
) from error
_LOGGER.debug(
"Requests remaining: %s/%s",
@@ -126,7 +133,11 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str | float | i
standards = measurements.current["standards"]
if index["description"] == NO_AIRLY_SENSORS:
raise UpdateFailed("Can't retrieve data: no Airly sensors in this area")
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="no_station",
translation_placeholders={"entry": self.config_entry.title},
)
for value in values:
data[value["name"]] = value["value"]
for standard in standards:
@@ -36,5 +36,13 @@
"name": "[%key:component::sensor::entity_component::carbon_monoxide::name%]"
}
}
},
"exceptions": {
"update_error": {
"message": "An error occurred while retrieving data from the Airly API for {entry}: {error}"
},
"no_station": {
"message": "An error occurred while retrieving data from the Airly API for {entry}: no measuring stations in this area"
}
}
}
+2 -2
View File
@@ -7,7 +7,7 @@
"api_key": "[%key:common::config_flow::data::api_key%]",
"latitude": "[%key:common::config_flow::data::latitude%]",
"longitude": "[%key:common::config_flow::data::longitude%]",
"radius": "Station Radius (miles; optional)"
"radius": "Station radius (miles; optional)"
}
}
},
@@ -25,7 +25,7 @@
"step": {
"init": {
"data": {
"radius": "Station Radius (miles)"
"radius": "Station radius (miles)"
}
}
}
+7 -7
View File
@@ -91,7 +91,7 @@
"name": "Hydrogen fluoride"
},
"health_index": {
"name": "Health Index"
"name": "Health index"
},
"absolute_humidity": {
"name": "Absolute humidity"
@@ -112,10 +112,10 @@
"name": "Oxygen"
},
"performance_index": {
"name": "Performance Index"
"name": "Performance index"
},
"hydrogen_phosphide": {
"name": "Hydrogen Phosphide"
"name": "Hydrogen phosphide"
},
"relative_pressure": {
"name": "Relative pressure"
@@ -127,22 +127,22 @@
"name": "Refrigerant"
},
"silicon_hydride": {
"name": "Silicon Hydride"
"name": "Silicon hydride"
},
"noise": {
"name": "Noise"
},
"maximum_noise": {
"name": "Noise (Maximum)"
"name": "Noise (maximum)"
},
"radon": {
"name": "Radon"
},
"industrial_volatile_organic_compounds": {
"name": "VOCs (Industrial)"
"name": "VOCs (industrial)"
},
"virus_index": {
"name": "Virus Index"
"name": "Virus index"
}
}
}
@@ -102,7 +102,8 @@ class AirthingsConfigFlow(ConfigFlow, domain=DOMAIN):
device = await self._get_device_data(discovery_info)
except AirthingsDeviceUpdateError:
return self.async_abort(reason="cannot_connect")
except Exception: # noqa: BLE001
except Exception:
_LOGGER.exception("Unknown error occurred")
return self.async_abort(reason="unknown")
name = get_name(device)
@@ -160,7 +161,8 @@ class AirthingsConfigFlow(ConfigFlow, domain=DOMAIN):
device = await self._get_device_data(discovery_info)
except AirthingsDeviceUpdateError:
return self.async_abort(reason="cannot_connect")
except Exception: # noqa: BLE001
except Exception:
_LOGGER.exception("Unknown error occurred")
return self.async_abort(reason="unknown")
name = get_name(device)
self._discovered_devices[address] = Discovery(name, discovery_info, device)
@@ -32,7 +32,8 @@ class AirTouch5ConfigFlow(ConfigFlow, domain=DOMAIN):
client = Airtouch5SimpleClient(user_input[CONF_HOST])
try:
await client.test_connection()
except Exception: # noqa: BLE001
except Exception:
_LOGGER.exception("Unexpected exception")
errors = {"base": "cannot_connect"}
else:
await self.async_set_unique_id(user_input[CONF_HOST])
@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/airzone_cloud",
"iot_class": "cloud_push",
"loggers": ["aioairzone_cloud"],
"requirements": ["aioairzone-cloud==0.6.10"]
"requirements": ["aioairzone-cloud==0.6.11"]
}
@@ -1438,7 +1438,7 @@ class AlexaModeController(AlexaCapability):
# Fan preset_mode
if self.instance == f"{fan.DOMAIN}.{fan.ATTR_PRESET_MODE}":
mode = self.entity.attributes.get(fan.ATTR_PRESET_MODE, None)
if mode in self.entity.attributes.get(fan.ATTR_PRESET_MODES, None):
if mode in self.entity.attributes.get(fan.ATTR_PRESET_MODES, ()):
return f"{fan.ATTR_PRESET_MODE}.{mode}"
# Humidifier mode
@@ -240,6 +240,7 @@ SENSOR_DESCRIPTIONS = (
suggested_display_precision=0,
entity_registry_enabled_default=False,
device_class=SensorDeviceClass.WIND_DIRECTION,
state_class=SensorStateClass.MEASUREMENT_ANGLE,
),
SensorEntityDescription(
key=TYPE_WINDGUSTMPH,
@@ -609,6 +609,7 @@ SENSOR_DESCRIPTIONS = (
translation_key="wind_direction",
native_unit_of_measurement=DEGREE,
device_class=SensorDeviceClass.WIND_DIRECTION,
state_class=SensorStateClass.MEASUREMENT_ANGLE,
),
SensorEntityDescription(
key=TYPE_WINDDIR_AVG10M,
@@ -7,6 +7,6 @@
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["androidtvremote2"],
"requirements": ["androidtvremote2==0.2.0"],
"requirements": ["androidtvremote2==0.2.1"],
"zeroconf": ["_androidtvremote2._tcp.local."]
}
@@ -2,6 +2,8 @@
from __future__ import annotations
import logging
from anova_wifi import AnovaApi, InvalidLogin
import voluptuous as vol
@@ -11,8 +13,10 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
class AnovaConfligFlow(ConfigFlow, domain=DOMAIN):
class AnovaConfigFlow(ConfigFlow, domain=DOMAIN):
"""Sets up a config flow for Anova."""
VERSION = 1
@@ -35,7 +39,8 @@ class AnovaConfligFlow(ConfigFlow, domain=DOMAIN):
await api.authenticate()
except InvalidLogin:
errors["base"] = "invalid_auth"
except Exception: # noqa: BLE001
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
return self.async_create_entry(
@@ -34,10 +34,12 @@ from .const import (
CONF_PROMPT,
CONF_RECOMMENDED,
CONF_TEMPERATURE,
CONF_THINKING_BUDGET,
DOMAIN,
RECOMMENDED_CHAT_MODEL,
RECOMMENDED_MAX_TOKENS,
RECOMMENDED_TEMPERATURE,
RECOMMENDED_THINKING_BUDGET,
)
_LOGGER = logging.getLogger(__name__)
@@ -128,21 +130,29 @@ class AnthropicOptionsFlow(OptionsFlow):
) -> ConfigFlowResult:
"""Manage the options."""
options: dict[str, Any] | MappingProxyType[str, Any] = self.config_entry.options
errors: dict[str, str] = {}
if user_input is not None:
if user_input[CONF_RECOMMENDED] == self.last_rendered_recommended:
if user_input[CONF_LLM_HASS_API] == "none":
user_input.pop(CONF_LLM_HASS_API)
return self.async_create_entry(title="", data=user_input)
# Re-render the options again, now with the recommended options shown/hidden
self.last_rendered_recommended = user_input[CONF_RECOMMENDED]
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"
options = {
CONF_RECOMMENDED: user_input[CONF_RECOMMENDED],
CONF_PROMPT: user_input[CONF_PROMPT],
CONF_LLM_HASS_API: user_input[CONF_LLM_HASS_API],
}
if not errors:
return self.async_create_entry(title="", data=user_input)
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[CONF_LLM_HASS_API],
}
suggested_values = options.copy()
if not suggested_values.get(CONF_PROMPT):
@@ -156,6 +166,7 @@ class AnthropicOptionsFlow(OptionsFlow):
return self.async_show_form(
step_id="init",
data_schema=schema,
errors=errors or None,
)
@@ -205,6 +216,10 @@ def anthropic_config_option_schema(
CONF_TEMPERATURE,
default=RECOMMENDED_TEMPERATURE,
): NumberSelector(NumberSelectorConfig(min=0, max=1, step=0.05)),
vol.Optional(
CONF_THINKING_BUDGET,
default=RECOMMENDED_THINKING_BUDGET,
): int,
}
)
return schema
@@ -13,3 +13,8 @@ CONF_MAX_TOKENS = "max_tokens"
RECOMMENDED_MAX_TOKENS = 1024
CONF_TEMPERATURE = "temperature"
RECOMMENDED_TEMPERATURE = 1.0
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"]
@@ -1,23 +1,32 @@
"""Conversation support for Anthropic."""
from collections.abc import AsyncGenerator, Callable
from collections.abc import AsyncGenerator, Callable, Iterable
import json
from typing import Any, Literal
from typing import Any, Literal, cast
import anthropic
from anthropic import AsyncStream
from anthropic._types import NOT_GIVEN
from anthropic.types import (
InputJSONDelta,
Message,
MessageParam,
MessageStreamEvent,
RawContentBlockDeltaEvent,
RawContentBlockStartEvent,
RawContentBlockStopEvent,
RawMessageStartEvent,
RawMessageStopEvent,
RedactedThinkingBlock,
RedactedThinkingBlockParam,
SignatureDelta,
TextBlock,
TextBlockParam,
TextDelta,
ThinkingBlock,
ThinkingBlockParam,
ThinkingConfigDisabledParam,
ThinkingConfigEnabledParam,
ThinkingDelta,
ToolParam,
ToolResultBlockParam,
ToolUseBlock,
@@ -39,11 +48,15 @@ from .const import (
CONF_MAX_TOKENS,
CONF_PROMPT,
CONF_TEMPERATURE,
CONF_THINKING_BUDGET,
DOMAIN,
LOGGER,
MIN_THINKING_BUDGET,
RECOMMENDED_CHAT_MODEL,
RECOMMENDED_MAX_TOKENS,
RECOMMENDED_TEMPERATURE,
RECOMMENDED_THINKING_BUDGET,
THINKING_MODELS,
)
# Max number of back and forth with the LLM to generate a response
@@ -71,73 +84,101 @@ def _format_tool(
)
def _message_convert(
message: Message,
) -> MessageParam:
"""Convert from class to TypedDict."""
param_content: list[TextBlockParam | ToolUseBlockParam] = []
def _convert_content(
chat_content: Iterable[conversation.Content],
) -> list[MessageParam]:
"""Transform HA chat_log content into Anthropic API format."""
messages: list[MessageParam] = []
for message_content in message.content:
if isinstance(message_content, TextBlock):
param_content.append(TextBlockParam(type="text", text=message_content.text))
elif isinstance(message_content, ToolUseBlock):
param_content.append(
ToolUseBlockParam(
type="tool_use",
id=message_content.id,
name=message_content.name,
input=message_content.input,
)
for content in chat_content:
if isinstance(content, conversation.ToolResultContent):
tool_result_block = ToolResultBlockParam(
type="tool_result",
tool_use_id=content.tool_call_id,
content=json.dumps(content.tool_result),
)
return MessageParam(role=message.role, content=param_content)
def _convert_content(chat_content: conversation.Content) -> MessageParam:
"""Create tool response content."""
if isinstance(chat_content, conversation.ToolResultContent):
return MessageParam(
role="user",
content=[
ToolResultBlockParam(
type="tool_result",
tool_use_id=chat_content.tool_call_id,
content=json.dumps(chat_content.tool_result),
)
],
)
if isinstance(chat_content, conversation.AssistantContent):
return MessageParam(
role="assistant",
content=[
TextBlockParam(type="text", text=chat_content.content or ""),
*[
ToolUseBlockParam(
type="tool_use",
id=tool_call.id,
name=tool_call.tool_name,
input=tool_call.tool_args,
if not messages or messages[-1]["role"] != "user":
messages.append(
MessageParam(
role="user",
content=[tool_result_block],
)
for tool_call in chat_content.tool_calls or ()
],
],
)
if isinstance(chat_content, conversation.UserContent):
return MessageParam(
role="user",
content=chat_content.content,
)
# Note: We don't pass SystemContent here as its passed to the API as the prompt
raise ValueError(f"Unexpected content type: {type(chat_content)}")
)
elif isinstance(messages[-1]["content"], str):
messages[-1]["content"] = [
TextBlockParam(type="text", text=messages[-1]["content"]),
tool_result_block,
]
else:
messages[-1]["content"].append(tool_result_block) # type: ignore[attr-defined]
elif isinstance(content, conversation.UserContent):
# Combine consequent user messages
if not messages or messages[-1]["role"] != "user":
messages.append(
MessageParam(
role="user",
content=content.content,
)
)
elif isinstance(messages[-1]["content"], str):
messages[-1]["content"] = [
TextBlockParam(type="text", text=messages[-1]["content"]),
TextBlockParam(type="text", text=content.content),
]
else:
messages[-1]["content"].append( # type: ignore[attr-defined]
TextBlockParam(type="text", text=content.content)
)
elif isinstance(content, conversation.AssistantContent):
# Combine consequent assistant messages
if not messages or messages[-1]["role"] != "assistant":
messages.append(
MessageParam(
role="assistant",
content=[],
)
)
if content.content:
messages[-1]["content"].append( # type: ignore[union-attr]
TextBlockParam(type="text", text=content.content)
)
if content.tool_calls:
messages[-1]["content"].extend( # type: ignore[union-attr]
[
ToolUseBlockParam(
type="tool_use",
id=tool_call.id,
name=tool_call.tool_name,
input=tool_call.tool_args,
)
for tool_call in content.tool_calls
]
)
else:
# Note: We don't pass SystemContent here as its passed to the API as the prompt
raise TypeError(f"Unexpected content type: {type(content)}")
return messages
async def _transform_stream(
result: AsyncStream[MessageStreamEvent],
messages: list[MessageParam],
) -> AsyncGenerator[conversation.AssistantContentDeltaDict]:
"""Transform the response stream into HA format.
A typical stream of responses might look something like the following:
- RawMessageStartEvent with no content
- RawContentBlockStartEvent with an empty ThinkingBlock (if extended thinking is enabled)
- RawContentBlockDeltaEvent with a ThinkingDelta
- RawContentBlockDeltaEvent with a ThinkingDelta
- RawContentBlockDeltaEvent with a ThinkingDelta
- ...
- RawContentBlockDeltaEvent with a SignatureDelta
- RawContentBlockStopEvent
- RawContentBlockStartEvent with a RedactedThinkingBlock (occasionally)
- RawContentBlockStopEvent (RedactedThinkingBlock does not have a delta)
- RawContentBlockStartEvent with an empty TextBlock
- RawContentBlockDeltaEvent with a TextDelta
- RawContentBlockDeltaEvent with a TextDelta
@@ -151,44 +192,103 @@ async def _transform_stream(
- RawContentBlockStopEvent
- RawMessageDeltaEvent with a stop_reason='tool_use'
- RawMessageStopEvent(type='message_stop')
Each message could contain multiple blocks of the same type.
"""
if result is None:
raise TypeError("Expected a stream of messages")
current_tool_call: dict | None = None
current_message: MessageParam | None = None
current_block: (
TextBlockParam
| ToolUseBlockParam
| ThinkingBlockParam
| RedactedThinkingBlockParam
| None
) = None
current_tool_args: str
async for response in result:
LOGGER.debug("Received response: %s", response)
if isinstance(response, RawContentBlockStartEvent):
if isinstance(response, RawMessageStartEvent):
if response.message.role != "assistant":
raise ValueError("Unexpected message role")
current_message = MessageParam(role=response.message.role, content=[])
elif isinstance(response, RawContentBlockStartEvent):
if isinstance(response.content_block, ToolUseBlock):
current_tool_call = {
"id": response.content_block.id,
"name": response.content_block.name,
"input": "",
}
current_block = ToolUseBlockParam(
type="tool_use",
id=response.content_block.id,
name=response.content_block.name,
input="",
)
current_tool_args = ""
elif isinstance(response.content_block, TextBlock):
current_block = TextBlockParam(
type="text", text=response.content_block.text
)
yield {"role": "assistant"}
if response.content_block.text:
yield {"content": response.content_block.text}
elif isinstance(response.content_block, ThinkingBlock):
current_block = ThinkingBlockParam(
type="thinking",
thinking=response.content_block.thinking,
signature=response.content_block.signature,
)
elif isinstance(response.content_block, RedactedThinkingBlock):
current_block = RedactedThinkingBlockParam(
type="redacted_thinking", data=response.content_block.data
)
LOGGER.debug(
"Some of Claudes internal reasoning has been automatically "
"encrypted for safety reasons. This doesnt affect the quality of "
"responses"
)
elif isinstance(response, RawContentBlockDeltaEvent):
if current_block is None:
raise ValueError("Unexpected delta without a block")
if isinstance(response.delta, InputJSONDelta):
if current_tool_call is None:
raise ValueError("Unexpected delta without a tool call")
current_tool_call["input"] += response.delta.partial_json
current_tool_args += response.delta.partial_json
elif isinstance(response.delta, TextDelta):
LOGGER.debug("yielding delta: %s", response.delta.text)
text_block = cast(TextBlockParam, current_block)
text_block["text"] += response.delta.text
yield {"content": response.delta.text}
elif isinstance(response.delta, ThinkingDelta):
thinking_block = cast(ThinkingBlockParam, current_block)
thinking_block["thinking"] += response.delta.thinking
elif isinstance(response.delta, SignatureDelta):
thinking_block = cast(ThinkingBlockParam, current_block)
thinking_block["signature"] += response.delta.signature
elif isinstance(response, RawContentBlockStopEvent):
if current_tool_call:
if current_block is None:
raise ValueError("Unexpected stop event without a current block")
if current_block["type"] == "tool_use":
tool_block = cast(ToolUseBlockParam, current_block)
tool_args = json.loads(current_tool_args)
tool_block["input"] = tool_args
yield {
"tool_calls": [
llm.ToolInput(
id=current_tool_call["id"],
tool_name=current_tool_call["name"],
tool_args=json.loads(current_tool_call["input"]),
id=tool_block["id"],
tool_name=tool_block["name"],
tool_args=tool_args,
)
]
}
current_tool_call = None
elif current_block["type"] == "thinking":
thinking_block = cast(ThinkingBlockParam, current_block)
LOGGER.debug("Thinking: %s", thinking_block["thinking"])
if current_message is None:
raise ValueError("Unexpected stop event without a current message")
current_message["content"].append(current_block) # type: ignore[union-attr]
current_block = None
elif isinstance(response, RawMessageStopEvent):
if current_message is not None:
messages.append(current_message)
current_message = None
class AnthropicConversationEntity(
@@ -254,34 +354,50 @@ class AnthropicConversationEntity(
system = chat_log.content[0]
if not isinstance(system, conversation.SystemContent):
raise TypeError("First message must be a system message")
messages = [_convert_content(content) for content in chat_log.content[1:]]
messages = _convert_content(chat_log.content[1:])
client = self.entry.runtime_data
thinking_budget = options.get(CONF_THINKING_BUDGET, RECOMMENDED_THINKING_BUDGET)
model = options.get(CONF_CHAT_MODEL, RECOMMENDED_CHAT_MODEL)
# To prevent infinite loops, we limit the number of iterations
for _iteration in range(MAX_TOOL_ITERATIONS):
try:
stream = await client.messages.create(
model=options.get(CONF_CHAT_MODEL, RECOMMENDED_CHAT_MODEL),
messages=messages,
tools=tools or NOT_GIVEN,
max_tokens=options.get(CONF_MAX_TOKENS, RECOMMENDED_MAX_TOKENS),
system=system.content,
temperature=options.get(CONF_TEMPERATURE, RECOMMENDED_TEMPERATURE),
stream=True,
model_args = {
"model": model,
"messages": messages,
"tools": tools or NOT_GIVEN,
"max_tokens": options.get(CONF_MAX_TOKENS, RECOMMENDED_MAX_TOKENS),
"system": system.content,
"stream": True,
}
if model in THINKING_MODELS and thinking_budget >= MIN_THINKING_BUDGET:
model_args["thinking"] = ThinkingConfigEnabledParam(
type="enabled", budget_tokens=thinking_budget
)
else:
model_args["thinking"] = ThinkingConfigDisabledParam(type="disabled")
model_args["temperature"] = options.get(
CONF_TEMPERATURE, RECOMMENDED_TEMPERATURE
)
try:
stream = await client.messages.create(**model_args)
except anthropic.AnthropicError as err:
raise HomeAssistantError(
f"Sorry, I had a problem talking to Anthropic: {err}"
) from err
messages.extend(
[
_convert_content(content)
async for content in chat_log.async_add_delta_content_stream(
user_input.agent_id, _transform_stream(stream)
)
]
_convert_content(
[
content
async for content in chat_log.async_add_delta_content_stream(
user_input.agent_id, _transform_stream(stream, messages)
)
if not isinstance(content, conversation.AssistantContent)
]
)
)
if not chat_log.unresponded_tool_results:
@@ -23,12 +23,17 @@
"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"
"recommended": "Recommended model settings",
"thinking_budget_tokens": "Thinking budget"
},
"data_description": {
"prompt": "Instruct how the LLM should respond. This can be a template."
"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."
}
}
},
"error": {
"thinking_budget_too_large": "Maximum tokens must be greater than the thinking budget."
}
}
}
@@ -57,7 +57,7 @@
"name": "Status date"
},
"dip_switch_settings": {
"name": "Dip switch settings"
"name": "DIP switch settings"
},
"low_battery_signal": {
"name": "Low battery signal"
@@ -7,5 +7,5 @@
"integration_type": "device",
"iot_class": "local_push",
"loggers": ["pyaprilaire"],
"requirements": ["pyaprilaire==0.7.7"]
"requirements": ["pyaprilaire==0.8.1"]
}
@@ -60,7 +60,7 @@ class AquaCellConfigFlow(ConfigFlow, domain=DOMAIN):
errors["base"] = "cannot_connect"
except AuthenticationFailed:
errors["base"] = "invalid_auth"
except Exception: # pylint: disable=broad-except
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
+8 -1
View File
@@ -6,7 +6,11 @@ import logging
from typing import Any
from homeassistant.components import mqtt
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorStateClass,
)
from homeassistant.const import DEGREE, UnitOfPrecipitationDepth, UnitOfTemperature
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@@ -98,6 +102,7 @@ def discover_sensors(topic: str, payload: dict[str, Any]) -> list[ArwnSensor] |
DEGREE,
"mdi:compass",
device_class=SensorDeviceClass.WIND_DIRECTION,
state_class=SensorStateClass.MEASUREMENT_ANGLE,
),
]
return None
@@ -178,6 +183,7 @@ class ArwnSensor(SensorEntity):
units: str,
icon: str | None = None,
device_class: SensorDeviceClass | None = None,
state_class: SensorStateClass | None = None,
) -> None:
"""Initialize the sensor."""
self.entity_id = _slug(name)
@@ -188,6 +194,7 @@ class ArwnSensor(SensorEntity):
self._attr_native_unit_of_measurement = units
self._attr_icon = icon
self._attr_device_class = device_class
self._attr_state_class = state_class
def set_event(self, event: dict[str, Any]) -> None:
"""Update the sensor with the most recent event."""
@@ -125,7 +125,7 @@ SAVE_DELAY = 10
@callback
def _async_local_fallback_intent_filter(result: RecognizeResult) -> bool:
"""Filter out intents that are not local fallback."""
return result.intent.name in (intent.INTENT_GET_STATE, intent.INTENT_NEVERMIND)
return result.intent.name in (intent.INTENT_GET_STATE)
@callback
@@ -56,6 +56,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
{
vol.Optional("message"): str,
vol.Optional("media_id"): str,
vol.Optional("preannounce_media_id"): str,
}
),
cv.has_at_least_one_key("message", "media_id"),
@@ -70,6 +71,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
{
vol.Optional("start_message"): str,
vol.Optional("start_media_id"): str,
vol.Optional("preannounce_media_id"): str,
vol.Optional("extra_system_prompt"): str,
}
),
@@ -23,9 +23,6 @@ from homeassistant.components.assist_pipeline import (
vad,
)
from homeassistant.components.media_player import async_process_play_media_url
from homeassistant.components.tts import (
generate_media_source_id as tts_generate_media_source_id,
)
from homeassistant.core import Context, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import chat_session, entity
@@ -98,9 +95,15 @@ class AssistSatelliteAnnouncement:
original_media_id: str
"""The raw media ID before processing."""
tts_token: str | None
"""The TTS token of the media."""
media_id_source: Literal["url", "media_id", "tts"]
"""Source of the media ID."""
preannounce_media_id: str | None = None
"""Media ID to be played before announcement."""
class AssistSatelliteEntity(entity.Entity):
"""Entity encapsulating the state and functionality of an Assist satellite."""
@@ -177,6 +180,7 @@ class AssistSatelliteEntity(entity.Entity):
self,
message: str | None = None,
media_id: str | None = None,
preannounce_media_id: str | None = None,
) -> None:
"""Play and show an announcement on the satellite.
@@ -186,6 +190,8 @@ class AssistSatelliteEntity(entity.Entity):
If 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_media_id is provided, it is played before the announcement.
Calls async_announce with message and media id.
"""
await self._cancel_running_pipeline()
@@ -193,7 +199,9 @@ class AssistSatelliteEntity(entity.Entity):
if message is None:
message = ""
announcement = await self._resolve_announcement_media_id(message, media_id)
announcement = await self._resolve_announcement_media_id(
message, media_id, preannounce_media_id
)
if self._is_announcing:
raise SatelliteBusyError
@@ -220,6 +228,7 @@ class AssistSatelliteEntity(entity.Entity):
start_message: str | None = None,
start_media_id: str | None = None,
extra_system_prompt: str | None = None,
preannounce_media_id: str | None = None,
) -> None:
"""Start a conversation from the satellite.
@@ -229,6 +238,8 @@ class AssistSatelliteEntity(entity.Entity):
If start_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_media_id is provided, it is played before the announcement.
Calls async_start_conversation.
"""
await self._cancel_running_pipeline()
@@ -244,13 +255,15 @@ class AssistSatelliteEntity(entity.Entity):
start_message = ""
announcement = await self._resolve_announcement_media_id(
start_message, start_media_id
start_message, start_media_id, preannounce_media_id
)
if self._is_announcing:
raise SatelliteBusyError
self._is_announcing = True
self._set_state(AssistSatelliteState.RESPONDING)
# Provide our start info to the LLM so it understands context of incoming message
if extra_system_prompt is not None:
self._extra_system_prompt = extra_system_prompt
@@ -280,6 +293,7 @@ class AssistSatelliteEntity(entity.Entity):
raise
finally:
self._is_announcing = False
self._set_state(AssistSatelliteState.IDLE)
async def async_start_conversation(
self, start_announcement: AssistSatelliteAnnouncement
@@ -470,20 +484,27 @@ class AssistSatelliteEntity(entity.Entity):
return vad.VadSensitivity.to_seconds(vad_sensitivity)
async def _resolve_announcement_media_id(
self, message: str, media_id: str | None
self,
message: str,
media_id: str | None,
preannounce_media_id: str | None = None,
) -> AssistSatelliteAnnouncement:
"""Resolve the media ID."""
media_id_source: Literal["url", "media_id", "tts"] | None = None
tts_token: str | None = None
if media_id:
original_media_id = media_id
else:
media_id_source = "tts"
# Synthesize audio and get URL
pipeline_id = self._resolve_pipeline()
pipeline = async_get_pipeline(self.hass, pipeline_id)
engine = tts.async_resolve_engine(self.hass, pipeline.tts_engine)
if engine is None:
raise HomeAssistantError(f"TTS engine {pipeline.tts_engine} not found")
tts_options: dict[str, Any] = {}
if pipeline.tts_voice is not None:
tts_options[tts.ATTR_VOICE] = pipeline.tts_voice
@@ -491,14 +512,23 @@ class AssistSatelliteEntity(entity.Entity):
if self.tts_options is not None:
tts_options.update(self.tts_options)
media_id = tts_generate_media_source_id(
stream = tts.async_create_stream(
self.hass,
engine=engine,
language=pipeline.tts_language,
options=tts_options,
)
stream.async_set_message(message)
tts_token = stream.token
media_id = stream.url
original_media_id = tts.generate_media_source_id(
self.hass,
message,
engine=pipeline.tts_engine,
engine=engine,
language=pipeline.tts_language,
options=tts_options,
)
original_media_id = media_id
if media_source.is_media_source_id(media_id):
if not media_id_source:
@@ -516,6 +546,26 @@ class AssistSatelliteEntity(entity.Entity):
# Resolve to full URL
media_id = async_process_play_media_url(self.hass, media_id)
# Resolve preannounce media id
if preannounce_media_id:
if media_source.is_media_source_id(preannounce_media_id):
preannounce_media = await media_source.async_resolve_media(
self.hass,
preannounce_media_id,
None,
)
preannounce_media_id = preannounce_media.url
# Resolve to full URL
preannounce_media_id = async_process_play_media_url(
self.hass, preannounce_media_id
)
return AssistSatelliteAnnouncement(
message, media_id, original_media_id, media_id_source
message=message,
media_id=media_id,
original_media_id=original_media_id,
tts_token=tts_token,
media_id_source=media_id_source,
preannounce_media_id=preannounce_media_id,
)
@@ -14,6 +14,10 @@ announce:
required: false
selector:
text:
preannounce_media_id:
required: false
selector:
text:
start_conversation:
target:
entity:
@@ -34,3 +38,7 @@ start_conversation:
required: false
selector:
text:
preannounce_media_id:
required: false
selector:
text:
@@ -23,6 +23,10 @@
"media_id": {
"name": "Media ID",
"description": "The media ID to announce instead of using text-to-speech."
},
"preannounce_media_id": {
"name": "Preannounce Media ID",
"description": "The media ID to play before the announcement."
}
}
},
@@ -41,6 +45,10 @@
"extra_system_prompt": {
"name": "Extra system prompt",
"description": "Provide background information to the AI about the request."
},
"preannounce_media_id": {
"name": "Preannounce Media ID",
"description": "The media ID to play before the start message or media."
}
}
}
@@ -66,28 +66,28 @@
"name": "Upload"
},
"load_avg_1m": {
"name": "Average load (1m)"
"name": "Average load (1 min)"
},
"load_avg_5m": {
"name": "Average load (5m)"
"name": "Average load (5 min)"
},
"load_avg_15m": {
"name": "Average load (15m)"
"name": "Average load (15 min)"
},
"24ghz_temperature": {
"name": "2.4GHz Temperature"
"name": "2.4GHz temperature"
},
"5ghz_temperature": {
"name": "5GHz Temperature"
"name": "5GHz temperature"
},
"cpu_temperature": {
"name": "CPU Temperature"
"name": "CPU temperature"
},
"5ghz_2_temperature": {
"name": "5GHz Temperature (Radio 2)"
"name": "5GHz temperature (Radio 2)"
},
"6ghz_temperature": {
"name": "6GHz Temperature"
"name": "6GHz temperature"
},
"cpu_usage": {
"name": "CPU usage"
@@ -14,7 +14,7 @@
"personal_access_token": "Personal Access Token (PAT)"
},
"description": "Set up an Azure DevOps instance to access your project. A Personal Access Token is only required for a private project.",
"title": "Add Azure DevOps Project"
"title": "Add Azure DevOps project"
},
"reauth_confirm": {
"data": {
@@ -32,7 +32,7 @@
"entity": {
"sensor": {
"build_id": {
"name": "{definition_name} latest build id"
"name": "{definition_name} latest build ID"
},
"finish_time": {
"name": "{definition_name} latest build finish time"
@@ -59,7 +59,7 @@
"name": "{definition_name} latest build start time"
},
"url": {
"name": "{definition_name} latest build url"
"name": "{definition_name} latest build URL"
},
"work_item_count": {
"name": "{item_type} {item_state} work items"
@@ -68,7 +68,7 @@
},
"exceptions": {
"authentication_failed": {
"message": "Could not authorize with Azure DevOps for {title}. You will need to update your personal access token."
"message": "Could not authorize with Azure DevOps for {title}. You will need to update your Personal Access Token."
}
}
}
+32 -1
View File
@@ -1,7 +1,9 @@
"""The Backup integration."""
from homeassistant.config_entries import SOURCE_SYSTEM
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import config_validation as cv, discovery_flow
from homeassistant.helpers.backup import DATA_BACKUP
from homeassistant.helpers.hassio import is_hassio
from homeassistant.helpers.typing import ConfigType
@@ -18,10 +20,12 @@ from .agent import (
)
from .config import BackupConfig, CreateBackupParametersDict
from .const import DATA_MANAGER, DOMAIN
from .coordinator import BackupConfigEntry, BackupDataUpdateCoordinator
from .http import async_register_http_views
from .manager import (
BackupManager,
BackupManagerError,
BackupPlatformEvent,
BackupPlatformProtocol,
BackupReaderWriter,
BackupReaderWriterError,
@@ -52,6 +56,7 @@ __all__ = [
"BackupConfig",
"BackupManagerError",
"BackupNotFound",
"BackupPlatformEvent",
"BackupPlatformProtocol",
"BackupReaderWriter",
"BackupReaderWriterError",
@@ -74,6 +79,8 @@ __all__ = [
"suggested_filename_from_name_date",
]
PLATFORMS = [Platform.SENSOR]
CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN)
@@ -128,4 +135,28 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
async_register_http_views(hass)
discovery_flow.async_create_flow(
hass, DOMAIN, context={"source": SOURCE_SYSTEM}, data={}
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: BackupConfigEntry) -> bool:
"""Set up a config entry."""
backup_manager: BackupManager = hass.data[DATA_MANAGER]
coordinator = BackupDataUpdateCoordinator(hass, entry, backup_manager)
await coordinator.async_config_entry_first_refresh()
entry.async_on_unload(coordinator.async_unsubscribe)
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: BackupConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
@@ -0,0 +1,21 @@
"""Config flow for Home Assistant Backup integration."""
from __future__ import annotations
from typing import Any
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from .const import DOMAIN
class BackupConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Home Assistant Backup."""
VERSION = 1
async def async_step_system(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
return self.async_create_entry(title="Backup", data={})
+2 -2
View File
@@ -16,8 +16,8 @@ DATA_MANAGER: HassKey[BackupManager] = HassKey(DOMAIN)
LOGGER = getLogger(__package__)
EXCLUDE_FROM_BACKUP = [
"__pycache__/*",
".DS_Store",
"**/__pycache__/*",
"**/.DS_Store",
".HA_RESTORE",
"*.db-shm",
"*.log.*",
@@ -0,0 +1,81 @@
"""Coordinator for Home Assistant Backup integration."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.backup import (
async_subscribe_events,
async_subscribe_platform_events,
)
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import DOMAIN, LOGGER
from .manager import (
BackupManager,
BackupManagerState,
BackupPlatformEvent,
ManagerStateEvent,
)
type BackupConfigEntry = ConfigEntry[BackupDataUpdateCoordinator]
@dataclass
class BackupCoordinatorData:
"""Class to hold backup data."""
backup_manager_state: BackupManagerState
last_successful_automatic_backup: datetime | None
next_scheduled_automatic_backup: datetime | None
class BackupDataUpdateCoordinator(DataUpdateCoordinator[BackupCoordinatorData]):
"""Class to retrieve backup status."""
config_entry: ConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: ConfigEntry,
backup_manager: BackupManager,
) -> None:
"""Initialize coordinator."""
super().__init__(
hass,
LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=None,
)
self.unsubscribe: list[Callable[[], None]] = [
async_subscribe_events(hass, self._on_event),
async_subscribe_platform_events(hass, self._on_event),
]
self.backup_manager = backup_manager
@callback
def _on_event(self, event: ManagerStateEvent | BackupPlatformEvent) -> None:
"""Handle new event."""
LOGGER.debug("Received backup event: %s", event)
self.config_entry.async_create_task(self.hass, self.async_refresh())
async def _async_update_data(self) -> BackupCoordinatorData:
"""Update backup manager data."""
return BackupCoordinatorData(
self.backup_manager.state,
self.backup_manager.config.data.last_completed_automatic_backup,
self.backup_manager.config.data.schedule.next_automatic_backup,
)
@callback
def async_unsubscribe(self) -> None:
"""Unsubscribe from events."""
for unsub in self.unsubscribe:
unsub()
@@ -0,0 +1,27 @@
"""Diagnostics support for Home Assistant Backup integration."""
from __future__ import annotations
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_PASSWORD
from homeassistant.core import HomeAssistant
from .coordinator import BackupConfigEntry
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: BackupConfigEntry
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
coordinator = entry.runtime_data
return {
"backup_agents": [
{"name": agent.name, "agent_id": agent.agent_id}
for agent in coordinator.backup_manager.backup_agents.values()
],
"backup_config": async_redact_data(
coordinator.backup_manager.config.data.to_dict(), [CONF_PASSWORD]
),
}
+36
View File
@@ -0,0 +1,36 @@
"""Base for backup entities."""
from __future__ import annotations
from homeassistant.const import __version__ as HA_VERSION
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import BackupDataUpdateCoordinator
class BackupManagerEntity(CoordinatorEntity[BackupDataUpdateCoordinator]):
"""Base entity for backup manager."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: BackupDataUpdateCoordinator,
entity_description: EntityDescription,
) -> None:
"""Initialize base entity."""
super().__init__(coordinator)
self.entity_description = entity_description
self._attr_unique_id = entity_description.key
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, "backup_manager")},
manufacturer="Home Assistant",
model="Home Assistant Backup",
sw_version=HA_VERSION,
name="Backup",
entry_type=DeviceEntryType.SERVICE,
configuration_url="homeassistant://config/backup",
)
+18 -3
View File
@@ -229,6 +229,13 @@ class RestoreBackupEvent(ManagerStateEvent):
state: RestoreBackupState
@dataclass(frozen=True, kw_only=True, slots=True)
class BackupPlatformEvent:
"""Backup platform class."""
domain: str
@dataclass(frozen=True, kw_only=True, slots=True)
class BlockedEvent(ManagerStateEvent):
"""Backup manager blocked, Home Assistant is starting."""
@@ -351,10 +358,13 @@ class BackupManager:
# Latest backup event and backup event subscribers
self.last_event: ManagerStateEvent = BlockedEvent()
self.last_non_idle_event: ManagerStateEvent | None = None
self.last_action_event: ManagerStateEvent | None = None
self._backup_event_subscriptions = hass.data[
DATA_BACKUP
].backup_event_subscriptions
self._backup_platform_event_subscriptions = hass.data[
DATA_BACKUP
].backup_platform_event_subscriptions
async def async_setup(self) -> None:
"""Set up the backup manager."""
@@ -465,6 +475,9 @@ class BackupManager:
LOGGER.debug("%s platforms loaded in total", len(self.platforms))
LOGGER.debug("%s agents loaded in total", len(self.backup_agents))
LOGGER.debug("%s local agents loaded in total", len(self.local_backup_agents))
event = BackupPlatformEvent(domain=integration_domain)
for subscription in self._backup_platform_event_subscriptions:
subscription(event)
async def async_pre_backup_actions(self) -> None:
"""Perform pre backup actions."""
@@ -1337,7 +1350,7 @@ class BackupManager:
LOGGER.debug("Backup state: %s -> %s", current_state, new_state)
self.last_event = event
if not isinstance(event, (BlockedEvent, IdleEvent)):
self.last_non_idle_event = event
self.last_action_event = event
for subscription in self._backup_event_subscriptions:
subscription(event)
@@ -1713,7 +1726,9 @@ class CoreBackupReaderWriter(BackupReaderWriter):
"""Filter to filter excludes."""
for exclude in excludes:
if not path.match(exclude):
# The home assistant core configuration directory is added as "data"
# in the tar file, so we need to prefix that path to the filters.
if not path.full_match(f"data/{exclude}"):
continue
LOGGER.debug("Ignoring %s because of %s", path, exclude)
return True
@@ -5,8 +5,9 @@
"codeowners": ["@home-assistant/core"],
"dependencies": ["http", "websocket_api"],
"documentation": "https://www.home-assistant.io/integrations/backup",
"integration_type": "system",
"integration_type": "service",
"iot_class": "calculated",
"quality_scale": "internal",
"requirements": ["cronsim==2.6", "securetar==2025.2.1"]
"requirements": ["cronsim==2.6", "securetar==2025.2.1"],
"single_config_entry": true
}
+75
View File
@@ -0,0 +1,75 @@
"""Sensor platform for Home Assistant Backup integration."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import BackupConfigEntry, BackupCoordinatorData
from .entity import BackupManagerEntity
from .manager import BackupManagerState
@dataclass(kw_only=True, frozen=True)
class BackupSensorEntityDescription(SensorEntityDescription):
"""Description for Home Assistant Backup sensor entities."""
value_fn: Callable[[BackupCoordinatorData], str | datetime | None]
BACKUP_MANAGER_DESCRIPTIONS = (
BackupSensorEntityDescription(
key="backup_manager_state",
translation_key="backup_manager_state",
device_class=SensorDeviceClass.ENUM,
options=[state.value for state in BackupManagerState],
value_fn=lambda data: data.backup_manager_state,
),
BackupSensorEntityDescription(
key="next_scheduled_automatic_backup",
translation_key="next_scheduled_automatic_backup",
device_class=SensorDeviceClass.TIMESTAMP,
value_fn=lambda data: data.next_scheduled_automatic_backup,
),
BackupSensorEntityDescription(
key="last_successful_automatic_backup",
translation_key="last_successful_automatic_backup",
device_class=SensorDeviceClass.TIMESTAMP,
value_fn=lambda data: data.last_successful_automatic_backup,
),
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: BackupConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Sensor set up for backup config entry."""
coordinator = config_entry.runtime_data
async_add_entities(
BackupManagerSensor(coordinator, description)
for description in BACKUP_MANAGER_DESCRIPTIONS
)
class BackupManagerSensor(BackupManagerEntity, SensorEntity):
"""Sensor to track backup manager state."""
entity_description: BackupSensorEntityDescription
@property
def native_value(self) -> str | datetime | None:
"""Return native value of entity."""
return self.entity_description.value_fn(self.coordinator.data)
@@ -22,5 +22,24 @@
"name": "Create automatic backup",
"description": "Creates a new backup with automatic backup settings."
}
},
"entity": {
"sensor": {
"backup_manager_state": {
"name": "Backup Manager State",
"state": {
"idle": "Idle",
"create_backup": "Creating a backup",
"receive_backup": "Receiving a backup",
"restore_backup": "Restoring a backup"
}
},
"next_scheduled_automatic_backup": {
"name": "Next scheduled automatic backup"
},
"last_successful_automatic_backup": {
"name": "Last successful automatic backup"
}
}
}
}
+1 -1
View File
@@ -55,7 +55,7 @@ async def handle_info(
"backups": list(backups.values()),
"last_attempted_automatic_backup": manager.config.data.last_attempted_automatic_backup,
"last_completed_automatic_backup": manager.config.data.last_completed_automatic_backup,
"last_non_idle_event": manager.last_non_idle_event,
"last_action_event": manager.last_action_event,
"next_automatic_backup": manager.config.data.schedule.next_automatic_backup,
"next_automatic_backup_additional": manager.config.data.schedule.next_automatic_backup_additional,
"state": manager.state,
@@ -274,7 +274,7 @@
"message": "An error occurred while attempting to play {media_type}: {error_message}."
},
"invalid_grouping_entity": {
"message": "Entity with id: {entity_id} can't be added to the Beolink session. Is the entity a Bang & Olufsen media_player?"
"message": "Entity with ID {entity_id} can't be added to the Beolink session. Is the entity a Bang & Olufsen media_player?"
},
"invalid_sound_mode": {
"message": "{invalid_sound_mode} is an invalid sound mode. Valid values are: {valid_sound_modes}."
@@ -75,6 +75,9 @@ class BluesoundConfigFlow(ConfigFlow, domain=DOMAIN):
self, discovery_info: ZeroconfServiceInfo
) -> ConfigFlowResult:
"""Handle a flow initialized by zeroconf discovery."""
# the player can have an ipv6 address, but the api is only available on ipv4
if discovery_info.ip_address.version != 4:
return self.async_abort(reason="no_ipv4_address")
if discovery_info.port is not None:
self._port = discovery_info.port
@@ -19,7 +19,8 @@
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]"
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
"no_ipv4_address": "No IPv4 address found."
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
@@ -18,9 +18,9 @@
"bleak==0.22.3",
"bleak-retry-connector==3.9.0",
"bluetooth-adapters==0.21.4",
"bluetooth-auto-recovery==1.4.4",
"bluetooth-data-tools==1.26.0",
"dbus-fast==2.39.3",
"habluetooth==3.25.0"
"bluetooth-auto-recovery==1.4.5",
"bluetooth-data-tools==1.26.1",
"dbus-fast==2.43.0",
"habluetooth==3.37.0"
]
}
@@ -0,0 +1,62 @@
"""The Bosch Alarm integration."""
from __future__ import annotations
from ssl import SSLError
from bosch_alarm_mode2 import Panel
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from .const import CONF_INSTALLER_CODE, CONF_USER_CODE, DOMAIN
PLATFORMS: list[Platform] = [Platform.ALARM_CONTROL_PANEL]
type BoschAlarmConfigEntry = ConfigEntry[Panel]
async def async_setup_entry(hass: HomeAssistant, entry: BoschAlarmConfigEntry) -> bool:
"""Set up Bosch Alarm from a config entry."""
panel = Panel(
host=entry.data[CONF_HOST],
port=entry.data[CONF_PORT],
automation_code=entry.data.get(CONF_PASSWORD),
installer_or_user_code=entry.data.get(
CONF_INSTALLER_CODE, entry.data.get(CONF_USER_CODE)
),
)
try:
await panel.connect()
except (PermissionError, ValueError) as err:
await panel.disconnect()
raise ConfigEntryNotReady from err
except (TimeoutError, OSError, ConnectionRefusedError, SSLError) as err:
await panel.disconnect()
raise ConfigEntryNotReady("Connection failed") from err
entry.runtime_data = panel
device_registry = dr.async_get(hass)
device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
identifiers={(DOMAIN, entry.unique_id or entry.entry_id)},
name=f"Bosch {panel.model}",
manufacturer="Bosch Security Systems",
model=panel.model,
sw_version=panel.firmware_version,
)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: BoschAlarmConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
await entry.runtime_data.disconnect()
return unload_ok
@@ -0,0 +1,109 @@
"""Support for Bosch Alarm Panel."""
from __future__ import annotations
from bosch_alarm_mode2 import Panel
from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
AlarmControlPanelEntityFeature,
AlarmControlPanelState,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import BoschAlarmConfigEntry
from .const import DOMAIN
async def async_setup_entry(
hass: HomeAssistant,
config_entry: BoschAlarmConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up control panels for each area."""
panel = config_entry.runtime_data
async_add_entities(
AreaAlarmControlPanel(
panel,
area_id,
config_entry.unique_id or config_entry.entry_id,
)
for area_id in panel.areas
)
class AreaAlarmControlPanel(AlarmControlPanelEntity):
"""An alarm control panel entity for a bosch alarm panel."""
_attr_has_entity_name = True
_attr_supported_features = (
AlarmControlPanelEntityFeature.ARM_HOME
| AlarmControlPanelEntityFeature.ARM_AWAY
)
_attr_code_arm_required = False
_attr_name = None
def __init__(self, panel: Panel, area_id: int, unique_id: str) -> None:
"""Initialise a Bosch Alarm control panel entity."""
self.panel = panel
self._area = panel.areas[area_id]
self._area_id = area_id
self._attr_unique_id = f"{unique_id}_area_{area_id}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, self._attr_unique_id)},
name=self._area.name,
manufacturer="Bosch Security Systems",
via_device=(
DOMAIN,
unique_id,
),
)
@property
def alarm_state(self) -> AlarmControlPanelState | None:
"""Return the state of the alarm."""
if self._area.is_triggered():
return AlarmControlPanelState.TRIGGERED
if self._area.is_disarmed():
return AlarmControlPanelState.DISARMED
if self._area.is_arming():
return AlarmControlPanelState.ARMING
if self._area.is_pending():
return AlarmControlPanelState.PENDING
if self._area.is_part_armed():
return AlarmControlPanelState.ARMED_HOME
if self._area.is_all_armed():
return AlarmControlPanelState.ARMED_AWAY
return None
async def async_alarm_disarm(self, code: str | None = None) -> None:
"""Disarm this panel."""
await self.panel.area_disarm(self._area_id)
async def async_alarm_arm_home(self, code: str | None = None) -> None:
"""Send arm home command."""
await self.panel.area_arm_part(self._area_id)
async def async_alarm_arm_away(self, code: str | None = None) -> None:
"""Send arm away command."""
await self.panel.area_arm_all(self._area_id)
@property
def available(self) -> bool:
"""Return True if entity is available."""
return self.panel.connection_status()
async def async_added_to_hass(self) -> None:
"""Run when entity attached to hass."""
await super().async_added_to_hass()
self._area.status_observer.attach(self.schedule_update_ha_state)
self.panel.connection_status_observer.attach(self.schedule_update_ha_state)
async def async_will_remove_from_hass(self) -> None:
"""Run when entity removed from hass."""
await super().async_will_remove_from_hass()
self._area.status_observer.detach(self.schedule_update_ha_state)
self.panel.connection_status_observer.detach(self.schedule_update_ha_state)
@@ -0,0 +1,165 @@
"""Config flow for Bosch Alarm integration."""
from __future__ import annotations
import asyncio
import logging
import ssl
from typing import Any
from bosch_alarm_mode2 import Panel
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import (
CONF_CODE,
CONF_HOST,
CONF_MODEL,
CONF_PASSWORD,
CONF_PORT,
)
import homeassistant.helpers.config_validation as cv
from .const import CONF_INSTALLER_CODE, CONF_USER_CODE, DOMAIN
_LOGGER = logging.getLogger(__name__)
STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): str,
vol.Required(CONF_PORT, default=7700): cv.positive_int,
}
)
STEP_AUTH_DATA_SCHEMA_SOLUTION = vol.Schema(
{
vol.Required(CONF_USER_CODE): str,
}
)
STEP_AUTH_DATA_SCHEMA_AMAX = vol.Schema(
{
vol.Required(CONF_INSTALLER_CODE): str,
vol.Required(CONF_PASSWORD): str,
}
)
STEP_AUTH_DATA_SCHEMA_BG = vol.Schema(
{
vol.Required(CONF_PASSWORD): str,
}
)
STEP_INIT_DATA_SCHEMA = vol.Schema({vol.Optional(CONF_CODE): str})
async def try_connect(
data: dict[str, Any], load_selector: int = 0
) -> tuple[str, int | None]:
"""Validate the user input allows us to connect.
Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user.
"""
panel = Panel(
host=data[CONF_HOST],
port=data[CONF_PORT],
automation_code=data.get(CONF_PASSWORD),
installer_or_user_code=data.get(CONF_INSTALLER_CODE, data.get(CONF_USER_CODE)),
)
try:
await panel.connect(load_selector)
finally:
await panel.disconnect()
return (panel.model, panel.serial_number)
class BoschAlarmConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Bosch Alarm."""
def __init__(self) -> None:
"""Init config flow."""
self._data: dict[str, Any] = {}
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}
if user_input is not None:
try:
# Use load_selector = 0 to fetch the panel model without authentication.
(model, serial) = await try_connect(user_input, 0)
except (
OSError,
ConnectionRefusedError,
ssl.SSLError,
asyncio.exceptions.TimeoutError,
) as e:
_LOGGER.error("Connection Error: %s", e)
errors["base"] = "cannot_connect"
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
self._data = user_input
self._data[CONF_MODEL] = model
return await self.async_step_auth()
return self.async_show_form(
step_id="user",
data_schema=self.add_suggested_values_to_schema(
STEP_USER_DATA_SCHEMA, user_input
),
errors=errors,
)
async def async_step_auth(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the auth step."""
errors: dict[str, str] = {}
# Each model variant requires a different authentication flow
if "Solution" in self._data[CONF_MODEL]:
schema = STEP_AUTH_DATA_SCHEMA_SOLUTION
elif "AMAX" in self._data[CONF_MODEL]:
schema = STEP_AUTH_DATA_SCHEMA_AMAX
else:
schema = STEP_AUTH_DATA_SCHEMA_BG
if user_input is not None:
self._data.update(user_input)
try:
(model, serial_number) = await try_connect(
self._data, Panel.LOAD_EXTENDED_INFO
)
except (PermissionError, ValueError) as e:
errors["base"] = "invalid_auth"
_LOGGER.error("Authentication Error: %s", e)
except (
OSError,
ConnectionRefusedError,
ssl.SSLError,
TimeoutError,
) as e:
_LOGGER.error("Connection Error: %s", e)
errors["base"] = "cannot_connect"
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
if serial_number:
await self.async_set_unique_id(str(serial_number))
self._abort_if_unique_id_configured()
else:
self._async_abort_entries_match({CONF_HOST: self._data[CONF_HOST]})
return self.async_create_entry(title=f"Bosch {model}", data=self._data)
return self.async_show_form(
step_id="auth",
data_schema=self.add_suggested_values_to_schema(schema, user_input),
errors=errors,
)
@@ -0,0 +1,6 @@
"""Constants for the Bosch Alarm integration."""
DOMAIN = "bosch_alarm"
HISTORY_ATTR = "history"
CONF_INSTALLER_CODE = "installer_code"
CONF_USER_CODE = "user_code"
@@ -0,0 +1,11 @@
{
"domain": "bosch_alarm",
"name": "Bosch Alarm",
"codeowners": ["@mag1024", "@sanjay900"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/bosch_alarm",
"integration_type": "device",
"iot_class": "local_push",
"quality_scale": "bronze",
"requirements": ["bosch-alarm-mode2==0.4.3"]
}
@@ -0,0 +1,84 @@
rules:
# Bronze
action-setup:
status: exempt
comment: |
No custom actions defined
appropriate-polling:
status: exempt
comment: |
No polling
brands: done
common-modules: done
config-flow-test-coverage: done
config-flow: done
dependency-transparency: done
docs-actions:
status: exempt
comment: |
No custom actions are defined.
docs-high-level-description: done
docs-installation-instructions: done
docs-removal-instructions: done
entity-event-setup: done
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: |
No custom actions are defined.
config-entry-unloading: done
docs-configuration-parameters: todo
docs-installation-parameters: todo
entity-unavailable: todo
integration-owner: done
log-when-unavailable: todo
parallel-updates: todo
reauthentication-flow: todo
test-coverage: done
# Gold
devices: done
diagnostics: todo
discovery-update-info: todo
discovery: todo
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: todo
entity-disabled-by-default: todo
entity-translations: todo
exception-translations: todo
icon-translations: todo
reconfiguration-flow: todo
repair-issues:
status: exempt
comment: |
No repairs
stale-devices:
status: exempt
comment: |
Device type integration
# Platinum
async-dependency: done
inject-websession:
status: exempt
comment: |
Integration does not make any HTTP requests.
strict-typing: done
@@ -0,0 +1,36 @@
{
"config": {
"step": {
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
"port": "[%key:common::config_flow::data::port%]"
},
"data_description": {
"host": "The hostname or IP address of your Bosch alarm panel",
"port": "The port used to connect to your Bosch alarm panel. This is usually 7700"
}
},
"auth": {
"data": {
"password": "[%key:common::config_flow::data::password%]",
"installer_code": "Installer code",
"user_code": "User code"
},
"data_description": {
"password": "The Mode 2 automation code from your panel",
"installer_code": "The installer code from your panel",
"user_code": "The user code from your panel"
}
}
},
"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%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
}
}
@@ -4,10 +4,14 @@ from __future__ import annotations
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_EMAIL, CONF_NAME
from homeassistant.core import HomeAssistant
from .coordinator import BringConfigEntry
TO_REDACT = {CONF_NAME, CONF_EMAIL}
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, config_entry: BringConfigEntry
@@ -15,7 +19,10 @@ async def async_get_config_entry_diagnostics(
"""Return diagnostics for a config entry."""
return {
"data": {k: v.to_dict() for k, v in config_entry.runtime_data.data.items()},
"data": {
k: async_redact_data(v.to_dict(), TO_REDACT)
for k, v in config_entry.runtime_data.data.items()
},
"lists": [lst.to_dict() for lst in config_entry.runtime_data.lists],
"user_settings": config_entry.runtime_data.user_settings.to_dict(),
}
+1 -1
View File
@@ -8,5 +8,5 @@
"iot_class": "cloud_polling",
"loggers": ["bring_api"],
"quality_scale": "platinum",
"requirements": ["bring-api==1.0.2"]
"requirements": ["bring-api==1.1.0"]
}
+9 -1
View File
@@ -9,6 +9,7 @@ from homeassistant.const import CONF_HOST, CONF_TYPE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from .const import DOMAIN
from .coordinator import BrotherConfigEntry, BrotherDataUpdateCoordinator
PLATFORMS = [Platform.SENSOR]
@@ -25,7 +26,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: BrotherConfigEntry) -> b
host, printer_type=printer_type, snmp_engine=snmp_engine
)
except (ConnectionError, SnmpError, TimeoutError) as error:
raise ConfigEntryNotReady from error
raise ConfigEntryNotReady(
translation_domain=DOMAIN,
translation_key="cannot_connect",
translation_placeholders={
"device": entry.title,
"error": repr(error),
},
) from error
coordinator = BrotherDataUpdateCoordinator(hass, entry, brother)
await coordinator.async_config_entry_first_refresh()
@@ -26,6 +26,7 @@ class BrotherDataUpdateCoordinator(DataUpdateCoordinator[BrotherSensors]):
) -> None:
"""Initialize."""
self.brother = brother
self.device_name = config_entry.title
super().__init__(
hass,
@@ -41,5 +42,12 @@ class BrotherDataUpdateCoordinator(DataUpdateCoordinator[BrotherSensors]):
async with timeout(20):
data = await self.brother.async_update()
except (ConnectionError, SnmpError, UnsupportedModelError) as error:
raise UpdateFailed(error) from error
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="update_error",
translation_placeholders={
"device": self.device_name,
"error": repr(error),
},
) from error
return data
@@ -159,5 +159,13 @@
"name": "Last restart"
}
}
},
"exceptions": {
"cannot_connect": {
"message": "An error occurred while connecting to the {device} printer: {error}"
},
"update_error": {
"message": "An error occurred while retrieving data from the {device} printer: {error}"
}
}
}
@@ -170,6 +170,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
native_unit_of_measurement=DEGREE,
icon="mdi:compass-outline",
device_class=SensorDeviceClass.WIND_DIRECTION,
state_class=SensorStateClass.MEASUREMENT_ANGLE,
),
SensorEntityDescription(
key="pressure",
+2 -2
View File
@@ -21,8 +21,8 @@
"step": {
"init": {
"data": {
"ffmpeg_arguments": "Arguments passed to ffmpeg for cameras",
"timeout": "Request Timeout (seconds)"
"ffmpeg_arguments": "Arguments passed to FFmpeg for cameras",
"timeout": "Request timeout (seconds)"
}
}
}
+40 -57
View File
@@ -16,12 +16,21 @@ from homeassistant.config_entries import (
from homeassistant.const import CONF_UUID
from homeassistant.core import callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.selector import SelectSelector, SelectSelectorConfig
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
from .const import CONF_IGNORE_CEC, CONF_KNOWN_HOSTS, DOMAIN
IGNORE_CEC_SCHEMA = vol.Schema(vol.All(cv.ensure_list, [cv.string]))
KNOWN_HOSTS_SCHEMA = vol.Schema(vol.All(cv.ensure_list, [cv.string]))
KNOWN_HOSTS_SCHEMA = vol.Schema(
{
vol.Optional(
CONF_KNOWN_HOSTS,
): SelectSelector(
SelectSelectorConfig(custom_value=True, options=[], multiple=True),
)
}
)
WANTED_UUID_SCHEMA = vol.Schema(vol.All(cv.ensure_list, [cv.string]))
@@ -30,12 +39,6 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
VERSION = 1
def __init__(self) -> None:
"""Initialize flow."""
self._ignore_cec = set[str]()
self._known_hosts = set[str]()
self._wanted_uuid = set[str]()
@staticmethod
@callback
def async_get_options_flow(
@@ -62,48 +65,31 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm the setup."""
errors = {}
data = {CONF_KNOWN_HOSTS: self._known_hosts}
if user_input is not None:
bad_hosts = False
known_hosts = user_input[CONF_KNOWN_HOSTS]
known_hosts = [x.strip() for x in known_hosts.split(",") if x.strip()]
try:
known_hosts = KNOWN_HOSTS_SCHEMA(known_hosts)
except vol.Invalid:
errors["base"] = "invalid_known_hosts"
bad_hosts = True
else:
self._known_hosts = known_hosts
data = self._get_data()
if not bad_hosts:
return self.async_create_entry(title="Google Cast", data=data)
known_hosts = _trim_items(user_input.get(CONF_KNOWN_HOSTS, []))
return self.async_create_entry(
title="Google Cast",
data=self._get_data(known_hosts=known_hosts),
)
fields = {}
fields[vol.Optional(CONF_KNOWN_HOSTS, default="")] = str
return self.async_show_form(
step_id="config", data_schema=vol.Schema(fields), errors=errors
)
return self.async_show_form(step_id="config", data_schema=KNOWN_HOSTS_SCHEMA)
async def async_step_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm the setup."""
data = self._get_data()
if user_input is not None or not onboarding.async_is_onboarded(self.hass):
return self.async_create_entry(title="Google Cast", data=data)
return self.async_create_entry(title="Google Cast", data=self._get_data())
return self.async_show_form(step_id="confirm")
def _get_data(self):
def _get_data(
self, *, known_hosts: list[str] | None = None
) -> dict[str, list[str]]:
return {
CONF_IGNORE_CEC: list(self._ignore_cec),
CONF_KNOWN_HOSTS: list(self._known_hosts),
CONF_UUID: list(self._wanted_uuid),
CONF_IGNORE_CEC: [],
CONF_KNOWN_HOSTS: known_hosts or [],
CONF_UUID: [],
}
@@ -123,31 +109,24 @@ class CastOptionsFlowHandler(OptionsFlow):
) -> ConfigFlowResult:
"""Manage the Google Cast options."""
errors: dict[str, str] = {}
current_config = self.config_entry.data
if user_input is not None:
bad_hosts, known_hosts = _string_to_list(
user_input.get(CONF_KNOWN_HOSTS, ""), KNOWN_HOSTS_SCHEMA
known_hosts = _trim_items(user_input.get(CONF_KNOWN_HOSTS, []))
self.updated_config = dict(self.config_entry.data)
self.updated_config[CONF_KNOWN_HOSTS] = known_hosts
if self.show_advanced_options:
return await self.async_step_advanced_options()
self.hass.config_entries.async_update_entry(
self.config_entry, data=self.updated_config
)
if not bad_hosts:
self.updated_config = dict(current_config)
self.updated_config[CONF_KNOWN_HOSTS] = known_hosts
if self.show_advanced_options:
return await self.async_step_advanced_options()
self.hass.config_entries.async_update_entry(
self.config_entry, data=self.updated_config
)
return self.async_create_entry(title="", data={})
fields: dict[vol.Marker, type[str]] = {}
suggested_value = _list_to_string(current_config.get(CONF_KNOWN_HOSTS))
_add_with_suggestion(fields, CONF_KNOWN_HOSTS, suggested_value)
return self.async_create_entry(title="", data={})
return self.async_show_form(
step_id="basic_options",
data_schema=vol.Schema(fields),
data_schema=self.add_suggested_values_to_schema(
KNOWN_HOSTS_SCHEMA, self.config_entry.data
),
errors=errors,
last_step=not self.show_advanced_options,
)
@@ -206,6 +185,10 @@ def _string_to_list(string, schema):
return invalid, items
def _trim_items(items: list[str]) -> list[str]:
return [x.strip() for x in items if x.strip()]
def _add_with_suggestion(
fields: dict[vol.Marker, type[str]], key: str, suggested_value: str
) -> None:
+2 -1
View File
@@ -2,7 +2,7 @@
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict
from typing import TYPE_CHECKING, NotRequired, TypedDict
from homeassistant.util.signal_type import SignalType
@@ -46,3 +46,4 @@ class HomeAssistantControllerData(TypedDict):
hass_uuid: str
client_id: str | None
refresh_token: str
app_id: NotRequired[str]
+8 -4
View File
@@ -7,6 +7,7 @@ from dataclasses import dataclass
import logging
from typing import TYPE_CHECKING, ClassVar
from urllib.parse import urlparse
from uuid import UUID
import aiohttp
import attr
@@ -40,7 +41,7 @@ class ChromecastInfo:
is_dynamic_group = attr.ib(type=bool | None, default=None)
@property
def friendly_name(self) -> str:
def friendly_name(self) -> str | None:
"""Return the Friendly Name."""
return self.cast_info.friendly_name
@@ -50,7 +51,7 @@ class ChromecastInfo:
return self.cast_info.cast_type == CAST_TYPE_GROUP
@property
def uuid(self) -> bool:
def uuid(self) -> UUID:
"""Return the UUID."""
return self.cast_info.uuid
@@ -80,7 +81,7 @@ class ChromecastInfo:
"+label%3A%22integration%3A+cast%22"
)
_LOGGER.debug(
_LOGGER.info(
(
"Fetched cast details for unknown model '%s' manufacturer:"
" '%s', type: '%s'. Please %s"
@@ -111,7 +112,10 @@ class ChromecastInfo:
is_dynamic_group = False
http_group_status = None
http_group_status = dial.get_multizone_status(
None,
# We pass services which will be used for the HTTP request, and we
# don't care about the host in http_group_status.dynamic_groups so
# we pass an empty string to simplify the code.
"",
services=self.cast_info.services,
zconf=ChromeCastZeroconf.get_zeroconf(),
)
+1 -1
View File
@@ -14,7 +14,7 @@
"documentation": "https://www.home-assistant.io/integrations/cast",
"iot_class": "local_polling",
"loggers": ["casttube", "pychromecast"],
"requirements": ["PyChromecast==14.0.5"],
"requirements": ["PyChromecast==14.0.7"],
"single_config_entry": true,
"zeroconf": ["_googlecast._tcp.local."]
}
+1 -1
View File
@@ -7,11 +7,11 @@ show_lovelace_view:
integration: cast
domain: media_player
dashboard_path:
required: true
example: lovelace-cast
selector:
text:
view_path:
required: true
example: downstairs
selector:
text:
+8 -4
View File
@@ -6,9 +6,11 @@
},
"config": {
"title": "Google Cast configuration",
"description": "Known Hosts - A comma-separated list of hostnames or IP-addresses of cast devices, use if mDNS discovery is not working.",
"data": {
"known_hosts": "Known hosts"
"known_hosts": "Add known host"
},
"data_description": {
"known_hosts": "Hostnames or IP-addresses of cast devices, use if mDNS discovery is not working"
}
}
},
@@ -20,9 +22,11 @@
"step": {
"basic_options": {
"title": "[%key:component::cast::config::step::config::title%]",
"description": "[%key:component::cast::config::step::config::description%]",
"data": {
"known_hosts": "[%key:component::cast::config::step::config::data::known_hosts%]"
},
"data_description": {
"known_hosts": "[%key:component::cast::config::step::config::data_description::known_hosts%]"
}
},
"advanced_options": {
@@ -49,7 +53,7 @@
},
"dashboard_path": {
"name": "Dashboard path",
"description": "The URL path of the dashboard to show."
"description": "The URL path of the dashboard to show, defaults to lovelace if not specified."
},
"view_path": {
"name": "View path",
@@ -44,7 +44,7 @@ class ChaconDioConfigFlow(ConfigFlow, domain=DOMAIN):
errors["base"] = "cannot_connect"
except DIOChaconInvalidAuthError:
errors["base"] = "invalid_auth"
except Exception: # pylint: disable=broad-except
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
+15 -3
View File
@@ -245,6 +245,10 @@ class CloudLoginView(HomeAssistantView):
name = "api:cloud:login"
@require_admin
async def post(self, request: web.Request) -> web.Response:
"""Handle login request."""
return await self._post(request)
@_handle_cloud_errors
@RequestDataValidator(
vol.Schema(
@@ -259,7 +263,7 @@ class CloudLoginView(HomeAssistantView):
)
)
)
async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
async def _post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
"""Handle login request."""
hass = request.app[KEY_HASS]
cloud = hass.data[DATA_CLOUD]
@@ -316,8 +320,12 @@ class CloudLogoutView(HomeAssistantView):
name = "api:cloud:logout"
@require_admin
@_handle_cloud_errors
async def post(self, request: web.Request) -> web.Response:
"""Handle logout request."""
return await self._post(request)
@_handle_cloud_errors
async def _post(self, request: web.Request) -> web.Response:
"""Handle logout request."""
hass = request.app[KEY_HASS]
cloud = hass.data[DATA_CLOUD]
@@ -400,9 +408,13 @@ class CloudForgotPasswordView(HomeAssistantView):
name = "api:cloud:forgot_password"
@require_admin
async def post(self, request: web.Request) -> web.Response:
"""Handle forgot password request."""
return await self._post(request)
@_handle_cloud_errors
@RequestDataValidator(vol.Schema({vol.Required("email"): str}))
async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
async def _post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
"""Handle forgot password request."""
hass = request.app[KEY_HASS]
cloud = hass.data[DATA_CLOUD]
@@ -4,19 +4,19 @@
"step": {
"user": {
"title": "Connect to Cloudflare",
"description": "This integration requires an API Token created with Zone:Zone:Read and Zone:DNS:Edit permissions for all zones in your account.",
"description": "This integration requires an API token created with Zone:Zone:Read and Zone:DNS:Edit permissions for all zones in your account.",
"data": {
"api_token": "[%key:common::config_flow::data::api_token%]"
}
},
"zone": {
"title": "Choose the Zone to Update",
"title": "Choose the zone to update",
"data": {
"zone": "Zone"
}
},
"records": {
"title": "Choose the Records to Update",
"title": "Choose the records to update",
"data": {
"records": "Records"
}
@@ -40,7 +40,7 @@
"services": {
"update_records": {
"name": "Update records",
"description": "Manually trigger update to Cloudflare records."
"description": "Manually triggers an update of Cloudflare records."
}
}
}
@@ -20,6 +20,9 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .coordinator import ComelitConfigEntry, ComelitVedoSystem
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
_LOGGER = logging.getLogger(__name__)
AWAY = "away"
@@ -16,6 +16,9 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .coordinator import ComelitConfigEntry, ComelitVedoSystem
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
async def async_setup_entry(
hass: HomeAssistant,
+20 -4
View File
@@ -21,8 +21,12 @@ from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import ComelitConfigEntry, ComelitSerialBridge
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
class ClimaComelitMode(StrEnum):
"""Serial Bridge clima modes."""
@@ -115,13 +119,15 @@ class ComelitClimateEntity(CoordinatorEntity[ComelitSerialBridge], ClimateEntity
# because no serial number or mac is available
self._attr_unique_id = f"{config_entry_entry_id}-{device.index}"
self._attr_device_info = coordinator.platform_device_info(device, device.type)
self._update_attributes()
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
def _update_attributes(self) -> None:
"""Update class attributes."""
device = self.coordinator.data[CLIMATE][self._device.index]
if not isinstance(device.val, list):
raise HomeAssistantError("Invalid clima data")
raise HomeAssistantError(
translation_domain=DOMAIN, translation_key="invalid_clima_data"
)
# CLIMATE has a 2 item tuple:
# - first for Clima
@@ -152,6 +158,12 @@ class ComelitClimateEntity(CoordinatorEntity[ComelitSerialBridge], ClimateEntity
self._attr_target_temperature = values[4] / 10
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._update_attributes()
super()._handle_coordinator_update()
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
if (
@@ -165,6 +177,8 @@ class ComelitClimateEntity(CoordinatorEntity[ComelitSerialBridge], ClimateEntity
await self.coordinator.api.set_clima_status(
self._device.index, ClimaComelitCommand.SET, target_temp
)
self._attr_target_temperature = target_temp
self.async_write_ha_state()
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set hvac mode."""
@@ -176,3 +190,5 @@ class ComelitClimateEntity(CoordinatorEntity[ComelitSerialBridge], ClimateEntity
await self.coordinator.api.set_clima_status(
self._device.index, MODE_TO_ACTION[hvac_mode]
)
self._attr_hvac_mode = hvac_mode
self.async_write_ha_state()
@@ -9,3 +9,5 @@ _LOGGER = logging.getLogger(__package__)
DOMAIN = "comelit"
DEFAULT_PORT = 80
DEVICE_TYPE_LIST = [BRIDGE, VEDO]
SCAN_INTERVAL = 5
@@ -22,7 +22,7 @@ from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import _LOGGER, DOMAIN
from .const import _LOGGER, DOMAIN, SCAN_INTERVAL
type ComelitConfigEntry = ConfigEntry[ComelitBaseCoordinator]
@@ -53,7 +53,7 @@ class ComelitBaseCoordinator(DataUpdateCoordinator[T]):
logger=_LOGGER,
config_entry=entry,
name=f"{DOMAIN}-{host}-coordinator",
update_interval=timedelta(seconds=5),
update_interval=timedelta(seconds=SCAN_INTERVAL),
)
device_registry = dr.async_get(self.hass)
device_registry.async_get_or_create(
@@ -15,6 +15,9 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .coordinator import ComelitConfigEntry, ComelitSerialBridge
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
async def async_setup_entry(
hass: HomeAssistant,
+19 -4
View File
@@ -24,6 +24,9 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import ComelitConfigEntry, ComelitSerialBridge
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
class HumidifierComelitMode(StrEnum):
"""Serial Bridge humidifier modes."""
@@ -121,13 +124,15 @@ class ComelitHumidifierEntity(CoordinatorEntity[ComelitSerialBridge], Humidifier
self._active_mode = active_mode
self._active_action = active_action
self._set_command = set_command
self._update_attributes()
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
def _update_attributes(self) -> None:
"""Update class attributes."""
device = self.coordinator.data[CLIMATE][self._device.index]
if not isinstance(device.val, list):
raise HomeAssistantError("Invalid clima data")
raise HomeAssistantError(
translation_domain=DOMAIN, translation_key="invalid_clima_data"
)
# CLIMATE has a 2 item tuple:
# - first for Clima
@@ -149,6 +154,12 @@ class ComelitHumidifierEntity(CoordinatorEntity[ComelitSerialBridge], Humidifier
self._attr_mode = MODE_AUTO if _automatic else MODE_NORMAL
self._attr_target_humidity = values[4] / 10
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._update_attributes()
super()._handle_coordinator_update()
async def async_set_humidity(self, humidity: int) -> None:
"""Set new target humidity."""
if self.mode == HumidifierComelitMode.OFF:
@@ -163,12 +174,16 @@ class ComelitHumidifierEntity(CoordinatorEntity[ComelitSerialBridge], Humidifier
await self.coordinator.api.set_humidity_status(
self._device.index, HumidifierComelitCommand.SET, humidity
)
self._attr_target_humidity = humidity
self.async_write_ha_state()
async def async_set_mode(self, mode: str) -> None:
"""Set humidifier mode."""
await self.coordinator.api.set_humidity_status(
self._device.index, MODE_TO_ACTION[mode]
)
self._attr_mode = mode
self.async_write_ha_state()
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on."""
@@ -14,6 +14,9 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .coordinator import ComelitConfigEntry, ComelitSerialBridge
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
async def async_setup_entry(
hass: HomeAssistant,
@@ -7,5 +7,5 @@
"integration_type": "hub",
"iot_class": "local_polling",
"loggers": ["aiocomelit"],
"requirements": ["aiocomelit==0.11.2"]
"requirements": ["aiocomelit==0.11.3"]
}
@@ -20,6 +20,9 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .coordinator import ComelitConfigEntry, ComelitSerialBridge, ComelitVedoSystem
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
SENSOR_BRIDGE_TYPES: Final = (
SensorEntityDescription(
key="power",
+12 -3
View File
@@ -3,19 +3,25 @@
"flow_title": "{host}",
"step": {
"reauth_confirm": {
"description": "Please enter the correct PIN for {host}",
"data": {
"pin": "[%key:common::config_flow::data::pin%]"
},
"data_description": {
"pin": "The PIN of your Comelit device."
}
},
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
"port": "[%key:common::config_flow::data::port%]",
"pin": "[%key:common::config_flow::data::pin%]"
"pin": "[%key:common::config_flow::data::pin%]",
"type": "Device type"
},
"data_description": {
"host": "The hostname or IP address of your Comelit device."
"host": "The hostname or IP address of your Comelit device.",
"port": "The port of your Comelit device.",
"pin": "[%key:component::comelit::config::step::reauth_confirm::data_description::pin%]",
"type": "The type of your Comelit device."
}
}
},
@@ -58,6 +64,9 @@
"exceptions": {
"humidity_while_off": {
"message": "Cannot change humidity while off"
},
"invalid_clima_data": {
"message": "Invalid 'clima' data"
}
}
}
@@ -14,6 +14,9 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .coordinator import ComelitConfigEntry, ComelitSerialBridge
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
async def async_setup_entry(
hass: HomeAssistant,
@@ -4,7 +4,6 @@ from __future__ import annotations
from collections.abc import Callable
import logging
import re
from typing import Literal
from hassil.recognize import RecognizeResult
@@ -91,8 +90,6 @@ __all__ = [
_LOGGER = logging.getLogger(__name__)
REGEX_TYPE = type(re.compile(""))
SERVICE_PROCESS_SCHEMA = vol.Schema(
{
vol.Required(ATTR_TEXT): cv.string,
@@ -8,7 +8,7 @@ from contextlib import contextmanager
from contextvars import ContextVar
from dataclasses import asdict, dataclass, field, replace
import logging
from typing import Literal, TypedDict
from typing import Any, Literal, TypedDict
import voluptuous as vol
@@ -51,8 +51,7 @@ def async_get_chat_log(
)
if user_input is not None and (
(content := chat_log.content[-1]).role != "user"
# MyPy doesn't understand that content is a UserContent here
or content.content != user_input.text # type: ignore[union-attr]
or content.content != user_input.text
):
chat_log.async_add_user_content(UserContent(content=user_input.text))
@@ -128,7 +127,7 @@ class ConverseError(HomeAssistantError):
class SystemContent:
"""Base class for chat messages."""
role: str = field(init=False, default="system")
role: Literal["system"] = field(init=False, default="system")
content: str
@@ -136,7 +135,7 @@ class SystemContent:
class UserContent:
"""Assistant content."""
role: str = field(init=False, default="user")
role: Literal["user"] = field(init=False, default="user")
content: str
@@ -144,7 +143,7 @@ class UserContent:
class AssistantContent:
"""Assistant content."""
role: str = field(init=False, default="assistant")
role: Literal["assistant"] = field(init=False, default="assistant")
agent_id: str
content: str | None = None
tool_calls: list[llm.ToolInput] | None = None
@@ -154,7 +153,7 @@ class AssistantContent:
class ToolResultContent:
"""Tool result content."""
role: str = field(init=False, default="tool_result")
role: Literal["tool_result"] = field(init=False, default="tool_result")
agent_id: str
tool_call_id: str
tool_name: str
@@ -193,8 +192,8 @@ class ChatLog:
return (
last_msg.role == "assistant"
and last_msg.content is not None # type: ignore[union-attr]
and last_msg.content.strip().endswith( # type: ignore[union-attr]
and last_msg.content is not None
and last_msg.content.strip().endswith(
(
"?",
";", # Greek question mark
@@ -457,10 +456,16 @@ class ChatLog:
LOGGER.debug("Prompt: %s", self.content)
LOGGER.debug("Tools: %s", self.llm_api.tools if self.llm_api else None)
trace.async_conversation_trace_append(
trace.ConversationTraceEventType.AGENT_DETAIL,
self.async_trace(
{
"messages": self.content,
"tools": self.llm_api.tools if self.llm_api else None,
},
}
)
def async_trace(self, agent_details: dict[str, Any]) -> None:
"""Append agent specific details to the conversation trace."""
trace.async_conversation_trace_append(
trace.ConversationTraceEventType.AGENT_DETAIL,
agent_details,
)
@@ -3,11 +3,13 @@
from __future__ import annotations
from collections.abc import Iterable
from dataclasses import asdict
from typing import Any
from aiohttp import web
from hassil.recognize import MISSING_ENTITY, RecognizeResult
from hassil.string_matcher import UnmatchedRangeEntity, UnmatchedTextEntity
from home_assistant_intents import get_language_scores
import voluptuous as vol
from homeassistant.components import http, websocket_api
@@ -38,6 +40,7 @@ def async_setup(hass: HomeAssistant) -> None:
websocket_api.async_register_command(hass, websocket_list_agents)
websocket_api.async_register_command(hass, websocket_list_sentences)
websocket_api.async_register_command(hass, websocket_hass_agent_debug)
websocket_api.async_register_command(hass, websocket_hass_agent_language_scores)
@websocket_api.websocket_command(
@@ -336,6 +339,36 @@ def _get_unmatched_slots(
return unmatched_slots
@websocket_api.websocket_command(
{
vol.Required("type"): "conversation/agent/homeassistant/language_scores",
vol.Optional("language"): str,
vol.Optional("country"): str,
}
)
@websocket_api.async_response
async def websocket_hass_agent_language_scores(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Get support scores per language."""
language = msg.get("language", hass.config.language)
country = msg.get("country", hass.config.country)
scores = await hass.async_add_executor_job(get_language_scores)
matching_langs = language_util.matches(language, scores.keys(), country=country)
preferred_lang = matching_langs[0] if matching_langs else language
result = {
"languages": {
lang_key: asdict(lang_scores) for lang_key, lang_scores in scores.items()
},
"preferred_language": preferred_lang,
}
connection.send_result(msg["id"], result)
class ConversationProcessView(http.HomeAssistantView):
"""View to process text."""
@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/conversation",
"integration_type": "system",
"quality_scale": "internal",
"requirements": ["hassil==2.2.3", "home-assistant-intents==2025.3.5"]
"requirements": ["hassil==2.2.3", "home-assistant-intents==2025.3.24"]
}
@@ -1,37 +0,0 @@
"""Util for Conversation."""
from __future__ import annotations
import re
def create_matcher(utterance: str) -> re.Pattern[str]:
"""Create a regex that matches the utterance."""
# Split utterance into parts that are type: NORMAL, GROUP or OPTIONAL
# Pattern matches (GROUP|OPTIONAL): Change light to [the color] {name}
parts = re.split(r"({\w+}|\[[\w\s]+\] *)", utterance)
# Pattern to extract name from GROUP part. Matches {name}
group_matcher = re.compile(r"{(\w+)}")
# Pattern to extract text from OPTIONAL part. Matches [the color]
optional_matcher = re.compile(r"\[([\w ]+)\] *")
pattern = ["^"]
for part in parts:
group_match = group_matcher.match(part)
optional_match = optional_matcher.match(part)
# Normal part
if group_match is None and optional_match is None:
pattern.append(part)
continue
# Group part
if group_match is not None:
pattern.append(rf"(?P<{group_match.groups()[0]}>[\w ]+?)\s*")
# Optional part
elif optional_match is not None:
pattern.append(rf"(?:{optional_match.groups()[0]} *)?")
pattern.append("$")
return re.compile("".join(pattern), re.IGNORECASE)

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