Compare commits

..

949 Commits

Author SHA1 Message Date
Erik b23eacc7ad Add cloud preference for backup sync 2024-11-11 13:23:52 +01:00
Erik Montnemery 5293fc73d8 Sort some code in cloud preferences (#130345)
Sort some code in cloud prefs
2024-11-11 13:21:16 +01:00
Simon Lamon 870bf388e0 Add seek support to LinkPlay (#130349) 2024-11-11 12:49:56 +01:00
Simon Lamon 7a4dac1eb1 Add Spotify and Tidal to playingmode mapping (#130351) 2024-11-11 12:46:02 +01:00
Erik Montnemery 88480d154a Fix typo in BaseBackupManager.async_restore_backup (#130329) 2024-11-11 12:10:49 +01:00
Lennard Beers 5497c440d9 Prepare eq3btsmart base entity for additional platforms (#130340) 2024-11-11 11:46:11 +01:00
Lennard Beers 1e26cf13d6 Use runtime data for eq3btsmart (#130334) 2024-11-11 10:59:50 +01:00
Nerdix 0dd208a4b9 Add alarm count sensor for Kostal Inverters (#130324) 2024-11-11 09:07:47 +01:00
dependabot[bot] c3492bc0ed Bump github/codeql-action from 3.27.0 to 3.27.1 (#130323) 2024-11-11 08:14:42 +01:00
G Johansson 85bf8d1374 Fix Homekit error handling alarm state unknown or unavailable (#130311) 2024-11-10 22:40:23 +00:00
Jan Bouwhuis e040eb0ff2 Remove extra state attributes from some QNAP sensors (#130310) 2024-11-10 22:26:00 +01:00
Max Shcherbina d7f41ff8a9 Update generic thermostat strings for clarity and accuracy (#130243) 2024-11-10 22:13:38 +01:00
Jan Bouwhuis de5437f61e Remove YAML warning for thethingsnetwork after warning for 6 months (#130307) 2024-11-10 22:12:31 +01:00
Jan Bouwhuis c52a893e21 Remove YAML import from lcl integration after 6 months deprecation (#130305) 2024-11-10 21:10:18 +01:00
Joost Lekkerkerker f7f1830b7e Add support for binary sensor states in Google Assistant (#127652) 2024-11-10 20:34:24 +01:00
Simon Lamon 784ad20fb6 Add diagnostics to LinkPlay (#126768) 2024-11-10 20:31:40 +01:00
Richard Cox 0468e7e7a3 Update Sonarr config flow to standardize ports (#127625)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-11-10 20:23:23 +01:00
dotvav 88c227681d Bump pypalazzetti to 0.1.11 (#130293) 2024-11-10 20:13:31 +01:00
Lennard Beers 3a37ff13a6 Bump eq3btsmart to 1.2.1 (#130297) 2024-11-10 20:12:46 +01:00
Simone Chemelli 73929e6791 Avoid Shelly data update during shutdown (#130301) 2024-11-10 20:11:42 +01:00
Manu 980b0fa5e6 Deprecate api_call action in Habitica integration (#128119) 2024-11-10 19:37:41 +01:00
Tsvi Mostovicz fbc4a87166 Remove Jewish Calendar config flow upgrade (#129612) 2024-11-10 19:35:01 +01:00
Allen Porter 7f9ec2a79e Ignore WebRTC candidates for nest cameras (#130294) 2024-11-10 19:27:40 +01:00
Jan Bouwhuis d8b55d39e4 Remove tibber legacy notify service after 6 months of deprecation (#130292) 2024-11-10 19:27:11 +01:00
Jan Bouwhuis ee41725b53 Remove jewish_calendar yaml support after 6 months of deprecation (#130291) 2024-11-10 16:51:08 +01:00
J. Diego Rodríguez Royo ae1203336d Add links to deprecation issue message for Home Connect Binary door (#129779) 2024-11-10 16:37:53 +01:00
Michael f10063c9be Fix translation key for done response in conversation (#130247) 2024-11-10 16:28:58 +01:00
Åke Strandberg 1da4579a09 Add more f-series models to myuplink (#130283) 2024-11-10 15:46:50 +01:00
Jan Bouwhuis 7fd9339ad8 Remove unused file CONFIG_SCHEMA (#130287) 2024-11-10 15:34:08 +01:00
Jan Bouwhuis de391fa98b Remove geniushub yaml support after 6 months of deprecation (#130285)
* Remove geniushub YAML import after 6 moths of deprecation

* Update homeassistant/components/geniushub/__init__.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-11-10 14:58:44 +01:00
J. Nick Koston 70211ab78e Bump aiohttp to 3.11.0rc0 (#130284) 2024-11-10 13:45:46 +00:00
Nicholas Romyn a1a08f7755 Ecobee aux cutover threshold (#129474)
* removing extra blank space

* Adding EcobeeAuxCutoverThreshold

First pass.

* minor reorg and changes; testing local check-in

* Adding entity, setting device class and name

* Bumping max value slightly to hopefully accomodate celsius, setting numberMode=box

* fixing the entity name for aux cutover threshold

* Combined async_add_entities

* Using a list comprehension

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

* fixing stuff with listcomprehension

* exchanging call to list.append() to extend with list comprehension

* Updating the class name and the entity name to match the device UI.
Removing abbreviations from entity names

* Fixing tests to match new entity names

* respecting 88 column limit

* Formatting

* Adding test coverage for update/set compressorMinTemp values

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-11-10 14:13:01 +01:00
G Johansson 433321136d Remove incorrect mark fixture in nordpool (#130278) 2024-11-10 12:28:18 +01:00
Manu 0677bba5bd Add actions for scoring habits and rewards in Habitica (#129605) 2024-11-10 12:26:07 +01:00
G Johansson d0ad834d93 Move manual trigger entity tests (#130134) 2024-11-10 12:14:13 +01:00
Simon Lamon 7d2d6a82b0 Allow dynamic max preset in linkplay play preset (#130160) 2024-11-10 12:02:55 +01:00
Allen Porter e8dc62411a Improve nest camera stream expiration to be defensive against errors (#130265) 2024-11-10 12:01:59 +01:00
G Johansson 7925007ab4 Bump psutil to 6.1.0 (#130254) 2024-11-10 12:00:45 +01:00
dotvav 7515deddab Palazzetti DHCP Discovery (#129731)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-11-10 11:48:52 +01:00
Marc Mueller e382f924e6 Add support for Python 3.13 (#129442) 2024-11-10 11:38:56 +01:00
Max Shcherbina 7fdcb98518 Update description for generic hygrostat description (#130244) 2024-11-10 11:25:32 +01:00
Noah Husby d0dbca41f7 Support additional media player states for Russound RIO (#130261) 2024-11-10 11:20:55 +01:00
G Johansson f3229c723c Bump pynordpool to 0.2.2 (#130257) 2024-11-10 11:19:10 +01:00
J. Nick Koston cafa598fd6 Bump aiohttp to 3.11.0b5 (#130264) 2024-11-10 11:18:12 +01:00
Allen Porter 73a62a09b0 Update nest tests to unload config entries to perform clean teardown (#130266) 2024-11-10 09:54:52 +01:00
Lothar Bach ecd8dde347 Fix path to tesla fleet key file in config folder (#130124)
* Tesla Fleet load key file from config folder

* Fix test

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-11-09 23:21:29 +01:00
Marc Mueller 31a2bb1b98 Fix flaky modbus tests (#130252) 2024-11-09 22:58:16 +01:00
Max Shcherbina 0fc019305e Fix typo in reminder date language string in Todoist integration (#130241) 2024-11-09 21:38:29 +01:00
Marc Mueller adb1c59859 Update grpcio to 1.67.1 (#130240) 2024-11-09 21:37:56 +01:00
Manu 5d0277a0d1 Add actions for quest handling to Habitica (#129650) 2024-11-09 19:34:25 +01:00
Allen Porter 21d81d5a5c Bump google-nest-sdm to 6.1.5 (#130229) 2024-11-09 19:02:15 +01:00
DeerMaximum 0de4bfcc2c Add missing translation string for NINA (#129826) 2024-11-09 18:33:28 +01:00
jjlawren 2cc5486794 Bump SoCo to 0.30.6 (#130223) 2024-11-09 17:14:40 +01:00
Noah Husby e3315383ab Improve entity test coverage for Russound RIO (#129828) 2024-11-09 17:13:57 +01:00
Markus Jacobsen 31b505828b Simplify Bang & Olufsen source determination (#130072) 2024-11-09 17:13:07 +01:00
Daniel Oltmanns b61580a937 Add fan preset mode icons and strings to vesync (#129584) 2024-11-09 16:48:00 +01:00
Markus Jacobsen 928e5348e4 Add custom integration action sections support to hassfest (#130148) 2024-11-09 16:47:02 +01:00
Josef Zweck 622682eb43 Change update after button press for lamarzocco (#129616) 2024-11-09 16:42:10 +01:00
Simon Lamon 97fa568876 No longer thrown an error when device is offline in linkplay (#130161) 2024-11-09 16:11:34 +01:00
Manu c10f078f2a Add sensors for attribute points (str, int, per, con) to Habitica (#130186) 2024-11-09 16:04:10 +01:00
Simone Chemelli e6d16f06fc Fix uptime sensor for Vodafone Station (#130215) 2024-11-09 15:55:39 +01:00
Daniel Hjelseth Høyer c89ab7a142 Bump pyTibber (#130216) 2024-11-09 15:54:58 +01:00
Jan Bouwhuis 6837ea947c Cleanup yaml import and legacy file notify service (#130219) 2024-11-09 15:54:18 +01:00
Marco 5f0f29704b Add smarty reset filters timer button (#129637) 2024-11-09 13:32:00 +01:00
Manu 1f43dc6676 Fix cast skill test in Habitica (#130213) 2024-11-09 13:12:04 +01:00
Marc Mueller 4d7405de2c Install zlib-dev for pillow wheel build (#130211) 2024-11-09 13:03:26 +01:00
Max Shcherbina 4adffdd1a6 Fix wording in Google Calendar create_event strings for consistency (#130183) 2024-11-09 13:01:59 +01:00
Manu 4e2f5bdb7d Add tests for cast skill action in Habitica (#129596) 2024-11-09 12:45:50 +01:00
starkillerOG 03bc711c51 Add Reolink chime vehicle tone (#129835) 2024-11-09 12:25:06 +01:00
Marc Mueller 8b8e949bdf Update wheel builder to 2024.11.0 (#130209) 2024-11-09 12:07:20 +01:00
Erik Montnemery 69ba0d3a50 Report update_percentage in ezviz update entity (#129377) 2024-11-09 11:35:18 +01:00
epenet 25fb70f281 Add blood glucose concentration device class (#129340) 2024-11-09 11:29:24 +01:00
Tom Gamull 0304588bb8 Fix missing unit of measurement for blink wifi strength (#128409) 2024-11-09 11:19:36 +01:00
Josef Zweck 08f5081197 Rename lamarzocco library (#130204) 2024-11-09 11:03:48 +01:00
jb101010-2 701f35488c Add water price sensor to suez water (#130141)
* Suez water: add water price sensor

* sensor description

* clean up
2024-11-09 10:57:22 +01:00
G Johansson d11012b2b7 Move check thresholds valid to platform schema in threshold (#129540) 2024-11-09 10:50:11 +01:00
Josef Zweck 8384100e1b Rename tedee library (#130203) 2024-11-09 10:46:38 +01:00
Tristan Bastian cd0349ee4d Bump tplink-omada-client to 1.4.3 (#130184) 2024-11-09 10:41:08 +01:00
Marc Mueller b413e481cb Update numpy to 2.1.3 (#130191) 2024-11-09 10:12:52 +01:00
Diogo Gomes 9f7e6048f8 Code quality improvements on utility_meter (#129918)
* clean

* update snapshot

* move name, native_value and native_unit_of_measurement to _attr's

* Apply suggestions from code review

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-09 00:17:43 +01:00
IceBotYT 2802b77f21 Bump nice-go to 0.3.10 (#130173)
Bump Nice G.O. to 0.3.10
2024-11-09 00:12:14 +01:00
J. Nick Koston 964ad43a27 Bump orjson to 3.10.11 (#130182) 2024-11-09 00:07:05 +01:00
TheJulianJES 182be6e0ea Fix failing UniFi Protect tests on some systems (#129516) 2024-11-08 23:10:29 +01:00
Jakob Schlyter cd11f01ace Add support for MW/GW/TW and GWh/TWh (#130089) 2024-11-08 22:12:16 +01:00
G Johansson 742eca5927 Use TemplateStateFromEntityId in Template trigger entity (#130136) 2024-11-08 22:09:43 +01:00
murfy76 48e7fed901 Add voc and formaldehyde to Tuya CO2 Detector (#130119) 2024-11-08 22:03:01 +01:00
Marc Mueller 0a4c0fe7cc Add option to specify additional markers for wheel build requirements (#129949) 2024-11-08 21:09:53 +01:00
Jan Bouwhuis 9037cb8a7d Fix typo in go2rtc (#130165)
Fix typo in original
2024-11-08 20:38:38 +01:00
Jan Bouwhuis c97cc34879 Use f-strings in go2rtc code and test and do not use abbreviation (#130158) 2024-11-08 20:16:46 +01:00
Sheldon Ip 1ac9217630 Fix translations in ollama (#130164) 2024-11-08 20:15:17 +01:00
Simon Lamon e4036a2f14 Bump python-linkplay to v0.0.18 (#130159) 2024-11-08 20:14:33 +01:00
G Johansson da9c73a767 Add reconfigure flow to Nord Pool (#130151) 2024-11-08 19:53:52 +01:00
Diogo Gomes e4aaaf10c3 Fix utility_meter on DST changes (#129862)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-08 18:44:15 +01:00
Louis Christ a7be76ba0a Fix volume_up not working in some cases in bluesound integration (#130146) 2024-11-08 18:40:43 +01:00
Allen Porter f7cc91903c Fix bugs in nest stream expiration handling (#130150) 2024-11-08 18:37:00 +01:00
Jan Bouwhuis 4a8a674bd3 Refrase imap fetch service description string (#130152) 2024-11-08 18:36:19 +01:00
Robert Resch a8db25fbd8 Split test doesn't need to be executed per Python version (#130147) 2024-11-08 18:05:05 +01:00
Klaas Schoute 2dc81ed866 Force int value on port in P1Monitor (#130084) 2024-11-08 16:15:57 +01:00
Shai Ungar c4762f3ff4 Fix issue when timestamp is None (#130133)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-08 16:15:28 +01:00
Martin Hjelmare 14285973b8 Bump ha-ffmpeg to 3.2.2 (#130142) 2024-11-08 16:00:24 +01:00
epenet 353ccf3ea7 Only apply OptionsFlowWithConfigEntry deprecation to core (#130054)
* Only apply OptionsFlowWithConfigEntry deprecation to core

* Fix match string in pytest.raises

* Improve coverage
2024-11-08 15:55:19 +01:00
Lektri.co 6b90d8ff1a Add binary sensor platform to the Lektrico integration (#129872) 2024-11-08 15:54:46 +01:00
Robert Resch 51e691f832 Add go2rtc workaround for HA managed one until upstream fixes it (#130139) 2024-11-08 15:54:14 +01:00
Joost Lekkerkerker 6c7ac7a6ef Bump spotifyaio to 0.8.7 (#130140) 2024-11-08 15:53:26 +01:00
Bram Kragten 52ed1bf44a Update frontend to 20241106.2 (#130128) 2024-11-08 15:13:05 +01:00
Petar Petrov 3eab0b704e Get/Set custom config parameter for zwave_js node (#129332)
* Get/Set custom config parameter for zwave_js node

* add tests

* handle errors on set

* test FailedCommand
2024-11-08 15:12:18 +01:00
G Johansson 1f32e02ba2 Add Nord Pool integration (#129983) 2024-11-08 15:10:51 +01:00
epenet 074418f8f7 Drop OptionsFlowWithConfigEntry usage in homeassistant_hardware (#130078)
* Drop OptionsFlowWithConfigEntry usage in homeassistant_hardware

* Add homeassistant_hardware as other components rely on it

* Maybe core_files not needed after all
2024-11-08 14:53:46 +01:00
Martin Hjelmare b711b17193 Remove Z-Wave incorrect lock service descriptions (#130034) 2024-11-08 14:50:41 +01:00
Steven B. 03c3d09583 Enable overriding connection port for tplink devices (#129619)
Enable setting a port override during manual config entry setup.

The feature will be undocumented as it's quite a specialized use case generally used for testing purposes.
2024-11-08 14:41:00 +01:00
Robert Resch f49547d598 Bump uv to 0.5.0 (#130127) 2024-11-08 14:19:46 +01:00
jb101010-2 7678be8e2b Suez water: simplify config flow (#130083)
Simplify config flow for suez water. Counter_id can now be automatically be fetched by the integration.
The value is provided only in the source code of suez website and therefore not easily accessible to user not familiar with devlopment.
Still possible to explicitly set the value for user with multiple value or value defined elsewhere.
2024-11-08 14:01:36 +01:00
epenet 7672215095 Trigger full CI run on homeassistant_hardware integration changes (#130129)
Add components/homeassistant_hardware to core files
2024-11-08 13:46:40 +01:00
epenet 18cf96b92b Bring emoncms coverage to 100% (#130092)
Remove mock_setup_entry from emoncms OptionsFlow test
2024-11-08 13:42:19 +01:00
epenet 94d597fd41 Add checks for flow title/description placeholders (#129140)
* Add checks for title placeholders

* Check both title and description

* Improve comment
2024-11-08 13:33:19 +01:00
Alexandre CUER 24b47b50ea Migrate from entry unique id to emoncms unique id (#129133)
* Migrate from entry unique id to emoncms unique id

* Use a placeholder for the documentation URL

* Use async_set_unique_id in config_flow

* use _abort_if_unique_id_configured in config_flow

* Avoid single-use variable

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Add async_migrate_entry

* Remove commented code

* Downgrade version if user add server without uuid

* Improve code quality

* Move code migrating HA to emoncms uuid to init

* Fit doc url in less than 88 chars

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Improve code quality

* Only update unique_id with async_update_entry

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Make emoncms_client compulsory to get_feed_list

* Improve readability with unique id functions

* Rmv test to give more sense to _migrate_unique_id

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-08 13:29:10 +01:00
Markus Jacobsen e3dfa84d65 Bang & Olufsen add beolink grouping (#113438)
* Add Beolink custom services
Add support for media player grouping via beolink
Give media player entity name

* Fix progress not being set to None as Beolink listener
Revert naming changes

* Update API
simplify Beolink attributes

* Improve beolink custom services

* Fix Beolink expandable source check
Add unexpand return value
Set entity name on initialization

* Handle entity naming as intended

* Fix "null" Beolink self friendly name

* Add regex service input validation
Add all_discovered to beolink_expand service
Improve beolink_expand response

* Add service icons

* Fix merge
Remove unnecessary assignment

* Remove invalid typing
Update response typing for updated API

* Revert to old typed response dict method
Remove mypy ignore line
Fix jid possibly used before assignment

* Re add debugging logging

* Fix coroutine
Fix formatting

* Remove unnecessary update control

* Make tests pass
Fix remote leader media position bug
Improve remote leader BangOlufsenSource comparison

* Fix naming and add callback decorators

* Move regex service check to variable
Suppress KeyError
Update tests

* Re-add hass running check

* Improve comments, naming and type hinting

* Remove old temporary fix

* Convert logged warning to raised exception for invalid media_player
Simplify code using walrus operator

* Fix test for invalid media_player grouping

* Improve method naming

* Improve _beolink_sources explanation

* Improve _beolink_sources explanation

* Fix tests

* Remove service responses
Fix and add tests

* Change service to action where applicable

* Show playback progress for listeners

* Fix testing

* Remove useless initialization

* Fix allstandby name

* Fix various casts with assertions
Fix comment placement
Fix group leader group_members rebase error
Replace entity_id method call with attribute

* Add syrupy snapshots for Beolink tests, checking entity states
Use test JIDs 3 and 4 instead of 2 and 3 to avoid invalid attributes in testing

* Add sections for fields using Beolink JIDs directly

* Fix typo

* FIx rebase mistake

* Sort actions alphabetically
2024-11-08 12:06:29 +01:00
nasWebio ed1366f463 Add NASweb integration (#98118)
* Add NASweb integration

* Fix DeviceInfo import

* Remove commented out code

* Change class name for uniquness

* Drop CoordinatorEntity inheritance

* Rename class Output to more descriptive: RelaySwitch

* Update required webio-api version

* Implement on-the-fly addition/removal of entities

* Set coordinator name matching device name

* Set entities with too old status as unavailable

* Drop Optional in favor of modern typing

* Fix spelling of a variable

* Rename commons to more fitting name: helper

* Remove redundant code

* Let unload fail when there is no coordinator

* Fix bad docstring

* Rename cord to coordinator for clarity

* Remove default value for pop and let it raise exception

* Drop workaround and use get_url from helper.network

* Use webhook to send data from device

* Deinitialize coordinator when no longer needed

* Use Python formattable string

* Use dataclass to store integration data in hass.data

* Raise ConfigEntryNotReady when appropriate

* Refactor NASwebData class

* Move RelaySwitch to switch.py

* Fix ConfigFlow tests

* Create issues when entry fails to load

* Respond when correctly received status update

* Depend on webhook instead of http

* Create issue when status is not received during entry set up

* Make issue_id unique across integration entries

* Remove unnecessary initializations

* Inherit CoordinatorEntity to avoid code duplication

* Optimize property access via assignment in __init__

* Use preexisting mechanism to fill schema with user input

* Fix translation strings

* Handle unavailable or unreachable internal url

* Implement custom coordinator for push driven data updates

* Move module-specific constants to respective modules

* Fix requirements_all.txt

* Fix CODEOWNERS file

* Raise ConfigEntryError instead of issue creation

* Fix entity registry import

* Use HassKey as key in hass.data

* Use typed ConfigEntry

* Store runtime data in config entry

* Rewrite to be more Pythonic

* Move add/remove of switch entities to switch.py

* Skip unnecessary check

* Remove unnecessary type hints

* Remove unnecessary nonlocal

* Use a more descriptive docstring

* Add docstrings to NASwebCoordinator

* Fix formatting

* Use correct return type

* Fix tests to align with changed code

* Remove commented code

* Use serial number as config entry id

* Catch AbortFlow exception

* Update tests to check ConfigEntry Unique ID

* Remove unnecessary form abort
2024-11-08 12:03:32 +01:00
Josef Zweck 5d5908a03f Add missing string to tedee plus test (#130081) 2024-11-08 08:47:28 +01:00
Kelvin Dekker 3062bad19e Fix typo in insteon strings (#130085) 2024-11-08 08:47:02 +01:00
Bram Kragten 28832cbd3e Update frontend to 20241106.1 (#130086) 2024-11-08 08:46:48 +01:00
Luke Lashley ce94073321 Bump python-roborock to 2.7.2 (#130100) 2024-11-08 08:39:41 +01:00
J. Nick Koston fa61e02207 Bump aiohttp to 3.11.0b4 (#130097) 2024-11-08 08:36:30 +01:00
Robert Resch d1dab83f10 Merge both stun server into one as it's the same server only on a different port (#130019)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-08 08:22:47 +01:00
Erik Montnemery 2b7d593ebe Avoid collision when replacing existing config entry with same unique id (#130062) 2024-11-08 07:45:16 +01:00
Allen Porter e407b4730d Fix KeyError in nest integration when the old key format does not exist (#130057)
* Fix bug in nest setup when the old key format does not exist

* Further simplify the entry.data check

* Update homeassistant/components/nest/api.py

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

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-11-07 20:03:07 -08:00
YogevBokobza 0d19e85a0d Align Switcher cover platform with changes from light platform (#130094)
Switcher small fix for cover
2024-11-08 02:59:30 +02:00
YogevBokobza dac6271e01 Add Switcher Lights support (#129494)
* switcher lights integration

* fix based on requested changes

* Update light.py

* switcher fix based on requested changes

* fix linting

* fix linting

* Update light.py

* Update light.py

* Update homeassistant/components/switcher_kis/light.py

* Update light.py

---------

Co-authored-by: Shay Levy <levyshay1@gmail.com>
2024-11-07 22:06:34 +02:00
Marc Mueller 8cae8edc55 Remove temporary pint constraint (#130070) 2024-11-07 19:10:24 +01:00
epenet a3b0909e3f Add new frame helper to better distinguish custom and core integrations (#130025)
* Add new frame helper to clarify options available

* Adjust

* Improve

* Use report_usage in core

* Add tests

* Use is/is not

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

* Use enum.auto()

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
2024-11-07 18:23:35 +01:00
Markus ee30520b57 Fix esphome mqtt discovery by handling case where payload is a empty string (#129969)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-11-07 11:16:01 -06:00
Erik Montnemery 536e686892 Don't create repairs asking user to remove duplicate flipr config entries (#130058)
* Don't create repairs asking user to remove duplicate flipr config entries

* Improve comments
2024-11-07 17:38:10 +01:00
epenet ef767c2b9f Improve tests for frame helper (#130046)
* Improve tests for frame helper

* Improve comments

* Add ids

* Apply suggestions from code review
2024-11-07 17:35:58 +01:00
Frank Wickström c1ecc13cb3 Bump huum to 0.7.11 (#130047)
* Update huum dependency 0.7.10 -> 0.7.11

This change includes an explicit MIT license for the package.

* Remove huum from license exceptions list
2024-11-07 17:18:36 +01:00
Erik Montnemery c5e3ba536c Don't create repairs asking user to remove duplicate ignored config entries (#130056) 2024-11-07 17:07:23 +01:00
jb101010-2 0e324c074a Bump PySuez to 1.3.1 (#129825) 2024-11-07 14:25:38 +01:00
epenet a3ba7803db Add checks for translation placeholders (#129963)
* Add checks for translation placeholders

* Remove async

* Apply suggestions from code review

* Apply suggestions from code review

* Apply suggestions from code review
2024-11-07 13:12:00 +01:00
Marc Mueller 49bf5db5ff Update pytest warnings filter (#130027) 2024-11-07 12:55:54 +01:00
Franck Nijhof 50981c26ad Merge branch 'master' into dev 2024-11-07 10:58:42 +01:00
Allen Porter 2adbf7c933 Bump google-nest-sdm to 6.1.4 (#130005)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-07 10:50:40 +01:00
Brett Adams 838ef0bb9f Fix Trunks in Teslemetry and Tesla Fleet (#129986) 2024-11-07 10:36:43 +01:00
sean t 43c2658962 Bump agent-py to 0.0.24 (#130018)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-07 10:34:54 +01:00
epenet bbefa971d8 Add missing placeholder description to twitch (#130013) 2024-11-07 10:32:23 +01:00
Petar Petrov cb97f2f13c Bump zwave-js-server-python to 0.59.0 (#129482) 2024-11-07 10:06:28 +01:00
epenet a657b9bb84 Add temporary package constraint on flexparser and pint to fix CI (#130016)
Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
2024-11-07 09:57:14 +01:00
Erik Montnemery 2d2f55a4df Report update_percentage in shelly update entity (#129382)
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2024-11-07 08:52:20 +01:00
Michael Hansen df16e6d022 Bump intents to 2024.11.6 (#129982) 2024-11-07 08:29:44 +01:00
Marc Mueller 56212c6fa5 Update numpy to 2.1.2 and pandas to 2.2.3 (#129958) 2024-11-07 08:24:47 +01:00
Keilin Bickar bc964ce7f0 Update sense energy library to 0.13.3 (#129998) 2024-11-07 08:14:54 +01:00
Mike Degatano ed4f55406c Replace Supervisor resolution API calls with aiohasupervisor (#129599)
* Replace Supervisor resolution API calls with aiohasupervisor

* Use consistent types to avoid uuid issues

* Fix mocking in http test

* Changes from feedback

* Put hass first

* Fix typo

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-11-07 01:33:51 +01:00
epenet 03d5b18974 Remove options property from OptionFlow (#129890)
* Remove options property from OptionFlow

* Update test_config_entries.py

* Partial revert of "Remove deprecated property setters in option flows (#129773)"

* Partial revert "Use new helper properties in crownstone options flow (#129774)"

* Restore onewire init

* Restore onvif

* Restore roborock

* Use deepcopy in onewire

* Restore steam_online

* Restore initial options property in OptionsFlowWithConfigEntry

* re-add options property in SchemaOptionsFlowHandler

* Restore test

* Cleanup
2024-11-06 23:28:01 +01:00
J. Nick Koston 53c486ccd1 Bump aiohttp to 3.11.0b3 (#129363) 2024-11-06 15:59:31 -06:00
Steven B. 9a2a177b28 Bump ring library ring-doorbell to 0.9.9 (#129966) 2024-11-06 15:46:08 -06:00
Franck Nijhof 18e12740d9 2024.11.0 (#129970) 2024-11-06 20:10:51 +01:00
Franck Nijhof 5a24b670a2 Ran ruff 2024-11-06 19:32:23 +01:00
Franck Nijhof 94c5c8f42e Bump version to 2024.11.0 2024-11-06 19:29:07 +01:00
Manu e84d5fba11 Add state invitation to list access sensor in Bring integration (#129960) 2024-11-06 19:28:54 +01:00
Manu b808c0c5eb Add state invitation to list access sensor in Bring integration (#129960) 2024-11-06 19:15:25 +01:00
Franck Nijhof 782417528c Bump version to 2024.11.0b9 2024-11-06 18:25:29 +01:00
Robert Resch 7757423d18 Bump go2rtc-client to 0.1.0 (#129965) 2024-11-06 18:24:12 +01:00
Joost Lekkerkerker e5a28f4f25 Remove deprecation issues for LCN once entities removed (#129955) 2024-11-06 18:21:32 +01:00
Erik Montnemery c18d50910f Call async_refresh_providers when camera entity feature changes (#129941) 2024-11-06 18:21:28 +01:00
Robert Resch d4adb1f298 Bump go2rtc-client to 0.1.0 (#129965) 2024-11-06 17:59:04 +01:00
Erik Montnemery fe0a822721 Call async_refresh_providers when camera entity feature changes (#129941) 2024-11-06 17:37:23 +01:00
Joost Lekkerkerker 9f427893b1 Remove deprecation issues for LCN once entities removed (#129955) 2024-11-06 17:00:20 +01:00
Franck Nijhof 3b840c684b Bump version to 2024.11.0b8 2024-11-06 15:44:10 +01:00
Bram Kragten bc84fdc64a Update frontend to 20241106.0 (#129953) 2024-11-06 15:43:33 +01:00
Robert Resch 401262c23d Bump go2rtc-client to 0.0.1b5 (#129952) 2024-11-06 15:42:22 +01:00
Manu 795384ca2d Improve error messages in Habitica (#129948)
Improve error messages
2024-11-06 15:41:44 +01:00
J. Diego Rodríguez Royo dfc3423c83 Delete binary door deprecation issue on unload at Home Connect (#129947) 2024-11-06 15:41:39 +01:00
Robert Resch 22b5071c26 Bump go2rtc-client to 0.0.1b4 (#129942) 2024-11-06 15:40:30 +01:00
Joost Lekkerkerker 4b9524c5c1 Write squeezebox player state after query (#129939) 2024-11-06 15:39:07 +01:00
Joost Lekkerkerker 9cd46c7f03 Bump spotifyaio to 0.8.5 (#129938) 2024-11-06 15:39:03 +01:00
Robert Resch 232a6868ff Fix native sync WebRTC offer (#129931) 2024-11-06 15:39:00 +01:00
Kunal Aggarwal 361e0d4fc7 Adding "peaceful" status as on value to Tuya Presence Sensor (#129925) 2024-11-06 15:38:57 +01:00
Paulus Schoutsen 26d8d5343a Ensure all template names are strings (#129921) 2024-11-06 15:38:53 +01:00
starkillerOG 995aab8347 Bump reolink_aio to 0.10.4 (#129914) 2024-11-06 15:38:50 +01:00
Robert Resch 399011552b Disable uv cache (#129912) 2024-11-06 15:38:46 +01:00
Markus Jacobsen 0c9f30364c Update Bang & Olufsen source list as availability changes (#129910) 2024-11-06 15:38:43 +01:00
Louis Christ bdc17621ee Map "stop" to MediaPlayerState.IDLE in bluesound integration (#129904)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-11-06 15:38:40 +01:00
Joost Lekkerkerker 399c53a57e Bump spotifyaio to 0.8.4 (#129899) 2024-11-06 15:38:36 +01:00
Daniel Hjelseth Høyer f55e13bde4 Bump pyTibber to 0.30.4 (#129844) 2024-11-06 15:38:32 +01:00
epenet dea31e5744 Ensure that all files in a folder are in the same test bucket (#129946) 2024-11-06 15:38:24 +01:00
Michael Hansen 48d9df89ac Bump intents and add HassRespond test (#129830) 2024-11-06 15:36:46 +01:00
kingal123 adf836d9ac Update pylutron to 0.2.16 (#129653)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-06 15:33:16 +01:00
epenet 51d6948848 Use read-only options in google cloud options flow (#129927) 2024-11-06 15:15:35 +01:00
epenet 7ce74cb5ec Use read-only options in onkyo options flow (#129929) 2024-11-06 15:14:59 +01:00
Bram Kragten 29ba140816 Update frontend to 20241106.0 (#129953) 2024-11-06 14:53:59 +01:00
Robert Resch 0ca4f3e1ba Bump go2rtc-client to 0.0.1b5 (#129952) 2024-11-06 14:52:21 +01:00
J. Diego Rodríguez Royo 0430e6794e Delete binary door deprecation issue on unload at Home Connect (#129947) 2024-11-06 14:44:17 +01:00
Marc Mueller 29fa7f827a Fix audit-licenses check for multiple Python versions [ci] (#129951) 2024-11-06 14:20:14 +01:00
Tsvi Mostovicz 57d1001603 Move Jewish Calendar to runtime data (#129609) 2024-11-06 14:19:58 +01:00
Brett Adams 96de4b3828 Improve history coordinator in Teslemetry (#128235) 2024-11-06 13:40:37 +01:00
Teemu R. c6cb2884f4 Add motion sensor setting to tplink (#129393) 2024-11-06 13:40:17 +01:00
Manu 27e81fe0ed Improve error messages in Habitica (#129948)
Improve error messages
2024-11-06 13:23:43 +01:00
Louis Christ 2c1db10986 Map "stop" to MediaPlayerState.IDLE in bluesound integration (#129904)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-11-06 13:10:23 +01:00
epenet a7ba4bd086 Use read-only options in emoncms options flow (#129926)
* Use read-only options in emoncms options flow

* Don't store URL and API_KEY in entry options
2024-11-06 13:09:05 +01:00
Robert Resch 25449b424f Bump go2rtc-client to 0.0.1b4 (#129942) 2024-11-06 12:05:23 +01:00
Markus Jacobsen f6f89bd807 Update Bang & Olufsen source list as availability changes (#129910) 2024-11-06 11:52:00 +01:00
Daniel Hjelseth Høyer 370d7d6bdf Bump pyTibber to 0.30.4 (#129844) 2024-11-06 11:44:54 +01:00
Kunal Aggarwal 4dbf3359c1 Adding "peaceful" status as on value to Tuya Presence Sensor (#129925) 2024-11-06 11:43:41 +01:00
Joost Lekkerkerker 25eb7173bf Write squeezebox player state after query (#129939) 2024-11-06 11:32:59 +01:00
Joost Lekkerkerker 648c3d500b Bump spotifyaio to 0.8.5 (#129938) 2024-11-06 11:32:35 +01:00
epenet 33016c2977 Use new helper properties in netatmo options flow (#129781)
* Use new helper properties in netatmo options flow

* Update homeassistant/components/netatmo/config_flow.py

* Apply suggestions from code review

* Improve

* Keep options

* Simplify
2024-11-06 10:37:55 +01:00
Robert Resch 5679b061d2 Fix native sync WebRTC offer (#129931) 2024-11-06 10:07:10 +01:00
Nicholas Romyn 2eb2bdd615 Consolidating async_add_entities into one call in Ecobee (#129917)
* Consolidating async_add_entities into one call.

* changing to comprehension.
2024-11-06 08:25:18 +01:00
epenet 184cbfea23 Use read-only options in lastfm options flow (#129928)
Use read-only options in lstfm options flow
2024-11-06 08:14:54 +01:00
dependabot[bot] f88bc008e5 Bump actions/attest-build-provenance from 1.4.3 to 1.4.4 (#129924) 2024-11-06 08:13:41 +01:00
Paulus Schoutsen a927312fb5 Ensure all template names are strings (#129921) 2024-11-05 22:36:26 -05:00
starkillerOG 5f13db2356 Bump reolink_aio to 0.10.4 (#129914) 2024-11-06 00:05:05 +01:00
kingal123 64e84e2aa0 Update pylutron to 0.2.16 (#129653)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-05 22:23:14 +01:00
Michael Hansen 901457e7aa Bump intents and add HassRespond test (#129830) 2024-11-05 22:22:49 +01:00
Robert Resch 89a9c2ec24 Disable uv cache (#129912) 2024-11-05 22:18:41 +01:00
Joost Lekkerkerker 9e04457472 Bump spotifyaio to 0.8.4 (#129899) 2024-11-05 21:04:58 +01:00
Ville Skyttä 6ecdbb677f Bump huawei-lte-api to 1.10.0 (#129911) 2024-11-05 21:03:26 +01:00
Franck Nijhof 211ce43127 Bump version to 2024.11.0b7 2024-11-05 20:33:48 +01:00
G Johansson f5555df990 Bump holidays to 0.60 (#129909) 2024-11-05 20:33:39 +01:00
Paul Bottein 82c2422990 Update frontend to 20241105.0 (#129906) 2024-11-05 20:33:36 +01:00
Erik Montnemery 734ebc1adb Improve improv BLE error handling (#129902) 2024-11-05 20:33:33 +01:00
Paulus Schoutsen eb3371beef Change Ollama default to llama3.2 (#129901) 2024-11-05 20:33:30 +01:00
Manu e1ef1063fe Prevent update entity becoming unavailable on device disconnect in IronOS (#129840)
* Don't render update entity unavailable when Pinecil device disconnects

* fixes
2024-11-05 20:33:27 +01:00
Diogo Gomes c355a53485 Set friendly name of utility meter select entity when configured through YAML (#128267)
* set select friendly name in YAML

* backward compatibility added

* clean

* cleaner backward compatibility approach

* don't introduce default unique_id

* split test according to review
2024-11-05 20:33:23 +01:00
G Johansson 79de1d9ed4 Bump holidays to 0.60 (#129909) 2024-11-05 20:26:22 +01:00
Paul Bottein 7fefa5c235 Update frontend to 20241105.0 (#129906) 2024-11-05 20:25:15 +01:00
Brett Adams 94db78a0be Add signing support to Tesla Fleet (#128407)
* Add command signing

* wip

* Update tests

* requirements

* Add test
2024-11-05 20:04:55 +01:00
Diogo Gomes 83a1b06b56 Set friendly name of utility meter select entity when configured through YAML (#128267)
* set select friendly name in YAML

* backward compatibility added

* clean

* cleaner backward compatibility approach

* don't introduce default unique_id

* split test according to review
2024-11-05 19:59:43 +01:00
epenet 1e42a38473 Remove usage of options property in OptionsFlow (part 2) (#129897) 2024-11-05 19:53:05 +01:00
epenet c54ed53a81 Remove usage of options property in OptionsFlow (part 1) (#129895)
* Remove usage of options property in OptionsFlow

* Improve
2024-11-05 19:51:20 +01:00
Manu 611a952232 Prevent update entity becoming unavailable on device disconnect in IronOS (#129840)
* Don't render update entity unavailable when Pinecil device disconnects

* fixes
2024-11-05 18:39:10 +01:00
Erik Montnemery 05e76105ad Improve improv BLE error handling (#129902) 2024-11-05 11:12:05 -05:00
Paulus Schoutsen ed56e5d631 Change Ollama default to llama3.2 (#129901) 2024-11-05 17:02:44 +01:00
Manu 9253fa4471 Add binary sensor platform to Habitica integration (#129613)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-11-05 17:01:38 +01:00
Franck Nijhof c85eb6bf8e Bump version to 2024.11.0b6 2024-11-05 16:51:05 +01:00
Joost Lekkerkerker cc30d34e87 Remove timers from LG ThinQ (#129898) 2024-11-05 16:50:41 +01:00
Erik Montnemery 14875a1101 Map go2rtc log levels to Python log levels (#129894) 2024-11-05 16:50:38 +01:00
Joost Lekkerkerker 030aebb97f Use default package for yt-dlp (#129886) 2024-11-05 16:50:35 +01:00
Erik Montnemery 6e2f36b6d4 Log go2rtc output with warning level on error (#129882) 2024-11-05 16:50:32 +01:00
Robert Resch 25a05eb156 Append a 1 to all go2rtc ports to avoid port conflicts (#129881) 2024-11-05 16:50:29 +01:00
J. Diego Rodríguez Royo b71c4377f6 Removed stale translation and improved set_setting translation at Home Connect (#129878) 2024-11-05 16:50:25 +01:00
Michael Arthur d671341864 Update snapshot for lg thinq (#129856)
update snapshot for lg thinq

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-05 16:39:02 +01:00
Mike Degatano 383f712d43 Add repair for add-on boot fail (#129847) 2024-11-05 16:38:59 +01:00
Alex Bush 8a20cd77a0 Bump pyfibaro to 0.8.0 (#129846) 2024-11-05 16:38:56 +01:00
Richard Kroegel 14023644ef Bump bimmer_connected to 0.16.4 (#129838) 2024-11-05 16:38:53 +01:00
dotvav 496fc42b94 Bump pypalazzetti to 0.1.10 (#129832) 2024-11-05 16:38:50 +01:00
Erik Montnemery da0688ce8e Validate go2rtc server version (#129810) 2024-11-05 16:38:47 +01:00
Robert Resch 89d3707cb7 Skip adding providers if the camera has native WebRTC (#129808)
* Skip adding providers if the camera has native WebRTC

* Update homeassistant/components/camera/__init__.py

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

* Implement suggestion

* Add tests

* Shorten test name

* Fix test

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-11-05 16:38:44 +01:00
Kunal Aggarwal 3f5e395e2f Adding new on values for Tuya Presence Detection Sensor (#129801) 2024-11-05 16:38:41 +01:00
Joost Lekkerkerker 00ea1cab9f Add basic testing framework to LG ThinQ (#127785)
Co-authored-by: jangwon.lee <jangwon.lee@lge.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
Co-authored-by: YunseonPark-LGE <34848373+YunseonPark-LGE@users.noreply.github.com>
Co-authored-by: LG-ThinQ-Integration <LG-ThinQ-Integration@lge.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-11-05 16:38:37 +01:00
Joost Lekkerkerker 5f36062ef3 Remove timers from LG ThinQ (#129898) 2024-11-05 16:32:05 +01:00
Erik Montnemery e562b6f42b Map go2rtc log levels to Python log levels (#129894) 2024-11-05 15:57:33 +01:00
dotvav b76a94bd42 Bump pypalazzetti to 0.1.10 (#129832) 2024-11-05 15:34:25 +01:00
Joost Lekkerkerker 4e11ff05de Use default package for yt-dlp (#129886) 2024-11-05 15:23:41 +01:00
J. Diego Rodríguez Royo 080e3d7a42 Removed stale translation and improved set_setting translation at Home Connect (#129878) 2024-11-05 15:17:03 +01:00
Michael Hansen 69e3348cd7 Use different VAD thresholds for before and during voice command (#129848)
* Use two VAD thresholds

* Fix VoiceActivityTimeout class

* Update homeassistant/components/assist_pipeline/audio_enhancer.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-11-05 08:01:45 -06:00
Alexandre CUER 6caa4baa00 Fix missing translation string in emoncms (#129859) 2024-11-05 14:58:25 +01:00
Robert Resch 4729b19dc6 Skip adding providers if the camera has native WebRTC (#129808)
* Skip adding providers if the camera has native WebRTC

* Update homeassistant/components/camera/__init__.py

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

* Implement suggestion

* Add tests

* Shorten test name

* Fix test

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-11-05 14:44:37 +01:00
Richard Kroegel 8abbc4abbc Bump bimmer_connected to 0.16.4 (#129838) 2024-11-05 14:13:48 +01:00
Erik Montnemery 3a667bce8c Log go2rtc output with warning level on error (#129882) 2024-11-05 14:05:04 +01:00
starkillerOG 4c86102daf Add Reolink PTZ tilt position sensor (#129837) 2024-11-05 13:39:45 +01:00
Karl Beecken 15bf652f37 Bump python-tado to 0.17.7 (#129842) 2024-11-05 12:30:48 +01:00
Robert Resch eafed2b86c Append a 1 to all go2rtc ports to avoid port conflicts (#129881) 2024-11-05 12:29:51 +01:00
epenet 79901cede9 Drop initialize_options helper from OptionsFlow (#129870) 2024-11-05 12:02:33 +01:00
tdfountain 27dc82d7d0 Add device model ID if provided by NUT (#124189)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-11-05 11:57:00 +01:00
Mike Degatano ae37c8cc7a Add repair for add-on boot fail (#129847) 2024-11-05 11:53:01 +01:00
Kunal Aggarwal 5eadfcc524 Adding new on values for Tuya Presence Detection Sensor (#129801) 2024-11-05 11:52:38 +01:00
Manu 5fd1e23255 Bump pynecil to 0.2.1 (#129843) 2024-11-05 11:52:11 +01:00
Teemu R. 72bcc6702f Add child lock for tplink thermostats (#129649) 2024-11-05 11:14:53 +01:00
Erik Montnemery 8889464e04 Validate go2rtc server version (#129810) 2024-11-05 11:09:10 +01:00
G Johansson af58b0c3b7 Add reconfigure flow to yale_smart_alarm (#129536) 2024-11-05 11:05:20 +01:00
epenet e9e20229a3 Drop use of initialize_options in androidtv_remote (#129855) 2024-11-05 10:57:03 +01:00
Alex Bush 80ff6dc618 Bump pyfibaro to 0.8.0 (#129846) 2024-11-05 10:56:34 +01:00
epenet fa30100160 Fix flaky tests in device_sun_light_trigger (#129871) 2024-11-05 10:55:40 +01:00
epenet e6c20333b3 Remove dead code in translation checks (#129875) 2024-11-05 10:47:37 +01:00
Joakim Sørensen 3858400a6f Bump hass-nabucasa from 0.83.0 to 0.84.0 (#129873) 2024-11-05 10:10:23 +01:00
epenet 95eefbac20 Drop use of initialize_options in androidtv (#129854)
* Drop use of initialize_options in androidtv

* Initialize instance attribute in init method

* Adjust
2024-11-05 09:01:29 +01:00
epenet e1e731eb48 Drop use of initialize_options in onkyo (#129869)
* Drop use of initialize_options in onkyo

* Apply suggestions from code review

Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>

---------

Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
2024-11-05 08:56:58 +01:00
Michael Arthur f7ce4ff25c Update snapshot for lg thinq (#129856)
update snapshot for lg thinq

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-05 08:15:42 +01:00
Paulus Schoutsen c7b2ffbc8e Bump version to 2024.11.0b5 2024-11-05 03:00:18 +00:00
J. Nick Koston 3a1502e2bb Disable SRTP for unifiprotect RTSPS stream (#129852) 2024-11-05 02:59:23 +00:00
J. Nick Koston b830f83a34 Bump uiprotect to 6.4.0 (#129851) 2024-11-05 02:59:23 +00:00
J. Nick Koston 2982e733bc Fix unifiprotect supported features being set too late (#129850) 2024-11-05 02:59:22 +00:00
starkillerOG e89ce215c6 Bump reolink-aio to 0.10.3 (#129841) 2024-11-05 02:59:21 +00:00
G Johansson b6345f8d07 Fix translations in hydrawise (#129834) 2024-11-05 02:59:20 +00:00
G Johansson 9d261bab48 Fix translation in ovo energy (#129833) 2024-11-05 02:59:19 +00:00
Michael Hansen b6f875134e Add HassRespond intent (#129755)
* Add HassHello intent

* Rename to HassRespond

* LLM's ignore HassRespond intent
2024-11-05 02:59:18 +00:00
Artur Pragacz 90ceebdf91 Fix source mapping in Onkyo (#129716)
* Fix source mapping

* Fix copy paste
2024-11-05 02:59:18 +00:00
Artur Pragacz 617e87e02c Fix source mapping in Onkyo (#129716)
* Fix source mapping

* Fix copy paste
2024-11-04 21:56:47 -05:00
starkillerOG dafd54ba2b Bump reolink-aio to 0.10.3 (#129841) 2024-11-04 21:34:40 -05:00
J. Nick Koston e8c3539709 Disable SRTP for unifiprotect RTSPS stream (#129852) 2024-11-04 16:13:52 -06:00
J. Nick Koston e5263dc0c8 Bump uiprotect to 6.4.0 (#129851) 2024-11-04 15:43:22 -06:00
J. Nick Koston 3584c710b9 Fix unifiprotect supported features being set too late (#129850) 2024-11-04 15:13:56 -06:00
G Johansson 0b56ef5699 Fix translation in ovo energy (#129833) 2024-11-04 19:57:49 +01:00
G Johansson 90bd9bb626 Fix translations in hydrawise (#129834) 2024-11-04 19:57:00 +01:00
Paulus Schoutsen 03e6a13896 Bump version to 2024.11.0b4 2024-11-04 18:48:58 +00:00
G Johansson 9fb3261f02 Fix translations in landisgyr (#129831) 2024-11-04 18:48:37 +00:00
Bram Kragten 0bc6b8b0d4 Update frontend to 20241104.0 (#129829) 2024-11-04 18:48:36 +00:00
G Johansson 18d2ced045 Fix translations in homeworks (#129824) 2024-11-04 18:48:35 +00:00
Robert Resch 6c75e0bee1 Remove all ice_servers on native sync WebRTC cameras (#129819) 2024-11-04 18:48:35 +00:00
Steven B. 0b981f42bb Bump python-kasa to 0.7.7 (#129817)
Bump tplink dependency python-kasa to 0.7.7
2024-11-04 18:48:34 +00:00
Paulus Schoutsen 82868a8588 Fix ESPHome dashboard check (#129812) 2024-11-04 18:48:33 +00:00
Erik Montnemery 6e93777f54 Fix create flow logic for single config entry integrations (#129807)
* Fix create flow logic for single config entry integrations

* Adjust MQTT test
2024-11-04 18:47:41 +00:00
Erik Montnemery 9349292464 Fix aborting flows for single config entry integrations (#129805) 2024-11-04 18:43:56 +00:00
Robert Resch 7084b3b52c Update go2rtc stream if stream_source is not matching (#129804) 2024-11-04 18:43:55 +00:00
epenet 0f0f5fd0ab Fix incorrect description placeholders in azure event hub (#129803) 2024-11-04 18:43:54 +00:00
Joost Lekkerkerker cb0b942db3 Improve error handling in Spotify (#129799) 2024-11-04 18:43:53 +00:00
Erik Montnemery b1c9f83952 Fix stringification of discovered hassio uuid (#129797) 2024-11-04 18:43:52 +00:00
Joost Lekkerkerker 1ff0efc97b Bump yt-dlp to 2024.11.04 (#129794) 2024-11-04 18:43:51 +00:00
Robert Resch a4da2a9eb5 Use RTCIceCandidate instead of str for candidate (#129793) 2024-11-04 18:43:51 +00:00
Antoine Reversat ba3cfb5f87 Bump ayla-iot-unofficial to 1.4.3 (#129743)
Upgrade to ayla-iot-unofficial v1.4.3
2024-11-04 18:43:50 +00:00
Luca Angemi bf196935f6 Add state class to precipitation_intensity in Aemet (#129670)
Update sensor.py
2024-11-04 18:43:49 +00:00
Joost Lekkerkerker 6e98343706 Update Spotify state after mutation (#129607) 2024-11-04 18:43:48 +00:00
Erik Montnemery de453ab5c1 Add watchdog to monitor and respawn go2rtc server (#129497) 2024-11-04 18:43:47 +00:00
Andre Lengwenus f408de4fc3 Bump lcn-frontend to 0.2.1 (#129457) 2024-11-04 18:43:47 +00:00
Bram Kragten 7863927c3a Update frontend to 20241104.0 (#129829) 2024-11-04 19:39:46 +01:00
G Johansson 9fcf757021 Fix translations in landisgyr (#129831) 2024-11-04 19:35:35 +01:00
epenet fc0547ccdf Pass the config entry explicitly in aemet coordinator (#128097) 2024-11-04 19:23:48 +01:00
Joost Lekkerkerker 22f8f117fb Add basic testing framework to LG ThinQ (#127785)
Co-authored-by: jangwon.lee <jangwon.lee@lge.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
Co-authored-by: YunseonPark-LGE <34848373+YunseonPark-LGE@users.noreply.github.com>
Co-authored-by: LG-ThinQ-Integration <LG-ThinQ-Integration@lge.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-11-04 19:22:12 +01:00
epenet 2052579efc Set config_entry explicitly in todoist coordinator (#129421) 2024-11-04 19:18:36 +01:00
epenet b8f2583bc3 Set config_entry explicitly in caldav coordinator (#129424) 2024-11-04 19:17:53 +01:00
epenet 6323a078e1 Set config_entry explicitly in wled coordinator (#129425) 2024-11-04 19:17:07 +01:00
G Johansson ca0be3ec8a Use coordinator async_setup in vizio (#129450) 2024-11-04 19:16:22 +01:00
epenet 91157c21ef Reapply "Fix unused snapshots not triggering failure in CI" (#129311) 2024-11-04 18:59:27 +01:00
epenet cc4fae10f5 Cleanup deprecated OptionsFlowWithConfigEntry (part 2) (#129754) 2024-11-04 18:55:49 +01:00
epenet d180ff417d Cleanup deprecated OptionsFlowWithConfigEntry (part 3) (#129756) 2024-11-04 18:55:01 +01:00
epenet 8870b657d1 Use new helper properties in hyperion options flow (#129777) 2024-11-04 18:54:22 +01:00
epenet 81735b7b47 Use new helper properties in konnected options flow (#129778) 2024-11-04 18:50:00 +01:00
Marc Mueller 7fd261347b Update charset-normalizer to 3.4.0 (#129821) 2024-11-04 18:49:19 +01:00
Robert Resch df796d432e Remove all ice_servers on native sync WebRTC cameras (#129819) 2024-11-04 18:41:37 +01:00
Steven B. f6e36615d6 Bump python-kasa to 0.7.7 (#129817)
Bump tplink dependency python-kasa to 0.7.7
2024-11-04 18:39:39 +01:00
Noah Husby 0278735dbf Use translated errors in Russound RIO (#129820) 2024-11-04 18:07:11 +01:00
tdfountain 9c8d8fef16 Suggest area for NUT based on device location (#129770) 2024-11-04 18:06:45 +01:00
G Johansson 6897b24c10 Fix translations in homeworks (#129824) 2024-11-04 18:03:37 +01:00
G Johansson a2a3f59e65 Fix missing translation in jewish_calendar (#129822) 2024-11-04 18:01:39 +01:00
G Johansson 2626a74840 Fix translations in honeywell (#129823) 2024-11-04 18:00:31 +01:00
Paulus Schoutsen 689260f581 Fix ESPHome dashboard check (#129812) 2024-11-04 17:37:14 +01:00
G Johansson f1a2c8be4b Stop recording of non-changing attributes in threshold (#129541) 2024-11-04 17:36:25 +01:00
epenet 0579d565dd Fix incorrect description placeholders in azure event hub (#129803) 2024-11-04 17:35:47 +01:00
Max Muth f141f5f908 Update codeowners of Fritz integration (#129595)
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-04 17:26:12 +01:00
Antoine Reversat 0c25252d9f Bump ayla-iot-unofficial to 1.4.3 (#129743)
Upgrade to ayla-iot-unofficial v1.4.3
2024-11-04 17:20:15 +01:00
Jake Martin 400b377aa8 Bump monzopy to 1.4.2 (#129726)
* Bump monzopy to 1.4.0

* Bump to 1.4.2

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-04 16:55:02 +01:00
Manu a5f3c434e0 Improve exceptions in habitica cast skill action (#129603)
* Raise a different exception when entry not loaded

* adjust type hints

* move `get_config_entry` to services module
2024-11-04 16:46:38 +01:00
epenet 365f8046ac Use new helper properties in yeelight options flow (#129791) 2024-11-04 16:09:50 +01:00
Erik Montnemery 4ac35d40cd Fix create flow logic for single config entry integrations (#129807)
* Fix create flow logic for single config entry integrations

* Adjust MQTT test
2024-11-04 15:45:29 +01:00
J. Nick Koston 7691991a93 Small cleanups to the websocket command phase (#129712)
* Small cleanups to the websocket command phase

- Remove unused argument
- Avoid multiple NamedTuple property lookups

* Update homeassistant/components/websocket_api/http.py

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Apply suggestions from code review

* touch ups

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-11-04 15:33:15 +01:00
Willem-Jan van Rootselaar d0c45b1857 Bump python-bsblan to 1.2.1 (#129635)
* Bump python-bsblan dependency to version 1.1.0

* Bump python-bsblan dependency to version 1.2.0

* Bump python-bsblan dependency to version 1.2.1

* Update test diagnostics snapshots to use numeric values and add error handling
2024-11-04 15:31:44 +01:00
Joost Lekkerkerker 02750452df Update Spotify state after mutation (#129607) 2024-11-04 15:01:37 +01:00
Marc Mueller 41a81cbf15 Switch back to av 13.1.0 (#129699) 2024-11-04 14:48:28 +01:00
Andre Lengwenus ff621d5bf3 Bump lcn-frontend to 0.2.1 (#129457) 2024-11-04 14:45:20 +01:00
epenet 6d561a9796 Remove deprecated property setters in option flows (#129773) 2024-11-04 14:21:26 +01:00
Erik Montnemery 4784199038 Fix aborting flows for single config entry integrations (#129805) 2024-11-04 13:59:10 +01:00
Robert Resch df35c8e707 Update go2rtc stream if stream_source is not matching (#129804) 2024-11-04 13:58:12 +01:00
Erik Montnemery 57eeaf1f75 Add watchdog to monitor and respawn go2rtc server (#129497) 2024-11-04 13:42:42 +01:00
Joakim Sørensen 3cadc1796f Use JSON as format for .HA_RESTORE (#129792)
* Use JSON as format for .HA_RESTORE

* Adjust bakup manager test
2024-11-04 13:07:11 +01:00
Joost Lekkerkerker ae06f734ce Improve error handling in Spotify (#129799) 2024-11-04 12:34:00 +01:00
Erik Montnemery 08a53362a7 Fix stringification of discovered hassio uuid (#129797) 2024-11-04 12:26:34 +01:00
jb101010-2 274c928ec0 Add coordinator to suez_water (#129242)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-11-04 12:18:12 +01:00
Robert Resch d75dda0c05 Use RTCIceCandidate instead of str for candidate (#129793) 2024-11-04 10:38:27 +01:00
Joost Lekkerkerker 0c40fcdaeb Bump yt-dlp to 2024.11.04 (#129794) 2024-11-04 10:33:08 +01:00
G Johansson 0a1ba8a4a3 Small code quality improvement/cleanup in random (#129542) 2024-11-04 09:52:35 +01:00
epenet 018acc0a3c Use new helper properties in crownstone options flow (#129774) 2024-11-04 09:43:25 +01:00
epenet 3a293c6bc4 Use new helper properties in dsmr options flow (#129775) 2024-11-04 09:43:10 +01:00
epenet 9155d56190 Use new helper properties in flux_led options flow (#129776) 2024-11-04 09:42:58 +01:00
epenet 461dc13da9 Use new helper properties in motioneye options flow (#129780) 2024-11-04 09:40:13 +01:00
epenet b48e2127b8 Use new helper properties in plaato options flow (#129782) 2024-11-04 09:39:56 +01:00
epenet 11ab992dbb Use new helper properties in recollect_waste options flow (#129783) 2024-11-04 09:39:41 +01:00
epenet 4be2cdf90a Use new helper properties in steam_online options flow (#129785) 2024-11-04 09:39:27 +01:00
epenet cdd5cb2876 Use new helper properties in tomorrowio options flow (#129787) 2024-11-04 09:39:13 +01:00
epenet cdc67aa891 Use new helper properties in verisure options flow (#129788) 2024-11-04 09:38:41 +01:00
epenet 6a22a2b867 Use new helper properties in watttime options flow (#129789) 2024-11-04 09:38:24 +01:00
epenet 0883b23d0c Use new helper properties in yalexs_ble options flow (#129790) 2024-11-04 09:38:11 +01:00
epenet 595459bfda Use new helper properties in rfxtrx options flow (#129784) 2024-11-04 09:34:20 +01:00
Bram Kragten 5141a4d292 Bump version to 2024.11.0b3 2024-11-04 09:32:53 +01:00
LG-ThinQ-Integration cf8b7607ae Bump thinqconnect to 1.0.0 (#129769)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
2024-11-04 09:31:43 +01:00
Joost Lekkerkerker b38fe00387 Bump spotifyaio to 0.8.3 (#129729) 2024-11-04 09:31:42 +01:00
J. Nick Koston 5d446f0e14 Bump HAP-python to 4.9.2 (#129715) 2024-11-04 09:31:41 +01:00
Josef Zweck a592ece9c8 Add missing translation string to lamarzocco (#129713)
* add missing translation string

* Update strings.json

* import pytest again
2024-11-04 09:31:40 +01:00
Allen Porter 9cb60c61d1 Fix nest streams broken due to CameraCapabilities change (#129711)
* Fix nest streams broken due to CameraCapabilities change

* Fix stream cleanup

* Apply suggestions from code review

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

* Update homeassistant/components/nest/camera.py

---------

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2024-11-04 09:31:39 +01:00
J. Nick Koston 90ed06c354 Bump DoorBirdPy to 3.0.8 (#129709) 2024-11-04 09:31:39 +01:00
Manu 22d64cb8f4 Bump bring-api to 0.9.1 (#129702) 2024-11-04 09:31:38 +01:00
Nathan Spencer 453039e860 Change alexa arm handler to allow switching arm states unless in armed_away mode (#129701)
* Change alexa arm handler to allow switching arm states unless in armed_away mode

* Address PR comments
2024-11-04 09:31:37 +01:00
Simon Lamon e727162225 Bump python-linkplay to 0.0.17 (#129683) 2024-11-04 09:31:36 +01:00
Ståle Storø Hauknes a898a5996e Bump Airthings BLE to 0.9.2 (#129659)
Bump airthings ble
2024-11-04 09:31:35 +01:00
Jesse Hills d501bb8d52 Only set ESPHome configuration url to addon if there is an existing configuration for the device (#129356)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-11-04 09:31:34 +01:00
Ståle Storø Hauknes 7ab8ff56b3 Bump Airthings BLE to 0.9.2 (#129659)
Bump airthings ble
2024-11-04 08:11:18 +01:00
Nathan Spencer eda36512ec Change alexa arm handler to allow switching arm states unless in armed_away mode (#129701)
* Change alexa arm handler to allow switching arm states unless in armed_away mode

* Address PR comments
2024-11-04 07:49:48 +01:00
LG-ThinQ-Integration 04aee812f8 Bump thinqconnect to 1.0.0 (#129769)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
2024-11-04 07:17:50 +01:00
Allen Porter 6718cce203 Fix nest streams broken due to CameraCapabilities change (#129711)
* Fix nest streams broken due to CameraCapabilities change

* Fix stream cleanup

* Apply suggestions from code review

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

* Update homeassistant/components/nest/camera.py

---------

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2024-11-03 20:45:09 -08:00
Bouwe Westerdijk 49f0bb6990 Bump plugwise to v1.5.0 (#129668)
* Bump plugwise to v1.5.0

* And adapt
2024-11-03 23:30:21 -05:00
Simon Lamon 38afcbb21f Bump python-linkplay to 0.0.17 (#129683) 2024-11-03 22:56:45 -05:00
Jesse Hills 87ab2beddf Only set ESPHome configuration url to addon if there is an existing configuration for the device (#129356)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-11-03 18:16:49 -06:00
tdfountain a05a34239d Show NUT device serial number if provided in Device Info (#124168) 2024-11-03 17:27:27 -06:00
epenet f11aba9648 Fix flaky tests in advantage_air (#129758) 2024-11-03 17:25:37 -06:00
Michael Hansen c2ef119e50 Add HassRespond intent (#129755)
* Add HassHello intent

* Rename to HassRespond

* LLM's ignore HassRespond intent
2024-11-03 16:38:52 -06:00
epenet 8b6c99776e Cleanup unnecessary OptionsFlowWithConfigEntry (part 1) (#129752)
* Cleanup unnecessary OptionsFlowWithConfigEntry

* Fix emoncms

* Fix imap

* Fix met

* Fix workday
2024-11-03 22:57:18 +01:00
Joost Lekkerkerker 463bffaeb6 Bump spotifyaio to 0.8.3 (#129729) 2024-11-03 21:55:12 +01:00
hahn-th 0cfd8032c0 Add Measurement StateClass to HomematicIP Cloud Wind and Rain Sensor (#129724)
Add Meassurement StateClass to Wind and Rain Sensor
2024-11-03 21:07:59 +01:00
Luca Angemi 144d5ff0cc Add state class to precipitation_intensity in Aemet (#129670)
Update sensor.py
2024-11-03 21:06:46 +01:00
G Johansson ab5c65b08c Improve code quality in yale_smart_alarm options flow (#129531)
* Improve code quality in yale_smart_alarm options flow

* mods

* Fix
2024-11-03 21:04:53 +01:00
Josef Zweck 6b33bf3961 Add missing translation string to lamarzocco (#129713)
* add missing translation string

* Update strings.json

* import pytest again
2024-11-03 20:56:08 +01:00
epenet 89eb395e2d Add OptionsFlow helper for a mutable copy of the config entry options (#129718)
* Add OptionsFlow helper for a mutable copy of the config entry options

* Add tests

* Improve coverage

* error_if_core=False

* Adjust report

* Avoid mutli-line ternary
2024-11-03 20:37:58 +01:00
G Johansson d671d48869 Small cleanup mold_indicator (#129736) 2024-11-03 19:17:37 +01:00
J. Nick Koston ed582fae91 Bump HAP-python to 4.9.2 (#129715) 2024-11-03 11:27:57 -06:00
Manu 4d5c3ee0aa Bump bring-api to 0.9.1 (#129702) 2024-11-03 10:46:16 -06:00
epenet 02046fcdb4 Fix advantage_air CI failure (#129735) 2024-11-03 17:29:33 +01:00
Josef Zweck fbe27749a0 Correct length of the serials in lamarzocco tests (#129725) 2024-11-03 13:35:42 +01:00
Josef Zweck eddab96a69 Add DHCP discovery to lamarzocco (#129675)
* Add DHCP discovery to lamarzocco

* ensure serial is upper

* shorten pattern

* parametrize across models
2024-11-03 09:44:35 +01:00
J. Nick Koston ed3376352d Bump DoorBirdPy to 3.0.8 (#129709) 2024-11-02 22:43:21 -05:00
J. Nick Koston dfbb763031 Disable cleanup_closed on python 3.12.7+ and 3.13.1+ (#129645) 2024-11-02 22:15:56 -05:00
Marc Mueller 5cf13d9273 Additional stream typing improvements (#129695) 2024-11-02 22:22:31 +01:00
Bram Kragten 5ef45fd12e Bump version to 2024.11.0b2 2024-11-02 20:42:48 +01:00
Klaas Schoute 8a293a41f5 Bump autarco lib to v3.1.0 (#129684)
Bump autarco to v3.1.0
2024-11-02 20:42:44 +01:00
J. Nick Koston 931820a170 Bump sensorpush-ble to 1.7.1 (#129657) 2024-11-02 20:42:44 +01:00
J. Nick Koston e9944b964a Bump aioesphomeapi to 27.0.1 (#129643) 2024-11-02 20:42:43 +01:00
J. Nick Koston dbae1d2f8b Bump aiohomekit to 3.2.6 (#129640) 2024-11-02 20:42:42 +01:00
Joost Lekkerkerker 0dc8feba05 Bump spotifyaio to 0.8.2 (#129639) 2024-11-02 20:42:41 +01:00
Robert Resch 5c7c2347f7 Bump webrtc-models to 0.2.0 (#129627) 2024-11-02 20:42:40 +01:00
J. Nick Koston d069907948 Pin async-timeout to 4.0.3 (#129592) 2024-11-02 20:42:39 +01:00
Erik Montnemery 725ab477a8 Revert "Create a script service schema based on fields" (#129591) 2024-11-02 20:42:38 +01:00
Robert Resch d05ee9ff60 Add go2rtc debug_ui yaml key to enable go2rtc ui (#129587)
* Add go2rtc debug_ui yaml key to enable go2rtc ui

* Apply suggestions from code review

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

* Order imports

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-11-02 20:42:36 +01:00
Joost Lekkerkerker 3c1f6d97cc Bump aiowithings to 3.1.1 (#129586) 2024-11-02 20:42:33 +01:00
epenet 5fe827f6c4 Fix flaky camera test (#129576) 2024-11-02 20:42:31 +01:00
Erik Montnemery 76f9a93ed7 Bump aiohasupervisor to version 0.2.1 (#129574) 2024-11-02 20:42:30 +01:00
Joost Lekkerkerker df2506bfbb Bump spotifyaio to 0.8.1 (#129573) 2024-11-02 20:42:29 +01:00
Joost Lekkerkerker b25ab04d2c Fix Geniushub setup (#129569) 2024-11-02 20:42:28 +01:00
Steven B. 6f094e8a54 Check for async web offer overrides in camera capabilities (#129519) 2024-11-02 20:42:27 +01:00
Erik Montnemery e18ffc53f2 Revert "Create a script service schema based on fields" (#129591) 2024-11-02 20:39:17 +01:00
Marc Mueller 0eea3176d6 Minor stream typing improvements (#129691) 2024-11-02 19:29:09 +01:00
Marc Mueller 4f20977a8e Update mypy-dev to 1.14.0a2 (#129625) 2024-11-02 19:15:50 +01:00
Marc Mueller 5bd63bb56b Replace AVError with FFmpegError (#129689) 2024-11-02 19:14:59 +01:00
Marc Mueller f7103da818 Refactor av.open calls to support type annotations (#129688) 2024-11-02 19:03:32 +01:00
Klaas Schoute bf4922a7ef Bump autarco lib to v3.1.0 (#129684)
Bump autarco to v3.1.0
2024-11-02 18:42:56 +01:00
J. Nick Koston 6f7eac5c6d Bump sensorpush-ble to 1.7.1 (#129657) 2024-11-02 12:26:31 -05:00
epenet d6e73a89f3 Cleanup unnecessary __init__ method in OptionsFlow (#129651)
* Cleanup unnecessary init step in OptionsFlow

* Increase coverage
2024-11-02 18:15:41 +01:00
Sid 269aefd405 Bump ruff to 0.7.2 (#129669) 2024-11-02 11:29:08 +01:00
J. Nick Koston a6865f1639 Bump aiohomekit to 3.2.6 (#129640) 2024-11-01 14:01:33 -05:00
J. Nick Koston f55aa0b86e Bump aioesphomeapi to 27.0.1 (#129643) 2024-11-01 13:16:15 -05:00
Joost Lekkerkerker 02b34f05aa Bump spotifyaio to 0.8.2 (#129639) 2024-11-01 18:25:26 +01:00
Joost Lekkerkerker 37f42707e5 Fix Geniushub setup (#129569) 2024-11-01 17:33:39 +01:00
Robert Resch 17f3ba1434 Bump webrtc-models to 0.2.0 (#129627) 2024-11-01 17:24:44 +01:00
Joakim Sørensen 31dcc25ba5 Add handler to restore a backup file with the backup integration (#128365)
* Early pushout of restore handling for core/container

* Adjust after rebase

* Move logging definition, we should only do this if we go ahead with the restore

* First round

* More paths

* Add async_restore_backup to base class

* Block restore of new backup files

* manager tests

* Add websocket test

* Add testing to main

* Add coverage for missing backup file

* Catch FileNotFoundError instead

* Patch Path.read_text instead

* Remove HA_RESTORE from keep

* Use secure paths

* Fix restart test

* extend coverage

* Mock argv

* Adjustments
2024-11-01 16:25:22 +01:00
Joost Lekkerkerker 4da93f6a5e Bump spotifyaio to 0.8.1 (#129573) 2024-11-01 15:12:15 +01:00
Marc Mueller 5ed7d32749 Remove unnecessary asyncio EventLoopPolicy init_watcher backport (#129628) 2024-11-01 13:44:49 +01:00
epenet ab5b9dbdc9 Add OptionsFlow helpers to get the current config entry (#129562)
* Add OptionsFlow helpers to get the current config entry

* Add tests

* Improve

* Add ValueError to indicate that the config entry is not available in `__init__` method

* Use a property

* Update config_entries.py

* Update config_entries.py

* Update config_entries.py

* Add a property setter for compatibility

* Add report

* Update config_flow.py

* Add tests

* Update test_config_entries.py
2024-11-01 12:54:35 +01:00
Marco 3b28bf07d1 Add boost switch to Smarty (#129466) 2024-11-01 11:08:55 +01:00
epenet b626c9b450 Ensure entry_id is set on reauth/reconfigure flows (#129319)
* Ensure entry_id is set on reauth/reconfigure flows

* Improve

* Improve

* Use report helper

* Adjust deprecation date

* Update config_entries.py

* Improve message and adjust tests

* Apply suggestions from code review

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

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-11-01 10:29:58 +01:00
Willem-Jan van Rootselaar 5430eca93e Bump python-bsblan to 1.0.0 (#129617) 2024-11-01 10:23:30 +01:00
epenet b41c477f44 Fix flaky camera test (#129576) 2024-11-01 10:15:20 +01:00
Robert Resch 5900413c08 Add zwave_js node_capabilities and invoke_cc_api websocket commands (#125327)
* Add zwave_js node_capabilities and invoke_cc_api websocket commands

* Map isSecure to is_secure

* Add tests

* Add error handling

* fix

* Use to_dict function

* Make response compatible with current expectations

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-11-01 00:32:01 +01:00
Marc Mueller c2ceab741f Remove unnecessary husqvarna_automower_ble test fixture (#129577) 2024-11-01 00:00:52 +01:00
J. Nick Koston 45ff4940eb Pin async-timeout to 4.0.3 (#129592) 2024-10-31 16:18:31 -05:00
Robert Resch 9c8a15cb64 Add go2rtc debug_ui yaml key to enable go2rtc ui (#129587)
* Add go2rtc debug_ui yaml key to enable go2rtc ui

* Apply suggestions from code review

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

* Order imports

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-10-31 20:56:53 +01:00
Erik Montnemery b09e54c961 Bump aiohasupervisor to version 0.2.1 (#129574) 2024-10-31 19:37:31 +01:00
Steven B. f44b7e202a Check for async web offer overrides in camera capabilities (#129519) 2024-10-31 18:57:40 +01:00
Joost Lekkerkerker 0f535e979f Bump aiowithings to 3.1.1 (#129586) 2024-10-31 18:28:53 +01:00
G Johansson 4c2c01b4f6 Use shorthand attribute for native_value in mold_indicator (#129538) 2024-10-31 17:40:14 +01:00
G Johansson b1d48fe9a2 Use class attributes in Times of Day (#129543)
* mypy ignore assignment in Times of Day so we can drop all type checking

* class attributes
2024-10-31 17:37:33 +01:00
Bram Kragten 41590f91ac Bump version to 2024.11.0b1 2024-10-31 16:38:09 +01:00
Paul Bottein e9d1f4f46e Update frontend to 20241031.0 (#129583) 2024-10-31 16:36:58 +01:00
epenet 7f287412ba Log type as well as value for unique_id checks (#129575) 2024-10-31 16:36:57 +01:00
Erik Montnemery 2df094de2b Stringify discovered hassio uuid (#129572)
* Stringify discovered hassio uuid

* Correct DiscoveryKey

* Adjust tests
2024-10-31 16:36:56 +01:00
starkillerOG 964ab5b351 Log Reolink select value KeyError only once (#129559) 2024-10-31 16:36:55 +01:00
Brett Adams 3f6e9a54fe Fix "home" route in Tesla Fleet & Teslemetry (#129546)
* translate Home to home

* refactor for mypy

* Fix home state

* Revert key change

* Add testing
2024-10-31 16:36:55 +01:00
J. Nick Koston 4ec5d5ae1e Bump yarl to 1.17.1 (#129539)
changelog: https://github.com/aio-libs/yarl/compare/v1.17.0...v1.17.1
2024-10-31 16:36:54 +01:00
Erik Montnemery c49b155c29 Allow importing homeassistant.core.Config until 2025.11 (#129537) 2024-10-31 16:36:53 +01:00
Luca Angemi fc602b1888 Fix bthome UnitOfConductivity (#129535)
Fix unit
2024-10-31 16:36:52 +01:00
G Johansson 81421992a2 Missing config_flow in manifest for local_file (#129529) 2024-10-31 16:36:51 +01:00
starkillerOG 4ef31f9331 Bump reolink_aio to 0.10.2 (#129528) 2024-10-31 16:36:50 +01:00
G Johansson d7e304badf Fix async_config_entry_first_refresh used after config entry is loaded in speedtestdotcom (#129527)
* Fix async_config_entry_first_refresh used after config entry is loaded in speedtestdotcom

* is
2024-10-31 16:36:49 +01:00
cryptk bf3f1b4b49 Bump uiprotect to 6.3.2 (#129513) 2024-10-31 16:36:49 +01:00
Jan Bouwhuis 2ac0ff03fc Fix current temperature calculation for incomfort boiler (#129496) 2024-10-31 16:36:48 +01:00
Aurore d10553d624 Fix timeout issue on Roomba integration when adding a new device (#129230)
* Update const.py

DEFAULT_DELAY = 1 to DEFAULT_DELAY = 100 to fix timeout when adding a new device

* Update config_flow.py

continuous=False to continuous=True to fix timeout when adding a new device

* Update homeassistant/components/roomba/const.py

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

* Update test_config_flow.py

Change CONF_DELAY to match DEFAULT_DELAY (30 sec instead of 1)

* Update tests/components/roomba/test_config_flow.py

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

* Use constant for DEFAULT_DELAY in tests

---------

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
Co-authored-by: jbouwh <jan@jbsoft.nl>
2024-10-31 16:36:47 +01:00
Paul Bottein b1dfc3cd23 Update frontend to 20241031.0 (#129583) 2024-10-31 16:35:36 +01:00
epenet 696efe349e Log type as well as value for unique_id checks (#129575) 2024-10-31 15:10:27 +01:00
Jan Bouwhuis 6a32722acc Fix current temperature calculation for incomfort boiler (#129496) 2024-10-31 14:57:09 +01:00
Erik Montnemery 8eaec56c6b Stringify discovered hassio uuid (#129572)
* Stringify discovered hassio uuid

* Correct DiscoveryKey

* Adjust tests
2024-10-31 13:54:27 +01:00
Thomas55555 60d3c9342d Fix flakey test in Husqvarna Automower (#129571) 2024-10-31 13:20:59 +01:00
Marcel van der Veldt 4dc2433e8b Revert "Add musicassistant integration (#128919)" (#129565)
This reverts commit 568bdef61f.
2024-10-31 12:18:10 +01:00
TheJulianJES 2bd5039f28 Fix capitalization in Philips Hue strings (#129552) 2024-10-31 10:04:51 +01:00
G Johansson 8b1b14a704 Missing config_flow in manifest for local_file (#129529) 2024-10-31 09:50:32 +01:00
starkillerOG 5e674ce1d0 Log Reolink select value KeyError only once (#129559) 2024-10-31 09:49:27 +01:00
Brett Adams 3656bcf752 Fix "home" route in Tesla Fleet & Teslemetry (#129546)
* translate Home to home

* refactor for mypy

* Fix home state

* Revert key change

* Add testing
2024-10-31 08:56:03 +01:00
J. Nick Koston 39093fc2bc Bump yarl to 1.17.1 (#129539)
changelog: https://github.com/aio-libs/yarl/compare/v1.17.0...v1.17.1
2024-10-30 23:56:29 +01:00
Teemu R. efa5838be4 Add last alert timestamp for tplink waterleak (#128644)
* Add last alert timestamp for tplink waterleak

* Fix snapshot
2024-10-30 23:25:30 +01:00
Erik Montnemery 1c6ad2fa66 Allow importing homeassistant.core.Config until 2025.11 (#129537) 2024-10-30 22:56:59 +01:00
starkillerOG af144e1b77 Bump reolink_aio to 0.10.2 (#129528) 2024-10-30 23:24:07 +02:00
Luca Angemi b451bfed81 Fix bthome UnitOfConductivity (#129535)
Fix unit
2024-10-30 23:22:17 +02:00
G Johansson 3e32c50936 Fix async_config_entry_first_refresh used after config entry is loaded in speedtestdotcom (#129527)
* Fix async_config_entry_first_refresh used after config entry is loaded in speedtestdotcom

* is
2024-10-30 21:17:03 +01:00
Bram Kragten 208b15637a Bump version to 2024.12 (#129525) 2024-10-30 20:59:56 +01:00
Marcel van der Veldt c958cce769 Bump Music Assistant Client library to 1.0.5 (#129518) 2024-10-30 19:34:43 +01:00
epenet 602ec54579 Set config_entry explicitly to None in relevant components (#129427)
Set config_entry explicitly to None in components
2024-10-30 19:32:10 +01:00
cryptk fa2bfc5d9d Bump uiprotect to 6.3.2 (#129513) 2024-10-30 18:43:34 +01:00
Aurore 94f906b34c Fix timeout issue on Roomba integration when adding a new device (#129230)
* Update const.py

DEFAULT_DELAY = 1 to DEFAULT_DELAY = 100 to fix timeout when adding a new device

* Update config_flow.py

continuous=False to continuous=True to fix timeout when adding a new device

* Update homeassistant/components/roomba/const.py

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

* Update test_config_flow.py

Change CONF_DELAY to match DEFAULT_DELAY (30 sec instead of 1)

* Update tests/components/roomba/test_config_flow.py

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

* Use constant for DEFAULT_DELAY in tests

---------

Co-authored-by: Jan Bouwhuis <jbouwh@users.noreply.github.com>
Co-authored-by: jbouwh <jan@jbsoft.nl>
2024-10-30 18:41:10 +01:00
Bram Kragten 60c93456c0 Merge branch 'dev' into rc 2024-10-30 18:33:24 +01:00
G Johansson a4f210379d Raise on non-string unique id for config entry (#125950)
* Raise on non-string unique id for config entry

* Add test update entry

* Fix breaking

* Add check get_entry_by_domain_and_unique_id

* Naming

* Add test

* Fix logic

* No unique id

* Fix tests

* Fixes

* Fix gardena

* Not related to this PR

* Update docstring and comment

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-10-30 18:09:50 +01:00
Bram Kragten 27e6205a37 Merge branch 'dev' into rc 2024-10-30 17:41:05 +01:00
G Johansson 3db6d82904 Add name to description placeholders automatically for reauth flows (#129232)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-10-30 17:38:59 +01:00
puddly b8ddfd642e Bump ZHA dependencies (#129510) 2024-10-30 17:38:24 +01:00
Bram Kragten c98acd42db Bump version to 2024.11.0b0 2024-10-30 17:34:45 +01:00
Paul Bottein 39f418f2d2 Update frontend to 20241030.0 (#129508) 2024-10-30 17:31:41 +01:00
Jan Bouwhuis 9fbd484dfe Add progress support to MQTT update platform (#129468)
* Add progress support to MQTT update platform and add validation on state updates

* Clean up cast to type class

* Add support for display_precision attribute
2024-10-30 17:22:55 +01:00
Jan Bouwhuis 1773f2aadc Allow MQTT device based auto discovery (#118757)
* Allow MQTT device based auto discovery

* Fix merge error

* Remove unused import

* Fix discovery device based topics

* Fix cannot delete twice

* Improve cleanup test

* Follow up comment

* Typo

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

* Explain more

* Use tuple

* Default a device payload to have priority over a platform based payload

* Add unique_id to sensor test data

* Set migration flag to mark a discovery topic for migration

* Correct type hint

* Make unique_id required for components in device based discovery payload

* Remove CONF_MIGRATE_DISCOVERY from platform schema

* Unload discovered MQTT item to allow migration

* Follow up comments from code review

* ruff

* Subscribe to platform discovery wildcards first

* Use normal dict

* Use dict to persist wildcard subscription order

* Remove missed unused parameter

* Add a comment to explain we use a dict  to preserve the subscription order

* Add wildcard subscription order test

* Remove discovery flag from test

* Improve discovery migration origin logging

* Assert initial  wildcard discovery topics subscription order and after reconnect

* Improve log messages

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-30 17:10:15 +01:00
Michael Hansen cb1b72d6ba Bump intents to 2024.10.30 (#129505) 2024-10-30 16:20:59 +01:00
Manu f5a2ec961d Remove unused snapshots from Habitica (#129499) 2024-10-30 15:44:21 +01:00
Krisjanis Lejejs bf40e77d65 Add Stun server with port 3478 (#129501) 2024-10-30 15:40:23 +01:00
Jozef Kruszynski 568bdef61f Add musicassistant integration (#128919)
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
2024-10-30 14:57:01 +01:00
Manu 2303521778 Use common translation strings for Habitica (#129498) 2024-10-30 14:56:47 +01:00
Josef Zweck 3bf2946d13 Change type of the config_entry in coordinator in tedee (#129502) 2024-10-30 14:53:11 +01:00
Josef Zweck 484e5cb3e8 Explicitly pass config_entry to coordinator in lamarzocco (#129434)
* Update __init__.py

* Update coordinator.py

* Update coordinator.py

* ruff

* Update coordinator.py

* move type to coordinator
2024-10-30 14:43:41 +01:00
Josef Zweck fbe8b6c34d Pass config_entry explicitly to coordinator in tedee (#129432)
* pass entry

* pass entry

* Update coordinator.py

* move type definition
2024-10-30 14:42:19 +01:00
Jan Bouwhuis 4e7397dc9d Test discovery subscriptions not done when discovery is disabled (#129458)
Test discovery subscriptions not performend when discovery is disabled
2024-10-30 14:38:44 +01:00
starkillerOG a6189106e1 Reolink add TCP push event connection as primary method (#129490) 2024-10-30 14:34:32 +01:00
Artur Pragacz ed6123a3e6 Add reconfigure step to Onkyo config flow (#129088) 2024-10-30 14:31:43 +01:00
Noah Husby 0cd5deaa3f Add audio output select to Cambridge Audio (#129366) 2024-10-30 14:28:01 +01:00
Allen Porter 6c047e2678 Refresh Nest WebRTC streams before expiration (#129478) 2024-10-30 14:25:43 +01:00
Martin Hjelmare 405a480cae Create repair issue for legacy webrtc provider (#129334)
* Add repair issue

* Add tests

* Add option to not use builtin go2rtc provider

* Add test

* Add domain to new providers

* Add learn more url

* Update placeholder

* Promote the builtin provider

* Refactor provider storage

* Move check for legacy provider conflict to refresh

* Test provider registration race

* Add test for registering the same legacy provider twice

* Test test_get_not_supported_legacy_provider

* Remove blank line between bullets

* Call it built-in

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

* Revert "Add option to not use builtin go2rtc provider"

This reverts commit 4e31bad6c0c23d5a1c0935c985351808a46163d6.

* Revert "Add test"

This reverts commit ddf85fd4db2c78b15c1cdc716804b965f3a1f4e3.

* Update issue description

* async_close_session is optional

* Clean up after rebase

* Add required domain property to provider tests

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-30 14:11:17 +01:00
Erik Montnemery b4e69bab71 Improve shutdown of esphome ffmpeg proxy (#129326)
* Improve shutdown of esphome ffmpeg proxy

* Add test
2024-10-30 13:46:05 +01:00
Erik Montnemery db81edfb2b Add config entry to go2rtc (#129436)
* Add config entry to go2rtc

* Address review comments

* Remove config entry if go2rtc is not configured

* Allow importing default_config

* Address review comment
2024-10-30 13:39:54 +01:00
Martin Hjelmare 24829bc44f Fix webrtc provider interface and tests (#129488)
* Fix webrtc provider tests

* Remove future code

* Add a test of the optional provider interface
2024-10-30 13:24:23 +01:00
starkillerOG c8594045df Bump reolink_aio to 0.10.1 (#129493) 2024-10-30 13:19:45 +01:00
YogevBokobza ea3f9b971f Bump aioswitcher to 4.4.0 (#129489) 2024-10-30 12:50:38 +01:00
Robert Resch 380974eed4 Remove hassio from ALLOWED_USED_COMPONENTS and move some functions to helper (#127228)
* Remove hassio from ALLOWED_USED_COMPONENTS

* Move HassioServiceInfo to helpers.service_info

* Deprecate moved functions

* Add note about deprecation

* Fix tests

* Implement suggestion

* Typo

* Update pyproject.toml

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-10-30 12:43:41 +01:00
Alistair Francis 8151403bf6 Bump automower-ble to 0.2.0 (#129473) 2024-10-30 12:31:11 +01:00
Christopher Fenner 16f5e76f00 Update PyViCare dependency to 2.35.0 (#129038) 2024-10-30 12:21:54 +01:00
J. Nick Koston b6b178cac0 Fix nexia emergency heat migration (#129365) 2024-10-30 12:20:19 +01:00
Robert Resch 0f020366e3 Bump go2rtc-client to 0.0.1b3 (#129486) 2024-10-30 12:13:03 +01:00
LG-ThinQ-Integration 27a19be369 Add translation_key in LG ThinQ (#129476)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
2024-10-30 11:28:28 +01:00
Blake Bryant 0c166eb307 Bump pydeako to 0.5.4 (#129475) 2024-10-30 11:25:11 +01:00
Erik Montnemery 79d73c28a7 Deduplicate wav creation in esphome ffmpeg_proxy tests (#129484) 2024-10-30 10:35:19 +01:00
LG-ThinQ-Integration 2aed01b530 Add entity_category to avoid header_toggle for switch (#129477)
add entity_category to avoid header_toggle

Co-authored-by: yunseon.park <yunseon.park@lge.com>
2024-10-30 10:34:04 +01:00
Erik Montnemery 3fb0d61271 Remove useless code from esphome ffmpeg_proxy tests (#129481) 2024-10-30 09:56:12 +01:00
Erik Montnemery 599acaf514 Improve demo integration's update entity (#129401)
* Improve demo integration's update entity

* Improve tests
2024-10-30 08:06:22 +01:00
TimL 5f4103a4a7 Allow smlight device to reboot before updating firmware data coordinator (#127442)
* Add delay before updating firmware coordinator

* fix update tests

* change sleep to 1s

* Timeout incase reboot fails

* update test

* test reboot timeout

* log hostname in warning
2024-10-30 08:02:30 +01:00
Kayden van Rijn c7c72231c7 Bump opower to 0.8.6 (#129454)
* Bump opower to 0.8.6

* Bump opower to 0.8.6
2024-10-29 22:44:06 -07:00
Manu 6887a4419e Add calendar platform to Habitica integration (#128248)
* Add calendar platform

* Add tests

* add missing reminders filter by date

* Add +1 day to todo end

* add 1 day to dailies, remove unused line of code

* Removing reminders calendar to a separate PR

* fix upcoming event for dailies

* util function for rrule string

* Add test for get_recurrence_rule

* use habitica daystart and account for isDue flag

* yesterdaily is still an active event

* Fix yesterdailies and add attribute

* Update snapshot

* Use iter, return attribute with None value

* various changes

* update snapshot

* fix merge error

* update snapshot

* change date range filtering for todos

* use datetimes instead of date in async_get_events

* Sort events

* Update snapshot

* add method for todos

* filter for upcoming events

* dailies

* refactor todos

* update dailies logic

* dedent loops
2024-10-29 20:53:49 -07:00
Erik Montnemery db5cb6233c Correct condition signalling non-live DB migration is in progress (#129464) 2024-10-29 12:26:52 -10:00
Robert Resch 963829712d Add CameraCapabilities (#128455) 2024-10-29 21:36:30 +01:00
Steven B. 46ceccfbb3 Use new try_connect_all discover command in tplink config flow (#128994)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-10-29 10:26:34 -10:00
J. Nick Koston aaf3039967 Bump DoorBirdPy to 3.0.7 (#129114) 2024-10-29 10:06:24 -10:00
Shay Levy 2509f18def Bump aioshelly to 12.0.1 (#129453) 2024-10-29 22:01:38 +02:00
Krisjanis Lejejs a1e2d79613 Add cloud ICE server registration (#128942)
* Add cloud ICE server registration

* Add ice_servers to prefs, fix registration flow

* Add support for list of ICE servers

* Add ICE server cleanup on cloud logout, create tests

* Fix RTCIceServer types

* Update homeassistant/components/cloud/client.py

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

* Improve tests based on PR reviews

* Improve tests

* Use set_cloud_prefs fixture

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Robert Resch <robert@resch.dev>
2024-10-29 20:35:52 +01:00
Andre Lengwenus 96ba5c3983 Remove LCN translation placeholder key (#129452) 2024-10-29 20:27:13 +01:00
ollo69 041282190a Allow set ScreenCap interval as option for AndroidTV (#124470)
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-29 20:24:20 +01:00
functionpointer 8cdd5de75c Change Tibber get_prices action to return datetimes as str (#123901) 2024-10-29 20:15:08 +01:00
Michael a95c232f11 Add addon support to Home Assistant Analytics Insights (#128806) 2024-10-29 20:13:56 +01:00
Andre Lengwenus c9aba288b4 Add switch entities for LCN key-locks and regulator-locks (#127731)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-29 20:08:30 +01:00
G Johansson 35a9d502af Use coordinator async_setup in dwd weather (#129448) 2024-10-29 20:07:37 +01:00
G Johansson 409c8783fe Use coordinator async_setup in iotty (#129449) 2024-10-29 20:07:13 +01:00
Keilin Bickar 3adc3d7732 Add sensors for energy trends for devices (#129439)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-29 20:02:08 +01:00
Steven B. ec19712388 Bump tplink python-kasa dependency to 0.7.6 (#129444) 2024-10-29 09:00:43 -10:00
Åke Strandberg 2c89e89c84 Improve mapping of myuplink entities (#129137) 2024-10-29 19:59:04 +01:00
Manu e602a464db Add tests for buttons in Habitica integration (#128194)
* Add tests for button platform

* update tests

* Add skill buttons

* Assert state, add fixtures/parametrization

* entity as list
2024-10-29 19:03:41 +01:00
Erik Montnemery ffc0651d89 Report update_percentage in zwave_js update entity (#129386) 2024-10-29 13:31:34 -04:00
Erik Montnemery 7162efd836 Remove duplicated entity_picture config from MQTT update entity (#129390) 2024-10-29 18:22:06 +01:00
epenet 8e7d782102 Move validation routine out of wallbox coordinator (#129415) 2024-10-29 18:13:11 +01:00
Marc Mueller dc2028f99c Fix devolo_home_network DataCoordinator arguments (#129441) 2024-10-29 18:06:42 +01:00
Adam Goode f12ba5f7a9 Unexport unavailable metrics in Prometheus (#125492) 2024-10-29 17:56:54 +01:00
Erik Montnemery 45fb21e32d Suppress update entity's update_percentage when update not in progress (#129397) 2024-10-29 17:56:09 +01:00
Erik Montnemery ecbb417736 Report update_percentage in esphome update entity (#129376) 2024-10-29 17:51:54 +01:00
Erik Montnemery 3a59a862d5 Report update_percentage in smlight update entity (#129383) 2024-10-29 17:50:43 +01:00
Erik Montnemery e34fab0045 Report update_percentage in tessie update entity (#129385) 2024-10-29 17:48:29 +01:00
Erik Montnemery 7254ebe0e3 Report update_percentage in teslemetry update entity (#129384) 2024-10-29 17:48:03 +01:00
Keilin Bickar b43bc3f32d Add Sense Devices for entities (#129182) 2024-10-29 17:44:19 +01:00
Erik Montnemery ca3d13b5cc Sort some code in core_config (#129388) 2024-10-29 17:26:08 +01:00
Robert Resch c8818bcce3 Bump go2rtc to 1.9.6 (#129430) 2024-10-29 16:46:58 +01:00
Guido Schmitz b234b5937a Disable pylint for DevoloScannerEntity (#129429) 2024-10-29 16:40:38 +01:00
Krisjanis Lejejs 1bdef0f2f7 Bump hass-nabucasa to 0.83.0 (#129422) 2024-10-29 16:34:02 +01:00
Erik Montnemery 56fb61bd6f Refactor esphome ffmpeg proxy (#129330) 2024-10-29 16:26:32 +01:00
epenet 2c7d0b8909 Initialise coordinator with config_entry in components (part 1) (#128080) 2024-10-29 16:18:04 +01:00
Marcel van der Veldt cbb8d76da7 Add support for vacuum cleaners to the Matter integration (#129420) 2024-10-29 16:17:40 +01:00
Erik Montnemery cce925c06c Fix bad falsy-check in homeassistant.set_location service (#129389) 2024-10-29 16:11:48 +01:00
Marco 505a4bfc34 Add Smarty versions to device (#129418) 2024-10-29 16:06:15 +01:00
Robert Resch 58e151966c Fix go2rtc no audio issue (#129428) 2024-10-29 16:01:51 +01:00
Michael 8a6c9b7afc Remove Mobile App config entries, when the related user gets removed (#129268)
* remove config entries, when related user gets removed

* add test
2024-10-29 15:53:00 +01:00
Jirka e72e2071b0 Fix typo in nest string (#129423)
Update strings.json

Fixed typos
2024-10-29 15:38:55 +01:00
epenet 5d3af27928 Set config_entry explicitly in history stats coordinator (#129417)
Set config_entry explicitely in history stats coordinator
2024-10-29 15:32:56 +01:00
Petar Petrov 5dc0bedbc4 Allow fetching HA url to display it in the network settings (#128432)
* Allow fetching HA url to display it in the network settings

* add tests

* use a constant for the url types

* just return all url types

* Prefer callback without await

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-10-29 15:28:54 +01:00
epenet 8f7ae2665c Set config_entry explicitly in switcher kis coordinator (#129419) 2024-10-29 16:14:36 +02:00
epenet 10fdf819d3 Set config_entry explicitely in scrape coordinator (#129416) 2024-10-29 14:54:24 +01:00
LG-ThinQ-Integration 02928601ef Add min, max for WATER_HEATER device (#129414)
Co-authored-by: jangwon.lee <jangwon.lee@lge.com>
2024-10-29 14:52:26 +01:00
LG-ThinQ-Integration c227f6dc2c Add timer sensor entity which has rw hour and read-only minute (#129413)
Co-authored-by: jangwon.lee <jangwon.lee@lge.com>
2024-10-29 14:44:06 +01:00
Mike Degatano 673f0224c9 Continue migration of methods from handler to aiohasupervisor (#129183) 2024-10-29 14:33:21 +01:00
Manu 79c602f59c Fix available conditions for chilling frost and stealth in Habitica (#129234)
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-29 14:24:23 +01:00
Raj Laud 07c070e253 Refactor squeezebox integration media_player to use coordinator (#127695) 2024-10-29 14:21:28 +01:00
Vendetta01 9bda3bd477 Fix bosch shc multi controller support (#127844)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-29 14:19:33 +01:00
Marc Hörsken 2c9ad9562e Fix visualization by inverting open/closed state of patio awnings (#128079) 2024-10-29 14:09:49 +01:00
Manu c264ee22e7 Add tests for switch platform of Habitica integration (#128204) 2024-10-29 14:08:05 +01:00
J. Diego Rodríguez Royo f194a689cc Fetch power off state for Home Connect appliances' power switch (#129289) 2024-10-29 13:56:45 +01:00
David Bonnes a36b350954 Fix evohome HVAC modes for VisionPro Wifi systems (#129161)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-29 13:37:35 +01:00
Josef Zweck db4278fb9d Cleanup select mappings in lamarzocco (#129407) 2024-10-29 13:32:14 +01:00
David Bonnes 39ba4cff2f Refactor evohome tests as per best practice (#129229)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-29 13:29:10 +01:00
Christopher Fenner d68da74790 Add number entities to set target temp for cooling programs in ViCare (#127267)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-29 13:28:12 +01:00
Tomer Shemesh 5fc45cd736 Add support for Lutron HWQS Proc discovery (#129274) 2024-10-29 13:27:44 +01:00
Guido Schmitz 5ae2f3d081 Add own coordinator to devolo_home_network (#128159) 2024-10-29 13:23:28 +01:00
Josef Zweck 478bf643bf Add smart standby functionality to lamarzocco (#129333)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-29 13:22:37 +01:00
Daniel Hjelseth Høyer 7929895b11 Change Tibber request spread (#129276) 2024-10-29 13:12:07 +01:00
Erik Montnemery da11a72b4c Create repair asking user to remove duplicate config entries (#127948)
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-29 13:10:56 +01:00
Mike Degatano 1649368cee Bump aiohasupervisor to 0.2.0 (#129348) 2024-10-29 13:07:59 +01:00
dontinelli a528d62c16 Add test for extended data in setup for solarlog (#129345) 2024-10-29 13:07:48 +01:00
Guido Schmitz bd13dbdad0 Use new generic notation in devolo_home_network (#129080) 2024-10-29 13:07:13 +01:00
Allen Porter 8e7ffd9e16 Update Nest configuration flow to handle upcoming changes to Pub/Sub provisioning (#128909)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-29 12:58:36 +01:00
Manu f0bff09b5e Bump habitipy to 0.3.3 (#129322) 2024-10-29 12:48:20 +01:00
J. Diego Rodríguez Royo 0e959b3019 Added deprecation to binary door sensor at Home Connect (#129245)
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-29 12:46:39 +01:00
Thomas55555 983cd9c3fc Add and remove entities during runtime in Husqvarna Automower (#127878) 2024-10-29 12:46:04 +01:00
Erik Montnemery 2236ca3e12 Fix typo in cv.url_no_path (#129402) 2024-10-29 12:06:59 +01:00
Robert Resch f3afa6a7d9 Fix hassfest docker image by pinning Python 3.12 (#129403) 2024-10-29 11:57:20 +01:00
Brett Adams ce7e2e3243 Clean up SensorRestore in Tesla Fleet (#129116)
* Remove, fix, and test restore

* slightly better comment

* use restore instead

* parametrize test

* Apply suggestions from code review

* revert change to Teslemetry

* revert change to Teslemetry

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-10-29 11:41:35 +01:00
Robert Resch 13416825b1 Go2rtc server start is waiting until we got the api listen stdout line (#129391) 2024-10-29 11:28:40 +01:00
J. Nick Koston 6c664e7ba9 Bump protobuf to 5.28.3 (#129370) 2024-10-29 11:22:31 +01:00
LG-ThinQ-Integration 34359617b5 Bump thinqconnect to 0.9.9 (#129394) 2024-10-29 11:16:19 +01:00
Erik Montnemery 9e2696b9bc Report update_percentage in matter update entity (#129380) 2024-10-29 10:57:52 +01:00
Paul Bottein bf840e8bfa Use device name for matter entities (#127798) 2024-10-29 10:54:25 +01:00
Robert Resch 1f03c140f5 Bump go2rtc-client to 0.0.1b2 (#129395) 2024-10-29 10:45:00 +01:00
Marc Mueller 2de161ce0e Fix mariadb recorder tests for Python 3.13 (#129303) 2024-10-29 09:17:47 +01:00
Marc Mueller 1171106afb Run postgres job on ubuntu 24.04 [ci] (#129381) 2024-10-29 09:15:04 +01:00
Robert Resch f57ae73071 Bump webrtc-models to 0.1.0 (#129373) 2024-10-29 08:33:54 +01:00
Robert Resch 59872b5698 Enable strict typing for go2rtc (#129374) 2024-10-29 08:25:49 +01:00
Robert Resch 7cd8ea00d1 Bump uv to 0.4.28 (#129372) 2024-10-28 21:20:59 -10:00
Robert Resch 4b2f38926a Bump go2rtc binary to 1.9.5 (#129371) 2024-10-29 08:01:59 +01:00
Allen Porter 537c95cf29 Update nest to use the async WebRTC APIs (#129369)
* Update nest to use the new `async_handle_webrtc_offer` APIs.

* Close sessions when sessions end

* Switch to the correct close API
2024-10-29 07:18:59 +01:00
epenet 81a5722708 Fix flaky DHCP tests in CI (#129327) 2024-10-28 13:41:50 -10:00
Jan Bouwhuis c150b913ac Use URL validation schema for mqtt update entity_picture and remove custom implementation (#129360) 2024-10-28 23:36:17 +01:00
J. Nick Koston 3e4b67db6c Bump yarl to 1.17.0 (#129358) 2024-10-28 23:11:14 +01:00
G Johansson d727f8ff50 Clarify event tracking in docstrings for track_state_change/report (#129338)
* Clarify event tracking in docstrings for track_state_change/report

* Fixes

* Update homeassistant/helpers/event.py

* Update homeassistant/helpers/event.py

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

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-10-28 23:05:06 +01:00
G Johansson 9546bf1dee Use shorthand attribute for native value in statistics (#129355) 2024-10-28 22:43:09 +01:00
Michael Hansen dd9ce34d18 Allow a fixed number of ffmpeg proxy conversions per device (#129246)
Allow a fixed number of conversions per device
2024-10-28 13:26:43 -07:00
G Johansson 73f2d972e4 Use shorthand attribute for available in statistics (#129354) 2024-10-28 21:01:34 +01:00
G Johansson 7d699c6c35 Fix calculation of attributes in statistics (#128475)
* Fix calculation of attributes in statistics

* Cleanup

* Mods

* Fix device class

* Typing

* Mod uom calc

* Fix UoM

* Fix docstrings

* state class docstring
2024-10-28 19:45:47 +01:00
dontinelli 21f23f67f4 Fix spelling mistake in notify (#129349) 2024-10-28 18:39:36 +01:00
Joost Lekkerkerker 8874ba2779 Add LG ThinQ to LG brand (#129346) 2024-10-28 18:24:24 +01:00
LG-ThinQ-Integration 420538e6e7 Add LG ThinQ integration (#129299)
Co-authored-by: jangwon.lee <jangwon.lee@lge.com>
2024-10-28 17:22:24 +01:00
dotvav 8eb68b54d9 Palazzetti integration (#128259)
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-28 17:19:05 +01:00
Robert Resch 80202f33cb Fix go2rtc tests (#129342) 2024-10-28 17:12:28 +01:00
YogevBokobza c24579bfb2 Add switcher s12 support (#127277)
Co-authored-by: Joostlek <joostlek@outlook.com>
Co-authored-by: Shay Levy <levyshay1@gmail.com>
2024-10-28 16:57:24 +01:00
Noah Husby 21256c4529 Remove media player shuffle check from Cambridge Audio (#129235)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-28 16:57:09 +01:00
J. Diego Rodríguez Royo 668626b920 Add ServiceValidationError to Home Connect (#129309)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-28 16:48:56 +01:00
Wendelin cbfa3bb56d Hassio logs boots (#129151)
* Add hassio logs/boots proxy settings

* Add hassio http tests
2024-10-28 16:41:14 +01:00
Robert Resch 536fcf02d7 Fix CI by running gen_requirements_all.py (#129339) 2024-10-28 16:39:49 +01:00
Erik Montnemery a8ac3acbbe Bump pychromecast to 14.0.5 (#129251) 2024-10-28 16:07:23 +01:00
TheJulianJES 7980155375 Bump ZHA to 0.0.36 (#129247) 2024-10-28 16:07:04 +01:00
Robert Resch aa855e31c8 Convert async_get_webrtc_client_configuration to a callback (#129329) 2024-10-28 15:47:22 +01:00
Robert Resch 675ee8e813 Add async webrtc offer support (#127981)
* Add async webrtc offer support

* Create dataclass for messages

* Send session ID over websocket

* Fixes

* Rename

* Implement some review findings

* Add WebRTCError and small renames

* Use dedicated function instead of inspec

* Update go2rtc-client to 0.0.1b1

* Improve checking for sync offer

* Revert change as not needed anymore

* Typo

* Fix tests

* Add missing go2rtc tests

* Move webrtc offer tests to test_webrtc file

* Add ws camera/webrtc/candidate tests

* Add missing tests

* Implement suggestions

* Implement review changes

* rename

* Revert test to use ws endpoints

* Change doc string

* Don't import from submodule

* Get type form class name

* Update homeassistant/components/camera/__init__.py

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

* Adopt tests

* Apply suggestions from code review

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

* Fix tests

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Erik <erik@montnemery.com>
2024-10-28 15:46:15 +01:00
unfug-at-github 50ccce7387 React to state report events to increase sample size of statistics (#129211)
* react to state reported events to increase sample size

* added test case for timinig and minor corrections
2024-10-28 14:41:48 +01:00
Markus Jacobsen 40b561ea69 Add shuffle media controls to Bang & Olufsen (#129325) 2024-10-28 13:39:49 +01:00
G Johansson a0f73bd30f Add reconfigure flow to Sensibo (#129280) 2024-10-28 12:29:06 +01:00
Tsvi Mostovicz 1b7fcce42d Assert keys exist in Jewish calendar tests (#129295) 2024-10-28 12:23:45 +01:00
J. Nick Koston 4749af6e90 Convert WebSocket messages to bytes before passing them to send_message (#129300) 2024-10-28 12:21:12 +01:00
Maikel Punie f7ad40263b Bump velbusaio to 2024.10.0 (#129305) 2024-10-28 12:19:08 +01:00
epenet e5b25bfa58 Use reauth_confirm in ovo_energy (#129306) 2024-10-28 11:52:38 +01:00
epenet 1d23adcda3 Use start_reauth_flow in system_bridge tests (#129318) 2024-10-28 11:52:13 +01:00
epenet 0216d36ab7 Use start_reauth_flow in permobil tests (#129314) 2024-10-28 11:51:16 +01:00
epenet 2bec20ad76 Ensure config entry is added to hass in reauth/reconfigure tests (#129315) 2024-10-28 11:03:42 +01:00
G Johansson 93c1245b0f Use start_reauth_flow in apple_tv test (#129313)
* Use start_reauth_flow in apple_tv test

* Fix
2024-10-28 10:42:19 +01:00
epenet 72504d7619 Use async_start_reauth helper in broadlink (#129308) 2024-10-28 09:00:11 +01:00
G Johansson 320aa34d39 Use async_start_reauth in xiaomi_miio (#129282)
* Use async_start_reauth in xiaomi_miio

* Apply suggestions from code review

Co-authored-by: Teemu R. <tpr@iki.fi>

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
Co-authored-by: Teemu R. <tpr@iki.fi>
2024-10-28 08:37:38 +01:00
G Johansson 87f2a4242e Use async_start_reauth in blink (#129281) 2024-10-28 07:57:18 +01:00
Joel Hawksley 9bf0cbd659 Omit declined Google Calendar events (#128900)
* Omit decline Google Calendar events

* move comment to top of function and update

* Apply suggestions from code review

* import ResponseStatus
2024-10-27 21:54:09 -07:00
Franck Nijhof b1470fd9b8 Merge branch 'master' into dev 2024-10-28 02:46:15 +01:00
Nicolás Alonso 08016dc3b6 Lazy discover for dmaker.fan.1c (#129297) 2024-10-28 02:09:08 +01:00
G Johansson 7a448f5528 Add battery binary sensor to Yale Smart Alarm (#129277)
* Add battery binary sensor to Yale Smart Alarm

* Fix docstrings
2024-10-27 20:57:10 +01:00
Michael 4ac23bf14c Add diagnostics platform to PEGELONLINE (#129279)
add diagnostics platform
2024-10-27 20:36:56 +01:00
Michael bc708dee30 Mark PEGELONLINE entries as service (#129278)
set entry_type service
2024-10-27 20:35:19 +01:00
Erik Montnemery 2888e5748e Fix ESPHome media proxy exit criteria (#129267) 2024-10-27 12:39:49 -05:00
Simone Chemelli 88f0a33e69 Update uptime deviation interval for Vodafone Station (#129257)
update uptime deviation interval
2024-10-27 15:40:58 +01:00
Michael 3165f92b6b Fix conntected_to attribute of device tracker entities in a AVM Fritz mesh setup (#129259)
ignore orphan node links
2024-10-27 14:42:43 +01:00
Marc Mueller 3bd0fca633 Properly validate License-Expression data for licenses check (#129216) 2024-10-27 10:43:21 +01:00
tleydxdy cdff10d281 Add new ZHA Inovelli blue switch strings (#127124)
ref: https://github.com/zigpy/zha/pull/203
2024-10-27 05:33:06 +01:00
Álvaro Fernández Rojas e425741c34 Update aioairzone-cloud to v0.6.10 (#129227) 2024-10-26 13:19:34 -10:00
Marc Mueller 20a367b243 Fix zha tests for Python 3.13 (#129241) 2024-10-27 00:18:21 +02:00
Manu fdded9e7ee Add tests for todo platform of Habitica integration (#128199)
* Add tests for todo platform

* refactor mock_called_with

* update tests
2024-10-26 10:48:07 -07:00
Galorhallen 7d29bff136 Update govee-local-api to 1.5.3 (#129226) 2024-10-26 18:28:22 +02:00
G Johansson 0abfbeed3c Fix flaky gardena_ble test (#129225) 2024-10-26 17:57:00 +02:00
Franck Nijhof 35b7c3038a Revert "Fix unused snapshots not triggering failure in CI" (#129223)
Revert "Fix unused snapshots not triggering failure in CI (#128162)"

This reverts commit e888a95bd1.
2024-10-26 16:12:47 +02:00
boergegrunicke 46dd96a4b7 Add dishwasher salt and rinse aid nearly empty sensors (#127762)
Co-authored-by: Robert Contreras <beastie29a@users.noreply.github.com>
2024-10-26 16:09:11 +02:00
dontinelli 788232ca35 Add and remove plants (i.e. devices) dynamically in fyta (#129221) 2024-10-26 15:35:43 +02:00
J. Nick Koston 3b458738e0 Fix setting brightness to 0 in HomeKit when the On characteristic is not sent (#129201) 2024-10-26 15:29:15 +02:00
David Bonnes 2c8fc67ab1 Fix evohome failing to start with 'NoneType' object has no attribute 'get' (#129222) 2024-10-26 15:24:41 +02:00
David Bonnes 9b3ed3ed72 Add tests of evohome integration-specific services (#129206)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-26 14:44:46 +02:00
Joost Lekkerkerker c59197e87a Add more spotify sensors (#129215) 2024-10-26 14:43:32 +02:00
Álvaro Fernández Rojas 03e3c88d8b Update aioairzone-cloud to v0.6.9 (#129217) 2024-10-26 14:37:58 +02:00
Joost Lekkerkerker 39693786ef Remove remnants of removed list_events action (#129210) 2024-10-26 14:37:05 +02:00
dontinelli 357c324df1 Add logger for fyta library in manifest.json (#129218) 2024-10-26 14:36:07 +02:00
dontinelli 650482208c Bump fyta_cli to 0.6.10 (#129220) 2024-10-26 14:34:45 +02:00
J. Diego Rodríguez Royo 2acad4a78c Home connect number platform with temperature set points entities (#126145) 2024-10-26 14:04:52 +02:00
jb101010-2 65ee4e1916 Bump pysuezV2 to 0.2.2 (#129205)
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-26 11:44:02 +02:00
J. Diego Rodríguez Royo 275bbc81f0 Add Time platform with alarm clock to Home Connect (#126155)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-26 11:42:51 +02:00
Marc Mueller beafcf74ab Update zeroconf to 0.136.0 (#129204) 2024-10-26 11:35:00 +02:00
Marc Mueller e47909bb3e Update gardena-bluetooth to 1.4.4 (#129202) 2024-10-26 11:34:32 +02:00
David Bonnes 0b3b9c2257 Make minor fixes / doc tweaks to evohome's WaterHeater tests (#129138) 2024-10-26 10:52:32 +02:00
Marc Mueller 8fb7a7e4cd Refactor licenses check (#129194) 2024-10-26 10:30:10 +02:00
unfug-at-github c5ed148c52 Fix race condition in statistics that created spikes (#129066)
* fixed race condition and added test case for updates before db load

* removed duplicated code

* improved comments, removed superfluous errors / assertions

* allow both possible outcomes of race condition

* use approx for float comparison

* Update tests/components/statistics/test_sensor.py

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

* force new state before database load in race condition test

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-26 09:23:47 +02:00
IceBotYT e774c710a8 Bump lacrosse_view to 1.0.3 (#129174)
Add Pydantic v2 support to LaCrosse View
2024-10-26 08:59:08 +02:00
Jan Bouwhuis d237180a98 Allow re-discovery of mqtt integration config payloads (#127362) 2024-10-26 07:21:52 +02:00
Erik Montnemery d8b618f7c3 Remove support for live recorder data migration of context ids (#125309) 2024-10-26 07:19:03 +02:00
epenet e888a95bd1 Fix unused snapshots not triggering failure in CI (#128162) 2024-10-26 07:15:51 +02:00
Joost Lekkerkerker 36c2404a46 Add base entity to Spotify (#128847)
Co-authored-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>
2024-10-26 07:09:18 +02:00
J. Nick Koston ba673beb82 Bump anyio to 4.6.2.post1 (#129199) 2024-10-26 07:06:27 +02:00
Erik Montnemery 4b56701152 Move core config class to core_config.py (#129163) 2024-10-26 07:00:31 +02:00
J. Nick Koston 59227116f3 Ensure go2rtc server starts using posix_spawn/vfork (#129196) 2024-10-26 06:51:29 +02:00
J. Nick Koston 9b0975b2ac Fix rainmachine update entities missing display_precision (#129195) 2024-10-26 06:29:39 +02:00
epenet 3a39a5caa3 Move brunt coordinator to separate module (#129090) 2024-10-26 02:30:59 +02:00
epenet 93e270f379 Use runtime_data in aranet (#129155) 2024-10-26 02:30:48 +02:00
epenet 98c81fa2af Move airthings coordinator to separate module (#129158) 2024-10-26 02:29:57 +02:00
Joost Lekkerkerker 1bb32a05a9 Migrate Smarty to has entity name (#129145) 2024-10-26 02:28:26 +02:00
Sid 5dd4b77270 Add JSON schema for manifest.json (#128560) 2024-10-26 02:10:58 +02:00
Andre Lengwenus 737d1aac7c Bump lcn-frontend to 0.2.0 (#129061) 2024-10-26 01:57:56 +02:00
Maciej Bieniek 886feae4ca Add support for Xiaomi Miio Standing Fan 2 (dmaker.fan.p18) (#129160) 2024-10-26 01:52:18 +02:00
Marc Mueller 1dfe26f14f Update apple_weatherkit to 1.1.3 (#129193) 2024-10-26 01:51:28 +02:00
Marc Mueller d66fcd23df Update radios to 0.3.2 and pycountry to 24.6.1 (#129186) 2024-10-26 01:49:26 +02:00
Marc Mueller bdfb47e999 Fix AsyncMock imports (#129192) 2024-10-26 01:47:27 +02:00
Paulus Schoutsen 10300cc478 Create a script service schema based on fields (#128622) 2024-10-26 01:05:00 +02:00
Marc Mueller ababa639b3 Fix cambridge_audio RuntimeWarning during tests (#129191) 2024-10-26 01:03:52 +02:00
Bouwe Westerdijk 9f6569d658 Bump plugwise to v1.4.4 (#129170) 2024-10-25 23:55:28 +02:00
J. Nick Koston 24c22ebdc7 Fix powerview entity unique id migration when the config entry unique id is missing (#129188)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-25 11:41:07 -10:00
Markus Jacobsen 6c365fffde Add media seek for sources other than Deezer for Bang & Olufsen (#128661)
* Add seeking for sources other than Deezer

* Add is_seekable attribute to fallback sources and BangOlufsenSource
Add testing

* Update comment

* Use support flags instead of raising errors when seeking on incompatible source
2024-10-25 23:34:39 +02:00
Marc Mueller dbb80dd6c0 Update krakenex to 2.2.2 (#129185) 2024-10-25 22:38:02 +02:00
Artur Pragacz 624834de9c Fix service target devices by label (#127229)
* Fix service target devices by label

* More explicit test
2024-10-25 21:30:04 +02:00
Franck Nijhof d31995f878 2024.10.4 (#129181) 2024-10-25 21:27:01 +02:00
Marc Mueller 017b1cae26 Update aiooui to 0.1.7 (#129179) 2024-10-25 21:24:43 +02:00
Franck Nijhof c09f15b0e9 Bump version to 2024.10.4 2024-10-25 20:49:36 +02:00
Keilin Bickar 68284bed74 Add coordinators to Sense (#129171) 2024-10-25 20:45:55 +02:00
Joost Lekkerkerker 9a44d668d6 Bump nyt_games to 0.4.4 (#129152) 2024-10-25 20:43:16 +02:00
Joost Lekkerkerker 67e0197a7a Fix NYT Games connection max streak (#129149) 2024-10-25 20:43:09 +02:00
Guido Schmitz a5a8cfa17d Fix adding multiple devices simultaneously to devolo Home Network's device tracker (#129082) 2024-10-25 20:43:02 +02:00
tronikos 60c3e701e9 Partially revert "LLM Tool parameters check (#123621)" (#129064) 2024-10-25 20:42:55 +02:00
Bram Kragten b9b129dcf5 Update frontend to 20241002.4 (#129049) 2024-10-25 20:42:48 +02:00
Daniel Albers d882ab236a Remove DHCP match from awair (#129047)
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-25 20:42:40 +02:00
Joost Lekkerkerker 140cc0e486 Bump yt-dlp to 2024.10.22 (#129034) 2024-10-25 20:42:17 +02:00
Guido Schmitz 6ac7c0f893 Fix devolo_home_network devices not reporting a MAC address (#129021) 2024-10-25 20:42:11 +02:00
J. Nick Koston 096d50617f Fix cancellation leaking upward from the timeout util (#129003) 2024-10-25 20:42:04 +02:00
Simone Chemelli 9dd8c0cc4f Fix uptime floating values for Vodafone Station (#128974) 2024-10-25 20:41:57 +02:00
Maikel Punie de0fab86ec Bump pyduotecno to 2024.10.1 (#128968) 2024-10-25 20:39:38 +02:00
Noah Husby bb36dd3893 Use translated exceptions for Cambridge Audio (#129177) 2024-10-25 20:30:49 +02:00
Simone Chemelli ada837ee95 Add diagnostics to Vodafone Station (#128923)
* Add diagnostics to Vodafone Station

* cleanup and exclude props based on date
2024-10-25 20:22:47 +02:00
Daniel Hjelseth Høyer 67e73173f6 Bump pyTibber to 0.30.3 (#128860) 2024-10-25 20:22:40 +02:00
Jan Bouwhuis 4b63829eef Allow to set entity picture on mqtt entity platforms (#128404) 2024-10-25 20:16:11 +02:00
Simone Chemelli 029411d3fa Add diagnostics to Comelit SimpleHome (#128794)
* Add diagnostics to Comelit SimpleHome

* add test

* add missing tests

* introduce SnapshotAssertion

* cleanup

* exclude date based props
2024-10-25 20:12:54 +02:00
Steven B. 6ba033f934 Bump ring-doorbell library to 0.9.8 (#128662) 2024-10-25 20:12:48 +02:00
Simon Lamon 3734fa948f LinkPlay multiroom support (#127862) 2024-10-25 20:12:42 +02:00
Steven B. 336742e335 Bump ring-doorbell to 0.9.7 (#127554) 2024-10-25 20:12:41 +02:00
Markus Jacobsen 66ca424d3a Add repeat media controls to Bang & Olufsen (#128170)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-25 20:10:08 +02:00
Heiko Carrasco 2da0a91a36 Add lock to switchbot_cloud (#115128)
Co-authored-by: Ravaka Razafimanantsoa <3774520+SeraphicRav@users.noreply.github.com>
Co-authored-by: Robert Resch <robert@resch.dev>
2024-10-25 20:09:14 +02:00
J. Diego Rodríguez Royo fee1bde231 Fix program switches unique ID at Home Connect (#128397) 2024-10-25 20:05:29 +02:00
mkmer 4a94430bf0 Handle temprorary hold in Honeywell (#128460) 2024-10-25 20:05:14 +02:00
David Bonnes cc337f7b1e Fix evohome regression preventing helpful messages when setup fails (#126441)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-10-25 20:05:05 +02:00
J. Diego Rodríguez Royo d8a06777fe Fix coffee maker device type name at applicances with programs list at Home Connect (#128538) 2024-10-25 20:04:53 +02:00
Marc Mueller 9207eedbfb Update heatmiserV3 to 2.0.3 (#129175) 2024-10-25 20:04:37 +02:00
bru73f0rc3 c97b832648 Add more Vesync IDs for the Vital200S (#127616) 2024-10-25 18:58:54 +02:00
alorente 4ef629f79d Remove check for obsolete "rain_product_available" in meteo_france (#128533)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-25 18:58:34 +02:00
Michael Hansen 0b4e3c3db5 Remove category from Assist satellite entities (#129172) 2024-10-25 18:43:42 +02:00
Noah Husby f12cc523b4 Enforce strict typing for Cambridge Audio (#129004) 2024-10-25 18:41:33 +02:00
Marc Mueller 5c3c9d2ed1 Update goslide-api to 0.7.0 (#129168) 2024-10-25 18:33:37 +02:00
Russell Cloran 3ac3673326 Improve prometheus metric name sanitization (#126967) 2024-10-25 18:33:16 +02:00
cdheiser 1a3940575e Use TAP to activate Lutron scenes (#127899) 2024-10-25 18:30:19 +02:00
Noah Husby 16c8b1efab Add all models to diagnostics for Cambridge Audio (#129157) 2024-10-25 18:20:54 +02:00
Marc Hörsken 0e789be09f Add light support to WMS WebControl pro (#128308)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-25 18:20:40 +02:00
J. Diego Rodríguez Royo a948c7d69d Door entity as enum sensor at Home Connect (#126158) 2024-10-25 18:18:21 +02:00
Marc Mueller d8ec0103a9 Update zeversolar to 0.3.2 (#129167) 2024-10-25 18:14:04 +02:00
Isaac 50161670ce Add "Albums" sensor to Lidarr (#125631)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-25 18:13:03 +02:00
Noah Husby c1f612dce1 Bump aiostreammagic to 2.8.4 (#129166) 2024-10-25 18:10:38 +02:00
J. Diego Rodríguez Royo 6fb74482d7 Add Diegorro98 as Home Connect code owner (#129169) 2024-10-25 18:06:22 +02:00
dontinelli 4b680ffa5f Dynamic add/remove devices for solarlog (#128668)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-25 18:02:14 +02:00
Marc Mueller c71c8d56ce Update pyxeoma to 1.4.2 (#129164) 2024-10-25 18:01:21 +02:00
IceBotYT 295ae7b4bc Add support for Mighty Mule MMS100 to Nice G.O. (#127765) 2024-10-25 17:49:32 +02:00
Marc Mueller 839c884cef Update aioopenexchangerates to 0.6.8 (#129162) 2024-10-25 17:40:02 +02:00
Jeef 13ffe7acfb Add Intellifire cloud/local connectivity sensors (#127122) 2024-10-25 17:23:51 +02:00
Manu 39a0c0d96e Add List access sensor to Bring integration (#126844) 2024-10-25 17:20:31 +02:00
Keilin Bickar a95a542148 Update sense-energy to 0.13.2 (#128670) 2024-10-25 16:59:39 +02:00
Alistair Francis b3cb2ac3ee Add husqvarna automower ble integration (#108326)
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-25 16:54:02 +02:00
Andre Lengwenus 759fe54132 Fix transition config storage in LCN light and scene platform (#127847) 2024-10-25 16:25:41 +02:00
Noah Husby 519a888e82 Bump aiostreammagic to 2.8.3 (#129113) 2024-10-25 16:21:08 +02:00
Erik Montnemery 4f1e4e7471 Include go2rtc in default_config (#129144)
* Include go2rtc in default_config

* Fail if binary not found in docker environment
2024-10-25 16:10:14 +02:00
epenet 7b8a32f630 Cleanup hass.data default in airtouch5 (#129156) 2024-10-25 15:37:07 +02:00
ashionky 92d91a65bb Add refoss em16 device model (#126798) 2024-10-25 15:22:24 +02:00
rappenze dab5289177 Add opening closing state to fibaro cover (#126958) 2024-10-25 15:10:20 +02:00
J. Diego Rodríguez Royo a77cb1e579 Home connect light generalization and RGB support (#126144) 2024-10-25 15:08:50 +02:00
Joost Lekkerkerker 01bdda0ae6 Bump nyt_games to 0.4.4 (#129152) 2024-10-25 14:46:43 +02:00
Joost Lekkerkerker fbe35e6e6b Fix NYT Games connection max streak (#129149) 2024-10-25 14:19:46 +02:00
Alexandre CUER a3cd74e30b Bump pymoncms library to version 0.1.1 (#129135) 2024-10-25 14:15:35 +02:00
YogevBokobza dbd4781de1 Bump aioswitcher to 4.2.0 (#129118)
* bump aioswitcher to 4.2.0

* Update cover.py

* switcher fix based on requested changes
2024-10-25 14:41:49 +03:00
Anton Tolchanov 6d48316436 Avoid creating Prometheus metrics for non-numeric states (#127262) 2024-10-25 13:31:30 +02:00
David Bonnes cca6965cd1 Fix evohome regression preventing helpful messages when setup fails (#126441)
Co-authored-by: Robert Resch <robert@resch.dev>
2024-10-25 13:23:17 +02:00
Simone Chemelli dd63ed7e69 Vodafone Station typing (#129143) 2024-10-25 12:57:52 +02:00
Joost Lekkerkerker 61e2283146 Add base class to Smarty (#129112) 2024-10-25 12:46:46 +02:00
Joost Lekkerkerker 97eb768748 Add entity descriptions to Smarty sensor (#129111) 2024-10-25 12:46:05 +02:00
Marc Mueller be8b5a8aeb Add option to extract licenses [ci] (#129095) 2024-10-25 12:41:05 +02:00
Erik Montnemery 99ed39b26c Fix go2rtc config schema (#129141) 2024-10-25 12:32:43 +02:00
G Johansson 48a0eb90a7 Migrate config entry in anova to remove devices from entry data (#128934) 2024-10-25 12:03:39 +02:00
Jan-Philipp Benecke 3c342077d6 Remove deprecated retries and lazy_error_count yaml option (#128932) 2024-10-25 12:02:47 +02:00
Claudio Ruggeri - CR-Tech f1bef1e7e6 Remove string literals from modbus component tests (#128899) 2024-10-25 12:01:42 +02:00
Brett Adams da9749ecce Add data streaming to Teslemetry (#127559) 2024-10-25 11:50:37 +02:00
Christopher Fenner fa7be597d2 Add energy consumption sensors for cooling in ViCare integration (#127274) 2024-10-25 11:40:25 +02:00
Jan-Philipp Benecke 53da418d68 Use NumberSelector in p1_monitor config flow (#128939) 2024-10-25 11:39:45 +02:00
Jan-Philipp Benecke 897ed7e381 Use ConfigEntry.runtime_data in govee_light_local (#128998) 2024-10-25 11:29:06 +02:00
epenet daf0939f09 Move bluesound service registration to separate module (#129086) 2024-10-25 11:27:25 +02:00
Simone Chemelli 7b1d6ddcf6 Fix uptime floating values for Vodafone Station (#128974) 2024-10-25 11:25:27 +02:00
tronikos 267e1dd0f8 Partially revert "LLM Tool parameters check (#123621)" (#129064) 2024-10-25 11:23:34 +02:00
Noah Husby c9d0bfce54 Add switch entity to Cambridge Audio (#128530) 2024-10-25 11:22:50 +02:00
Jacob Feisley 7f9e5e29a8 Add support for Faucet services in HomeKit Controller (#129094) 2024-10-25 11:15:13 +02:00
epenet d0f685183d Add comment to Rflink battery sensor definition (#129131) 2024-10-25 11:14:26 +02:00
Erik Montnemery bed77bd356 Remove go2rtc config flow (#129020)
* Remove go2rtc config flow

* Address review comments

* Update manifest

* Always validate go2rtc server URL

* Remove extra client

* Update homeassistant/components/go2rtc/__init__.py

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

* Improve test coverage

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-10-25 11:13:43 +02:00
Noah Husby bc0e3b254b Add additional tests to Cambridge Audio (#128213) 2024-10-25 11:13:27 +02:00
Petar Petrov 47bf0ebb47 Resume adding Z-Wave device if the page is refreshed (#129081)
* ZwaveJS: Resume adding a device if the page is refreshed

* add test

* address PR comments
2024-10-25 11:08:07 +02:00
Marc Hörsken 0acb95bbd5 Prevent duplicate WMS WebControl pro config entry creation (#128315) 2024-10-25 11:02:13 +02:00
Manu 8665f4a251 Refactor services setup in Habitica integration (#128186) 2024-10-25 11:00:58 +02:00
Manu 3adacb8799 Add entity picture for healing potion in Habitica (#129107) 2024-10-25 10:59:37 +02:00
David Bonnes 76aa69b9ac Switch to using a fixture for evohome Climate tests (of zones) (#129100) 2024-10-25 10:57:37 +02:00
Manu 78116f1596 Set up single coordinator for all config entries in IronOS (#129108) 2024-10-25 10:51:23 +02:00
dependabot[bot] 36693b7d9d Bump actions/setup-python from 5.2.0 to 5.3.0 (#129121)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.2.0...v5.3.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>
2024-10-25 10:45:14 +02:00
Keilin Bickar 8ce68f93ea Add typing for sense component (#129119)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-25 10:31:33 +02:00
Robert Resch 3512cb9599 Use webrtc-models package (#129032) 2024-10-25 10:18:55 +02:00
dontinelli ea164a2030 Add missing state_class to sensors in solarlog (#128296)
* Add missing state_class

* Update snapshot
2024-10-25 09:32:56 +02:00
Joost Lekkerkerker 929ba70ef8 Add entity descriptions to Smarty Binary sensor (#129110) 2024-10-25 08:47:29 +02:00
Mike Degatano 5b2113c43d Fix null hass error in supervisor update entities (#129030)
* Fix null hass error in supervisor update entities

* Share the supervisor client with coordinator

* Remove unnecessary patch of helper

* Attribute not property
2024-10-24 22:45:35 +02:00
Joost Lekkerkerker 6df2c0bab5 Add coordinator to Smarty (#129083)
* Add coordinator to Smarty

* Add coordinator to Smarty

* Fix
2024-10-24 22:41:21 +02:00
Thomas55555 1c5193aa4d Bump aioautomower to 2024.10.3 (#128788) 2024-10-24 09:56:38 -10:00
Erik Montnemery bd55fe868d Allow update entities to report progress as a float (#128930)
* Allow update entities to report progress as a float

* Add test

* Update snapshots

* Update recorder test

* Use _attr_* in MockUpdateEntity
2024-10-24 21:20:18 +02:00
Sid 87a2465a25 Bump ruff to 0.7.1 (#129102) 2024-10-24 21:03:48 +02:00
Noah Husby 5f839ad3ee Add play media capability to Cambridge Audio (#129002) 2024-10-24 20:33:53 +02:00
Sid 1663d8dfa9 Simplify webmin tests to use snapshot_platform (#127754) 2024-10-24 20:10:53 +02:00
Guido Schmitz 08eafc54e6 Fix adding multiple devices simultaneously to devolo Home Network's device tracker (#129082) 2024-10-24 20:10:06 +02:00
mkmer fe1d8b137e Handle temprorary hold in Honeywell (#128460) 2024-10-24 20:07:20 +02:00
Manu 39c0826f3c Add buttons to cast skills in Habitica integration (#126350) 2024-10-24 19:54:59 +02:00
Jason Parker bf63b0993d Reduce the number of API calls in Twitch integration (#128996) 2024-10-24 19:51:19 +02:00
epenet f91a1363cb Use runtime_data in bsblan (#129089) 2024-10-24 17:53:06 +02:00
J. Nick Koston a2c9aa7662 Add Meter Pro support to SwitchBot (#128991) 2024-10-24 17:49:40 +02:00
Noah Husby d135da6c1d Fix update callback in Cambridge Audio test (#129092) 2024-10-24 17:27:05 +02:00
Daniel Albers d27051f04d Remove DHCP match from awair (#129047)
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-24 16:53:55 +02:00
epenet b28fa2a1ad Use shorthand attribute in template binary sensor (#128966) 2024-10-24 16:16:46 +02:00
David Bonnes 77a91f5a8f Switch to using a fixture for evohome WaterHeater tests (#127701)
Co-authored-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: thecem <46648579+thecem@users.noreply.github.com>
Co-authored-by: Franck Nijhof <git@frenck.dev>
Co-authored-by: Jan-Philipp Benecke <github@bnck.me>
Co-authored-by: G Johansson <goran.johansson@shiftit.se>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-10-24 16:01:29 +02:00
Marc Mueller dcc7ee98b3 Update pytest warnings filter (#129075) 2024-10-24 15:59:25 +02:00
epenet 30edb2a44f Use runtime_data in buienradar (#129087) 2024-10-24 15:58:33 +02:00
epenet f63332a7aa Use runtime_data in blue_current (#129084) 2024-10-24 15:46:31 +02:00
epenet 86c37ce192 Use runtime_data in bluemaestro (#129085) 2024-10-24 15:45:46 +02:00
Louis Christ 93e6c9e5a0 Add tests for media_player to bluesound integration (#125864) 2024-10-24 15:42:25 +02:00
Joost Lekkerkerker 92e1fa4d3a Add unique id and tests for Smarty (#129078) 2024-10-24 14:54:19 +02:00
epenet bf7d292884 Use runtime_data in blink (#129072) 2024-10-24 14:32:48 +02:00
epenet add8db0186 Use runtime_data in blebox (#129070) 2024-10-24 14:32:20 +02:00
Erik Montnemery 3e62c6ae2f Move core config functionality to its own module (#129065)
* Move core config functionality to its own module

* Adjust test
2024-10-24 13:34:51 +02:00
Joost Lekkerkerker cd4aa8ccd6 Add config flow to Smarty (#127540)
Co-authored-by: Sid <27780930+autinerd@users.noreply.github.com>
2024-10-24 13:32:27 +02:00
Nebula83 937dbdc71f Add config flow to Onkyo (#117319)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Artur Pragacz <49985303+arturpragacz@users.noreply.github.com>
Co-authored-by: Artur Pragacz <artur@pragacz.com>
Co-authored-by: Joostlek <joostlek@outlook.com>
2024-10-24 12:45:25 +02:00
jb101010-2 66a7b508b2 Switch from pysuez to pysuezV2 in Suez Water (#127113) 2024-10-24 12:36:36 +02:00
epenet a5493f7947 Remove bloomsky integration (#129073)
* Small refactor to bloomsky

* Remove bloomsky integration

* Update integrations.json
2024-10-24 11:52:00 +02:00
Bram Kragten 979c4907da Update frontend to 20241002.4 (#129049) 2024-10-24 11:25:11 +02:00
Joshua Shaffer b8f6fdeb2b Use fan mode when heat/cool is idle in homekit_controller (#128618) 2024-10-24 09:25:40 +01:00
dependabot[bot] 067376cb3b Bump actions/checkout from 4.2.1 to 4.2.2 (#129063) 2024-10-24 10:04:21 +02:00
Max R bdbe9255a6 Add 'select' to configure Schlage locks "Auto Lock Time" (#123758) 2024-10-24 09:26:43 +02:00
J. Nick Koston c460e1bbbe Fix cancellation leaking upward from the timeout util (#129003) 2024-10-23 12:00:01 -10:00
Thomas55555 7e2b72fa5e Fix get_time_zone annotations in dt_util (#129050) 2024-10-23 10:34:53 -10:00
G Johansson 6ee6a8a74f Fix calculation of attributes in group sensor (#128601)
* Fix calculation of attributes in group sensor

* Fixes

* Fixes

* Make module level function
2024-10-23 20:51:18 +02:00
J. Nick Koston 80984c94a1 Bump sensorpush-ble to 1.7.0 (#128951)
changelog: https://github.com/Bluetooth-Devices/sensorpush-ble/compare/v1.6.2...v1.7.0
2024-10-23 19:25:20 +02:00
Joost Lekkerkerker 1757b66467 Bump yt-dlp to 2024.10.22 (#129034) 2024-10-23 19:18:57 +02:00
Keilin Bickar 8aa25af014 Create tests for sense integration (#128418)
* Create tests for sense integration

* Rearrange files

* Update to use snapshots

* Update tests/components/sense/__init__.py

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Update tests/components/sense/__init__.py

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Update tests/components/sense/test_binary_sensor.py

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Update tests/components/sense/test_sensor.py

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Add missing imports

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
2024-10-23 18:22:21 +02:00
epenet 5a0e47be48 Use runtime_data in bang_olufsen (#129037) 2024-10-23 18:21:25 +02:00
Jonas Bergler 756a866ffd Add completed to the wait variable when using triggers (wait_for_trigger) (#123427)
* Add support for the wait.completed variable when using wait with triggers

* Remove junk comment

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-23 17:19:07 +02:00
epenet 29305be23b Use runtime_data in balboa (#129035) 2024-10-23 16:41:45 +02:00
Jason Parker 8253cfd21d Remove deprecated channel views attribute from Twitch (#129008) 2024-10-23 16:27:19 +02:00
dependabot[bot] 165a00896e Bump actions/cache from 4.1.1 to 4.1.2 (#129018)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-23 16:23:07 +02:00
Guido Schmitz 2149ea1306 Fix devolo_home_network devices not reporting a MAC address (#129021) 2024-10-23 16:22:08 +02:00
Lektri.co 90547da007 Add switch platform to the Lektrico integration (#126721) 2024-10-23 16:20:08 +02:00
unfug-at-github 9ec4881d8d Have statistics functions return a meaningful, non-none result even if only one value is available (#127305)
* have statistics functions return a meaningful, non-none result even if only one value is available

* improved code coverage
2024-10-23 16:02:46 +02:00
Erik Montnemery 487593af38 Allow configuring WebRTC stun and turn servers (#128984)
* Allow configuring WebRTC stun and turn servers

* Add tests

* Remove class WebRTCCoreConfiguration
2024-10-23 14:41:45 +02:00
Willem-Jan van Rootselaar 4e8f878d83 Bump python bsblan version 0.6.4 (#128999) 2024-10-23 14:16:34 +02:00
Maikel Punie af6544c64d Bump pyduotecno to 2024.10.1 (#128968) 2024-10-23 14:15:33 +02:00
kingy444 09e1f53b3e Powerview migrate scene to string unique_id (#128131) 2024-10-23 14:04:07 +02:00
dependabot[bot] 1c4f191f42 Bump github/codeql-action from 3.26.13 to 3.27.0 (#129019)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.13 to 3.27.0.
- [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.26.13...v3.27.0)

---
updated-dependencies:
- dependency-name: github/codeql-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>
2024-10-23 12:14:08 +02:00
Robert Resch a37bd824d5 Add go2rtc binary config to expose api only on localhost (#129025) 2024-10-23 11:53:50 +02:00
Erik Montnemery 2c79173d20 Refactor camera.webrtc.register_ice_server (#129024)
* Refactor camera.webrtc.register_ice_server

* Apply suggestions from code review

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

* Add missing import

---------

Co-authored-by: Robert Resch <robert@resch.dev>
2024-10-23 11:49:39 +02:00
Josef Zweck eb45b89557 Remove battery device class from bmw secondary sensor (#128970)
Remove battery device class
2024-10-23 11:19:22 +02:00
Claudio Ruggeri - CR-Tech bf8c345341 Adjust logging level in ModBus (#128980)
Fix issue 127570 in ModBus Component
2024-10-23 11:16:01 +02:00
J. Nick Koston ef46280716 Bump orjson to 3.10.10 (#129015)
changelog: https://github.com/ijl/orjson/compare/3.10.9...3.10.10
2024-10-23 10:58:15 +02:00
Wendelin 2453e1284f Add Hassio HTTP logs/follow to allowed paths (#126606)
* Add logs/follow to admin paths in hassio.http

* Add tests for logs/follow admin paths in hassio.http

* Add tests for logs/follow admin paths in hassio.http

* Add compress and timeout exclusions for hassio http api

* Fix should_compress usage in hassio/ingress

* Add missing follow exceptions for hassio/http

* Add hassio range header forward for logs endpoints

* Fix test syntax hassio/http
2024-10-23 09:57:14 +02:00
Pascal Vizeli 95bcb272e0 Fix FUNDING.yml to OHF (#129013) 2024-10-23 08:48:41 +02:00
Denis Shulyaka e0e61b5262 Expose scripts with no fields as entities (#123061) 2024-10-22 23:14:07 -07:00
G Johansson 3ddef56167 Fix step in presets for generic thermostat (#128922) 2024-10-23 08:13:42 +02:00
epenet f8e6fb81d6 Improve template docstring (#128967) 2024-10-22 19:15:27 -10:00
Jan-Philipp Benecke 683ec87adf Use ConfigEntry.runtime_data in gardena_bluetooth (#129000) 2024-10-22 17:45:58 -10:00
Lektri.co 23edbe5ce7 Bump lektricowifi to 0.0.43 (#128979) 2024-10-22 17:41:43 -10:00
Luke Lashley 6ff32a51e3 Bump python-roborock to 2.6.1 (#128804) 2024-10-22 17:39:19 -10:00
Peter 4cbac3a864 Bump axis to v63 (#129005) 2024-10-22 23:16:52 +02:00
Álvaro Fernández Rojas 94a99b5bec Update aioairzone-cloud to v0.6.8 (#128992) 2024-10-22 10:35:47 -10:00
Petro31 810bf06e16 Add limited template to at field for time triggers (#126584)
* Add limited template to at field for time triggers

* fix mypy

* Fix comments

* fix-tests

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-22 21:06:19 +02:00
J. Nick Koston 1254667b2c Bump PySwitchBot to 0.51.0 (#128990) 2024-10-22 08:01:06 -10:00
Simone Chemelli 053eb8a0fd Bump aiovodafone to 0.6.1 (#128976)
* Bump aiovodafone to 0.6.1

* remove exception
2024-10-22 18:28:00 +02:00
Simone Chemelli 82ef380256 Bump aiocomelit to 0.9.1 (#128977)
* Bump aiocomelit to 0.9.1

* remove exception
2024-10-22 18:25:33 +02:00
Marc Mueller 44449d8e72 Fix zha test RuntimeWarnings (#128975) 2024-10-22 18:05:40 +02:00
J. Nick Koston 6c3a0890c7 Add support for fetching bindkey from Mi cloud (#128394) 2024-10-22 05:53:02 -10:00
Allen Porter 8c0def7c79 Fix google tasks todo docstrings (#128978) 2024-10-22 07:17:48 -07:00
Krisjanis Lejejs de77751779 Change Stun server port to 80 (#128879) 2024-10-22 14:23:29 +02:00
osohotwateriot cdf809926b Add OSO Energy services (#118770)
* Add OSO Energy services

* Fixes after review

* Add tests for OSO Energy water heater

* Fixes after review

* Revert changes for service schema in OSO Energy

* Improve osoenergy unit tests
2024-10-22 12:22:46 +02:00
Nicolas Mowen d40341f1ad Add snapshot service to image entity (#110057)
* Add service definition for saving snapshot of image entity

* Add service to image

* Add tests for image entity service

* Fix tests

* Formatting

* Add service icon

* Formatting

* Formatting

* Raise home assistant error instead of single log error

* Correctly pass entity id

* Raise exception from existing exception

* Expect home assistant error

* Fix services example

* Add test for templated snapshot

* Correct icon service config

* Set correct type for service template

* Remove unneeded

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

* remove template

* fix imports

* Update homeassistant/components/image/__init__.py

* Apply suggestions from code review

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-22 10:20:41 +02:00
J. Nick Koston 4a94fb91d7 Bump pySwitchbot to 0.50.1 (#128953)
changelog: https://github.com/Danielhiversen/pySwitchbot/compare/0.49.0...0.50.1
2024-10-22 07:47:36 +02:00
J. Nick Koston 24ea9ca947 Bump orjson to 3.10.9 (#128952) 2024-10-22 07:06:51 +02:00
Allen Porter 98eb9bf2bd Bump gcal_sync to 6.2.0 (#128949) 2024-10-21 22:00:50 -07:00
J. Nick Koston 1eb30cf3ab Bump yarl to 1.16.0 (#128941) 2024-10-21 17:29:03 -10:00
Marc Mueller 6fd7c0ff8e Update astroid to 3.3.5 (#128948) 2024-10-22 02:23:53 +02:00
J. Nick Koston 263e81cb2c Bump xiaomi-ble to 0.33.0 (#128946) 2024-10-21 12:22:24 -10:00
J. Nick Koston 92ebf37d86 Bump PySwitchbot to 0.49.0 (#128945) 2024-10-21 12:18:26 -10:00
G Johansson a10e406131 Fix flaky update coordinator test (#128943) 2024-10-21 11:52:28 -10:00
Teemu R. 21095e80a7 Expose tplink temperature sensor as measurement (#128640)
Add state_class=measurement to the temperature sensor, making it available for long-term statistics.
2024-10-21 23:39:56 +02:00
Teemu R. 55ae43ed03 Add motion detected binary_sensor for tplink (#127883)
* Add motion binary_sensor for tplink

* Remove strings definition as we have device class that handles this

* Simplify instructions

* Remove mentions about fixture creation and snapshot updates as requested

* re-add newline
2024-10-21 23:39:23 +02:00
rappenze 9cc934a972 Fix description placeholder in transmission reauth (#128938) 2024-10-21 23:05:24 +02:00
G Johansson cdfec7ebb4 Implement new state property for alarm_control_panel which is using an enum (#126283)
* Alarm state from enum

* Fixes

* Set final

* Fix rebase

* Test const

* Fix breaking version

* Fix other for alarm_control_panel

* Fix integrations

* More

* More

* More

* More

* Fix zha

* Replace _attr_state

* Fix alarm_control_panel

* Fix tests

* Fixes

* Mods

* Change some

* More

* More

* More

* Tests

* Last tests

* Return enum

* Fix zha

* Remove not needed check

* Fix wording

* Fix homekit

* Mod prometheus

* Fix mypy

* Fix homekit

* Fix ifttt
2024-10-21 22:54:27 +02:00
rappenze 59ad69b637 Fix description placeholder in imap reauth (#128940) 2024-10-21 22:29:24 +02:00
epenet ca6b759607 Use new reauth helpers in unifi (#128837)
* Use new reauth helpers in unifi

* Apply suggestions from code review

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

* Update config_flow.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-21 22:25:10 +02:00
G Johansson f9d857211f Drop not needed reauth strings in tplink (#128937) 2024-10-21 22:13:54 +02:00
rahulsamant37 01ad8661d6 Add missing strings for mold indicator (#128205)
* Add missing localization keys for random component configuration

* Add missing localization keys for mold_indicator component configuration

* one_integration_at_a_time

* Fix localization strings for mold_indicator: use direct values instead of non-existing keys

* Fix localization strings for mold_indicator: use direct values instead of non-existing key

* Add missing translations for Mold Indicator helper

* correcting it for hassfest

* Fixes

---------

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
2024-10-21 22:01:23 +02:00
Jason Parker d21b8166f0 Add subscription tier attribute to Twitch integration. (#128870)
* Add subscription tier to Twitch integration.

* Add test for Twitch tiers.  Tests do not currently pass, so this is only theoretical.

* Fix variable type

* Show tier levels as 1,2,3 instead of the raw API values of 1000,2000,3000.

* Make Twitch subscription tier fixtures strings.

* Use proper assertion value for subscription tier test.

Edited on a bus on my phone. 😎

* Update homeassistant/components/twitch/coordinator.py

* Update tests/components/twitch/test_sensor.py

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-21 21:54:10 +02:00
rappenze 63582bb489 Fix description placeholder in brunt reauth (#128933)
* Fix description placeholder in brunt reauth

* Update homeassistant/components/brunt/config_flow.py

Co-authored-by: Jan-Philipp Benecke <github@bnck.me>

* Update homeassistant/components/brunt/config_flow.py

Co-authored-by: Jan-Philipp Benecke <github@bnck.me>

---------

Co-authored-by: Jan-Philipp Benecke <github@bnck.me>
2024-10-21 21:02:22 +02:00
G Johansson c19f2de3a8 Allow Timer title to be translated (#128927) 2024-10-21 20:42:18 +02:00
Erik Montnemery d2e7b61eb2 Remove explicit templating of logbook service data (#128902) 2024-10-21 20:21:05 +02:00
Erik Montnemery 13a448ebfe Remove explicit templating of velbus service data (#128904) 2024-10-21 20:20:54 +02:00
Erik Montnemery bad2e1f9c4 Remove explicit templating of minio service data (#128905) 2024-10-21 20:20:44 +02:00
Erik Montnemery 8edac51401 Remove explicit templating of telegram_bot service data (#128906) 2024-10-21 20:20:29 +02:00
G Johansson f34ba9bf96 Bump holidays to 0.59 (#128924) 2024-10-21 20:19:56 +02:00
G Johansson 82aea946a2 Allow Random title to be translated (#128928) 2024-10-21 20:19:43 +02:00
G Johansson a0665dc431 Fix description placeholder in fibaro reauth (#128925) 2024-10-21 20:16:05 +02:00
G Johansson e32d6cdecd Allow Trend title to be translated (#128926) 2024-10-21 20:10:54 +02:00
Erik Montnemery 23b43319a8 Add update_percentage property to update entity (#128908) 2024-10-21 19:49:50 +02:00
Simone Chemelli e7a7a18c43 Add diagnostics to Vodafone Station (#128923)
* Add diagnostics to Vodafone Station

* cleanup and exclude props based on date
2024-10-21 19:47:12 +02:00
Erik Montnemery 8e5abcf5c2 Deprecate entity_id template variable in camera services (#128592)
* Deprecate entity_id template variable in camera services

* Update snapshots

* Tiny lang tweak

* Fix translation

---------

Co-authored-by: Franck Nijhof <git@frenck.dev>
2024-10-21 19:38:02 +02:00
Simone Chemelli e08e8641cb Add diagnostics to Comelit SimpleHome (#128794)
* Add diagnostics to Comelit SimpleHome

* add test

* add missing tests

* introduce SnapshotAssertion

* cleanup

* exclude date based props
2024-10-21 19:33:32 +02:00
Manu 3e8f3cfb49 Add firmware update entity to IronOS integration (#123031) 2024-10-21 19:20:23 +02:00
G Johansson 1eaaa5c6d3 Add config flow to local_file (#125835)
* Add config flow to local_file

* Small mods

* Add/fix tests

* Fix

* slug

* Fix strings

* Mod strings
2024-10-21 19:04:43 +02:00
Manu 1cc776d332 Add fan set_speed support for Xiaomi Mi Air Purifier 3C (#126870) 2024-10-21 18:16:12 +02:00
Barry vd. Heuvel 4009ae7d77 Add floor heating device valve positions in Homematic IP Cloud (#122759)
* Update sensor.py for new FALMOT Sensors

First Integration attemp to support ValvePosition as Sensor for HmIP-FALMOT-C12

* Update sensor.py

* Update sensor.py

* Add Valve Position to FALMOT-C12

* modified: devcontainer

* Service für minimum vale postion hinzugefügt.

* update to services

* Service call optimized

* Add valvePosition to HomematicIP Cloud for Falmot-C12 and show only channels that are connected with an motorized actuator

* Fix some tests

* Add icon for service

* Fix tests, add check for ValveState in icon

* Remove minimum valve service

* REmove minimum valve

* Use list comprehension for devices, support other terminal blocks

* Remove unused constant

* Check correct channel

---------

Co-authored-by: thecem <46648579+thecem@users.noreply.github.com>
2024-10-21 17:54:31 +02:00
DurandAN 07506faa3a Add SIA alarm code (#127467) 2024-10-21 17:38:33 +02:00
Álvaro Fernández Rojas 4d787ec93c Add Airzone Cloud switch entities to zones (#125917)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-21 17:03:48 +02:00
Álvaro Fernández Rojas 188413a531 Add Airzone Cloud main zone mode select (#125918)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-21 16:50:44 +02:00
Mike Degatano ad55c9cc19 Remaining addon management to aiohasupervisor (#128484)
* Move set addon options to aiohasupervisor

* addon stats to aiohasupervisor and test fixes

* addon changelogs to aiohasupervisor

* Raise correct error for library in tests

* Cache client in instance property

* Use singleton method rather then HassIO instance method

* Mock supervisor client in more tests
2024-10-21 16:41:00 +02:00
Erik Montnemery 9b3ac49298 Remove explicit templating of persistent_notification service data (#128903) 2024-10-21 16:34:36 +02:00
Álvaro Fernández Rojas 4306b0caba Add new QNAP QSW uptime timestamp sensor (#122589)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-21 16:33:41 +02:00
Álvaro Fernández Rojas ebd1baa42c Add Airzone switch entities to zones (#124562) 2024-10-21 16:33:22 +02:00
myztillx 6861bbed79 Add ecobee set_sensors_used_in_climate service (#102871)
* Add set_active_sensors Service

* Remove version bump from service addition commit

* Reviewer suggested changes

* Changed naming to be more clear of functionality

* Adjusted additional naming to follow new convention

* Updated to pass failing CI tests

* Fix typo

* Fix to pass CI

* Changed argument from climate_name to preset_mode and changed service error

* Made loop more clear and changed raised error to log msg

* Fix typo

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

* Removed code that was accidentally added back in and fixed mypy errors

* Add icon for service

* Added sensors as attributes and updated tests

* Revert changes made in #126587

* Added tests for remote_sensors and set_sensors_used_in_climate

* Changed back to load multiplatforms (#126587)

* Check for empty sensor list and negative tests for errors raised

* Added tests and fixed errors

* Add hass to class init to allow for device_registry lookup at startup and check for name changed by user

* Added tests to test the new functions

* Simplified code and fixed testing error for simplification

* Added freeze in test

* Fixed device filtering

* Simplified code section

* Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant.

* Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api

* Changed function parameter

* Search for specific ecobee identifier

* Moved errors to strings.json

* Added test for sensor not on thermostat

* Improved tests and updated device check

* Added attributes to _unrecoreded_attributes

* Changed name to be more clear

* Improve error message and add test for added property

* Renamed variables for clarity

* Added device_id to available_sensors to make it easier on user to find it

---------

Co-authored-by: Robert Resch <robert@resch.dev>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 16:21:56 +02:00
Andrew 25f66e6ac0 Bump pyopenweathermap to v0.2.1 (#128892) 2024-10-21 16:20:39 +02:00
epenet 838519e89f Use STATE_ON/STATE_OFF constants in template test (#128883) 2024-10-21 16:19:44 +02:00
epenet be4641b8f3 Push real binary sensor states to state machine in tests (#128894) 2024-10-21 16:19:25 +02:00
Erik Montnemery e861cab727 Add update_percentage state attribute to update entity (#128877)
* Add update_percentage state attribute to update entity

* Update tests

* Update tests
2024-10-21 15:31:48 +02:00
Steven B. f8f87ec091 Add reconfigure flow to ring integration (#128357)
Co-authored-by: Christopher Fenner <9592452+CFenner@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-10-21 15:30:05 +02:00
Erik Montnemery c0f1996478 Remove dead code from concord232 (#128907) 2024-10-21 15:23:43 +02:00
Petar Petrov 106746ce58 Include Z-Wave JS lowSecurityReason in node added websocket message (#128896)
* Propagate lowSecurityReason to FE when adding a zwavejs device insecurely

* update tests
2024-10-21 14:27:04 +02:00
Cyrill Raccaud 62773fa88a Simplify Swiss public transport coordinator (#128891) 2024-10-21 14:15:18 +02:00
Paul Bottein 28a8ed62f3 Add translations for Netatmo thermostat preset modes (#128890) 2024-10-21 13:00:23 +02:00
Cyrill Raccaud 110751e992 Use runtime_data for Swiss Public Transport (#128369)
* use runtime_data instead of hass.data[<key>]

* fix service response export type

* reduce runtime_data to be just the coordinator

* fix rebase

* fix ruff

* address reviews

* address reviews

* no general core import

* no general config_entries import

* fix also for services

* remove untyped config entry

* remove unneeded cast
2024-10-21 11:50:22 +02:00
Erik Montnemery 0d447c9d50 Improve entity cached attributes (#128876) 2024-10-21 10:29:01 +02:00
Joost Lekkerkerker 827d6d1d2d Add audio feature sensors to Spotify (#128785) 2024-10-21 09:46:38 +02:00
J. Nick Koston a64972fe38 Bump habluetooth to 3.6.0 (#128815) 2024-10-21 09:45:24 +02:00
Xitee 09bdc81aeb Remove myself from roomba codeowners (#128858) 2024-10-21 09:10:07 +02:00
Daniel Hjelseth Høyer c057de3a3c Bump pyTibber to 0.30.3 (#128860) 2024-10-21 09:09:29 +02:00
Allen Porter 1c4aff3ee1 Bump google-nest-sdm to 6.1.3 (#128871) 2024-10-21 09:05:37 +02:00
1874 changed files with 80025 additions and 20252 deletions
+1
View File
@@ -79,6 +79,7 @@ components: &components
- homeassistant/components/group/**
- homeassistant/components/hassio/**
- homeassistant/components/homeassistant/**
- homeassistant/components/homeassistant_hardware/**
- homeassistant/components/http/**
- homeassistant/components/image/**
- homeassistant/components/input_boolean/**
+7 -1
View File
@@ -58,7 +58,13 @@
],
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
}
},
"json.schemas": [
{
"fileMatch": ["homeassistant/components/*/manifest.json"],
"url": "./script/json_schemas/manifest_schema.json"
}
]
}
}
}
+1 -2
View File
@@ -1,2 +1 @@
custom: https://www.nabucasa.com
github: balloob
custom: https://www.openhomefoundation.org
+11 -11
View File
@@ -27,12 +27,12 @@ jobs:
publish: ${{ steps.version.outputs.publish }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -90,7 +90,7 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Download nightly wheels of frontend
if: needs.init.outputs.channel == 'dev'
@@ -116,7 +116,7 @@ jobs:
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
if: needs.init.outputs.channel == 'dev'
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -242,7 +242,7 @@ jobs:
- green
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set build additional args
run: |
@@ -279,7 +279,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Initialize git
uses: home-assistant/actions/helpers/git-init@master
@@ -321,7 +321,7 @@ jobs:
registry: ["ghcr.io/home-assistant", "docker.io/homeassistant"]
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Install Cosign
uses: sigstore/cosign-installer@v3.7.0
@@ -451,10 +451,10 @@ jobs:
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
@@ -499,7 +499,7 @@ jobs:
HASSFEST_IMAGE_TAG: ghcr.io/home-assistant/hassfest:${{ needs.init.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Login to GitHub Container Registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
@@ -531,7 +531,7 @@ jobs:
- name: Generate artifact attestation
if: needs.init.outputs.channel != 'dev' && needs.init.outputs.publish == 'true'
uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3
uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4
with:
subject-name: ${{ env.HASSFEST_IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }}
+86 -80
View File
@@ -40,9 +40,9 @@ env:
CACHE_VERSION: 11
UV_CACHE_VERSION: 1
MYPY_CACHE_VERSION: 9
HA_SHORT_VERSION: "2024.11"
HA_SHORT_VERSION: "2024.12"
DEFAULT_PYTHON: "3.12"
ALL_PYTHON_VERSIONS: "['3.12']"
ALL_PYTHON_VERSIONS: "['3.12', '3.13']"
# 10.3 is the oldest supported version
# - 10.3.32 is the version currently shipped with Synology (as of 17 Feb 2022)
# 10.6 is the current long-term-support
@@ -93,7 +93,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Generate partial Python venv restore key
id: generate_python_cache_key
run: |
@@ -231,16 +231,16 @@ jobs:
- info
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: venv
key: >-
@@ -256,7 +256,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.1.1
uses: actions/cache@v4.1.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
lookup-only: true
@@ -277,16 +277,16 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -295,7 +295,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v4.1.1
uses: actions/cache/restore@v4.1.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -317,16 +317,16 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -335,7 +335,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v4.1.1
uses: actions/cache/restore@v4.1.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -357,16 +357,16 @@ jobs:
- pre-commit
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -375,7 +375,7 @@ jobs:
needs.info.outputs.pre-commit_cache_key }}
- name: Restore pre-commit environment from cache
id: cache-precommit
uses: actions/cache/restore@v4.1.1
uses: actions/cache/restore@v4.1.2
with:
path: ${{ env.PRE_COMMIT_CACHE }}
fail-on-cache-miss: true
@@ -447,7 +447,7 @@ jobs:
- script/hassfest/docker/Dockerfile
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Register hadolint problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/hadolint.json"
@@ -466,10 +466,10 @@ jobs:
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ matrix.python-version }}
check-latest: true
@@ -482,7 +482,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.1.1
uses: actions/cache@v4.1.2
with:
path: venv
lookup-only: true
@@ -491,7 +491,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.1.1
uses: actions/cache@v4.1.2
with:
path: ${{ env.UV_CACHE_DIR }}
key: >-
@@ -550,16 +550,16 @@ jobs:
sudo apt-get -y install \
libturbojpeg
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -583,16 +583,16 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -615,37 +615,41 @@ jobs:
&& github.event.inputs.mypy-only != 'true'
|| github.event.inputs.audit-licenses-only == 'true')
&& needs.info.outputs.requirements == 'true'
strategy:
fail-fast: false
matrix:
python-version: ${{ fromJson(needs.info.outputs.python_versions) }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
python-version: ${{ matrix.python-version }}
check-latest: true
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
- name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv
uses: actions/cache/restore@v4.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Run pip-licenses
- name: Extract license data
run: |
. venv/bin/activate
pip-licenses --format=json --output-file=licenses.json
python -m script.licenses extract --output-file=licenses-${{ matrix.python-version }}.json
- name: Upload licenses
uses: actions/upload-artifact@v4.4.3
with:
name: licenses
path: licenses.json
- name: Process licenses
name: licenses-${{ github.run_number }}-${{ matrix.python-version }}
path: licenses-${{ matrix.python-version }}.json
- name: Check licenses
run: |
. venv/bin/activate
python -m script.licenses licenses.json
python -m script.licenses check licenses-${{ matrix.python-version }}.json
pylint:
name: Check pylint
@@ -660,16 +664,16 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -707,16 +711,16 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -752,10 +756,10 @@ jobs:
- base
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -768,7 +772,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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -776,7 +780,7 @@ jobs:
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
- name: Restore mypy cache
uses: actions/cache@v4.1.1
uses: actions/cache@v4.1.2
with:
path: .mypy_cache
key: >-
@@ -815,11 +819,7 @@ jobs:
needs:
- info
- base
strategy:
fail-fast: false
matrix:
python-version: ${{ fromJson(needs.info.outputs.python_versions) }}
name: Split tests for full run Python ${{ matrix.python-version }}
name: Split tests for full run
steps:
- name: Install additional OS dependencies
run: |
@@ -831,16 +831,16 @@ jobs:
libturbojpeg \
libgammu-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ matrix.python-version }}
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache/restore@v4.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -854,7 +854,7 @@ jobs:
- name: Upload pytest_buckets
uses: actions/upload-artifact@v4.4.3
with:
name: pytest_buckets-${{ matrix.python-version }}
name: pytest_buckets
path: pytest_buckets.txt
overwrite: true
@@ -895,16 +895,16 @@ jobs:
libturbojpeg \
libgammu-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -919,7 +919,7 @@ jobs:
- name: Download pytest_buckets
uses: actions/download-artifact@v4.1.8
with:
name: pytest_buckets-${{ matrix.python-version }}
name: pytest_buckets
- name: Compile English translations
run: |
. venv/bin/activate
@@ -945,6 +945,7 @@ jobs:
--timeout=9 \
--durations=10 \
--numprocesses auto \
--snapshot-details \
--dist=loadfile \
${cov_params[@]} \
-o console_output_style=count \
@@ -1015,16 +1016,16 @@ jobs:
libturbojpeg \
libmariadb-dev-compat
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -1067,6 +1068,7 @@ jobs:
-qq \
--timeout=20 \
--numprocesses 1 \
--snapshot-details \
${cov_params[@]} \
-o console_output_style=count \
--durations=10 \
@@ -1098,7 +1100,7 @@ jobs:
./script/check_dirty
pytest-postgres:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
services:
postgres:
image: ${{ matrix.postgresql-group }}
@@ -1138,19 +1140,21 @@ jobs:
sudo apt-get -y install \
bluez \
ffmpeg \
libturbojpeg \
libturbojpeg
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y
sudo apt-get -y install \
postgresql-server-dev-14
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -1193,6 +1197,7 @@ jobs:
-qq \
--timeout=9 \
--numprocesses 1 \
--snapshot-details \
${cov_params[@]} \
-o console_output_style=count \
--durations=0 \
@@ -1236,7 +1241,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Download all coverage artifacts
uses: actions/download-artifact@v4.1.8
with:
@@ -1287,16 +1292,16 @@ jobs:
libturbojpeg \
libgammu-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ matrix.python-version }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.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.1.1
uses: actions/cache/restore@v4.1.2
with:
path: venv
fail-on-cache-miss: true
@@ -1339,6 +1344,7 @@ jobs:
-qq \
--timeout=9 \
--numprocesses auto \
--snapshot-details \
${cov_params[@]} \
-o console_output_style=count \
--durations=0 \
@@ -1374,7 +1380,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Download all coverage artifacts
uses: actions/download-artifact@v4.1.8
with:
+3 -3
View File
@@ -21,14 +21,14 @@ jobs:
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.26.13
uses: github/codeql-action/init@v3.27.1
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.26.13
uses: github/codeql-action/analyze@v3.27.1
with:
category: "/language:python"
+2 -2
View File
@@ -19,10 +19,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
+20 -18
View File
@@ -32,11 +32,11 @@ jobs:
architectures: ${{ steps.info.outputs.architectures }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python
uses: actions/setup-python@v5.2.0
uses: actions/setup-python@v5.3.0
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true
@@ -112,11 +112,11 @@ jobs:
strategy:
fail-fast: false
matrix:
abi: ["cp312"]
abi: ["cp312", "cp313"]
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Download env_file
uses: actions/download-artifact@v4.1.8
@@ -135,14 +135,14 @@ jobs:
sed -i "/uv/d" requirements_diff.txt
- name: Build wheels
uses: home-assistant/wheels@2024.07.1
uses: home-assistant/wheels@2024.11.0
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
arch: ${{ matrix.arch }}
wheels-key: ${{ secrets.WHEELS_KEY }}
env-file: true
apk: "libffi-dev;openssl-dev;yaml-dev;nasm"
apk: "libffi-dev;openssl-dev;yaml-dev;nasm;zlib-dev"
skip-binary: aiohttp;multidict;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
@@ -156,11 +156,11 @@ jobs:
strategy:
fail-fast: false
matrix:
abi: ["cp312"]
abi: ["cp312", "cp313"]
arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps:
- name: Checkout the repository
uses: actions/checkout@v4.2.1
uses: actions/checkout@v4.2.2
- name: Download env_file
uses: actions/download-artifact@v4.1.8
@@ -198,6 +198,7 @@ jobs:
split -l $(expr $(expr $(cat requirements_all.txt | wc -l) + 1) / 3) requirements_all_wheels_${{ matrix.arch }}.txt requirements_all.txt
- name: Create requirements for cython<3
if: matrix.abi == 'cp312'
run: |
# Some dependencies still require 'cython<3'
# and don't yet use isolated build environments.
@@ -208,7 +209,8 @@ jobs:
cat homeassistant/package_constraints.txt | grep 'pydantic==' >> requirements_old-cython.txt
- name: Build wheels (old cython)
uses: home-assistant/wheels@2024.07.1
uses: home-assistant/wheels@2024.11.0
if: matrix.abi == 'cp312'
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
@@ -223,43 +225,43 @@ jobs:
pip: "'cython<3'"
- name: Build wheels (part 1)
uses: home-assistant/wheels@2024.07.1
uses: home-assistant/wheels@2024.11.0
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
arch: ${{ matrix.arch }}
wheels-key: ${{ secrets.WHEELS_KEY }}
env-file: true
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm"
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pydantic;pymicro-vad;yarl
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-dev"
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pymicro-vad;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_all.txtaa"
- name: Build wheels (part 2)
uses: home-assistant/wheels@2024.07.1
uses: home-assistant/wheels@2024.11.0
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
arch: ${{ matrix.arch }}
wheels-key: ${{ secrets.WHEELS_KEY }}
env-file: true
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm"
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pydantic;pymicro-vad;yarl
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-dev"
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pymicro-vad;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_all.txtab"
- name: Build wheels (part 3)
uses: home-assistant/wheels@2024.07.1
uses: home-assistant/wheels@2024.11.0
with:
abi: ${{ matrix.abi }}
tag: musllinux_1_2
arch: ${{ matrix.arch }}
wheels-key: ${{ secrets.WHEELS_KEY }}
env-file: true
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm"
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pydantic;pymicro-vad;yarl
apk: "bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev;uchardet-dev;nasm;zlib-dev"
skip-binary: aiohttp;charset-normalizer;grpcio;multidict;SQLAlchemy;propcache;protobuf;pymicro-vad;yarl
constraints: "homeassistant/package_constraints.txt"
requirements-diff: "requirements_diff.txt"
requirements: "requirements_all.txtac"
+1 -1
View File
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.0
rev: v0.7.2
hooks:
- id: ruff
args:
+5
View File
@@ -124,6 +124,7 @@ homeassistant.components.bryant_evolution.*
homeassistant.components.bthome.*
homeassistant.components.button.*
homeassistant.components.calendar.*
homeassistant.components.cambridge_audio.*
homeassistant.components.camera.*
homeassistant.components.canary.*
homeassistant.components.cert_expiry.*
@@ -208,6 +209,7 @@ homeassistant.components.geo_location.*
homeassistant.components.geocaching.*
homeassistant.components.gios.*
homeassistant.components.glances.*
homeassistant.components.go2rtc.*
homeassistant.components.goalzero.*
homeassistant.components.google.*
homeassistant.components.google_assistant_sdk.*
@@ -322,11 +324,13 @@ homeassistant.components.moon.*
homeassistant.components.mopeka.*
homeassistant.components.motionmount.*
homeassistant.components.mqtt.*
homeassistant.components.music_assistant.*
homeassistant.components.my.*
homeassistant.components.mysensors.*
homeassistant.components.myuplink.*
homeassistant.components.nam.*
homeassistant.components.nanoleaf.*
homeassistant.components.nasweb.*
homeassistant.components.neato.*
homeassistant.components.nest.*
homeassistant.components.netatmo.*
@@ -336,6 +340,7 @@ homeassistant.components.nfandroidtv.*
homeassistant.components.nightscout.*
homeassistant.components.nissan_leaf.*
homeassistant.components.no_ip.*
homeassistant.components.nordpool.*
homeassistant.components.notify.*
homeassistant.components.notion.*
homeassistant.components.number.*
+9 -1
View File
@@ -6,5 +6,13 @@
// https://code.visualstudio.com/docs/python/testing#_pytest-configuration-settings
"python.testing.pytestEnabled": false,
// https://code.visualstudio.com/docs/python/linting#_general-settings
"pylint.importStrategy": "fromEnvironment"
"pylint.importStrategy": "fromEnvironment",
"json.schemas": [
{
"fileMatch": [
"homeassistant/components/*/manifest.json"
],
"url": "./script/json_schemas/manifest_schema.json"
}
]
}
+22 -8
View File
@@ -496,8 +496,8 @@ build.json @home-assistant/supervisor
/tests/components/freebox/ @hacf-fr @Quentame
/homeassistant/components/freedompro/ @stefano055415
/tests/components/freedompro/ @stefano055415
/homeassistant/components/fritz/ @mammuth @AaronDavidSchneider @chemelli74 @mib1185
/tests/components/fritz/ @mammuth @AaronDavidSchneider @chemelli74 @mib1185
/homeassistant/components/fritz/ @AaronDavidSchneider @chemelli74 @mib1185
/tests/components/fritz/ @AaronDavidSchneider @chemelli74 @mib1185
/homeassistant/components/fritzbox/ @mib1185 @flabbamann
/tests/components/fritzbox/ @mib1185 @flabbamann
/homeassistant/components/fritzbox_callmonitor/ @cdce8p
@@ -617,8 +617,8 @@ build.json @home-assistant/supervisor
/tests/components/hlk_sw16/ @jameshilliard
/homeassistant/components/holiday/ @jrieger @gjohansson-ST
/tests/components/holiday/ @jrieger @gjohansson-ST
/homeassistant/components/home_connect/ @DavidMStraub
/tests/components/home_connect/ @DavidMStraub
/homeassistant/components/home_connect/ @DavidMStraub @Diegorro98
/tests/components/home_connect/ @DavidMStraub @Diegorro98
/homeassistant/components/homeassistant/ @home-assistant/core
/tests/components/homeassistant/ @home-assistant/core
/homeassistant/components/homeassistant_alerts/ @home-assistant/core
@@ -659,6 +659,8 @@ build.json @home-assistant/supervisor
/tests/components/hunterdouglas_powerview/ @bdraco @kingy444 @trullock
/homeassistant/components/husqvarna_automower/ @Thomas55555
/tests/components/husqvarna_automower/ @Thomas55555
/homeassistant/components/husqvarna_automower_ble/ @alistair23
/tests/components/husqvarna_automower_ble/ @alistair23
/homeassistant/components/huum/ @frwickst
/tests/components/huum/ @frwickst
/homeassistant/components/hvv_departures/ @vigonotion
@@ -819,6 +821,8 @@ build.json @home-assistant/supervisor
/tests/components/lektrico/ @lektrico
/homeassistant/components/lg_netcast/ @Drafteed @splinter98
/tests/components/lg_netcast/ @Drafteed @splinter98
/homeassistant/components/lg_thinq/ @LG-ThinQ-Integration
/tests/components/lg_thinq/ @LG-ThinQ-Integration
/homeassistant/components/lidarr/ @tkdrob
/tests/components/lidarr/ @tkdrob
/homeassistant/components/lifx/ @Djelibeybi
@@ -950,6 +954,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/msteams/ @peroyvind
/homeassistant/components/mullvad/ @meichthys
/tests/components/mullvad/ @meichthys
/homeassistant/components/music_assistant/ @music-assistant
/tests/components/music_assistant/ @music-assistant
/homeassistant/components/mutesync/ @currentoor
/tests/components/mutesync/ @currentoor
/homeassistant/components/my/ @home-assistant/core
@@ -964,6 +970,8 @@ build.json @home-assistant/supervisor
/tests/components/nam/ @bieniu
/homeassistant/components/nanoleaf/ @milanmeu @joostlek
/tests/components/nanoleaf/ @milanmeu @joostlek
/homeassistant/components/nasweb/ @nasWebio
/tests/components/nasweb/ @nasWebio
/homeassistant/components/neato/ @Santobert
/tests/components/neato/ @Santobert
/homeassistant/components/nederlandse_spoorwegen/ @YarmoM
@@ -1004,6 +1012,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/noaa_tides/ @jdelaney72
/homeassistant/components/nobo_hub/ @echoromeo @oyvindwe
/tests/components/nobo_hub/ @echoromeo @oyvindwe
/homeassistant/components/nordpool/ @gjohansson-ST
/tests/components/nordpool/ @gjohansson-ST
/homeassistant/components/notify/ @home-assistant/core
/tests/components/notify/ @home-assistant/core
/homeassistant/components/notify_events/ @matrozov @papajojo
@@ -1047,6 +1057,7 @@ build.json @home-assistant/supervisor
/homeassistant/components/onewire/ @garbled1 @epenet
/tests/components/onewire/ @garbled1 @epenet
/homeassistant/components/onkyo/ @arturpragacz
/tests/components/onkyo/ @arturpragacz
/homeassistant/components/onvif/ @hunterjm
/tests/components/onvif/ @hunterjm
/homeassistant/components/open_meteo/ @frenck
@@ -1088,6 +1099,8 @@ build.json @home-assistant/supervisor
/tests/components/ovo_energy/ @timmo001
/homeassistant/components/p1_monitor/ @klaasnicolaas
/tests/components/p1_monitor/ @klaasnicolaas
/homeassistant/components/palazzetti/ @dotvav
/tests/components/palazzetti/ @dotvav
/homeassistant/components/panel_custom/ @home-assistant/frontend
/tests/components/panel_custom/ @home-assistant/frontend
/homeassistant/components/peco/ @IceBotYT
@@ -1237,8 +1250,8 @@ build.json @home-assistant/supervisor
/tests/components/roku/ @ctalkington
/homeassistant/components/romy/ @xeniter
/tests/components/romy/ @xeniter
/homeassistant/components/roomba/ @pschmitt @cyr-ius @shenxn @Xitee1 @Orhideous
/tests/components/roomba/ @pschmitt @cyr-ius @shenxn @Xitee1 @Orhideous
/homeassistant/components/roomba/ @pschmitt @cyr-ius @shenxn @Orhideous
/tests/components/roomba/ @pschmitt @cyr-ius @shenxn @Orhideous
/homeassistant/components/roon/ @pavoni
/tests/components/roon/ @pavoni
/homeassistant/components/rpi_power/ @shenxn @swetoast
@@ -1349,6 +1362,7 @@ build.json @home-assistant/supervisor
/homeassistant/components/smarttub/ @mdz
/tests/components/smarttub/ @mdz
/homeassistant/components/smarty/ @z0mbieprocess
/tests/components/smarty/ @z0mbieprocess
/homeassistant/components/smhi/ @gjohansson-ST
/tests/components/smhi/ @gjohansson-ST
/homeassistant/components/smlight/ @tl-sl
@@ -1412,8 +1426,8 @@ build.json @home-assistant/supervisor
/tests/components/stt/ @home-assistant/core
/homeassistant/components/subaru/ @G-Two
/tests/components/subaru/ @G-Two
/homeassistant/components/suez_water/ @ooii
/tests/components/suez_water/ @ooii
/homeassistant/components/suez_water/ @ooii @jb101010-2
/tests/components/suez_water/ @ooii @jb101010-2
/homeassistant/components/sun/ @Swamp-Ig
/tests/components/sun/ @Swamp-Ig
/homeassistant/components/sunweg/ @rokam
+4 -3
View File
@@ -7,12 +7,13 @@ FROM ${BUILD_FROM}
# Synchronize with homeassistant/core.py:async_stop
ENV \
S6_SERVICES_GRACETIME=240000 \
UV_SYSTEM_PYTHON=true
UV_SYSTEM_PYTHON=true \
UV_NO_CACHE=true
ARG QEMU_CPU
# Install uv
RUN pip3 install uv==0.4.22
RUN pip3 install uv==0.5.0
WORKDIR /usr/src
@@ -54,7 +55,7 @@ RUN \
"armv7") go2rtc_suffix='arm' ;; \
*) go2rtc_suffix=${BUILD_ARCH} ;; \
esac \
&& curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.4/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
&& curl -L https://github.com/AlexxIT/go2rtc/releases/download/v1.9.6/go2rtc_linux_${go2rtc_suffix} --output /bin/go2rtc \
&& chmod +x /bin/go2rtc \
# Verify go2rtc can be executed
&& go2rtc --version
+4
View File
@@ -9,6 +9,7 @@ import os
import sys
import threading
from .backup_restore import restore_backup
from .const import REQUIRED_PYTHON_VER, RESTART_EXIT_CODE, __version__
FAULT_LOG_FILENAME = "home-assistant.log.fault"
@@ -182,6 +183,9 @@ def main() -> int:
return scripts.run(args.script)
config_dir = os.path.abspath(os.path.join(os.getcwd(), args.config))
if restore_backup(config_dir):
return RESTART_EXIT_CODE
ensure_config_path(config_dir)
# pylint: disable-next=import-outside-toplevel
+126
View File
@@ -0,0 +1,126 @@
"""Home Assistant module to handle restoring backups."""
from dataclasses import dataclass
import json
import logging
from pathlib import Path
import shutil
import sys
from tempfile import TemporaryDirectory
from awesomeversion import AwesomeVersion
import securetar
from .const import __version__ as HA_VERSION
RESTORE_BACKUP_FILE = ".HA_RESTORE"
KEEP_PATHS = ("backups",)
_LOGGER = logging.getLogger(__name__)
@dataclass
class RestoreBackupFileContent:
"""Definition for restore backup file content."""
backup_file_path: Path
def restore_backup_file_content(config_dir: Path) -> RestoreBackupFileContent | None:
"""Return the contents of the restore backup file."""
instruction_path = config_dir.joinpath(RESTORE_BACKUP_FILE)
try:
instruction_content = json.loads(instruction_path.read_text(encoding="utf-8"))
return RestoreBackupFileContent(
backup_file_path=Path(instruction_content["path"])
)
except (FileNotFoundError, json.JSONDecodeError):
return None
def _clear_configuration_directory(config_dir: Path) -> None:
"""Delete all files and directories in the config directory except for the backups directory."""
keep_paths = [config_dir.joinpath(path) for path in KEEP_PATHS]
config_contents = sorted(
[entry for entry in config_dir.iterdir() if entry not in keep_paths]
)
for entry in config_contents:
entrypath = config_dir.joinpath(entry)
if entrypath.is_file():
entrypath.unlink()
elif entrypath.is_dir():
shutil.rmtree(entrypath)
def _extract_backup(config_dir: Path, backup_file_path: Path) -> None:
"""Extract the backup file to the config directory."""
with (
TemporaryDirectory() as tempdir,
securetar.SecureTarFile(
backup_file_path,
gzip=False,
mode="r",
) as ostf,
):
ostf.extractall(
path=Path(tempdir, "extracted"),
members=securetar.secure_path(ostf),
filter="fully_trusted",
)
backup_meta_file = Path(tempdir, "extracted", "backup.json")
backup_meta = json.loads(backup_meta_file.read_text(encoding="utf8"))
if (
backup_meta_version := AwesomeVersion(
backup_meta["homeassistant"]["version"]
)
) > HA_VERSION:
raise ValueError(
f"You need at least Home Assistant version {backup_meta_version} to restore this backup"
)
with securetar.SecureTarFile(
Path(
tempdir,
"extracted",
f"homeassistant.tar{'.gz' if backup_meta["compressed"] else ''}",
),
gzip=backup_meta["compressed"],
mode="r",
) as istf:
for member in istf.getmembers():
if member.name == "data":
continue
member.name = member.name.replace("data/", "")
_clear_configuration_directory(config_dir)
istf.extractall(
path=config_dir,
members=[
member
for member in securetar.secure_path(istf)
if member.name != "data"
],
filter="fully_trusted",
)
def restore_backup(config_dir_path: str) -> bool:
"""Restore the backup file if any.
Returns True if a restore backup file was found and restored, False otherwise.
"""
config_dir = Path(config_dir_path)
if not (restore_content := restore_backup_file_content(config_dir)):
return False
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
backup_file_path = restore_content.backup_file_path
_LOGGER.info("Restoring %s", backup_file_path)
try:
_extract_backup(config_dir, backup_file_path)
except FileNotFoundError as err:
raise ValueError(f"Backup file {backup_file_path} does not exist") from err
_LOGGER.info("Restore complete, restarting")
return True
+2 -1
View File
@@ -70,6 +70,7 @@ from .const import (
REQUIRED_NEXT_PYTHON_VER,
SIGNAL_BOOTSTRAP_INTEGRATIONS,
)
from .core_config import async_process_ha_core_config
from .exceptions import HomeAssistantError
from .helpers import (
area_registry,
@@ -479,7 +480,7 @@ async def async_from_config_dict(
core_config = config.get(core.DOMAIN, {})
try:
await conf_util.async_process_ha_core_config(hass, core_config)
await async_process_ha_core_config(hass, core_config)
except vol.Invalid as config_err:
conf_util.async_log_schema_error(config_err, core.DOMAIN, core_config, hass)
async_notify_setup_error(hass, core.DOMAIN)
+5
View File
@@ -0,0 +1,5 @@
{
"domain": "husqvarna",
"name": "Husqvarna",
"integrations": ["husqvarna_automower", "husqvarna_automower_ble"]
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
"domain": "lg",
"name": "LG",
"integrations": ["lg_netcast", "lg_soundbar", "webostv"]
"integrations": ["lg_netcast", "lg_soundbar", "lg_thinq", "webostv"]
}
@@ -7,13 +7,9 @@ from jaraco.abode.devices.alarm import Alarm
from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
AlarmControlPanelEntityFeature,
AlarmControlPanelState,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_DISARMED,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@@ -44,14 +40,14 @@ class AbodeAlarm(AbodeDevice, AlarmControlPanelEntity):
_device: Alarm
@property
def state(self) -> str | None:
def alarm_state(self) -> AlarmControlPanelState | None:
"""Return the state of the device."""
if self._device.is_standby:
return STATE_ALARM_DISARMED
return AlarmControlPanelState.DISARMED
if self._device.is_away:
return STATE_ALARM_ARMED_AWAY
return AlarmControlPanelState.ARMED_AWAY
if self._device.is_home:
return STATE_ALARM_ARMED_HOME
return AlarmControlPanelState.ARMED_HOME
return None
def alarm_disarm(self, code: str | None = None) -> None:
@@ -7,7 +7,6 @@ from typing import Any
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
import voluptuous as vol
from homeassistant.components.hassio import HassioServiceInfo
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import (
CONF_HOST,
@@ -18,6 +17,7 @@ from homeassistant.const import (
CONF_VERIFY_SSL,
)
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.service_info.hassio import HassioServiceInfo
from .const import DOMAIN
@@ -55,6 +55,7 @@ async def async_setup_entry(
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
config_entry=entry,
name="Advantage Air",
update_method=async_get,
update_interval=timedelta(seconds=ADVANTAGE_AIR_SYNC_INTERVAL),
+2 -13
View File
@@ -1,6 +1,5 @@
"""The AEMET OpenData component."""
from dataclasses import dataclass
import logging
from aemet_opendata.exceptions import AemetError, TownNotFound
@@ -13,20 +12,10 @@ from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client
from .const import CONF_STATION_UPDATES, PLATFORMS
from .coordinator import WeatherUpdateCoordinator
from .coordinator import AemetConfigEntry, AemetData, WeatherUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
type AemetConfigEntry = ConfigEntry[AemetData]
@dataclass
class AemetData:
"""Aemet runtime data."""
name: str
coordinator: WeatherUpdateCoordinator
async def async_setup_entry(hass: HomeAssistant, entry: AemetConfigEntry) -> bool:
"""Set up AEMET OpenData as config entry."""
@@ -46,7 +35,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AemetConfigEntry) -> boo
except AemetError as err:
raise ConfigEntryNotReady(err) from err
weather_coordinator = WeatherUpdateCoordinator(hass, aemet)
weather_coordinator = WeatherUpdateCoordinator(hass, entry, aemet)
await weather_coordinator.async_config_entry_first_refresh()
entry.runtime_data = AemetData(name=name, coordinator=weather_coordinator)
@@ -3,6 +3,7 @@
from __future__ import annotations
from asyncio import timeout
from dataclasses import dataclass
from datetime import timedelta
import logging
from typing import Any, Final, cast
@@ -19,6 +20,7 @@ from aemet_opendata.helpers import dict_nested_value
from aemet_opendata.interface import AEMET
from homeassistant.components.weather import Forecast
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
@@ -29,6 +31,16 @@ _LOGGER = logging.getLogger(__name__)
API_TIMEOUT: Final[int] = 120
WEATHER_UPDATE_INTERVAL = timedelta(minutes=10)
type AemetConfigEntry = ConfigEntry[AemetData]
@dataclass
class AemetData:
"""Aemet runtime data."""
name: str
coordinator: WeatherUpdateCoordinator
class WeatherUpdateCoordinator(DataUpdateCoordinator):
"""Weather data update coordinator."""
@@ -36,6 +48,7 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
def __init__(
self,
hass: HomeAssistant,
entry: AemetConfigEntry,
aemet: AEMET,
) -> None:
"""Initialize coordinator."""
@@ -44,6 +57,7 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
super().__init__(
hass,
_LOGGER,
config_entry=entry,
name=DOMAIN,
update_interval=WEATHER_UPDATE_INTERVAL,
)
@@ -15,7 +15,7 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from . import AemetConfigEntry
from .coordinator import AemetConfigEntry
TO_REDACT_CONFIG = [
CONF_API_KEY,
+3 -2
View File
@@ -55,7 +55,6 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import dt as dt_util
from . import AemetConfigEntry
from .const import (
ATTR_API_CONDITION,
ATTR_API_FORECAST_CONDITION,
@@ -87,7 +86,7 @@ from .const import (
ATTR_API_WIND_SPEED,
CONDITIONS_MAP,
)
from .coordinator import WeatherUpdateCoordinator
from .coordinator import AemetConfigEntry, WeatherUpdateCoordinator
from .entity import AemetEntity
@@ -249,6 +248,7 @@ WEATHER_SENSORS: Final[tuple[AemetSensorEntityDescription, ...]] = (
name="Rain",
native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
state_class=SensorStateClass.MEASUREMENT,
),
AemetSensorEntityDescription(
key=ATTR_API_RAIN_PROB,
@@ -263,6 +263,7 @@ WEATHER_SENSORS: Final[tuple[AemetSensorEntityDescription, ...]] = (
name="Snow",
native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
state_class=SensorStateClass.MEASUREMENT,
),
AemetSensorEntityDescription(
key=ATTR_API_SNOW_PROB,
+1 -2
View File
@@ -27,9 +27,8 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AemetConfigEntry
from .const import CONDITIONS_MAP
from .coordinator import WeatherUpdateCoordinator
from .coordinator import AemetConfigEntry, WeatherUpdateCoordinator
from .entity import AemetEntity
@@ -5,12 +5,7 @@ from __future__ import annotations
from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
AlarmControlPanelEntityFeature,
)
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_DISARMED,
AlarmControlPanelState,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
@@ -65,37 +60,37 @@ class AgentBaseStation(AlarmControlPanelEntity):
self._attr_available = self._client.is_available
armed = self._client.is_armed
if armed is None:
self._attr_state = None
self._attr_alarm_state = None
return
if armed:
prof = (await self._client.get_active_profile()).lower()
self._attr_state = STATE_ALARM_ARMED_AWAY
self._attr_alarm_state = AlarmControlPanelState.ARMED_AWAY
if prof == CONF_HOME_MODE_NAME:
self._attr_state = STATE_ALARM_ARMED_HOME
self._attr_alarm_state = AlarmControlPanelState.ARMED_HOME
elif prof == CONF_NIGHT_MODE_NAME:
self._attr_state = STATE_ALARM_ARMED_NIGHT
self._attr_alarm_state = AlarmControlPanelState.ARMED_NIGHT
else:
self._attr_state = STATE_ALARM_DISARMED
self._attr_alarm_state = AlarmControlPanelState.DISARMED
async def async_alarm_disarm(self, code: str | None = None) -> None:
"""Send disarm command."""
await self._client.disarm()
self._attr_state = STATE_ALARM_DISARMED
self._attr_alarm_state = AlarmControlPanelState.DISARMED
async def async_alarm_arm_away(self, code: str | None = None) -> None:
"""Send arm away command. Uses custom mode."""
await self._client.arm()
await self._client.set_active_profile(CONF_AWAY_MODE_NAME)
self._attr_state = STATE_ALARM_ARMED_AWAY
self._attr_alarm_state = AlarmControlPanelState.ARMED_AWAY
async def async_alarm_arm_home(self, code: str | None = None) -> None:
"""Send arm home command. Uses custom mode."""
await self._client.arm()
await self._client.set_active_profile(CONF_HOME_MODE_NAME)
self._attr_state = STATE_ALARM_ARMED_HOME
self._attr_alarm_state = AlarmControlPanelState.ARMED_HOME
async def async_alarm_arm_night(self, code: str | None = None) -> None:
"""Send arm night command. Uses custom mode."""
await self._client.arm()
await self._client.set_active_profile(CONF_NIGHT_MODE_NAME)
self._attr_state = STATE_ALARM_ARMED_NIGHT
self._attr_alarm_state = AlarmControlPanelState.ARMED_NIGHT
@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/agent_dvr",
"iot_class": "local_polling",
"loggers": ["agent"],
"requirements": ["agent-py==0.0.23"]
"requirements": ["agent-py==0.0.24"]
}
+6 -10
View File
@@ -1,5 +1,7 @@
"""Config flow for AirNow integration."""
from __future__ import annotations
import logging
from typing import Any
@@ -12,7 +14,6 @@ from homeassistant.config_entries import (
ConfigFlow,
ConfigFlowResult,
OptionsFlow,
OptionsFlowWithConfigEntry,
)
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS
from homeassistant.core import HomeAssistant, callback
@@ -120,12 +121,12 @@ class AirNowConfigFlow(ConfigFlow, domain=DOMAIN):
@callback
def async_get_options_flow(
config_entry: ConfigEntry,
) -> OptionsFlow:
) -> AirNowOptionsFlowHandler:
"""Return the options flow."""
return AirNowOptionsFlowHandler(config_entry)
return AirNowOptionsFlowHandler()
class AirNowOptionsFlowHandler(OptionsFlowWithConfigEntry):
class AirNowOptionsFlowHandler(OptionsFlow):
"""Handle an options flow for AirNow."""
async def async_step_init(
@@ -136,12 +137,7 @@ class AirNowOptionsFlowHandler(OptionsFlowWithConfigEntry):
return self.async_create_entry(data=user_input)
options_schema = vol.Schema(
{
vol.Optional(CONF_RADIUS): vol.All(
int,
vol.Range(min=5),
),
}
{vol.Optional(CONF_RADIUS): vol.All(int, vol.Range(min=5))}
)
return self.async_show_form(
@@ -42,6 +42,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirthingsConfigEntry) ->
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
config_entry=entry,
name=DOMAIN,
update_method=_update_method,
update_interval=SCAN_INTERVAL,
@@ -2,75 +2,27 @@
from __future__ import annotations
from datetime import timedelta
import logging
from airthings_ble import AirthingsBluetoothDeviceData, AirthingsDevice
from bleak_retry_connector import close_stale_connections_by_address
from homeassistant.components import bluetooth
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util.unit_system import METRIC_SYSTEM
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN, MAX_RETRIES_AFTER_STARTUP
from .const import MAX_RETRIES_AFTER_STARTUP
from .coordinator import AirthingsBLEConfigEntry, AirthingsBLEDataUpdateCoordinator
PLATFORMS: list[Platform] = [Platform.SENSOR]
_LOGGER = logging.getLogger(__name__)
AirthingsBLEDataUpdateCoordinator = DataUpdateCoordinator[AirthingsDevice]
AirthingsBLEConfigEntry = ConfigEntry[AirthingsBLEDataUpdateCoordinator]
async def async_setup_entry(
hass: HomeAssistant, entry: AirthingsBLEConfigEntry
) -> bool:
"""Set up Airthings BLE device from a config entry."""
hass.data.setdefault(DOMAIN, {})
address = entry.unique_id
is_metric = hass.config.units is METRIC_SYSTEM
assert address is not None
await close_stale_connections_by_address(address)
ble_device = bluetooth.async_ble_device_from_address(hass, address)
if not ble_device:
raise ConfigEntryNotReady(
f"Could not find Airthings device with address {address}"
)
airthings = AirthingsBluetoothDeviceData(_LOGGER, is_metric)
async def _async_update_method() -> AirthingsDevice:
"""Get data from Airthings BLE."""
try:
data = await airthings.update_device(ble_device)
except Exception as err:
raise UpdateFailed(f"Unable to fetch data: {err}") from err
return data
coordinator: AirthingsBLEDataUpdateCoordinator = DataUpdateCoordinator(
hass,
_LOGGER,
name=DOMAIN,
update_method=_async_update_method,
update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL),
)
coordinator = AirthingsBLEDataUpdateCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh()
# Once its setup and we know we are not going to delay
# the startup of Home Assistant, we can set the max attempts
# to a higher value. If the first connection attempt fails,
# Home Assistant's built-in retry logic will take over.
airthings.set_max_attempts(MAX_RETRIES_AFTER_STARTUP)
coordinator.airthings.set_max_attempts(MAX_RETRIES_AFTER_STARTUP)
entry.runtime_data = coordinator
@@ -0,0 +1,68 @@
"""The Airthings BLE integration."""
from __future__ import annotations
from datetime import timedelta
import logging
from airthings_ble import AirthingsBluetoothDeviceData, AirthingsDevice
from bleak.backends.device import BLEDevice
from bleak_retry_connector import close_stale_connections_by_address
from homeassistant.components import bluetooth
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util.unit_system import METRIC_SYSTEM
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN
_LOGGER = logging.getLogger(__name__)
type AirthingsBLEConfigEntry = ConfigEntry[AirthingsBLEDataUpdateCoordinator]
class AirthingsBLEDataUpdateCoordinator(DataUpdateCoordinator[AirthingsDevice]):
"""Class to manage fetching Airthings BLE data."""
ble_device: BLEDevice
config_entry: AirthingsBLEConfigEntry
def __init__(self, hass: HomeAssistant, entry: AirthingsBLEConfigEntry) -> None:
"""Initialize the coordinator."""
self.airthings = AirthingsBluetoothDeviceData(
_LOGGER, hass.config.units is METRIC_SYSTEM
)
super().__init__(
hass,
_LOGGER,
config_entry=entry,
name=DOMAIN,
update_interval=timedelta(seconds=DEFAULT_SCAN_INTERVAL),
)
async def _async_setup(self) -> None:
"""Set up the coordinator."""
address = self.config_entry.unique_id
assert address is not None
await close_stale_connections_by_address(address)
ble_device = bluetooth.async_ble_device_from_address(self.hass, address)
if not ble_device:
raise ConfigEntryNotReady(
f"Could not find Airthings device with address {address}"
)
self.ble_device = ble_device
async def _async_update_data(self) -> AirthingsDevice:
"""Get data from Airthings BLE."""
try:
data = await self.airthings.update_device(self.ble_device)
except Exception as err:
raise UpdateFailed(f"Unable to fetch data: {err}") from err
return data
@@ -24,5 +24,5 @@
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",
"iot_class": "local_polling",
"requirements": ["airthings-ble==0.9.1"]
"requirements": ["airthings-ble==0.9.2"]
}
@@ -34,8 +34,8 @@ from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util.unit_system import METRIC_SYSTEM
from . import AirthingsBLEConfigEntry, AirthingsBLEDataUpdateCoordinator
from .const import DOMAIN, VOLUME_BECQUEREL, VOLUME_PICOCURIE
from .coordinator import AirthingsBLEConfigEntry, AirthingsBLEDataUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
@@ -9,8 +9,6 @@ from homeassistant.const import CONF_HOST, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from .const import DOMAIN
PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.COVER]
type Airtouch5ConfigEntry = ConfigEntry[Airtouch5SimpleClient]
@@ -19,8 +17,6 @@ type Airtouch5ConfigEntry = ConfigEntry[Airtouch5SimpleClient]
async def async_setup_entry(hass: HomeAssistant, entry: Airtouch5ConfigEntry) -> bool:
"""Set up Airtouch 5 from a config entry."""
hass.data.setdefault(DOMAIN, {})
# Create API instance
host = entry.data[CONF_HOST]
client = Airtouch5SimpleClient(host)
@@ -204,6 +204,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirVisualConfigEntry) ->
coordinator = DataUpdateCoordinator(
hass,
LOGGER,
config_entry=entry,
name=async_get_geography_id(entry.data),
# We give a placeholder update interval in order to create the coordinator;
# then, below, we use the coordinator's presence (along with any other
@@ -81,6 +81,7 @@ async def async_setup_entry(
coordinator = DataUpdateCoordinator(
hass,
LOGGER,
config_entry=entry,
name="Node/Pro data",
update_interval=UPDATE_INTERVAL,
update_method=async_get_data,
@@ -24,6 +24,7 @@ PLATFORMS: list[Platform] = [
Platform.CLIMATE,
Platform.SELECT,
Platform.SENSOR,
Platform.SWITCH,
Platform.WATER_HEATER,
]
+122
View File
@@ -0,0 +1,122 @@
"""Support for the Airzone switch."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Final
from aioairzone.const import API_ON, AZD_ON, AZD_ZONES
from homeassistant.components.switch import (
SwitchDeviceClass,
SwitchEntity,
SwitchEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .entity import AirzoneEntity, AirzoneZoneEntity
@dataclass(frozen=True, kw_only=True)
class AirzoneSwitchDescription(SwitchEntityDescription):
"""Class to describe an Airzone switch entity."""
api_param: str
ZONE_SWITCH_TYPES: Final[tuple[AirzoneSwitchDescription, ...]] = (
AirzoneSwitchDescription(
api_param=API_ON,
device_class=SwitchDeviceClass.SWITCH,
key=AZD_ON,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AirzoneConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Add Airzone switch from a config_entry."""
coordinator = entry.runtime_data
added_zones: set[str] = set()
def _async_entity_listener() -> None:
"""Handle additions of switch."""
zones_data = coordinator.data.get(AZD_ZONES, {})
received_zones = set(zones_data)
new_zones = received_zones - added_zones
if new_zones:
async_add_entities(
AirzoneZoneSwitch(
coordinator,
description,
entry,
system_zone_id,
zones_data.get(system_zone_id),
)
for system_zone_id in new_zones
for description in ZONE_SWITCH_TYPES
if description.key in zones_data.get(system_zone_id)
)
added_zones.update(new_zones)
entry.async_on_unload(coordinator.async_add_listener(_async_entity_listener))
_async_entity_listener()
class AirzoneBaseSwitch(AirzoneEntity, SwitchEntity):
"""Define an Airzone switch."""
entity_description: AirzoneSwitchDescription
@callback
def _handle_coordinator_update(self) -> None:
"""Update attributes when the coordinator updates."""
self._async_update_attrs()
super()._handle_coordinator_update()
@callback
def _async_update_attrs(self) -> None:
"""Update switch attributes."""
self._attr_is_on = self.get_airzone_value(self.entity_description.key)
class AirzoneZoneSwitch(AirzoneZoneEntity, AirzoneBaseSwitch):
"""Define an Airzone Zone switch."""
def __init__(
self,
coordinator: AirzoneUpdateCoordinator,
description: AirzoneSwitchDescription,
entry: ConfigEntry,
system_zone_id: str,
zone_data: dict[str, Any],
) -> None:
"""Initialize."""
super().__init__(coordinator, entry, system_zone_id, zone_data)
self._attr_name = None
self._attr_unique_id = (
f"{self._attr_unique_id}_{system_zone_id}_{description.key}"
)
self.entity_description = description
self._async_update_attrs()
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the entity on."""
param = self.entity_description.api_param
await self._async_update_hvac_params({param: True})
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off."""
param = self.entity_description.api_param
await self._async_update_hvac_params({param: False})
@@ -17,6 +17,7 @@ PLATFORMS: list[Platform] = [
Platform.CLIMATE,
Platform.SELECT,
Platform.SENSOR,
Platform.SWITCH,
Platform.WATER_HEATER,
]
@@ -310,6 +310,10 @@ class AirzoneDeviceClimate(AirzoneClimate):
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
hvac_mode = kwargs.get(ATTR_HVAC_MODE)
if hvac_mode is not None:
await self.async_set_hvac_mode(hvac_mode)
params: dict[str, Any] = {}
if ATTR_TEMPERATURE in kwargs:
params[API_SETPOINT] = {
@@ -333,9 +337,6 @@ class AirzoneDeviceClimate(AirzoneClimate):
}
await self._async_update_params(params)
if ATTR_HVAC_MODE in kwargs:
await self.async_set_hvac_mode(kwargs[ATTR_HVAC_MODE])
class AirzoneDeviceGroupClimate(AirzoneClimate):
"""Define an Airzone Cloud DeviceGroup base class."""
@@ -366,6 +367,10 @@ class AirzoneDeviceGroupClimate(AirzoneClimate):
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
hvac_mode = kwargs.get(ATTR_HVAC_MODE)
if hvac_mode is not None:
await self.async_set_hvac_mode(hvac_mode)
params: dict[str, Any] = {}
if ATTR_TEMPERATURE in kwargs:
params[API_PARAMS] = {
@@ -376,9 +381,6 @@ class AirzoneDeviceGroupClimate(AirzoneClimate):
}
await self._async_update_params(params)
if ATTR_HVAC_MODE in kwargs:
await self.async_set_hvac_mode(kwargs[ATTR_HVAC_MODE])
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set hvac mode."""
params: dict[str, Any] = {
@@ -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.7"]
"requirements": ["aioairzone-cloud==0.6.10"]
}
@@ -2,14 +2,19 @@
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any, Final
from aioairzone_cloud.common import AirQualityMode
from aioairzone_cloud.common import AirQualityMode, OperationMode
from aioairzone_cloud.const import (
API_AQ_MODE_CONF,
API_MODE,
API_VALUE,
AZD_AQ_MODE_CONF,
AZD_MASTER,
AZD_MODE,
AZD_MODES,
AZD_ZONES,
)
@@ -28,7 +33,10 @@ class AirzoneSelectDescription(SelectEntityDescription):
"""Class to describe an Airzone select entity."""
api_param: str
options_dict: dict[str, str]
options_dict: dict[str, Any]
options_fn: Callable[[dict[str, Any], dict[str, Any]], list[str]] = (
lambda zone_data, value: list(value)
)
AIR_QUALITY_MAP: Final[dict[str, str]] = {
@@ -37,6 +45,35 @@ AIR_QUALITY_MAP: Final[dict[str, str]] = {
"auto": AirQualityMode.AUTO,
}
MODE_MAP: Final[dict[str, int]] = {
"cool": OperationMode.COOLING,
"dry": OperationMode.DRY,
"fan": OperationMode.VENTILATION,
"heat": OperationMode.HEATING,
"heat_cool": OperationMode.AUTO,
"stop": OperationMode.STOP,
}
def main_zone_options(
zone_data: dict[str, Any],
options: dict[str, int],
) -> list[str]:
"""Filter available modes."""
modes = zone_data.get(AZD_MODES, [])
return [k for k, v in options.items() if v in modes]
MAIN_ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
AirzoneSelectDescription(
api_param=API_MODE,
key=AZD_MODE,
options_dict=MODE_MAP,
options_fn=main_zone_options,
translation_key="modes",
),
)
ZONE_SELECT_TYPES: Final[tuple[AirzoneSelectDescription, ...]] = (
AirzoneSelectDescription(
@@ -59,7 +96,19 @@ async def async_setup_entry(
coordinator = entry.runtime_data
# Zones
async_add_entities(
entities: list[AirzoneZoneSelect] = [
AirzoneZoneSelect(
coordinator,
description,
zone_id,
zone_data,
)
for description in MAIN_ZONE_SELECT_TYPES
for zone_id, zone_data in coordinator.data.get(AZD_ZONES, {}).items()
if description.key in zone_data and zone_data.get(AZD_MASTER)
]
entities.extend(
AirzoneZoneSelect(
coordinator,
description,
@@ -71,6 +120,8 @@ async def async_setup_entry(
if description.key in zone_data
)
async_add_entities(entities)
class AirzoneBaseSelect(AirzoneEntity, SelectEntity):
"""Define an Airzone Cloud select."""
@@ -110,6 +161,11 @@ class AirzoneZoneSelect(AirzoneZoneEntity, AirzoneBaseSelect):
self._attr_unique_id = f"{zone_id}_{description.key}"
self.entity_description = description
self._attr_options = self.entity_description.options_fn(
zone_data, description.options_dict
)
self.values_dict = {v: k for k, v in description.options_dict.items()}
self._async_update_attrs()
@@ -36,6 +36,17 @@
"on": "On",
"auto": "Auto"
}
},
"modes": {
"name": "Mode",
"state": {
"cool": "[%key:component::climate::entity_component::_::state::cool%]",
"dry": "[%key:component::climate::entity_component::_::state::dry%]",
"fan": "[%key:component::climate::entity_component::_::state::fan_only%]",
"heat": "[%key:component::climate::entity_component::_::state::heat%]",
"heat_cool": "[%key:component::climate::entity_component::_::state::heat_cool%]",
"stop": "Stop"
}
}
},
"sensor": {
@@ -0,0 +1,115 @@
"""Support for the Airzone Cloud switch."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Final
from aioairzone_cloud.const import API_POWER, API_VALUE, AZD_POWER, AZD_ZONES
from homeassistant.components.switch import (
SwitchDeviceClass,
SwitchEntity,
SwitchEntityDescription,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneCloudConfigEntry
from .coordinator import AirzoneUpdateCoordinator
from .entity import AirzoneEntity, AirzoneZoneEntity
@dataclass(frozen=True, kw_only=True)
class AirzoneSwitchDescription(SwitchEntityDescription):
"""Class to describe an Airzone switch entity."""
api_param: str
ZONE_SWITCH_TYPES: Final[tuple[AirzoneSwitchDescription, ...]] = (
AirzoneSwitchDescription(
api_param=API_POWER,
device_class=SwitchDeviceClass.SWITCH,
key=AZD_POWER,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: AirzoneCloudConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Add Airzone Cloud switch from a config_entry."""
coordinator = entry.runtime_data
# Zones
async_add_entities(
AirzoneZoneSwitch(
coordinator,
description,
zone_id,
zone_data,
)
for description in ZONE_SWITCH_TYPES
for zone_id, zone_data in coordinator.data.get(AZD_ZONES, {}).items()
if description.key in zone_data
)
class AirzoneBaseSwitch(AirzoneEntity, SwitchEntity):
"""Define an Airzone Cloud switch."""
entity_description: AirzoneSwitchDescription
@callback
def _handle_coordinator_update(self) -> None:
"""Update attributes when the coordinator updates."""
self._async_update_attrs()
super()._handle_coordinator_update()
@callback
def _async_update_attrs(self) -> None:
"""Update switch attributes."""
self._attr_is_on = self.get_airzone_value(self.entity_description.key)
class AirzoneZoneSwitch(AirzoneZoneEntity, AirzoneBaseSwitch):
"""Define an Airzone Cloud Zone switch."""
def __init__(
self,
coordinator: AirzoneUpdateCoordinator,
description: AirzoneSwitchDescription,
zone_id: str,
zone_data: dict[str, Any],
) -> None:
"""Initialize."""
super().__init__(coordinator, zone_id, zone_data)
self._attr_name = None
self._attr_unique_id = f"{zone_id}_{description.key}"
self.entity_description = description
self._async_update_attrs()
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the entity on."""
param = self.entity_description.api_param
params: dict[str, Any] = {
param: {
API_VALUE: True,
}
}
await self._async_update_params(params)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off."""
param = self.entity_description.api_param
params: dict[str, Any] = {
param: {
API_VALUE: False,
}
}
await self._async_update_params(params)
@@ -2,6 +2,7 @@
from __future__ import annotations
import asyncio
from datetime import timedelta
from functools import partial
import logging
@@ -33,6 +34,7 @@ from homeassistant.helpers.deprecation import (
)
from homeassistant.helpers.entity import Entity, EntityDescription
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity_platform import EntityPlatform
from homeassistant.helpers.typing import ConfigType
from homeassistant.util.hass_dict import HassKey
@@ -49,6 +51,7 @@ from .const import ( # noqa: F401
ATTR_CODE_ARM_REQUIRED,
DOMAIN,
AlarmControlPanelEntityFeature,
AlarmControlPanelState,
CodeFormat,
)
@@ -142,6 +145,7 @@ CACHED_PROPERTIES_WITH_ATTR_ = {
"changed_by",
"code_arm_required",
"supported_features",
"alarm_state",
}
@@ -149,6 +153,7 @@ class AlarmControlPanelEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_A
"""An abstract class for alarm control entities."""
entity_description: AlarmControlPanelEntityDescription
_attr_alarm_state: AlarmControlPanelState | None = None
_attr_changed_by: str | None = None
_attr_code_arm_required: bool = True
_attr_code_format: CodeFormat | None = None
@@ -157,6 +162,78 @@ class AlarmControlPanelEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_A
)
_alarm_control_panel_option_default_code: str | None = None
__alarm_legacy_state: bool = False
__alarm_legacy_state_reported: bool = False
def __init_subclass__(cls, **kwargs: Any) -> None:
"""Post initialisation processing."""
super().__init_subclass__(**kwargs)
if any(method in cls.__dict__ for method in ("_attr_state", "state")):
# Integrations should use the 'alarm_state' property instead of
# setting the state directly.
cls.__alarm_legacy_state = True
def __setattr__(self, __name: str, __value: Any) -> None:
"""Set attribute.
Deprecation warning if setting '_attr_state' directly
unless already reported.
"""
if __name == "_attr_state":
if self.__alarm_legacy_state_reported is not True:
self._report_deprecated_alarm_state_handling()
self.__alarm_legacy_state_reported = True
return super().__setattr__(__name, __value)
@callback
def add_to_platform_start(
self,
hass: HomeAssistant,
platform: EntityPlatform,
parallel_updates: asyncio.Semaphore | None,
) -> None:
"""Start adding an entity to a platform."""
super().add_to_platform_start(hass, platform, parallel_updates)
if self.__alarm_legacy_state and not self.__alarm_legacy_state_reported:
self._report_deprecated_alarm_state_handling()
@callback
def _report_deprecated_alarm_state_handling(self) -> None:
"""Report on deprecated handling of alarm state.
Integrations should implement alarm_state instead of using state directly.
"""
self.__alarm_legacy_state_reported = True
if "custom_components" in type(self).__module__:
# Do not report on core integrations as they have been fixed.
report_issue = "report it to the custom integration author."
_LOGGER.warning(
"Entity %s (%s) is setting state directly"
" which will stop working in HA Core 2025.11."
" Entities should implement the 'alarm_state' property and"
" return its state using the AlarmControlPanelState enum, please %s",
self.entity_id,
type(self),
report_issue,
)
@final
@property
def state(self) -> str | None:
"""Return the current state."""
if (alarm_state := self.alarm_state) is None:
return None
return alarm_state
@cached_property
def alarm_state(self) -> AlarmControlPanelState | None:
"""Return the current alarm control panel entity state.
Integrations should overwrite this or use the '_attr_alarm_state'
attribute to set the alarm status using the 'AlarmControlPanelState' enum.
"""
return self._attr_alarm_state
@final
@callback
def code_or_default_code(self, code: str | None) -> str | None:
@@ -17,6 +17,21 @@ ATTR_CHANGED_BY: Final = "changed_by"
ATTR_CODE_ARM_REQUIRED: Final = "code_arm_required"
class AlarmControlPanelState(StrEnum):
"""Alarm control panel entity states."""
DISARMED = "disarmed"
ARMED_HOME = "armed_home"
ARMED_AWAY = "armed_away"
ARMED_NIGHT = "armed_night"
ARMED_VACATION = "armed_vacation"
ARMED_CUSTOM_BYPASS = "armed_custom_bypass"
PENDING = "pending"
ARMING = "arming"
DISARMING = "disarming"
TRIGGERED = "triggered"
class CodeFormat(StrEnum):
"""Code formats for the Alarm Control Panel."""
@@ -13,13 +13,6 @@ from homeassistant.const import (
CONF_DOMAIN,
CONF_ENTITY_ID,
CONF_TYPE,
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_CUSTOM_BYPASS,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_ARMED_VACATION,
STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import (
@@ -31,7 +24,7 @@ from homeassistant.helpers.config_validation import DEVICE_CONDITION_BASE_SCHEMA
from homeassistant.helpers.entity import get_supported_features
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
from . import DOMAIN
from . import DOMAIN, AlarmControlPanelState
from .const import (
CONDITION_ARMED_AWAY,
CONDITION_ARMED_CUSTOM_BYPASS,
@@ -109,19 +102,19 @@ def async_condition_from_config(
) -> condition.ConditionCheckerType:
"""Create a function to test a device condition."""
if config[CONF_TYPE] == CONDITION_TRIGGERED:
state = STATE_ALARM_TRIGGERED
state = AlarmControlPanelState.TRIGGERED
elif config[CONF_TYPE] == CONDITION_DISARMED:
state = STATE_ALARM_DISARMED
state = AlarmControlPanelState.DISARMED
elif config[CONF_TYPE] == CONDITION_ARMED_HOME:
state = STATE_ALARM_ARMED_HOME
state = AlarmControlPanelState.ARMED_HOME
elif config[CONF_TYPE] == CONDITION_ARMED_AWAY:
state = STATE_ALARM_ARMED_AWAY
state = AlarmControlPanelState.ARMED_AWAY
elif config[CONF_TYPE] == CONDITION_ARMED_NIGHT:
state = STATE_ALARM_ARMED_NIGHT
state = AlarmControlPanelState.ARMED_NIGHT
elif config[CONF_TYPE] == CONDITION_ARMED_VACATION:
state = STATE_ALARM_ARMED_VACATION
state = AlarmControlPanelState.ARMED_VACATION
elif config[CONF_TYPE] == CONDITION_ARMED_CUSTOM_BYPASS:
state = STATE_ALARM_ARMED_CUSTOM_BYPASS
state = AlarmControlPanelState.ARMED_CUSTOM_BYPASS
registry = er.async_get(hass)
entity_id = er.async_resolve_entity_id(registry, config[ATTR_ENTITY_ID])
@@ -15,13 +15,6 @@ from homeassistant.const import (
CONF_FOR,
CONF_PLATFORM,
CONF_TYPE,
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_ARMED_VACATION,
STATE_ALARM_ARMING,
STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED,
)
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
from homeassistant.helpers import config_validation as cv, entity_registry as er
@@ -29,7 +22,7 @@ from homeassistant.helpers.entity import get_supported_features
from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo
from homeassistant.helpers.typing import ConfigType
from . import DOMAIN
from . import DOMAIN, AlarmControlPanelState
from .const import AlarmControlPanelEntityFeature
BASIC_TRIGGER_TYPES: Final[set[str]] = {"triggered", "disarmed", "arming"}
@@ -129,19 +122,19 @@ async def async_attach_trigger(
) -> CALLBACK_TYPE:
"""Attach a trigger."""
if config[CONF_TYPE] == "triggered":
to_state = STATE_ALARM_TRIGGERED
to_state = AlarmControlPanelState.TRIGGERED
elif config[CONF_TYPE] == "disarmed":
to_state = STATE_ALARM_DISARMED
to_state = AlarmControlPanelState.DISARMED
elif config[CONF_TYPE] == "arming":
to_state = STATE_ALARM_ARMING
to_state = AlarmControlPanelState.ARMING
elif config[CONF_TYPE] == "armed_home":
to_state = STATE_ALARM_ARMED_HOME
to_state = AlarmControlPanelState.ARMED_HOME
elif config[CONF_TYPE] == "armed_away":
to_state = STATE_ALARM_ARMED_AWAY
to_state = AlarmControlPanelState.ARMED_AWAY
elif config[CONF_TYPE] == "armed_night":
to_state = STATE_ALARM_ARMED_NIGHT
to_state = AlarmControlPanelState.ARMED_NIGHT
elif config[CONF_TYPE] == "armed_vacation":
to_state = STATE_ALARM_ARMED_VACATION
to_state = AlarmControlPanelState.ARMED_VACATION
state_config = {
state_trigger.CONF_PLATFORM: "state",
@@ -16,28 +16,21 @@ from homeassistant.const import (
SERVICE_ALARM_ARM_VACATION,
SERVICE_ALARM_DISARM,
SERVICE_ALARM_TRIGGER,
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_CUSTOM_BYPASS,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_ARMED_VACATION,
STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED,
)
from homeassistant.core import Context, HomeAssistant, State
from . import DOMAIN
from . import DOMAIN, AlarmControlPanelState
_LOGGER: Final = logging.getLogger(__name__)
VALID_STATES: Final[set[str]] = {
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_CUSTOM_BYPASS,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_ARMED_VACATION,
STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED,
AlarmControlPanelState.ARMED_AWAY,
AlarmControlPanelState.ARMED_CUSTOM_BYPASS,
AlarmControlPanelState.ARMED_HOME,
AlarmControlPanelState.ARMED_NIGHT,
AlarmControlPanelState.ARMED_VACATION,
AlarmControlPanelState.DISARMED,
AlarmControlPanelState.TRIGGERED,
}
@@ -65,19 +58,19 @@ async def _async_reproduce_state(
service_data = {ATTR_ENTITY_ID: state.entity_id}
if state.state == STATE_ALARM_ARMED_AWAY:
if state.state == AlarmControlPanelState.ARMED_AWAY:
service = SERVICE_ALARM_ARM_AWAY
elif state.state == STATE_ALARM_ARMED_CUSTOM_BYPASS:
elif state.state == AlarmControlPanelState.ARMED_CUSTOM_BYPASS:
service = SERVICE_ALARM_ARM_CUSTOM_BYPASS
elif state.state == STATE_ALARM_ARMED_HOME:
elif state.state == AlarmControlPanelState.ARMED_HOME:
service = SERVICE_ALARM_ARM_HOME
elif state.state == STATE_ALARM_ARMED_NIGHT:
elif state.state == AlarmControlPanelState.ARMED_NIGHT:
service = SERVICE_ALARM_ARM_NIGHT
elif state.state == STATE_ALARM_ARMED_VACATION:
elif state.state == AlarmControlPanelState.ARMED_VACATION:
service = SERVICE_ALARM_ARM_VACATION
elif state.state == STATE_ALARM_DISARMED:
elif state.state == AlarmControlPanelState.DISARMED:
service = SERVICE_ALARM_DISARM
elif state.state == STATE_ALARM_TRIGGERED:
elif state.state == AlarmControlPanelState.TRIGGERED:
service = SERVICE_ALARM_TRIGGER
await hass.services.async_call(
@@ -7,16 +7,10 @@ import voluptuous as vol
from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
AlarmControlPanelEntityFeature,
AlarmControlPanelState,
CodeFormat,
)
from homeassistant.const import (
ATTR_CODE,
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED,
)
from homeassistant.const import ATTR_CODE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_platform
import homeassistant.helpers.config_validation as cv
@@ -106,15 +100,15 @@ class AlarmDecoderAlarmPanel(AlarmDecoderEntity, AlarmControlPanelEntity):
def _message_callback(self, message):
"""Handle received messages."""
if message.alarm_sounding or message.fire_alarm:
self._attr_state = STATE_ALARM_TRIGGERED
self._attr_alarm_state = AlarmControlPanelState.TRIGGERED
elif message.armed_away:
self._attr_state = STATE_ALARM_ARMED_AWAY
self._attr_alarm_state = AlarmControlPanelState.ARMED_AWAY
elif message.armed_home and (message.entry_delay_off or message.perimeter_only):
self._attr_state = STATE_ALARM_ARMED_NIGHT
self._attr_alarm_state = AlarmControlPanelState.ARMED_NIGHT
elif message.armed_home:
self._attr_state = STATE_ALARM_ARMED_HOME
self._attr_alarm_state = AlarmControlPanelState.ARMED_HOME
else:
self._attr_state = STATE_ALARM_DISARMED
self._attr_alarm_state = AlarmControlPanelState.DISARMED
self._attr_extra_state_attributes = {
"ac_power": message.ac_power,
@@ -26,6 +26,7 @@ from homeassistant.components import (
)
from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntityFeature,
AlarmControlPanelState,
CodeFormat,
)
from homeassistant.components.climate import HVACMode
@@ -36,10 +37,6 @@ from homeassistant.const import (
ATTR_TEMPERATURE,
ATTR_UNIT_OF_MEASUREMENT,
PERCENTAGE,
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_CUSTOM_BYPASS,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_IDLE,
STATE_OFF,
STATE_ON,
@@ -1317,13 +1314,13 @@ class AlexaSecurityPanelController(AlexaCapability):
raise UnsupportedProperty(name)
arm_state = self.entity.state
if arm_state == STATE_ALARM_ARMED_HOME:
if arm_state == AlarmControlPanelState.ARMED_HOME:
return "ARMED_STAY"
if arm_state == STATE_ALARM_ARMED_AWAY:
if arm_state == AlarmControlPanelState.ARMED_AWAY:
return "ARMED_AWAY"
if arm_state == STATE_ALARM_ARMED_NIGHT:
if arm_state == AlarmControlPanelState.ARMED_NIGHT:
return "ARMED_NIGHT"
if arm_state == STATE_ALARM_ARMED_CUSTOM_BYPASS:
if arm_state == AlarmControlPanelState.ARMED_CUSTOM_BYPASS:
return "ARMED_STAY"
return "DISARMED"
+9 -3
View File
@@ -9,6 +9,7 @@ from typing import Any
from homeassistant import core as ha
from homeassistant.components import (
alarm_control_panel,
button,
camera,
climate,
@@ -51,7 +52,6 @@ from homeassistant.const import (
SERVICE_VOLUME_MUTE,
SERVICE_VOLUME_SET,
SERVICE_VOLUME_UP,
STATE_ALARM_DISARMED,
UnitOfTemperature,
)
from homeassistant.helpers import network
@@ -1083,7 +1083,13 @@ async def async_api_arm(
arm_state = directive.payload["armState"]
data: dict[str, Any] = {ATTR_ENTITY_ID: entity.entity_id}
if entity.state != STATE_ALARM_DISARMED:
# Per Alexa Documentation: users are not allowed to switch from armed_away
# directly to another armed state without first disarming the system.
# https://developer.amazon.com/en-US/docs/alexa/device-apis/alexa-securitypanelcontroller.html#arming
if (
entity.state == alarm_control_panel.AlarmControlPanelState.ARMED_AWAY
and arm_state != "ARMED_AWAY"
):
msg = "You must disarm the system before you can set the requested arm state."
raise AlexaSecurityPanelAuthorizationRequired(msg)
@@ -1133,7 +1139,7 @@ async def async_api_disarm(
# Per Alexa Documentation: If you receive a Disarm directive, and the
# system is already disarmed, respond with a success response,
# not an error response.
if entity.state == STATE_ALARM_DISARMED:
if entity.state == alarm_control_panel.AlarmControlPanelState.DISARMED:
return response
payload = directive.payload
@@ -29,6 +29,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.entity_registry as er
from homeassistant.helpers.hassio import is_hassio
from homeassistant.helpers.storage import Store
from homeassistant.helpers.system_info import async_get_system_info
from homeassistant.loader import (
@@ -136,7 +137,7 @@ class Analytics:
@property
def supervisor(self) -> bool:
"""Return bool if a supervisor is present."""
return hassio.is_hassio(self.hass)
return is_hassio(self.hass)
async def load(self) -> None:
"""Load preferences."""
@@ -1,7 +1,7 @@
{
"domain": "analytics",
"name": "Analytics",
"after_dependencies": ["energy", "recorder"],
"after_dependencies": ["energy", "hassio", "recorder"],
"codeowners": ["@home-assistant/core", "@ludeeus"],
"dependencies": ["api", "websocket_api"],
"documentation": "https://www.home-assistant.io/integrations/analytics",
@@ -16,7 +16,6 @@ from homeassistant.config_entries import (
ConfigFlow,
ConfigFlowResult,
OptionsFlow,
OptionsFlowWithConfigEntry,
)
from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_get_clientsession
@@ -27,6 +26,7 @@ from homeassistant.helpers.selector import (
)
from .const import (
CONF_TRACKED_ADDONS,
CONF_TRACKED_CUSTOM_INTEGRATIONS,
CONF_TRACKED_INTEGRATIONS,
DOMAIN,
@@ -45,9 +45,11 @@ class HomeassistantAnalyticsConfigFlow(ConfigFlow, domain=DOMAIN):
@staticmethod
@callback
def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow:
def async_get_options_flow(
config_entry: ConfigEntry,
) -> HomeassistantAnalyticsOptionsFlowHandler:
"""Get the options flow for this handler."""
return HomeassistantAnalyticsOptionsFlowHandler(config_entry)
return HomeassistantAnalyticsOptionsFlowHandler()
async def async_step_user(
self, user_input: dict[str, Any] | None = None
@@ -55,8 +57,12 @@ class HomeassistantAnalyticsConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle the initial step."""
errors: dict[str, str] = {}
if user_input is not None:
if not user_input.get(CONF_TRACKED_INTEGRATIONS) and not user_input.get(
CONF_TRACKED_CUSTOM_INTEGRATIONS
if all(
[
not user_input.get(CONF_TRACKED_ADDONS),
not user_input.get(CONF_TRACKED_INTEGRATIONS),
not user_input.get(CONF_TRACKED_CUSTOM_INTEGRATIONS),
]
):
errors["base"] = "no_integrations_selected"
else:
@@ -64,6 +70,7 @@ class HomeassistantAnalyticsConfigFlow(ConfigFlow, domain=DOMAIN):
title="Home Assistant Analytics Insights",
data={},
options={
CONF_TRACKED_ADDONS: user_input.get(CONF_TRACKED_ADDONS, []),
CONF_TRACKED_INTEGRATIONS: user_input.get(
CONF_TRACKED_INTEGRATIONS, []
),
@@ -77,6 +84,7 @@ class HomeassistantAnalyticsConfigFlow(ConfigFlow, domain=DOMAIN):
session=async_get_clientsession(self.hass)
)
try:
addons = await client.get_addons()
integrations = await client.get_integrations()
custom_integrations = await client.get_custom_integrations()
except HomeassistantAnalyticsConnectionError:
@@ -99,6 +107,13 @@ class HomeassistantAnalyticsConfigFlow(ConfigFlow, domain=DOMAIN):
errors=errors,
data_schema=vol.Schema(
{
vol.Optional(CONF_TRACKED_ADDONS): SelectSelector(
SelectSelectorConfig(
options=list(addons),
multiple=True,
sort=True,
)
),
vol.Optional(CONF_TRACKED_INTEGRATIONS): SelectSelector(
SelectSelectorConfig(
options=options,
@@ -118,7 +133,7 @@ class HomeassistantAnalyticsConfigFlow(ConfigFlow, domain=DOMAIN):
)
class HomeassistantAnalyticsOptionsFlowHandler(OptionsFlowWithConfigEntry):
class HomeassistantAnalyticsOptionsFlowHandler(OptionsFlow):
"""Handle Homeassistant Analytics options."""
async def async_step_init(
@@ -127,14 +142,19 @@ class HomeassistantAnalyticsOptionsFlowHandler(OptionsFlowWithConfigEntry):
"""Manage the options."""
errors: dict[str, str] = {}
if user_input is not None:
if not user_input.get(CONF_TRACKED_INTEGRATIONS) and not user_input.get(
CONF_TRACKED_CUSTOM_INTEGRATIONS
if all(
[
not user_input.get(CONF_TRACKED_ADDONS),
not user_input.get(CONF_TRACKED_INTEGRATIONS),
not user_input.get(CONF_TRACKED_CUSTOM_INTEGRATIONS),
]
):
errors["base"] = "no_integrations_selected"
else:
return self.async_create_entry(
title="",
data={
CONF_TRACKED_ADDONS: user_input.get(CONF_TRACKED_ADDONS, []),
CONF_TRACKED_INTEGRATIONS: user_input.get(
CONF_TRACKED_INTEGRATIONS, []
),
@@ -148,6 +168,7 @@ class HomeassistantAnalyticsOptionsFlowHandler(OptionsFlowWithConfigEntry):
session=async_get_clientsession(self.hass)
)
try:
addons = await client.get_addons()
integrations = await client.get_integrations()
custom_integrations = await client.get_custom_integrations()
except HomeassistantAnalyticsConnectionError:
@@ -168,6 +189,13 @@ class HomeassistantAnalyticsOptionsFlowHandler(OptionsFlowWithConfigEntry):
data_schema=self.add_suggested_values_to_schema(
vol.Schema(
{
vol.Optional(CONF_TRACKED_ADDONS): SelectSelector(
SelectSelectorConfig(
options=list(addons),
multiple=True,
sort=True,
)
),
vol.Optional(CONF_TRACKED_INTEGRATIONS): SelectSelector(
SelectSelectorConfig(
options=options,
@@ -184,6 +212,6 @@ class HomeassistantAnalyticsOptionsFlowHandler(OptionsFlowWithConfigEntry):
),
},
),
self.options,
self.config_entry.options,
),
)
@@ -4,6 +4,7 @@ import logging
DOMAIN = "analytics_insights"
CONF_TRACKED_ADDONS = "tracked_addons"
CONF_TRACKED_INTEGRATIONS = "tracked_integrations"
CONF_TRACKED_CUSTOM_INTEGRATIONS = "tracked_custom_integrations"
@@ -12,11 +12,13 @@ from python_homeassistant_analytics import (
HomeassistantAnalyticsConnectionError,
HomeassistantAnalyticsNotModifiedError,
)
from python_homeassistant_analytics.models import Addon
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import (
CONF_TRACKED_ADDONS,
CONF_TRACKED_CUSTOM_INTEGRATIONS,
CONF_TRACKED_INTEGRATIONS,
DOMAIN,
@@ -33,6 +35,7 @@ class AnalyticsData:
active_installations: int
reports_integrations: int
addons: dict[str, int]
core_integrations: dict[str, int]
custom_integrations: dict[str, int]
@@ -53,6 +56,7 @@ class HomeassistantAnalyticsDataUpdateCoordinator(DataUpdateCoordinator[Analytic
update_interval=timedelta(hours=12),
)
self._client = client
self._tracked_addons = self.config_entry.options.get(CONF_TRACKED_ADDONS, [])
self._tracked_integrations = self.config_entry.options[
CONF_TRACKED_INTEGRATIONS
]
@@ -62,6 +66,7 @@ class HomeassistantAnalyticsDataUpdateCoordinator(DataUpdateCoordinator[Analytic
async def _async_update_data(self) -> AnalyticsData:
try:
addons_data = await self._client.get_addons()
data = await self._client.get_current_analytics()
custom_data = await self._client.get_custom_integrations()
except HomeassistantAnalyticsConnectionError as err:
@@ -70,6 +75,9 @@ class HomeassistantAnalyticsDataUpdateCoordinator(DataUpdateCoordinator[Analytic
) from err
except HomeassistantAnalyticsNotModifiedError:
return self.data
addons = {
addon: get_addon_value(addons_data, addon) for addon in self._tracked_addons
}
core_integrations = {
integration: data.integrations.get(integration, 0)
for integration in self._tracked_integrations
@@ -81,11 +89,19 @@ class HomeassistantAnalyticsDataUpdateCoordinator(DataUpdateCoordinator[Analytic
return AnalyticsData(
data.active_installations,
data.reports_integrations,
addons,
core_integrations,
custom_integrations,
)
def get_addon_value(data: dict[str, Addon], name_slug: str) -> int:
"""Get addon value."""
if name_slug in data:
return data[name_slug].total
return 0
def get_custom_integration_value(
data: dict[str, CustomIntegration], domain: str
) -> int:
@@ -29,6 +29,20 @@ class AnalyticsSensorEntityDescription(SensorEntityDescription):
value_fn: Callable[[AnalyticsData], StateType]
def get_addon_entity_description(
name_slug: str,
) -> AnalyticsSensorEntityDescription:
"""Get addon entity description."""
return AnalyticsSensorEntityDescription(
key=f"addon_{name_slug}_active_installations",
translation_key="addons",
name=name_slug,
state_class=SensorStateClass.TOTAL,
native_unit_of_measurement="active installations",
value_fn=lambda data: data.addons.get(name_slug),
)
def get_core_integration_entity_description(
domain: str, name: str
) -> AnalyticsSensorEntityDescription:
@@ -89,6 +103,13 @@ async def async_setup_entry(
analytics_data.coordinator
)
entities: list[HomeassistantAnalyticsSensor] = []
entities.extend(
HomeassistantAnalyticsSensor(
coordinator,
get_addon_entity_description(addon_name_slug),
)
for addon_name_slug in coordinator.data.addons
)
entities.extend(
HomeassistantAnalyticsSensor(
coordinator,
@@ -3,10 +3,12 @@
"step": {
"user": {
"data": {
"tracked_addons": "Addons",
"tracked_integrations": "Integrations",
"tracked_custom_integrations": "Custom integrations"
},
"data_description": {
"tracked_addons": "Select the addons you want to track",
"tracked_integrations": "Select the integrations you want to track",
"tracked_custom_integrations": "Select the custom integrations you want to track"
}
@@ -24,10 +26,12 @@
"step": {
"init": {
"data": {
"tracked_addons": "[%key:component::analytics_insights::config::step::user::data::tracked_addons%]",
"tracked_integrations": "[%key:component::analytics_insights::config::step::user::data::tracked_integrations%]",
"tracked_custom_integrations": "[%key:component::analytics_insights::config::step::user::data::tracked_custom_integrations%]"
},
"data_description": {
"tracked_addons": "[%key:component::analytics_insights::config::step::user::data_description::tracked_addons%]",
"tracked_integrations": "[%key:component::analytics_insights::config::step::user::data_description::tracked_integrations%]",
"tracked_custom_integrations": "[%key:component::analytics_insights::config::step::user::data_description::tracked_custom_integrations%]"
}
@@ -4,6 +4,7 @@ from __future__ import annotations
from collections.abc import Mapping
from dataclasses import dataclass
import logging
import os
from typing import Any
@@ -40,6 +41,7 @@ from .const import (
CONF_ADB_SERVER_IP,
CONF_ADB_SERVER_PORT,
CONF_ADBKEY,
CONF_SCREENCAP_INTERVAL,
CONF_STATE_DETECTION_RULES,
DEFAULT_ADB_SERVER_PORT,
DEVICE_ANDROIDTV,
@@ -66,6 +68,8 @@ RELOAD_OPTIONS = [CONF_STATE_DETECTION_RULES]
_INVALID_MACS = {"ff:ff:ff:ff:ff:ff"}
_LOGGER = logging.getLogger(__name__)
@dataclass
class AndroidTVRuntimeData:
@@ -157,6 +161,32 @@ async def async_connect_androidtv(
return aftv, None
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Migrate old entry."""
_LOGGER.debug(
"Migrating configuration from version %s.%s", entry.version, entry.minor_version
)
if entry.version == 1:
new_options = {**entry.options}
# Migrate MinorVersion 1 -> MinorVersion 2: New option
if entry.minor_version < 2:
new_options = {**new_options, CONF_SCREENCAP_INTERVAL: 0}
hass.config_entries.async_update_entry(
entry, options=new_options, minor_version=2, version=1
)
_LOGGER.debug(
"Migration to configuration version %s.%s successful",
entry.version,
entry.minor_version,
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: AndroidTVConfigEntry) -> bool:
"""Set up Android Debug Bridge platform."""
@@ -13,7 +13,7 @@ from homeassistant.config_entries import (
ConfigEntry,
ConfigFlow,
ConfigFlowResult,
OptionsFlowWithConfigEntry,
OptionsFlow,
)
from homeassistant.const import CONF_DEVICE_CLASS, CONF_HOST, CONF_PORT
from homeassistant.core import callback
@@ -34,7 +34,7 @@ from .const import (
CONF_APPS,
CONF_EXCLUDE_UNNAMED_APPS,
CONF_GET_SOURCES,
CONF_SCREENCAP,
CONF_SCREENCAP_INTERVAL,
CONF_STATE_DETECTION_RULES,
CONF_TURN_OFF_COMMAND,
CONF_TURN_ON_COMMAND,
@@ -43,7 +43,7 @@ from .const import (
DEFAULT_EXCLUDE_UNNAMED_APPS,
DEFAULT_GET_SOURCES,
DEFAULT_PORT,
DEFAULT_SCREENCAP,
DEFAULT_SCREENCAP_INTERVAL,
DEVICE_CLASSES,
DOMAIN,
PROP_ETHMAC,
@@ -76,6 +76,7 @@ class AndroidTVFlowHandler(ConfigFlow, domain=DOMAIN):
"""Handle a config flow."""
VERSION = 1
MINOR_VERSION = 2
@callback
def _show_setup_form(
@@ -185,16 +186,14 @@ class AndroidTVFlowHandler(ConfigFlow, domain=DOMAIN):
return OptionsFlowHandler(config_entry)
class OptionsFlowHandler(OptionsFlowWithConfigEntry):
class OptionsFlowHandler(OptionsFlow):
"""Handle an option flow for Android Debug Bridge."""
def __init__(self, config_entry: ConfigEntry) -> None:
"""Initialize options flow."""
super().__init__(config_entry)
self._apps: dict[str, Any] = self.options.setdefault(CONF_APPS, {})
self._state_det_rules: dict[str, Any] = self.options.setdefault(
CONF_STATE_DETECTION_RULES, {}
self._apps: dict[str, Any] = dict(config_entry.options.get(CONF_APPS, {}))
self._state_det_rules: dict[str, Any] = dict(
config_entry.options.get(CONF_STATE_DETECTION_RULES, {})
)
self._conf_app_id: str | None = None
self._conf_rule_id: str | None = None
@@ -236,7 +235,7 @@ class OptionsFlowHandler(OptionsFlowWithConfigEntry):
SelectOptionDict(value=k, label=v) for k, v in apps_list.items()
]
rules = [RULES_NEW_ID, *self._state_det_rules]
options = self.options
options = self.config_entry.options
data_schema = vol.Schema(
{
@@ -253,10 +252,12 @@ class OptionsFlowHandler(OptionsFlowWithConfigEntry):
CONF_EXCLUDE_UNNAMED_APPS, DEFAULT_EXCLUDE_UNNAMED_APPS
),
): bool,
vol.Optional(
CONF_SCREENCAP,
default=options.get(CONF_SCREENCAP, DEFAULT_SCREENCAP),
): bool,
vol.Required(
CONF_SCREENCAP_INTERVAL,
default=options.get(
CONF_SCREENCAP_INTERVAL, DEFAULT_SCREENCAP_INTERVAL
),
): vol.All(vol.Coerce(int), vol.Clamp(min=0, max=15)),
vol.Optional(
CONF_TURN_OFF_COMMAND,
description={
+2 -1
View File
@@ -9,6 +9,7 @@ CONF_APPS = "apps"
CONF_EXCLUDE_UNNAMED_APPS = "exclude_unnamed_apps"
CONF_GET_SOURCES = "get_sources"
CONF_SCREENCAP = "screencap"
CONF_SCREENCAP_INTERVAL = "screencap_interval"
CONF_STATE_DETECTION_RULES = "state_detection_rules"
CONF_TURN_OFF_COMMAND = "turn_off_command"
CONF_TURN_ON_COMMAND = "turn_on_command"
@@ -18,7 +19,7 @@ DEFAULT_DEVICE_CLASS = "auto"
DEFAULT_EXCLUDE_UNNAMED_APPS = False
DEFAULT_GET_SOURCES = True
DEFAULT_PORT = 5555
DEFAULT_SCREENCAP = True
DEFAULT_SCREENCAP_INTERVAL = 5
DEVICE_ANDROIDTV = "androidtv"
DEVICE_FIRETV = "firetv"
@@ -2,10 +2,9 @@
from __future__ import annotations
from datetime import timedelta
from datetime import datetime, timedelta
import hashlib
import logging
from typing import Any
from androidtv.constants import APPS, KEYS
from androidtv.setup_async import AndroidTVAsync, FireTVAsync
@@ -23,19 +22,19 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import Throttle
from homeassistant.util.dt import utcnow
from . import AndroidTVConfigEntry
from .const import (
CONF_APPS,
CONF_EXCLUDE_UNNAMED_APPS,
CONF_GET_SOURCES,
CONF_SCREENCAP,
CONF_SCREENCAP_INTERVAL,
CONF_TURN_OFF_COMMAND,
CONF_TURN_ON_COMMAND,
DEFAULT_EXCLUDE_UNNAMED_APPS,
DEFAULT_GET_SOURCES,
DEFAULT_SCREENCAP,
DEFAULT_SCREENCAP_INTERVAL,
DEVICE_ANDROIDTV,
SIGNAL_CONFIG_ENTITY,
)
@@ -48,8 +47,6 @@ ATTR_DEVICE_PATH = "device_path"
ATTR_HDMI_INPUT = "hdmi_input"
ATTR_LOCAL_PATH = "local_path"
MIN_TIME_BETWEEN_SCREENCAPS = timedelta(seconds=60)
SERVICE_ADB_COMMAND = "adb_command"
SERVICE_DOWNLOAD = "download"
SERVICE_LEARN_SENDEVENT = "learn_sendevent"
@@ -125,7 +122,8 @@ class ADBDevice(AndroidTVEntity, MediaPlayerEntity):
self._app_name_to_id: dict[str, str] = {}
self._get_sources = DEFAULT_GET_SOURCES
self._exclude_unnamed_apps = DEFAULT_EXCLUDE_UNNAMED_APPS
self._screencap = DEFAULT_SCREENCAP
self._screencap_delta: timedelta | None = None
self._last_screencap: datetime | None = None
self.turn_on_command: str | None = None
self.turn_off_command: str | None = None
@@ -159,7 +157,13 @@ class ADBDevice(AndroidTVEntity, MediaPlayerEntity):
self._exclude_unnamed_apps = options.get(
CONF_EXCLUDE_UNNAMED_APPS, DEFAULT_EXCLUDE_UNNAMED_APPS
)
self._screencap = options.get(CONF_SCREENCAP, DEFAULT_SCREENCAP)
screencap_interval: int = options.get(
CONF_SCREENCAP_INTERVAL, DEFAULT_SCREENCAP_INTERVAL
)
if screencap_interval > 0:
self._screencap_delta = timedelta(minutes=screencap_interval)
else:
self._screencap_delta = None
self.turn_off_command = options.get(CONF_TURN_OFF_COMMAND)
self.turn_on_command = options.get(CONF_TURN_ON_COMMAND)
@@ -183,7 +187,7 @@ class ADBDevice(AndroidTVEntity, MediaPlayerEntity):
async def _async_get_screencap(self, prev_app_id: str | None = None) -> None:
"""Take a screen capture from the device when enabled."""
if (
not self._screencap
not self._screencap_delta
or self.state in {MediaPlayerState.OFF, None}
or not self.available
):
@@ -193,11 +197,18 @@ class ADBDevice(AndroidTVEntity, MediaPlayerEntity):
force: bool = prev_app_id is not None
if force:
force = prev_app_id != self._attr_app_id
await self._adb_get_screencap(no_throttle=force)
await self._adb_get_screencap(force)
@Throttle(MIN_TIME_BETWEEN_SCREENCAPS)
async def _adb_get_screencap(self, **kwargs: Any) -> None:
"""Take a screen capture from the device every 60 seconds."""
async def _adb_get_screencap(self, force: bool = False) -> None:
"""Take a screen capture from the device every configured minutes."""
time_elapsed = self._screencap_delta is not None and (
self._last_screencap is None
or (utcnow() - self._last_screencap) >= self._screencap_delta
)
if not (force or time_elapsed):
return
self._last_screencap = utcnow()
if media_data := await self._adb_screencap():
self._media_image = media_data, "image/png"
self._attr_media_image_hash = hashlib.sha256(media_data).hexdigest()[:16]
@@ -31,7 +31,7 @@
"apps": "Configure applications list",
"get_sources": "Retrieve the running apps as the list of sources",
"exclude_unnamed_apps": "Exclude apps with unknown name from the sources list",
"screencap": "Use screen capture for album art",
"screencap_interval": "Interval in minutes between screen capture for album art (set 0 to disable)",
"state_detection_rules": "Configure state detection rules",
"turn_off_command": "ADB shell turn off command (leave empty for default)",
"turn_on_command": "ADB shell turn on command (leave empty for default)"
@@ -20,7 +20,7 @@ from homeassistant.config_entries import (
ConfigEntry,
ConfigFlow,
ConfigFlowResult,
OptionsFlowWithConfigEntry,
OptionsFlow,
)
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME
from homeassistant.core import callback
@@ -221,13 +221,12 @@ class AndroidTVRemoteConfigFlow(ConfigFlow, domain=DOMAIN):
return AndroidTVRemoteOptionsFlowHandler(config_entry)
class AndroidTVRemoteOptionsFlowHandler(OptionsFlowWithConfigEntry):
class AndroidTVRemoteOptionsFlowHandler(OptionsFlow):
"""Android TV Remote options flow."""
def __init__(self, config_entry: ConfigEntry) -> None:
"""Initialize options flow."""
super().__init__(config_entry)
self._apps: dict[str, Any] = self.options.setdefault(CONF_APPS, {})
self._apps: dict[str, Any] = dict(config_entry.options.get(CONF_APPS, {}))
self._conf_app_id: str | None = None
@callback
+23 -1
View File
@@ -13,7 +13,7 @@ from anova_wifi import (
WebsocketFailure,
)
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.const import CONF_DEVICES, CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client
@@ -71,3 +71,25 @@ async def async_unload_entry(hass: HomeAssistant, entry: AnovaConfigEntry) -> bo
# Disconnect from WS
await entry.runtime_data.api.disconnect_websocket()
return unload_ok
async def async_migrate_entry(hass: HomeAssistant, entry: AnovaConfigEntry) -> bool:
"""Migrate entry."""
_LOGGER.debug("Migrating from version %s:%s", entry.version, entry.minor_version)
if entry.version > 1:
# This means the user has downgraded from a future version
return False
if entry.version == 1 and entry.minor_version == 1:
new_data = {**entry.data}
if CONF_DEVICES in new_data:
new_data.pop(CONF_DEVICES)
hass.config_entries.async_update_entry(entry, data=new_data, minor_version=2)
_LOGGER.debug(
"Migration to version %s:%s successful", entry.version, entry.minor_version
)
return True
@@ -6,7 +6,7 @@ from anova_wifi import AnovaApi, InvalidLogin
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_DEVICES, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN
@@ -16,6 +16,7 @@ class AnovaConfligFlow(ConfigFlow, domain=DOMAIN):
"""Sets up a config flow for Anova."""
VERSION = 1
MINOR_VERSION = 2
async def async_step_user(
self, user_input: dict[str, str] | None = None
@@ -42,8 +43,6 @@ class AnovaConfligFlow(ConfigFlow, domain=DOMAIN):
data={
CONF_USERNAME: user_input[CONF_USERNAME],
CONF_PASSWORD: user_input[CONF_PASSWORD],
# this can be removed in a migration to 1.2 in 2024.11
CONF_DEVICES: [],
},
)
@@ -121,7 +121,6 @@ class AnthropicOptionsFlow(OptionsFlow):
def __init__(self, config_entry: ConfigEntry) -> None:
"""Initialize options flow."""
self.config_entry = config_entry
self.last_rendered_recommended = config_entry.options.get(
CONF_RECOMMENDED, False
)
+16 -19
View File
@@ -15,12 +15,14 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from .const import DOMAIN
PLATFORMS: list[Platform] = [Platform.SENSOR]
_LOGGER = logging.getLogger(__name__)
type AranetConfigEntry = ConfigEntry[
PassiveBluetoothProcessorCoordinator[Aranet4Advertisement]
]
def _service_info_to_adv(
service_info: BluetoothServiceInfoBleak,
@@ -28,30 +30,25 @@ def _service_info_to_adv(
return Aranet4Advertisement(service_info.device, service_info.advertisement)
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: AranetConfigEntry) -> bool:
"""Set up Aranet from a config entry."""
address = entry.unique_id
assert address is not None
coordinator = hass.data.setdefault(DOMAIN, {})[entry.entry_id] = (
PassiveBluetoothProcessorCoordinator(
hass,
_LOGGER,
address=address,
mode=BluetoothScanningMode.PASSIVE,
update_method=_service_info_to_adv,
)
coordinator = PassiveBluetoothProcessorCoordinator(
hass,
_LOGGER,
address=address,
mode=BluetoothScanningMode.PASSIVE,
update_method=_service_info_to_adv,
)
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
entry.async_on_unload(
coordinator.async_start()
) # only start after all platforms have had a chance to subscribe
# only start after all platforms have had a chance to subscribe
entry.async_on_unload(coordinator.async_start())
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: AranetConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
+4 -8
View File
@@ -8,12 +8,10 @@ from typing import Any
from aranet4.client import Aranet4Advertisement
from bleak.backends.device import BLEDevice
from homeassistant import config_entries
from homeassistant.components.bluetooth.passive_update_processor import (
PassiveBluetoothDataProcessor,
PassiveBluetoothDataUpdate,
PassiveBluetoothEntityKey,
PassiveBluetoothProcessorCoordinator,
PassiveBluetoothProcessorEntity,
)
from homeassistant.components.sensor import (
@@ -38,7 +36,8 @@ from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import ARANET_MANUFACTURER_NAME, DOMAIN
from . import AranetConfigEntry
from .const import ARANET_MANUFACTURER_NAME
@dataclass(frozen=True)
@@ -174,20 +173,17 @@ def sensor_update_to_bluetooth_data_update(
async def async_setup_entry(
hass: HomeAssistant,
entry: config_entries.ConfigEntry,
entry: AranetConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Aranet sensors."""
coordinator: PassiveBluetoothProcessorCoordinator[Aranet4Advertisement] = hass.data[
DOMAIN
][entry.entry_id]
processor = PassiveBluetoothDataProcessor(sensor_update_to_bluetooth_data_update)
entry.async_on_unload(
processor.async_add_entities_listener(
Aranet4BluetoothSensorEntity, async_add_entities
)
)
entry.async_on_unload(coordinator.async_register_processor(processor))
entry.async_on_unload(entry.runtime_data.async_register_processor(processor))
class Aranet4BluetoothSensorEntity(
@@ -22,8 +22,8 @@ class EnhancedAudioChunk:
timestamp_ms: int
"""Timestamp relative to start of audio stream (milliseconds)"""
is_speech: bool | None
"""True if audio chunk likely contains speech, False if not, None if unknown"""
speech_probability: float | None
"""Probability that audio chunk contains speech (0-1), None if unknown"""
class AudioEnhancer(ABC):
@@ -70,27 +70,27 @@ class MicroVadSpeexEnhancer(AudioEnhancer):
)
self.vad: MicroVad | None = None
self.threshold = 0.5
if self.is_vad_enabled:
self.vad = MicroVad()
_LOGGER.debug("Initialized microVAD with threshold=%s", self.threshold)
_LOGGER.debug("Initialized microVAD")
def enhance_chunk(self, audio: bytes, timestamp_ms: int) -> EnhancedAudioChunk:
"""Enhance 10ms chunk of PCM audio @ 16Khz with 16-bit mono samples."""
is_speech: bool | None = None
speech_probability: float | None = None
assert len(audio) == BYTES_PER_CHUNK
if self.vad is not None:
# Run VAD
speech_prob = self.vad.Process10ms(audio)
is_speech = speech_prob > self.threshold
speech_probability = self.vad.Process10ms(audio)
if self.audio_processor is not None:
# Run noise suppression and auto gain
audio = self.audio_processor.Process10ms(audio).audio
return EnhancedAudioChunk(
audio=audio, timestamp_ms=timestamp_ms, is_speech=is_speech
audio=audio,
timestamp_ms=timestamp_ms,
speech_probability=speech_probability,
)
@@ -780,7 +780,9 @@ class PipelineRun:
# speaking the voice command.
audio_chunks_for_stt.extend(
EnhancedAudioChunk(
audio=chunk_ts[0], timestamp_ms=chunk_ts[1], is_speech=False
audio=chunk_ts[0],
timestamp_ms=chunk_ts[1],
speech_probability=None,
)
for chunk_ts in result.queued_audio
)
@@ -827,7 +829,7 @@ class PipelineRun:
if wake_word_vad is not None:
chunk_seconds = (len(chunk.audio) // sample_width) / sample_rate
if not wake_word_vad.process(chunk_seconds, chunk.is_speech):
if not wake_word_vad.process(chunk_seconds, chunk.speech_probability):
raise WakeWordTimeoutError(
code="wake-word-timeout", message="Wake word was not detected"
)
@@ -955,7 +957,7 @@ class PipelineRun:
if stt_vad is not None:
chunk_seconds = (len(chunk.audio) // sample_width) / sample_rate
if not stt_vad.process(chunk_seconds, chunk.is_speech):
if not stt_vad.process(chunk_seconds, chunk.speech_probability):
# Silence detected at the end of voice command
self.process_event(
PipelineEvent(
@@ -1221,7 +1223,7 @@ class PipelineRun:
yield EnhancedAudioChunk(
audio=sub_chunk,
timestamp_ms=timestamp_ms,
is_speech=None, # no VAD
speech_probability=None, # no VAD
)
timestamp_ms += MS_PER_CHUNK
+42 -20
View File
@@ -75,7 +75,7 @@ class AudioBuffer:
class VoiceCommandSegmenter:
"""Segments an audio stream into voice commands."""
speech_seconds: float = 0.3
speech_seconds: float = 0.1
"""Seconds of speech before voice command has started."""
command_seconds: float = 1.0
@@ -96,6 +96,12 @@ class VoiceCommandSegmenter:
timed_out: bool = False
"""True a timeout occurred during voice command."""
before_command_speech_threshold: float = 0.2
"""Probability threshold for speech before voice command."""
in_command_speech_threshold: float = 0.5
"""Probability threshold for speech during voice command."""
_speech_seconds_left: float = 0.0
"""Seconds left before considering voice command as started."""
@@ -124,7 +130,7 @@ class VoiceCommandSegmenter:
self._reset_seconds_left = self.reset_seconds
self.in_command = False
def process(self, chunk_seconds: float, is_speech: bool | None) -> bool:
def process(self, chunk_seconds: float, speech_probability: float | None) -> bool:
"""Process samples using external VAD.
Returns False when command is done.
@@ -142,7 +148,12 @@ class VoiceCommandSegmenter:
self.timed_out = True
return False
if speech_probability is None:
speech_probability = 0.0
if not self.in_command:
# Before command
is_speech = speech_probability > self.before_command_speech_threshold
if is_speech:
self._reset_seconds_left = self.reset_seconds
self._speech_seconds_left -= chunk_seconds
@@ -160,24 +171,29 @@ class VoiceCommandSegmenter:
if self._reset_seconds_left <= 0:
self._speech_seconds_left = self.speech_seconds
self._reset_seconds_left = self.reset_seconds
elif not is_speech:
# Silence in command
self._reset_seconds_left = self.reset_seconds
self._silence_seconds_left -= chunk_seconds
self._command_seconds_left -= chunk_seconds
if (self._silence_seconds_left <= 0) and (self._command_seconds_left <= 0):
# Command finished successfully
self.reset()
_LOGGER.debug("Voice command finished")
return False
else:
# Speech in command.
# Reset silence counter if enough speech.
self._reset_seconds_left -= chunk_seconds
self._command_seconds_left -= chunk_seconds
if self._reset_seconds_left <= 0:
self._silence_seconds_left = self.silence_seconds
# In command
is_speech = speech_probability > self.in_command_speech_threshold
if not is_speech:
# Silence in command
self._reset_seconds_left = self.reset_seconds
self._silence_seconds_left -= chunk_seconds
self._command_seconds_left -= chunk_seconds
if (self._silence_seconds_left <= 0) and (
self._command_seconds_left <= 0
):
# Command finished successfully
self.reset()
_LOGGER.debug("Voice command finished")
return False
else:
# Speech in command.
# Reset silence counter if enough speech.
self._reset_seconds_left -= chunk_seconds
self._command_seconds_left -= chunk_seconds
if self._reset_seconds_left <= 0:
self._silence_seconds_left = self.silence_seconds
self._reset_seconds_left = self.reset_seconds
return True
@@ -226,6 +242,9 @@ class VoiceActivityTimeout:
reset_seconds: float = 0.5
"""Seconds of speech before resetting timeout."""
speech_threshold: float = 0.5
"""Threshold for speech."""
_silence_seconds_left: float = 0.0
"""Seconds left before considering voice command as stopped."""
@@ -241,12 +260,15 @@ class VoiceActivityTimeout:
self._silence_seconds_left = self.silence_seconds
self._reset_seconds_left = self.reset_seconds
def process(self, chunk_seconds: float, is_speech: bool | None) -> bool:
def process(self, chunk_seconds: float, speech_probability: float | None) -> bool:
"""Process samples using external VAD.
Returns False when timeout is reached.
"""
if is_speech:
if speech_probability is None:
speech_probability = 0.0
if speech_probability > self.speech_threshold:
# Speech
self._reset_seconds_left -= chunk_seconds
if self._reset_seconds_left <= 0:
@@ -5,5 +5,5 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/autarco",
"iot_class": "cloud_polling",
"requirements": ["autarco==3.0.0"]
"requirements": ["autarco==3.1.0"]
}
@@ -3,11 +3,6 @@
"name": "Awair",
"codeowners": ["@ahayworth", "@danielsjf"],
"config_flow": true,
"dhcp": [
{
"macaddress": "70886B1*"
}
],
"documentation": "https://www.home-assistant.io/integrations/awair",
"iot_class": "local_polling",
"loggers": ["python_awair"],
+7 -6
View File
@@ -18,7 +18,7 @@ from homeassistant.config_entries import (
ConfigEntry,
ConfigFlow,
ConfigFlowResult,
OptionsFlowWithConfigEntry,
OptionsFlow,
)
from homeassistant.const import (
CONF_HOST,
@@ -59,9 +59,11 @@ class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
@staticmethod
@callback
def async_get_options_flow(config_entry: ConfigEntry) -> AxisOptionsFlowHandler:
def async_get_options_flow(
config_entry: ConfigEntry,
) -> AxisOptionsFlowHandler:
"""Get the options flow for this handler."""
return AxisOptionsFlowHandler(config_entry)
return AxisOptionsFlowHandler()
def __init__(self) -> None:
"""Initialize the Axis config flow."""
@@ -264,7 +266,7 @@ class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
return await self.async_step_user()
class AxisOptionsFlowHandler(OptionsFlowWithConfigEntry):
class AxisOptionsFlowHandler(OptionsFlow):
"""Handle Axis device options."""
config_entry: AxisConfigEntry
@@ -282,8 +284,7 @@ class AxisOptionsFlowHandler(OptionsFlowWithConfigEntry):
) -> ConfigFlowResult:
"""Manage the Axis device stream options."""
if user_input is not None:
self.options.update(user_input)
return self.async_create_entry(title="", data=self.options)
return self.async_create_entry(data=self.config_entry.options | user_input)
schema = {}
+1 -1
View File
@@ -30,7 +30,7 @@
"iot_class": "local_push",
"loggers": ["axis"],
"quality_scale": "platinum",
"requirements": ["axis==62"],
"requirements": ["axis==63"],
"ssdp": [
{
"manufacturer": "AXIS"
@@ -124,7 +124,9 @@ class AEHConfigFlow(ConfigFlow, domain=DOMAIN):
step_id=STEP_CONN_STRING,
data_schema=CONN_STRING_SCHEMA,
errors=errors,
description_placeholders=self._data[CONF_EVENT_HUB_INSTANCE_NAME],
description_placeholders={
"event_hub_instance_name": self._data[CONF_EVENT_HUB_INSTANCE_NAME]
},
last_step=True,
)
@@ -144,7 +146,9 @@ class AEHConfigFlow(ConfigFlow, domain=DOMAIN):
step_id=STEP_SAS,
data_schema=SAS_SCHEMA,
errors=errors,
description_placeholders=self._data[CONF_EVENT_HUB_INSTANCE_NAME],
description_placeholders={
"event_hub_instance_name": self._data[CONF_EVENT_HUB_INSTANCE_NAME]
},
last_step=True,
)
+1 -1
View File
@@ -1,8 +1,8 @@
"""The Backup integration."""
from homeassistant.components.hassio import is_hassio
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.hassio import is_hassio
from homeassistant.helpers.typing import ConfigType
from .const import DATA_MANAGER, DOMAIN, LOGGER
+1
View File
@@ -17,6 +17,7 @@ LOGGER = getLogger(__package__)
EXCLUDE_FROM_BACKUP = [
"__pycache__/*",
".DS_Store",
".HA_RESTORE",
"*.db-shm",
"*.log.*",
"*.log",
@@ -16,6 +16,7 @@ from typing import Any, Protocol, cast
from securetar import SecureTarFile, atomic_contents_add
from homeassistant.backup_restore import RESTORE_BACKUP_FILE
from homeassistant.const import __version__ as HAVERSION
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
@@ -123,6 +124,10 @@ class BaseBackupManager(abc.ABC):
LOGGER.debug("Loaded %s platforms", len(self.platforms))
self.loaded_platforms = True
@abc.abstractmethod
async def async_restore_backup(self, slug: str, **kwargs: Any) -> None:
"""Restore a backup."""
@abc.abstractmethod
async def async_create_backup(self, **kwargs: Any) -> Backup:
"""Generate a backup."""
@@ -291,6 +296,25 @@ class BackupManager(BaseBackupManager):
return tar_file_path.stat().st_size
async def async_restore_backup(self, slug: str, **kwargs: Any) -> None:
"""Restore a backup.
This will write the restore information to .HA_RESTORE which
will be handled during startup by the restore_backup module.
"""
if (backup := await self.async_get_backup(slug=slug)) is None:
raise HomeAssistantError(f"Backup {slug} not found")
def _write_restore_file() -> None:
"""Write the restore file."""
Path(self.hass.config.path(RESTORE_BACKUP_FILE)).write_text(
json.dumps({"path": backup.path.as_posix()}),
encoding="utf-8",
)
await self.hass.async_add_executor_job(_write_restore_file)
await self.hass.services.async_call("homeassistant", "restart", {})
def _generate_slug(date: str, name: str) -> str:
"""Generate a backup slug."""
@@ -22,6 +22,7 @@ def async_register_websocket_handlers(hass: HomeAssistant, with_hassio: bool) ->
websocket_api.async_register_command(hass, handle_info)
websocket_api.async_register_command(hass, handle_create)
websocket_api.async_register_command(hass, handle_remove)
websocket_api.async_register_command(hass, handle_restore)
@websocket_api.require_admin
@@ -85,6 +86,24 @@ async def handle_remove(
connection.send_result(msg["id"])
@websocket_api.require_admin
@websocket_api.websocket_command(
{
vol.Required("type"): "backup/restore",
vol.Required("slug"): str,
}
)
@websocket_api.async_response
async def handle_restore(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Restore a backup."""
await hass.data[DATA_MANAGER].async_restore_backup(msg["slug"])
connection.send_result(msg["id"])
@websocket_api.require_admin
@websocket_api.websocket_command({vol.Required("type"): "backup/generate"})
@websocket_api.async_response
+11 -16
View File
@@ -14,7 +14,7 @@ from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.event import async_track_time_interval
import homeassistant.util.dt as dt_util
from .const import CONF_SYNC_TIME, DEFAULT_SYNC_TIME, DOMAIN
from .const import CONF_SYNC_TIME, DEFAULT_SYNC_TIME
_LOGGER = logging.getLogger(__name__)
@@ -30,8 +30,10 @@ PLATFORMS = [
KEEP_ALIVE_INTERVAL = timedelta(minutes=1)
SYNC_TIME_INTERVAL = timedelta(hours=1)
type BalboaConfigEntry = ConfigEntry[SpaClient]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: BalboaConfigEntry) -> bool:
"""Set up Balboa Spa from a config entry."""
host = entry.data[CONF_HOST]
@@ -44,41 +46,34 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
_LOGGER.error("Failed to get spa info at %s", host)
raise ConfigEntryNotReady("Unable to configure")
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = spa
entry.runtime_data = spa
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
await async_setup_time_sync(hass, entry)
entry.async_on_unload(entry.add_update_listener(update_listener))
entry.async_on_unload(spa.disconnect)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: BalboaConfigEntry) -> bool:
"""Unload a config entry."""
_LOGGER.debug("Disconnecting from spa")
spa: SpaClient = hass.data[DOMAIN][entry.entry_id]
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
hass.data[DOMAIN].pop(entry.entry_id)
await spa.disconnect()
return unload_ok
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
async def update_listener(hass: HomeAssistant, entry: BalboaConfigEntry) -> None:
"""Handle options update."""
await hass.config_entries.async_reload(entry.entry_id)
async def async_setup_time_sync(hass: HomeAssistant, entry: ConfigEntry) -> None:
async def async_setup_time_sync(hass: HomeAssistant, entry: BalboaConfigEntry) -> None:
"""Set up the time sync."""
if not entry.options.get(CONF_SYNC_TIME, DEFAULT_SYNC_TIME):
return
_LOGGER.debug("Setting up daily time sync")
spa: SpaClient = hass.data[DOMAIN][entry.entry_id]
spa = entry.runtime_data
async def sync_time(now: datetime) -> None:
now = dt_util.as_local(now)
@@ -12,19 +12,20 @@ from homeassistant.components.binary_sensor import (
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from . import BalboaConfigEntry
from .entity import BalboaEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
hass: HomeAssistant,
entry: BalboaConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the spa's binary sensors."""
spa: SpaClient = hass.data[DOMAIN][entry.entry_id]
spa = entry.runtime_data
entities = [
BalboaBinarySensorEntity(spa, description)
for description in BINARY_SENSOR_DESCRIPTIONS
+5 -3
View File
@@ -14,7 +14,6 @@ from homeassistant.components.climate import (
HVACAction,
HVACMode,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_TEMPERATURE,
PRECISION_HALVES,
@@ -24,6 +23,7 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import BalboaConfigEntry
from .const import DOMAIN
from .entity import BalboaEntity
@@ -45,10 +45,12 @@ TEMPERATURE_UNIT_MAP = {
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
hass: HomeAssistant,
entry: BalboaConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the spa climate entity."""
async_add_entities([BalboaClimateEntity(hass.data[DOMAIN][entry.entry_id])])
async_add_entities([BalboaClimateEntity(entry.runtime_data)])
class BalboaClimateEntity(BalboaEntity, ClimateEntity):
+6 -5
View File
@@ -5,11 +5,10 @@ from __future__ import annotations
import math
from typing import Any, cast
from pybalboa import SpaClient, SpaControl
from pybalboa import SpaControl
from pybalboa.enums import OffOnState, UnknownState
from homeassistant.components.fan import FanEntity, FanEntityFeature
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.percentage import (
@@ -17,15 +16,17 @@ from homeassistant.util.percentage import (
ranged_value_to_percentage,
)
from .const import DOMAIN
from . import BalboaConfigEntry
from .entity import BalboaEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
hass: HomeAssistant,
entry: BalboaConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the spa's pumps."""
spa: SpaClient = hass.data[DOMAIN][entry.entry_id]
spa = entry.runtime_data
async_add_entities(BalboaPumpFanEntity(control) for control in spa.pumps)
+6 -5
View File
@@ -4,23 +4,24 @@ from __future__ import annotations
from typing import Any, cast
from pybalboa import SpaClient, SpaControl
from pybalboa import SpaControl
from pybalboa.enums import OffOnState, UnknownState
from homeassistant.components.light import ColorMode, LightEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from . import BalboaConfigEntry
from .entity import BalboaEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
hass: HomeAssistant,
entry: BalboaConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the spa's lights."""
spa: SpaClient = hass.data[DOMAIN][entry.entry_id]
spa = entry.runtime_data
async_add_entities(BalboaLightEntity(control) for control in spa.lights)
+6 -5
View File
@@ -1,22 +1,23 @@
"""Support for Spa Client selects."""
from pybalboa import SpaClient, SpaControl
from pybalboa import SpaControl
from pybalboa.enums import LowHighRange
from homeassistant.components.select import SelectEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from . import BalboaConfigEntry
from .entity import BalboaEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
hass: HomeAssistant,
entry: BalboaConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the spa select entity."""
spa: SpaClient = hass.data[DOMAIN][entry.entry_id]
spa = entry.runtime_data
async_add_entities([BalboaTempRangeSelectEntity(spa.temperature_range)])
@@ -31,10 +31,12 @@ class BangOlufsenData:
client: MozartClient
type BangOlufsenConfigEntry = ConfigEntry[BangOlufsenData]
PLATFORMS = [Platform.MEDIA_PLAYER]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: BangOlufsenConfigEntry) -> bool:
"""Set up from a config entry."""
# Remove casts to str
@@ -67,10 +69,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
websocket = BangOlufsenWebsocket(hass, entry, client)
# Add the websocket and API client
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = BangOlufsenData(
websocket,
client,
)
entry.runtime_data = BangOlufsenData(websocket, client)
# Start WebSocket connection
await client.connect_notifications(remote_control=True, reconnect=True)
@@ -80,15 +79,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(
hass: HomeAssistant, entry: BangOlufsenConfigEntry
) -> bool:
"""Unload a config entry."""
# Close the API client and WebSocket notification listener
hass.data[DOMAIN][entry.entry_id].client.disconnect_notifications()
await hass.data[DOMAIN][entry.entry_id].client.close_api_client()
entry.runtime_data.client.disconnect_notifications()
await entry.runtime_data.client.close_api_client()
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
+28 -24
View File
@@ -7,20 +7,19 @@ from typing import Final
from mozart_api.models import Source, SourceArray, SourceTypeEnum
from homeassistant.components.media_player import MediaPlayerState, MediaType
from homeassistant.components.media_player import (
MediaPlayerState,
MediaType,
RepeatMode,
)
class BangOlufsenSource:
"""Class used for associating device source ids with friendly names. May not include all sources."""
URI_STREAMER: Final[Source] = Source(name="Audio Streamer", id="uriStreamer")
BLUETOOTH: Final[Source] = Source(name="Bluetooth", id="bluetooth")
CHROMECAST: Final[Source] = Source(name="Chromecast built-in", id="chromeCast")
LINE_IN: Final[Source] = Source(name="Line-In", id="lineIn")
SPDIF: Final[Source] = Source(name="Optical", id="spdif")
NET_RADIO: Final[Source] = Source(name="B&O Radio", id="netRadio")
DEEZER: Final[Source] = Source(name="Deezer", id="deezer")
TIDAL: Final[Source] = Source(name="Tidal", id="tidal")
URI_STREAMER: Final[Source] = Source(name="Audio Streamer", id="uriStreamer")
BANG_OLUFSEN_STATES: dict[str, MediaPlayerState] = {
@@ -36,6 +35,17 @@ BANG_OLUFSEN_STATES: dict[str, MediaPlayerState] = {
"unknown": MediaPlayerState.IDLE,
}
# Dict used for translating Home Assistant settings to device repeat settings.
BANG_OLUFSEN_REPEAT_FROM_HA: dict[RepeatMode, str] = {
RepeatMode.ALL: "all",
RepeatMode.ONE: "track",
RepeatMode.OFF: "none",
}
# Dict used for translating device repeat settings to Home Assistant settings.
BANG_OLUFSEN_REPEAT_TO_HA: dict[str, RepeatMode] = {
value: key for key, value in BANG_OLUFSEN_REPEAT_FROM_HA.items()
}
# Media types for play_media
class BangOlufsenMediaType(StrEnum):
@@ -123,20 +133,6 @@ VALID_MEDIA_TYPES: Final[tuple] = (
MediaType.CHANNEL,
)
# Sources on the device that should not be selectable by the user
HIDDEN_SOURCE_IDS: Final[tuple] = (
"airPlay",
"bluetooth",
"chromeCast",
"generator",
"local",
"dlna",
"qplay",
"wpl",
"pl",
"beolink",
"usbIn",
)
# Fallback sources to use in case of API failure.
FALLBACK_SOURCES: Final[SourceArray] = SourceArray(
@@ -144,23 +140,26 @@ FALLBACK_SOURCES: Final[SourceArray] = SourceArray(
Source(
id="uriStreamer",
is_enabled=True,
is_playable=False,
is_playable=True,
name="Audio Streamer",
type=SourceTypeEnum(value="uriStreamer"),
is_seekable=False,
),
Source(
id="bluetooth",
is_enabled=True,
is_playable=False,
is_playable=True,
name="Bluetooth",
type=SourceTypeEnum(value="bluetooth"),
is_seekable=False,
),
Source(
id="spotify",
is_enabled=True,
is_playable=False,
is_playable=True,
name="Spotify Connect",
type=SourceTypeEnum(value="spotify"),
is_seekable=True,
),
Source(
id="lineIn",
@@ -168,6 +167,7 @@ FALLBACK_SOURCES: Final[SourceArray] = SourceArray(
is_playable=True,
name="Line-In",
type=SourceTypeEnum(value="lineIn"),
is_seekable=False,
),
Source(
id="spdif",
@@ -175,6 +175,7 @@ FALLBACK_SOURCES: Final[SourceArray] = SourceArray(
is_playable=True,
name="Optical",
type=SourceTypeEnum(value="spdif"),
is_seekable=False,
),
Source(
id="netRadio",
@@ -182,6 +183,7 @@ FALLBACK_SOURCES: Final[SourceArray] = SourceArray(
is_playable=True,
name="B&O Radio",
type=SourceTypeEnum(value="netRadio"),
is_seekable=False,
),
Source(
id="deezer",
@@ -189,6 +191,7 @@ FALLBACK_SOURCES: Final[SourceArray] = SourceArray(
is_playable=True,
name="Deezer",
type=SourceTypeEnum(value="deezer"),
is_seekable=True,
),
Source(
id="tidalConnect",
@@ -196,6 +199,7 @@ FALLBACK_SOURCES: Final[SourceArray] = SourceArray(
is_playable=True,
name="Tidal Connect",
type=SourceTypeEnum(value="tidalConnect"),
is_seekable=True,
),
]
)
@@ -0,0 +1,9 @@
{
"services": {
"beolink_join": { "service": "mdi:location-enter" },
"beolink_expand": { "service": "mdi:location-enter" },
"beolink_unexpand": { "service": "mdi:location-exit" },
"beolink_leave": { "service": "mdi:close-circle-outline" },
"beolink_allstandby": { "service": "mdi:close-circle-multiple-outline" }
}
}
@@ -3,12 +3,15 @@
from __future__ import annotations
from collections.abc import Callable
import contextlib
from datetime import timedelta
import json
import logging
from typing import TYPE_CHECKING, Any, cast
from aiohttp import ClientConnectorError
from mozart_api import __version__ as MOZART_API_VERSION
from mozart_api.exceptions import ApiException
from mozart_api.exceptions import ApiException, NotFoundException
from mozart_api.models import (
Action,
Art,
@@ -22,6 +25,7 @@ from mozart_api.models import (
PlaybackProgress,
PlayQueueItem,
PlayQueueItemType,
PlayQueueSettings,
RenderingState,
SceneProperties,
SoftwareUpdateState,
@@ -34,6 +38,7 @@ from mozart_api.models import (
VolumeState,
)
from mozart_api.mozart_client import MozartClient, get_highest_resolution_artwork
import voluptuous as vol
from homeassistant.components import media_source
from homeassistant.components.media_player import (
@@ -44,26 +49,35 @@ from homeassistant.components.media_player import (
MediaPlayerEntityFeature,
MediaPlayerState,
MediaType,
RepeatMode,
async_process_play_media_url,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_MODEL, Platform
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers import (
config_validation as cv,
device_registry as dr,
entity_registry as er,
)
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.entity_platform import (
AddEntitiesCallback,
async_get_current_platform,
)
from homeassistant.util.dt import utcnow
from . import BangOlufsenData
from . import BangOlufsenConfigEntry
from .const import (
BANG_OLUFSEN_REPEAT_FROM_HA,
BANG_OLUFSEN_REPEAT_TO_HA,
BANG_OLUFSEN_STATES,
CONF_BEOLINK_JID,
CONNECTION_STATUS,
DOMAIN,
FALLBACK_SOURCES,
HIDDEN_SOURCE_IDS,
VALID_MEDIA_TYPES,
BangOlufsenMediaType,
BangOlufsenSource,
@@ -72,6 +86,8 @@ from .const import (
from .entity import BangOlufsenEntity
from .util import get_serial_number_from_jid
SCAN_INTERVAL = timedelta(seconds=30)
_LOGGER = logging.getLogger(__name__)
BANG_OLUFSEN_FEATURES = (
@@ -84,8 +100,9 @@ BANG_OLUFSEN_FEATURES = (
| MediaPlayerEntityFeature.PLAY
| MediaPlayerEntityFeature.PLAY_MEDIA
| MediaPlayerEntityFeature.PREVIOUS_TRACK
| MediaPlayerEntityFeature.SEEK
| MediaPlayerEntityFeature.REPEAT_SET
| MediaPlayerEntityFeature.SELECT_SOURCE
| MediaPlayerEntityFeature.SHUFFLE_SET
| MediaPlayerEntityFeature.STOP
| MediaPlayerEntityFeature.TURN_OFF
| MediaPlayerEntityFeature.VOLUME_MUTE
@@ -96,14 +113,68 @@ BANG_OLUFSEN_FEATURES = (
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: BangOlufsenConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up a Media Player entity from config entry."""
data: BangOlufsenData = hass.data[DOMAIN][config_entry.entry_id]
# Add MediaPlayer entity
async_add_entities(new_entities=[BangOlufsenMediaPlayer(config_entry, data.client)])
async_add_entities(
new_entities=[
BangOlufsenMediaPlayer(config_entry, config_entry.runtime_data.client)
]
)
# Register actions.
platform = async_get_current_platform()
jid_regex = vol.Match(
r"(^\d{4})[.](\d{7})[.](\d{8})(@products\.bang-olufsen\.com)$"
)
platform.async_register_entity_service(
name="beolink_join",
schema={vol.Optional("beolink_jid"): jid_regex},
func="async_beolink_join",
)
platform.async_register_entity_service(
name="beolink_expand",
schema={
vol.Exclusive("all_discovered", "devices", ""): cv.boolean,
vol.Exclusive(
"beolink_jids",
"devices",
"Define either specific Beolink JIDs or all discovered",
): vol.All(
cv.ensure_list,
[jid_regex],
),
},
func="async_beolink_expand",
)
platform.async_register_entity_service(
name="beolink_unexpand",
schema={
vol.Required("beolink_jids"): vol.All(
cv.ensure_list,
[jid_regex],
),
},
func="async_beolink_unexpand",
)
platform.async_register_entity_service(
name="beolink_leave",
schema=None,
func="async_beolink_leave",
)
platform.async_register_entity_service(
name="beolink_allstandby",
schema=None,
func="async_beolink_allstandby",
)
class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
@@ -112,7 +183,6 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
_attr_icon = "mdi:speaker-wireless"
_attr_name = None
_attr_device_class = MediaPlayerDeviceClass.SPEAKER
_attr_supported_features = BANG_OLUFSEN_FEATURES
def __init__(self, entry: ConfigEntry, client: MozartClient) -> None:
"""Initialize the media player."""
@@ -129,6 +199,7 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
serial_number=self._unique_id,
)
self._attr_unique_id = self._unique_id
self._attr_should_poll = True
# Misc. variables.
self._audio_sources: dict[str, str] = {}
@@ -145,6 +216,8 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
# Beolink compatible sources
self._beolink_sources: dict[str, bool] = {}
self._remote_leader: BeolinkLeader | None = None
# Extra state attributes for showing Beolink: peer(s), listener(s), leader and self
self._beolink_attributes: dict[str, dict[str, dict[str, str]]] = {}
async def async_added_to_hass(self) -> None:
"""Turn on the dispatchers."""
@@ -154,9 +227,11 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
CONNECTION_STATUS: self._async_update_connection_state,
WebsocketNotification.ACTIVE_LISTENING_MODE: self._async_update_sound_modes,
WebsocketNotification.BEOLINK: self._async_update_beolink,
WebsocketNotification.CONFIGURATION: self._async_update_name_and_beolink,
WebsocketNotification.PLAYBACK_ERROR: self._async_update_playback_error,
WebsocketNotification.PLAYBACK_METADATA: self._async_update_playback_metadata_and_beolink,
WebsocketNotification.PLAYBACK_PROGRESS: self._async_update_playback_progress,
WebsocketNotification.PLAYBACK_SOURCE: self._async_update_sources,
WebsocketNotification.PLAYBACK_STATE: self._async_update_playback_state,
WebsocketNotification.REMOTE_MENU_CHANGED: self._async_update_sources,
WebsocketNotification.SOURCE_CHANGE: self._async_update_source_change,
@@ -218,7 +293,23 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
await self._async_update_sound_modes()
async def _async_update_sources(self) -> None:
# Update beolink attributes and device name.
await self._async_update_name_and_beolink()
async def async_update(self) -> None:
"""Update queue settings."""
# The WebSocket event listener is the main handler for connection state.
# The polling updates do therefore not set the device as available or unavailable
with contextlib.suppress(ApiException, ClientConnectorError, TimeoutError):
queue_settings = await self._client.get_settings_queue(_request_timeout=5)
if queue_settings.repeat is not None:
self._attr_repeat = BANG_OLUFSEN_REPEAT_TO_HA[queue_settings.repeat]
if queue_settings.shuffle is not None:
self._attr_shuffle = queue_settings.shuffle
async def _async_update_sources(self, _: Source | None = None) -> None:
"""Get sources for the specific product."""
# Audio sources
@@ -245,10 +336,7 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
self._audio_sources = {
source.id: source.name
for source in cast(list[Source], sources.items)
if source.is_enabled
and source.id
and source.name
and source.id not in HIDDEN_SOURCE_IDS
if source.is_enabled and source.id and source.name and source.is_playable
}
# Some sources are not Beolink expandable, meaning that they can't be joined by
@@ -350,9 +438,44 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
self.async_write_ha_state()
async def _async_update_name_and_beolink(self) -> None:
"""Update the device friendly name."""
beolink_self = await self._client.get_beolink_self()
# Update device name
device_registry = dr.async_get(self.hass)
assert self.device_entry is not None
device_registry.async_update_device(
device_id=self.device_entry.id,
name=beolink_self.friendly_name,
)
await self._async_update_beolink()
async def _async_update_beolink(self) -> None:
"""Update the current Beolink leader, listeners, peers and self."""
self._beolink_attributes = {}
assert self.device_entry is not None
assert self.device_entry.name is not None
# Add Beolink self
self._beolink_attributes = {
"beolink": {"self": {self.device_entry.name: self._beolink_jid}}
}
# Add Beolink peers
peers = await self._client.get_beolink_peers()
if len(peers) > 0:
self._beolink_attributes["beolink"]["peers"] = {}
for peer in peers:
self._beolink_attributes["beolink"]["peers"][peer.friendly_name] = (
peer.jid
)
# Add Beolink listeners / leader
self._remote_leader = self._playback_metadata.remote_leader
@@ -372,9 +495,14 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
# Add self
group_members.append(self.entity_id)
self._beolink_attributes["beolink"]["leader"] = {
self._remote_leader.friendly_name: self._remote_leader.jid,
}
# If not listener, check if leader.
else:
beolink_listeners = await self._client.get_beolink_listeners()
beolink_listeners_attribute = {}
# Check if the device is a leader.
if len(beolink_listeners) > 0:
@@ -395,6 +523,18 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
for beolink_listener in beolink_listeners
]
)
# Update Beolink attributes
for beolink_listener in beolink_listeners:
for peer in peers:
if peer.jid == beolink_listener.jid:
# Get the friendly names for the listeners from the peers
beolink_listeners_attribute[peer.friendly_name] = (
beolink_listener.jid
)
break
self._beolink_attributes["beolink"]["listeners"] = (
beolink_listeners_attribute
)
self._attr_group_members = group_members
@@ -462,6 +602,17 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
self.async_write_ha_state()
@property
def supported_features(self) -> MediaPlayerEntityFeature:
"""Flag media player features that are supported."""
features = BANG_OLUFSEN_FEATURES
# Add seeking if supported by the current source
if self._source_change.is_seekable is True:
features |= MediaPlayerEntityFeature.SEEK
return features
@property
def state(self) -> MediaPlayerState:
"""Return the current state of the media player."""
@@ -537,38 +688,19 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
@property
def source(self) -> str | None:
"""Return the current audio source."""
# Try to fix some of the source_change chromecast weirdness.
if hasattr(self._playback_metadata, "title"):
# source_change is chromecast but line in is selected.
if self._playback_metadata.title == BangOlufsenSource.LINE_IN.name:
return BangOlufsenSource.LINE_IN.name
# source_change is chromecast but bluetooth is selected.
if self._playback_metadata.title == BangOlufsenSource.BLUETOOTH.name:
return BangOlufsenSource.BLUETOOTH.name
# source_change is line in, bluetooth or optical but stale metadata is sent through the WebSocket,
# And the source has not changed.
if self._source_change.id in (
BangOlufsenSource.BLUETOOTH.id,
BangOlufsenSource.LINE_IN.id,
BangOlufsenSource.SPDIF.id,
):
return BangOlufsenSource.CHROMECAST.name
# source_change is chromecast and there is metadata but no artwork. Bluetooth does support metadata but not artwork
# So i assume that it is bluetooth and not chromecast
if (
hasattr(self._playback_metadata, "art")
and self._playback_metadata.art is not None
and len(self._playback_metadata.art) == 0
and self._source_change.id == BangOlufsenSource.CHROMECAST.id
):
return BangOlufsenSource.BLUETOOTH.name
return self._source_change.name
@property
def extra_state_attributes(self) -> dict[str, Any] | None:
"""Return information that is not returned anywhere else."""
attributes: dict[str, Any] = {}
# Add Beolink attributes
if self._beolink_attributes:
attributes.update(self._beolink_attributes)
return attributes
async def async_turn_off(self) -> None:
"""Set the device to "networkStandby"."""
await self._client.post_standby()
@@ -608,17 +740,12 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
async def async_media_seek(self, position: float) -> None:
"""Seek to position in ms."""
if self._source_change.id == BangOlufsenSource.DEEZER.id:
await self._client.seek_to_position(position_ms=int(position * 1000))
# Try to prevent the playback progress from bouncing in the UI.
self._attr_media_position_updated_at = utcnow()
self._playback_progress = PlaybackProgress(progress=int(position))
await self._client.seek_to_position(position_ms=int(position * 1000))
# Try to prevent the playback progress from bouncing in the UI.
self._attr_media_position_updated_at = utcnow()
self._playback_progress = PlaybackProgress(progress=int(position))
self.async_write_ha_state()
else:
raise HomeAssistantError(
translation_domain=DOMAIN, translation_key="non_deezer_seeking"
)
self.async_write_ha_state()
async def async_media_previous_track(self) -> None:
"""Send the previous track command."""
@@ -628,6 +755,20 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
"""Clear the current playback queue."""
await self._client.post_clear_queue()
async def async_set_repeat(self, repeat: RepeatMode) -> None:
"""Set playback queues to repeat."""
await self._client.set_settings_queue(
play_queue_settings=PlayQueueSettings(
repeat=BANG_OLUFSEN_REPEAT_FROM_HA[repeat]
)
)
async def async_set_shuffle(self, shuffle: bool) -> None:
"""Set playback queues to shuffle."""
await self._client.set_settings_queue(
play_queue_settings=PlayQueueSettings(shuffle=shuffle),
)
async def async_select_source(self, source: str) -> None:
"""Select an input source."""
if source not in self._sources.values():
@@ -831,23 +972,30 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
# Beolink compatible B&O device.
# Repeated presses / calls will cycle between compatible playing devices.
if len(group_members) == 0:
await self._async_beolink_join()
await self.async_beolink_join()
return
# Get JID for each group member
jids = [self._get_beolink_jid(group_member) for group_member in group_members]
await self._async_beolink_expand(jids)
await self.async_beolink_expand(jids)
async def async_unjoin_player(self) -> None:
"""Unjoin Beolink session. End session if leader."""
await self._async_beolink_leave()
await self.async_beolink_leave()
async def _async_beolink_join(self) -> None:
# Custom actions:
async def async_beolink_join(self, beolink_jid: str | None = None) -> None:
"""Join a Beolink multi-room experience."""
await self._client.join_latest_beolink_experience()
if beolink_jid is None:
await self._client.join_latest_beolink_experience()
else:
await self._client.join_beolink_peer(jid=beolink_jid)
async def _async_beolink_expand(self, beolink_jids: list[str]) -> None:
async def async_beolink_expand(
self, beolink_jids: list[str] | None = None, all_discovered: bool = False
) -> None:
"""Expand a Beolink multi-room experience with a device or devices."""
# Ensure that the current source is expandable
if not self._beolink_sources[cast(str, self._source_change.id)]:
raise ServiceValidationError(
@@ -859,10 +1007,37 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
},
)
# Try to expand to all defined devices
for beolink_jid in beolink_jids:
await self._client.post_beolink_expand(jid=beolink_jid)
# Expand to all discovered devices
if all_discovered:
peers = await self._client.get_beolink_peers()
async def _async_beolink_leave(self) -> None:
for peer in peers:
try:
await self._client.post_beolink_expand(jid=peer.jid)
except NotFoundException:
_LOGGER.warning("Unable to expand to %s", peer.jid)
# Try to expand to all defined devices
elif beolink_jids:
for beolink_jid in beolink_jids:
try:
await self._client.post_beolink_expand(jid=beolink_jid)
except NotFoundException:
_LOGGER.warning(
"Unable to expand to %s. Is the device available on the network?",
beolink_jid,
)
async def async_beolink_unexpand(self, beolink_jids: list[str]) -> None:
"""Unexpand a Beolink multi-room experience with a device or devices."""
# Unexpand all defined devices
for beolink_jid in beolink_jids:
await self._client.post_beolink_unexpand(jid=beolink_jid)
async def async_beolink_leave(self) -> None:
"""Leave the current Beolink experience."""
await self._client.post_beolink_leave()
async def async_beolink_allstandby(self) -> None:
"""Set all connected Beolink devices to standby."""
await self._client.post_beolink_allstandby()
@@ -0,0 +1,79 @@
beolink_allstandby:
target:
entity:
integration: bang_olufsen
domain: media_player
device:
integration: bang_olufsen
beolink_expand:
target:
entity:
integration: bang_olufsen
domain: media_player
device:
integration: bang_olufsen
fields:
all_discovered:
required: false
example: false
selector:
boolean:
jid_options:
collapsed: false
fields:
beolink_jids:
required: false
example: >-
[
1111.2222222.33333333@products.bang-olufsen.com,
4444.5555555.66666666@products.bang-olufsen.com
]
selector:
object:
beolink_join:
target:
entity:
integration: bang_olufsen
domain: media_player
device:
integration: bang_olufsen
fields:
jid_options:
collapsed: false
fields:
beolink_jid:
required: false
example: 1111.2222222.33333333@products.bang-olufsen.com
selector:
text:
beolink_leave:
target:
entity:
integration: bang_olufsen
domain: media_player
device:
integration: bang_olufsen
beolink_unexpand:
target:
entity:
integration: bang_olufsen
domain: media_player
device:
integration: bang_olufsen
fields:
jid_options:
collapsed: false
fields:
beolink_jids:
required: true
example: >-
[
1111.2222222.33333333@products.bang-olufsen.com,
4444.5555555.66666666@products.bang-olufsen.com
]
selector:
object:
@@ -1,4 +1,8 @@
{
"common": {
"jid_options_name": "JID options",
"jid_options_description": "Advanced grouping options, where devices' unique Beolink IDs (Called JIDs) are used directly. JIDs can be found in the state attributes of the media player entity."
},
"config": {
"error": {
"api_exception": "[%key:common::config_flow::error::cannot_connect%]",
@@ -25,13 +29,72 @@
}
}
},
"services": {
"beolink_allstandby": {
"name": "Beolink all standby",
"description": "Set all Connected Beolink devices to standby."
},
"beolink_expand": {
"name": "Beolink expand",
"description": "Expand current Beolink experience.",
"fields": {
"all_discovered": {
"name": "All discovered",
"description": "Expand Beolink experience to all discovered devices."
},
"beolink_jids": {
"name": "Beolink JIDs",
"description": "Specify which Beolink JIDs will join current Beolink experience."
}
},
"sections": {
"jid_options": {
"name": "[%key:component::bang_olufsen::common::jid_options_name%]",
"description": "[%key:component::bang_olufsen::common::jid_options_description%]"
}
}
},
"beolink_join": {
"name": "Beolink join",
"description": "Join a Beolink experience.",
"fields": {
"beolink_jid": {
"name": "Beolink JID",
"description": "Manually specify Beolink JID to join."
}
},
"sections": {
"jid_options": {
"name": "[%key:component::bang_olufsen::common::jid_options_name%]",
"description": "[%key:component::bang_olufsen::common::jid_options_description%]"
}
}
},
"beolink_leave": {
"name": "Beolink leave",
"description": "Leave a Beolink experience."
},
"beolink_unexpand": {
"name": "Beolink unexpand",
"description": "Unexpand from current Beolink experience.",
"fields": {
"beolink_jids": {
"name": "Beolink JIDs",
"description": "Specify which Beolink JIDs will leave from current Beolink experience."
}
},
"sections": {
"jid_options": {
"name": "[%key:component::bang_olufsen::common::jid_options_name%]",
"description": "[%key:component::bang_olufsen::common::jid_options_description%]"
}
}
}
},
"exceptions": {
"m3u_invalid_format": {
"message": "Media sources with the .m3u extension are not supported."
},
"non_deezer_seeking": {
"message": "Seeking is currently only supported when using Deezer"
},
"invalid_source": {
"message": "Invalid source: {invalid_source}. Valid sources are: {valid_sources}"
},
@@ -63,6 +63,9 @@ class BangOlufsenWebsocket(BangOlufsenBase):
self._client.get_playback_progress_notifications(
self.on_playback_progress_notification
)
self._client.get_playback_source_notifications(
self.on_playback_source_notification
)
self._client.get_playback_state_notifications(
self.on_playback_state_notification
)
@@ -117,6 +120,11 @@ class BangOlufsenWebsocket(BangOlufsenBase):
self.hass,
f"{self._unique_id}_{WebsocketNotification.BEOLINK}",
)
elif notification_type is WebsocketNotification.CONFIGURATION:
async_dispatcher_send(
self.hass,
f"{self._unique_id}_{WebsocketNotification.CONFIGURATION}",
)
elif notification_type is WebsocketNotification.REMOTE_MENU_CHANGED:
async_dispatcher_send(
self.hass,
@@ -157,6 +165,14 @@ class BangOlufsenWebsocket(BangOlufsenBase):
notification,
)
def on_playback_source_notification(self, notification: Source) -> None:
"""Send playback_source dispatch."""
async_dispatcher_send(
self.hass,
f"{self._unique_id}_{WebsocketNotification.PLAYBACK_SOURCE}",
notification,
)
def on_source_change_notification(self, notification: Source) -> None:
"""Send source_change dispatch."""
async_dispatcher_send(
+7 -12
View File
@@ -17,9 +17,11 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from .const import DEFAULT_SETUP_TIMEOUT, DOMAIN, PRODUCT
from .const import DEFAULT_SETUP_TIMEOUT
from .helpers import get_maybe_authenticated_session
type BleBoxConfigEntry = ConfigEntry[Box]
_LOGGER = logging.getLogger(__name__)
PLATFORMS = [
@@ -35,7 +37,7 @@ PLATFORMS = [
PARALLEL_UPDATES = 0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: BleBoxConfigEntry) -> bool:
"""Set up BleBox devices from a config entry."""
host = entry.data[CONF_HOST]
port = entry.data[CONF_PORT]
@@ -55,20 +57,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
_LOGGER.error("Identify failed at %s:%d (%s)", api_host.host, api_host.port, ex)
raise ConfigEntryNotReady from ex
domain = hass.data.setdefault(DOMAIN, {})
domain_entry = domain.setdefault(entry.entry_id, {})
product = domain_entry.setdefault(PRODUCT, product)
entry.runtime_data = product
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: BleBoxConfigEntry) -> bool:
"""Unload a config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
@@ -1,18 +1,16 @@
"""BleBox binary sensor entities."""
from blebox_uniapi.binary_sensor import BinarySensor as BinarySensorFeature
from blebox_uniapi.box import Box
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, PRODUCT
from . import BleBoxConfigEntry
from .entity import BleBoxEntity
BINARY_SENSOR_TYPES = (
@@ -25,15 +23,13 @@ BINARY_SENSOR_TYPES = (
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: BleBoxConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up a BleBox entry."""
product: Box = hass.data[DOMAIN][config_entry.entry_id][PRODUCT]
entities = [
BleBoxBinarySensorEntity(feature, description)
for feature in product.features.get("binary_sensors", [])
for feature in config_entry.runtime_data.features.get("binary_sensors", [])
for description in BINARY_SENSOR_TYPES
if description.key == feature.device_class
]
+4 -7
View File
@@ -2,28 +2,25 @@
from __future__ import annotations
from blebox_uniapi.box import Box
import blebox_uniapi.button
from homeassistant.components.button import ButtonEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, PRODUCT
from . import BleBoxConfigEntry
from .entity import BleBoxEntity
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: BleBoxConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up a BleBox button entry."""
product: Box = hass.data[DOMAIN][config_entry.entry_id][PRODUCT]
entities = [
BleBoxButtonEntity(feature) for feature in product.features.get("buttons", [])
BleBoxButtonEntity(feature)
for feature in config_entry.runtime_data.features.get("buttons", [])
]
async_add_entities(entities, True)
+4 -7
View File
@@ -3,7 +3,6 @@
from datetime import timedelta
from typing import Any
from blebox_uniapi.box import Box
import blebox_uniapi.climate
from homeassistant.components.climate import (
@@ -12,12 +11,11 @@ from homeassistant.components.climate import (
HVACAction,
HVACMode,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, PRODUCT
from . import BleBoxConfigEntry
from .entity import BleBoxEntity
SCAN_INTERVAL = timedelta(seconds=5)
@@ -39,14 +37,13 @@ BLEBOX_TO_HVACACTION = {
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: BleBoxConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up a BleBox climate entity."""
product: Box = hass.data[DOMAIN][config_entry.entry_id][PRODUCT]
entities = [
BleBoxClimateEntity(feature) for feature in product.features.get("climates", [])
BleBoxClimateEntity(feature)
for feature in config_entry.runtime_data.features.get("climates", [])
]
async_add_entities(entities, True)

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